mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 16:56:42 +08:00
122 lines
4.4 KiB
Python
Executable File
122 lines
4.4 KiB
Python
Executable File
#! /usr/bin/env python
|
|
|
|
# This file is part of Better Enums, released under the BSD 2-clause license.
|
|
# See LICENSE for details, or visit http://github.com/aantron/better-enums.
|
|
|
|
# This script generates the macro _ENUM_PP_MAP, used internally by enum.h.
|
|
#
|
|
# _ENUM_PP_MAP has a size limit. By default, it is 256 arguments, so enum.h can
|
|
# support enumerations with at most 256 constants. If you have a larger enum,
|
|
# you can create a replacement _ENUM_PP_MAP macro as follows:
|
|
#
|
|
# 0. MACRO_FILE is the name of a file for the replacement macro you will create.
|
|
# 1. Run python pp_map_gen.py MACRO_FILE 512
|
|
# 2. Make sure MACRO_FILE is somewhere in your include path.
|
|
# 3. Build your files with an additional compiler flag:
|
|
# - for gcc and clang, -DBETTER_ENUM_PP_MAP_FILE='<MACRO_FILE>'
|
|
# - for VC++, /DBETTER_ENUM_PP_MAP_FILE='<MACRO_FILE>'
|
|
# or use any other method of getting these macros declared.
|
|
# 4. Compile your code as before. enum.h should now include your replacement
|
|
# macro file.
|
|
|
|
import os
|
|
import sys
|
|
|
|
class MultiLine(object):
|
|
def __init__(self, stream, indent = 4, columns = 80, initial_column = 0):
|
|
self._columns_left = columns - initial_column
|
|
self._indent = indent
|
|
self._columns = columns
|
|
self._stream = stream
|
|
|
|
def write(self, token, last = False):
|
|
break_line = False
|
|
if last:
|
|
if len(token) > self._columns_left:
|
|
break_line = True
|
|
else:
|
|
if len(token) > self._columns_left - 1:
|
|
break_line = True
|
|
|
|
if break_line:
|
|
print >> self._stream, ' ' * (self._columns_left - 1) + '\\'
|
|
self._stream.write(' ' * self._indent)
|
|
self._columns_left = self._columns - self._indent
|
|
token = token.lstrip()
|
|
|
|
self._stream.write(token)
|
|
self._columns_left -= len(token)
|
|
|
|
def generate(stream, filename, count, script):
|
|
print >> stream, '// This file was automatically generated by ' + script
|
|
|
|
print >> stream, ''
|
|
print >> stream, '#pragma once'
|
|
print >> stream, ''
|
|
print >> stream, '#ifndef _BETTER_ENUM_ENUM_PREPROCESSOR_MAP_H_'
|
|
print >> stream, '#define _BETTER_ENUM_ENUM_PREPROCESSOR_MAP_H_'
|
|
|
|
print >> stream, ''
|
|
print >> stream, '#define _ENUM_PP_MAP(macro, data, ...) \\'
|
|
print >> stream, ' _ENUM_A(_ENUM_PP_MAP_VAR_COUNT, ' + \
|
|
'_ENUM_PP_COUNT(__VA_ARGS__)) \\'
|
|
print >> stream, ' (macro, data, __VA_ARGS__)'
|
|
|
|
print >> stream, ''
|
|
print >> stream, '#define _ENUM_PP_MAP_VAR_COUNT(count) ' + \
|
|
'_ENUM_M ## count'
|
|
|
|
print >> stream, ''
|
|
print >> stream, '#define _ENUM_A(macro, ...) macro(__VA_ARGS__)'
|
|
|
|
print >> stream, ''
|
|
print >> stream, '#define _ENUM_M1(m, d, x) _ENUM_A(m, d, x)'
|
|
for index in range(2, count + 1):
|
|
print >> stream, '#define _ENUM_M' + str(index) + \
|
|
'(m, d, x, ...) _ENUM_A(m, d, x), ' + \
|
|
'_ENUM_M' + str(index - 1) + \
|
|
'(m, d, __VA_ARGS__)'
|
|
|
|
print >> stream, ''
|
|
pp_count_impl_prefix = '#define _ENUM_PP_COUNT_IMPL(_1,'
|
|
stream.write(pp_count_impl_prefix)
|
|
pp_count_impl = MultiLine(stream = stream, indent = 4,
|
|
initial_column = len(pp_count_impl_prefix))
|
|
for index in range(2, count + 1):
|
|
pp_count_impl.write(' _' + str(index) + ',')
|
|
pp_count_impl.write(' count,')
|
|
pp_count_impl.write(' ...)')
|
|
pp_count_impl.write(' count', last = True)
|
|
print >> stream, ''
|
|
|
|
print >> stream, ''
|
|
pp_count_prefix = \
|
|
'#define _ENUM_PP_COUNT(...) _ENUM_PP_COUNT_IMPL(__VA_ARGS__,'
|
|
stream.write(pp_count_prefix)
|
|
pp_count = MultiLine(stream = stream, indent = 4,
|
|
initial_column = len(pp_count_prefix))
|
|
for index in range(0, count - 1):
|
|
pp_count.write(' ' + str(count - index) + ',')
|
|
pp_count.write(' 1)', last = True)
|
|
print >> stream, ''
|
|
|
|
print >> stream, ''
|
|
print >> stream, '#endif // #ifndef _BETTER_ENUM_ENUM_PREPROCESSOR_MAP_H_'
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) != 3:
|
|
print >> sys.stderr, 'Usage: ' + sys.argv[0] + ' FILE COUNT'
|
|
print >> sys.stderr, ''
|
|
print >> sys.stderr, 'Prints map macro definition to FILE.'
|
|
sys.exit(1)
|
|
|
|
output_file = open(sys.argv[1], "w")
|
|
|
|
try:
|
|
generate(output_file, sys.argv[1], int(sys.argv[2]),
|
|
os.path.basename(sys.argv[0]))
|
|
finally:
|
|
output_file.close()
|
|
|
|
sys.exit(0)
|