forked from Dentosal/python-sc2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate_id_constants.py
69 lines (53 loc) · 2.2 KB
/
generate_id_constants.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from pathlib import Path
import re
import requests
HEADER = f"# DO NOT EDIT!\n# This file was automatically generated by \"{__file__}\"\n"
PREFIXES = ["Protoss", "Terran", "Zerg", "Neutral", "Effect"]
def clike_enum_parse(code):
# remove comments etc.
code = re.sub(r"#[^\n]*\n", "", code, flags=re.DOTALL)
code = re.sub(r"//[^\n]+\n", "", code, flags=re.DOTALL)
code = re.sub(r"/\*.*?\*/", "", code, flags=re.DOTALL)
# normalize whitespace
code = re.sub(r"\s+", " ", code)
# parse enum blocks
enums = {}
for enum in re.findall(r"enum(?: class)? ([a-zA-Z_][a-zA-Z0-9_]*) {\s?(.+?)\s?}", code):
name, body = enum
body = {key: int(value) for key, value in re.findall(r"([a-zA-Z_][a-zA-Z0-9_]*) = (\d+),?\s?", body)}
enums[name] = body
return enums
def generate_python_code(enums):
assert {"UNIT_TYPEID", "ABILITY_ID", "UPGRADE_ID", "BUFF_ID"} <= enums.keys()
sc2dir = Path("sc2/")
idsdir = (sc2dir / "ids")
idsdir.mkdir(exist_ok=True)
with (idsdir / "__init__.py").open("w") as f:
f.write("\n".join([
HEADER,
f"__all__ = {[n.lower() for n in enums.keys()] !r}\n"
]))
for name, body in enums.items():
class_name = "".join(p.capitalize() for p in name.split("_")).replace("Typeid", "TypeId")
code = [
HEADER,
"import enum",
"",
f"class {class_name}(enum.Enum):"
]
for key, value in sorted(body.items(), key=lambda p: p[1]):
# Unprefixed alternative names for structures
if any(key.startswith(p.upper()+"_") for p in PREFIXES):
code.append(f" {key.split('_',1)[1]} = {value}")
code.append(f" {key} = {value}")
code += [
"",
f"for item in {class_name}:",
f" globals()[item.name] = item",
""
]
with (idsdir / name.lower()).with_suffix(".py").open("w") as f:
f.write("\n".join(code))
if __name__ == '__main__':
r = requests.get("https://raw.githubusercontent.com/Blizzard/s2client-api/master/include/sc2api/sc2_typeenums.h")
code = generate_python_code(clike_enum_parse(r.text))