mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 16:56:42 +08:00
Merge 33f45c978d44067ff8513f653aee85a9cb99f920 into 520d8ee39037c9c94aa6e708a4fd6c0fa313ae80
This commit is contained in:
commit
843802a304
158
script/make_macros_py3.py
Normal file
158
script/make_macros_py3.py
Normal file
@ -0,0 +1,158 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
# This file is based on script/make_macros.py and updated for Python3.
|
||||
|
||||
# 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.
|
||||
|
||||
# You only need this script if you are developing enum.h, or run into a limit.
|
||||
#
|
||||
# This script generates the macros BETTER_ENUMS_PP_MAP and BETTER_ENUMS_ITERATE,
|
||||
# used internally by enum.h. These are already inlined into enum.h.
|
||||
#
|
||||
# BETTER_ENUMS_PP_MAP has a limit, which determines the maximum number of
|
||||
# constants an enum can have. By default, this limit is 64 constants.
|
||||
#
|
||||
# BETTER_ENUMS_ITERATE also has a limit. This one determines the maximum length
|
||||
# of the name of a constant that is followed by an initializer (" = 2") when
|
||||
# compiling an enum with constexpr _to_string function (i.e. usually, this limit
|
||||
# does not apply). By default, the limit is 23 characters (24 with the
|
||||
# obligatory null terminator).
|
||||
#
|
||||
# If either of these limits is inadequate, you can still compile your code
|
||||
# without changing enum.h. You need to generate an external macro file with
|
||||
# definitions of these macros with relaxed limits, and tell enum.h to use the
|
||||
# external macro file. Here is how this is done, supposing you want support for
|
||||
# 512 constants of length up to 127 (128 with null terminator):
|
||||
#
|
||||
# 0. MACRO_FILE is the name of the external macro file. Make sure you put it
|
||||
# somewhere in your include path.
|
||||
# 1. Run python make_macros.py 512 128 > MACRO_FILE
|
||||
# 2. Build your code with an additional compiler flag:
|
||||
# - for gcc and clang, -DBETTER_ENUMS_MACRO_FILE='<MACRO_FILE>'
|
||||
# - for VC++, /DBETTER_ENUMS_MACRO_FILE='<MACRO_FILE>'
|
||||
# or use any other method of getting these macros defined.
|
||||
# 3. Compile your code. Your macro file should be included, and enum.h should
|
||||
# happily work with whatever limits you chose.
|
||||
|
||||
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._columns_left - 1) + '\\', file=self._stream)
|
||||
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 fprint(stream, *args):
|
||||
fline = " ".join(map(str, args))
|
||||
stream.write(fline + "\n")
|
||||
|
||||
def generate(stream, constants, length, script):
|
||||
fprint(stream, '// This file was automatically generated by ' + script)
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#pragma once')
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#ifndef BETTER_ENUMS_MACRO_FILE_H')
|
||||
fprint(stream, '#define BETTER_ENUMS_MACRO_FILE_H')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#define BETTER_ENUMS_PP_MAP(macro, data, ...) \\')
|
||||
fprint(stream, ' BETTER_ENUMS_ID( \\')
|
||||
fprint(stream, ' BETTER_ENUMS_APPLY( \\')
|
||||
fprint(stream, ' BETTER_ENUMS_PP_MAP_VAR_COUNT, \\')
|
||||
fprint(stream, ' BETTER_ENUMS_PP_COUNT(__VA_ARGS__)) \\')
|
||||
fprint(stream, ' (macro, data, __VA_ARGS__))')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#define BETTER_ENUMS_PP_MAP_VAR_COUNT(count) ' + \
|
||||
'BETTER_ENUMS_M ## count')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#define BETTER_ENUMS_APPLY(macro, ...) ' + \
|
||||
'BETTER_ENUMS_ID(macro(__VA_ARGS__))')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#define BETTER_ENUMS_ID(x) x')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#define BETTER_ENUMS_M1(m, d, x) m(d,0,x)')
|
||||
for index in range(2, constants + 1):
|
||||
fprint(stream, '#define BETTER_ENUMS_M' + str(index) + \
|
||||
'(m,d,x,...) m(d,' + str(index - 1) + ',x) \\')
|
||||
fprint(stream, ' BETTER_ENUMS_ID(BETTER_ENUMS_M' + \
|
||||
str(index - 1) + '(m,d,__VA_ARGS__))')
|
||||
|
||||
fprint(stream, '')
|
||||
pp_count_impl_prefix = '#define BETTER_ENUMS_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, constants + 1):
|
||||
pp_count_impl.write(' _' + str(index) + ',')
|
||||
pp_count_impl.write(' count,')
|
||||
pp_count_impl.write(' ...)')
|
||||
pp_count_impl.write(' count', last = True)
|
||||
fprint(stream, '')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#define BETTER_ENUMS_PP_COUNT(...) \\')
|
||||
pp_count_prefix = \
|
||||
' BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT_IMPL(__VA_ARGS__,'
|
||||
stream.write(pp_count_prefix)
|
||||
pp_count = MultiLine(stream = stream, indent = 8,
|
||||
initial_column = len(pp_count_prefix))
|
||||
for index in range(0, constants - 1):
|
||||
pp_count.write(' ' + str(constants - index) + ',')
|
||||
pp_count.write(' 1))', last = True)
|
||||
fprint(stream, '')
|
||||
|
||||
fprint(stream, '')
|
||||
iterate_prefix = '#define BETTER_ENUMS_ITERATE(X, f, l)'
|
||||
stream.write(iterate_prefix)
|
||||
iterate = MultiLine(stream = stream, indent = 4,
|
||||
initial_column = len(iterate_prefix))
|
||||
for index in range(0, length):
|
||||
iterate.write(' X(f, l, %i)' % index)
|
||||
fprint(stream, '')
|
||||
|
||||
fprint(stream, '')
|
||||
fprint(stream, '#endif // #ifndef BETTER_ENUMS_MACRO_FILE_H')
|
||||
|
||||
def print_err(*args):
|
||||
err_msg= " ".join(str(arg) for arg in args)
|
||||
sys.stderr.write(err_msg + "\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print_err('Usage: ' + sys.argv[0] + ' CONSTANTS LENGTH > FILE')
|
||||
print_err("")
|
||||
print_err("Prints map macro definition to FILE.")
|
||||
print_err("CONSTANTS is the number of constants to support.")
|
||||
print_err("LENGTH is the maximum length of a constant name.")
|
||||
sys.exit(1)
|
||||
|
||||
generate(sys.stdout, int(sys.argv[1]), int(sys.argv[2]),
|
||||
os.path.basename(sys.argv[0]))
|
||||
|
||||
sys.exit(0)
|
||||
Loading…
x
Reference in New Issue
Block a user