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