diff options
Diffstat (limited to 'Build/source/utils/asymptote/generate_enums.py')
-rwxr-xr-x | Build/source/utils/asymptote/generate_enums.py | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/generate_enums.py b/Build/source/utils/asymptote/generate_enums.py new file mode 100755 index 00000000000..07f2d772318 --- /dev/null +++ b/Build/source/utils/asymptote/generate_enums.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 + +# A script to generate enums in different languages from a CSV file. +# A CSV File contains +# enum1, 0 +# enum2, .. +# ... +# enumn, n +# where 0,...,n are numbers. +# +# Written by Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com> + +from typing import List, Tuple, Any, Union +from datetime import datetime +import io +import argparse +import sys +import re + +def cleanComment(s): + return re.sub(r' *#',' ',s) + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-language', '--language', type=str, required=True) + parser.add_argument('-o', '--output', type=str, required=True) + parser.add_argument('-i', '--input', type=str, required=True) + parser.add_argument('-name', '--name', type=str, required=True) + parser.add_argument('-xopt', '--xopt', type=str, nargs='*') + return parser.parse_args() + + +def create_enums(filename: str) -> List[Union[Tuple[str, int, str], Tuple[str, int]]]: + final_list=[] + with io.open(filename,newline='') as rawfile: + for line in rawfile.readlines(): + if line.startswith('#') or line.strip() == '': + continue + raw_line=line.strip().split(',') + raw_str, raw_number=raw_line[0:2] + comment=None + if len(raw_line)>=3: + comment=raw_line[-1] + final_list.append((raw_str.strip(), int(raw_number.strip()),comment)) + else: + final_list.append((raw_str.strip(), int(raw_number.strip()))) + return final_list + + +def generate_enum_cpp(outname, enums, name, comment=None, *args, **kwargs): + with io.open(outname, 'w') as fil: + fil.write('// Enum class for {0}\n'.format(name)) + if comment is not None: + fil.write('// {0}\n'.format(comment)) + fil.write('// Generated at {0}\n\n'.format(datetime.now())) + if 'namespace' in kwargs: + fil.write('namespace {0}\n'.format(kwargs['namespace'])) + fil.write('{\n') + + fil.write('enum {0} : uint32_t\n'.format(name)) + fil.write('{\n') + + for enumTxt, enumNum, *ar in enums: + fil.write('{0}={1},\n'.format(enumTxt, enumNum)) + if len(ar) > 0: + comment=cleanComment(ar[-1]) + if comment is not None: + fil.write('// {0}\n\n'.format(comment.strip())) + + fil.write('};\n\n') + + if 'namespace' in kwargs: + fil.write('}} // namespace {0}\n'.format(kwargs['namespace'])) + fil.write('// End of File\n') + + +def generate_enum_java(outname, enums, name, comment=None, *args, **kwargs): + with io.open(outname, 'w') as fil: + fil.write('// Enum class for {0}\n'.format(name)) + if comment is not None: + fil.write('// {0}\n'.format(comment)) + fil.write('// Generated at {0}\n\n'.format(datetime.now())) + + if 'package' in kwargs: + fil.write('package {0};\n'.format(kwargs['package'])) + fil.write('\n') + + fil.write('public enum {0} {{\n'.format(name)) + + spaces = kwargs.get('spaces', 4) + spaces_tab=' '*spaces + + for i in range(len(enums)): + enumTxt, enumNum, *ar = enums[i] + endsep=',' if i < len(enums) - 1 else ';' + fil.write('{2}{0}({1}){3}\n'.format(enumTxt,enumNum,spaces_tab,endsep)) + if len(ar) > 0: + comment=cleanComment(ar[-1]) + if comment is not None: + fil.write('// {0}\n\n'.format(comment.strip())) + + out_lines=[ + '', + '{0}(int value) {{'.format(name), + '{0}this.value=value;'.format(spaces_tab), + '}', + 'public String toString() {', + '{0}return Integer.toString(value);'.format(spaces_tab), + '}', + 'private int value;'] + + for line in out_lines: + fil.write(spaces_tab) + fil.write(line) + fil.write('\n') + fil.write('};\n\n') + fil.write('// End of File\n') + + +def generate_enum_asy(outname, enums, name, comment=None, *args, **kwargs): + with io.open(outname, 'w') as fil: + fil.write('// Enum class for {0}\n'.format(name)) + if comment is not None: + fil.write('// {0}\n'.format(comment)) + fil.write('// Generated at {0}\n\n'.format(datetime.now())) + + fil.write('struct {0}\n'.format(name)) + fil.write('{\n') + + for enumTxt, enumNum, *ar in enums: + fil.write(' int {0}={1};\n'.format(enumTxt, enumNum)) + if len(ar) > 0: + comment=cleanComment(ar[-1]) + if comment is not None: + fil.write('// {0}\n\n'.format(comment.strip())) + fil.write('};\n\n') + fil.write('{0} {0};'.format(name)) + + fil.write('// End of File\n') + + +def generate_enum_py(outname, enums, name, comment=None, *args, **kwargs): + with io.open(outname, 'w') as fil: + fil.write('#!/usr/bin/env python3\n') + fil.write('# Enum class for {0}\n'.format(name)) + if comment is not None: + fil.write('""" {0} """\n'.format(comment)) + fil.write('# Generated at {0}\n\n'.format(datetime.now())) + fil.write('class {0}:\n'.format(name)) + for enumTxt, enumNum, *ar in enums: + fil.write(' {0}_{2}={1}\n'.format(name, enumNum, enumTxt)) + if len(ar) > 0: + comment=cleanComment(ar[-1]) + if comment is not None: + fil.write(' # {0}\n\n'.format(comment.strip())) + fil.write('# End of File\n') + + +def main(): + arg = parse_args() + if arg.language in {'python', 'py'}: + fn = generate_enum_py + elif arg.language in {'cxx', 'c++', 'cpp'}: + fn = generate_enum_cpp + elif arg.language in {'asy', 'asymptote'}: + fn = generate_enum_asy + elif arg.language in {'java'}: + fn = generate_enum_java + else: + return 1 + + custom_args = dict() + if arg.xopt is not None: + for xopt in arg.xopt: + key, val = xopt.split('=') + custom_args[key] = val + + enums = create_enums(arg.input) + fn(arg.output, enums, arg.name, 'AUTO-GENERATED from '+arg.input, **custom_args) + + +if __name__ == '__main__': + sys.exit(main() or 0) |