1#! /usr/bin/env python3 2# This script generates Modules/_sre/sre_constants.h from Lib/re/_constants.py. 3 4SCRIPT_NAME = 'Tools/build/generate_sre_constants.py' 5 6 7def update_file(file, content): 8 try: 9 with open(file, 'r') as fobj: 10 if fobj.read() == content: 11 return False 12 except (OSError, ValueError): 13 pass 14 with open(file, 'w') as fobj: 15 fobj.write(content) 16 return True 17 18sre_constants_header = f"""\ 19/* 20 * Secret Labs' Regular Expression Engine 21 * 22 * regular expression matching engine 23 * 24 * Auto-generated by {SCRIPT_NAME} from 25 * Lib/re/_constants.py. 26 * 27 * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. 28 * 29 * See the sre.c file for information on usage and redistribution. 30 */ 31 32""" 33 34def main( 35 infile="Lib/re/_constants.py", 36 outfile_constants="Modules/_sre/sre_constants.h", 37 outfile_targets="Modules/_sre/sre_targets.h", 38): 39 ns = {} 40 with open(infile) as fp: 41 code = fp.read() 42 exec(code, ns) 43 44 def dump(d, prefix): 45 items = sorted(d) 46 for item in items: 47 yield "#define %s_%s %d\n" % (prefix, item, item) 48 49 def dump2(d, prefix): 50 items = [(value, name) for name, value in d.items() 51 if name.startswith(prefix)] 52 for value, name in sorted(items): 53 yield "#define %s %d\n" % (name, value) 54 55 def dump_gotos(d, prefix): 56 for i, item in enumerate(sorted(d)): 57 assert i == item 58 yield f" &&{prefix}_{item},\n" 59 60 content = [sre_constants_header] 61 content.append("#define SRE_MAGIC %d\n" % ns["MAGIC"]) 62 content.extend(dump(ns["OPCODES"], "SRE_OP")) 63 content.extend(dump(ns["ATCODES"], "SRE")) 64 content.extend(dump(ns["CHCODES"], "SRE")) 65 content.extend(dump2(ns, "SRE_FLAG_")) 66 content.extend(dump2(ns, "SRE_INFO_")) 67 68 update_file(outfile_constants, ''.join(content)) 69 70 content = [sre_constants_header] 71 content.append(f"static void *sre_targets[{len(ns['OPCODES'])}] = {{\n") 72 content.extend(dump_gotos(ns["OPCODES"], "TARGET_SRE_OP")) 73 content.append("};\n") 74 75 update_file(outfile_targets, ''.join(content)) 76 77 78if __name__ == '__main__': 79 import sys 80 main(*sys.argv[1:]) 81