diff options
author | Bob Halley <halley@dnspython.org> | 2020-08-03 06:35:22 -0700 |
---|---|---|
committer | Bob Halley <halley@dnspython.org> | 2020-08-03 06:35:22 -0700 |
commit | 82bc428366df9694ce0b4cfb7d4503e9d0c38248 (patch) | |
tree | 5bd8e9641f2d229f998fffc7436bb291e17e1d7b /util/constants-tool | |
parent | 049eedd8ab25f211d0fcd88726098327cc27ddb2 (diff) | |
download | dnspython-82bc428366df9694ce0b4cfb7d4503e9d0c38248.tar.gz |
add constants
Diffstat (limited to 'util/constants-tool')
-rwxr-xr-x | util/constants-tool | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/util/constants-tool b/util/constants-tool new file mode 100755 index 0000000..baf54b6 --- /dev/null +++ b/util/constants-tool @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 + +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +from importlib import import_module +import os +import sys + +enum_names = [ + 'dns.dnssec.Algorithm', + 'dns.edns.OptionType', + 'dns.flags.Flag', + 'dns.flags.EDNSFlag', + 'dns.message.MessageSection', + 'dns.opcode.Opcode', + 'dns.rcode.Rcode', + 'dns.rdataclass.RdataClass', + 'dns.rdatatype.RdataType', + 'dns.rdtypes.dnskeybase.Flag', + 'dns.update.UpdateSection', +] + +def generate(): + for enum_name in enum_names: + dot = enum_name.rindex('.') + module_name = enum_name[:dot] + type_name = enum_name[dot + 1:] + mod = import_module(module_name) + enum = getattr(mod, type_name) + filename = module_name.replace('.', '/') + '.py' + new_filename = filename + '.new' + with open(filename) as f: + with open(new_filename, 'w') as nf: + lines = f.readlines() + found = False + i = 0 + length = len(lines) + while i < length: + l = lines[i].rstrip() + i += 1 + if l.startswith(f'### BEGIN generated {type_name} ' + + 'constants'): + found = True + break + else: + print(l, file=nf) + if found: + found = False + while i < length: + l = lines[i].rstrip() + i += 1 + if l.startswith(f'### END generated {type_name} ' + + 'constants'): + found = True + break + if not found: + print(f'Found begin marker for {type_name} but did ' + + 'not find end marker!', file=sys.stderr) + sys.exit(1) + if not found: + print('', file=nf) + print(f'### BEGIN generated {type_name} constants', file=nf) + print('', file=nf) + # We have to use __members__.items() and not "in enum" because + # otherwise we miss values that have multiple names (e.g. NONE + # and TYPE0 for rdatatypes). + for name, value in enum.__members__.items(): + print(f'{name} = {type_name}.{name}', file=nf) + print('', file=nf) + print(f'### END generated {type_name} constants', file=nf) + # Copy remaining lines (if any) + while i < length: + l = lines[i].rstrip() + i += 1 + print(l, file=nf) + os.rename(new_filename, filename) + +def check(): + ok = True + for enum_name in enum_names: + dot = enum_name.rindex('.') + module_name = enum_name[:dot] + type_name = enum_name[dot + 1:] + mod = import_module(module_name) + enum = getattr(mod, type_name) + for name, value in enum.__members__.items(): + try: + if value != getattr(mod, name): + ok = False + print(f'{name} != {value}', file=sys.stderr) + except Exception: + ok = False + print('exception checking', name, file=sys.stderr) + return ok + +def usage(): + print('usage: constants-tool [generate|check]', file=sys.stderr) + sys.exit(1) + +def main(): + if len(sys.argv) < 2: + usage() + if sys.argv[1] == 'generate': + generate() + elif sys.argv[1] == 'check': + if not check(): + sys.exit(2) + else: + usage() + +if __name__ == '__main__': + main() |