• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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