diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.72.0/scripts/make_option_enum.py')
-rw-r--r-- | debian/uncrustify-trinity/uncrustify-trinity-0.72.0/scripts/make_option_enum.py | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.72.0/scripts/make_option_enum.py b/debian/uncrustify-trinity/uncrustify-trinity-0.72.0/scripts/make_option_enum.py new file mode 100644 index 00000000..c141bb04 --- /dev/null +++ b/debian/uncrustify-trinity/uncrustify-trinity-0.72.0/scripts/make_option_enum.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python + +import argparse +import io +import os +import re + +re_enum_decl = re.compile(r'enum class (\w+)( *// *<(\w+)>)?') +re_enum_value = re.compile(r'(\w+)(?= *([,=]|//|$))') +re_values = re.compile(r'UNC_OPTVALS\((\w+)\)') +re_aliases = re.compile(r'UNC_OPTVAL_ALIAS\(([^)]+)\)') +enums = {} +values = {} + +root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +script = os.path.relpath(__file__, root) + + +# ============================================================================= +class Enumeration(object): + # ------------------------------------------------------------------------- + def __init__(self, name, prefix, f): + self.name = name + self.prefix = prefix + + self.values = [] + self.value_aliases = {} + + self.convert_internal = False + + for line in iter(f.readline, ''): + line = line.strip() + + if line.startswith('{'): + for line in iter(f.readline, ''): + line = line.strip() + if line.startswith('};'): + return + + if 'UNC_INTERNAL' in line: + return + + if 'UNC_CONVERT_INTERNAL' in line: + self.convert_internal = True + continue + + mv = re_enum_value.match(line) + if mv is not None: + v = mv.group(1) + self.values.append(v) + self.value_aliases[v] = [v.lower()] + + # ------------------------------------------------------------------------- + def add_aliases(self, value, *args): + aliases = [x[1:-1] for x in args] # strip quotes + self.value_aliases[value] += aliases + +# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +# ----------------------------------------------------------------------------- +def enum_value(enum, value): + if enum.prefix is not None: + return u'{}_{}'.format(enum.prefix, value) + return value + +# ----------------------------------------------------------------------------- +def write_banner(out, args): + out.write( + u'/**\n' + u' * @file {out_name}\n' + u' * Helpers for option enumerators.\n' + u' * Automatically generated by <code>{script}</code>\n' + u' * from {in_name}.\n' + u' */\n' + u'\n'.format( + in_name=os.path.basename(args.header), + out_name=os.path.basename(args.output), + script=script)) + + +# ----------------------------------------------------------------------------- +def write_value_strings(out, args): + for vn, vs in values.items(): + out.write(u'const char *const {}_values[] = {{\n'.format(vn)) + out.write(u'{}\n nullptr\n}};\n\n'.format( + u'\n'.join([u' "{}",'.format(x.lower()) for x in vs]))) + + +# ----------------------------------------------------------------------------- +def write_aliases(out, args): + for enum in enums.values(): + if enum.prefix is None: + continue + + for v in enum.values: + out.write(u'constexpr auto {p}_{v} = {n}::{v};\n'.format( + p=enum.prefix, n=enum.name, v=v)) + + out.write(u'\n') + + +# ----------------------------------------------------------------------------- +def write_conversions(out, args): + header = u'\n//{}\n'.format('-' * 77) + + for enum in enums.values(): + if enum.convert_internal: + continue + + out.write(header) + out.write( + u'bool convert_string(const char *in, {} &out)\n'.format( + enum.name)) + out.write( + u'{\n' + u' if (false)\n' + u' {\n' + u' }\n') + + for v in enum.values: + for a in enum.value_aliases[v]: + out.write( + u' else if (strcasecmp(in, "{}") == 0)\n' + u' {{\n' + u' out = {};\n' + u' return(true);\n' + u' }}\n'.format(a, enum_value(enum, v))) + + out.write( + u' else\n' + u' {\n' + u' return(false);\n' + u' }\n' + u'}\n\n') + + for enum in enums.values(): + out.write(header) + out.write(u'const char *to_string({} val)\n'.format(enum.name)) + out.write(u'{\n' + u' switch (val)\n' + u' {\n') + + for v in enum.values: + vs = v if enum.convert_internal else v.lower() + out.write( + u' case {}:\n' + u' return "{}";\n\n'.format( + enum_value(enum, v), vs)) + + out.write( + u' default:\n' + u' fprintf(stderr, "%s: Unknown {} \'%d\'\\n",\n' + u' __func__, static_cast<int>(val));\n' + u' log_flush(true);\n' + u' exit(EX_SOFTWARE);\n' + u' }}\n' + u'}}\n\n'.format(enum.name)) + + +# ----------------------------------------------------------------------------- +def main(): + parser = argparse.ArgumentParser(description='Generate options.cpp') + parser.add_argument('output', type=str, + help='location of options.cpp to write') + parser.add_argument('header', type=str, + help='location of options.h to read') + parser.add_argument('template', type=str, + help='location of option_enum.cpp.in ' + 'to use as template') + args = parser.parse_args() + + with io.open(args.header, 'rt', encoding='utf-8') as f: + for line in iter(f.readline, ''): + line = line.strip() + + me = re_enum_decl.match(line) + if me is not None: + e = Enumeration(me.group(1), me.group(3), f) + enums[e.name] = e + continue + + mv = re_values.match(line) + if mv is not None: + enum_name = mv.group(1) + enum = enums['{}_e'.format(enum_name)] + values[enum_name] = enum.values + + ma = re_aliases.match(line) + if ma is not None: + alias_args = [x.strip() for x in ma.group(1).split(',')] + enum = enums[alias_args[0]] + enum.add_aliases(*alias_args[1:]) + + replacements = { + u'##BANNER##': write_banner, + u'##VALUE_STRINGS##': write_value_strings, + u'##ALIASES##': write_aliases, + u'##CONVERSIONS##': write_conversions, + } + + with io.open(args.output, 'wt', encoding='utf-8') as out: + with io.open(args.template, 'rt', encoding='utf-8') as t: + for line in t: + directive = line.strip() + if directive in replacements: + replacements[directive](out, args) + else: + out.write(line) + + +# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +if __name__ == '__main__': + main() |