115 lines
3.3 KiB
Python
115 lines
3.3 KiB
Python
import re
|
|
import os
|
|
import json
|
|
from dataclasses import dataclass
|
|
|
|
|
|
class Jsonify:
|
|
def encode(self, value=None):
|
|
if not value:
|
|
value = self.__dict__
|
|
return value
|
|
|
|
@dataclass
|
|
class Flag(Jsonify):
|
|
bit: int
|
|
description: str
|
|
|
|
@dataclass
|
|
class Record(Jsonify):
|
|
fourcc: str
|
|
name: str
|
|
flags: list[Flag]
|
|
|
|
|
|
re_flags = re.compile(".*?(\d+?),.*?'(.*)'")
|
|
|
|
|
|
def find_records(data, re_record, re_first):
|
|
found_records = re_record.findall(data)
|
|
|
|
seen = set()
|
|
records = []
|
|
for record in found_records:
|
|
s = record.split('\n')
|
|
[first] = re_first.findall(s[0])
|
|
assert len(first) == 2, "Could not parse first line of record:\n{}".format(record)
|
|
flags = []
|
|
for line in s[2:-1]:
|
|
[f] = re_flags.findall(line)
|
|
assert len(f) == 2, "Could not parse flag definition: {}".format(line)
|
|
desc = f[1].replace("''", "'").replace("', '", "")
|
|
flags += [Flag(int(f[0]), desc)]
|
|
r = Record(first[0], first[1], flags)
|
|
if r.fourcc not in seen:
|
|
records += [r]
|
|
seen.add(r.fourcc)
|
|
|
|
return records
|
|
|
|
|
|
def find_wbRecords(data):
|
|
re_wbRecord = re.compile("wbRecord\(.*?\n.*?wbFlagsList\(\[\n(?:.*?\n)*?.*?\]")
|
|
re_wbRecord_first = re.compile("wbRecord\((\w{4}).*?'(.+?)'.*?")
|
|
return find_records(data, re_wbRecord, re_wbRecord_first)
|
|
|
|
|
|
def find_stat(data):
|
|
re_stat = re.compile("wbRecord\(STAT,.*?\n.*?\n(?:.*?\n)+?.*?]")
|
|
lines = re_stat.findall(data)[0].split('\n')
|
|
|
|
re_stat_first = re.compile("STAT, '(.*?)'")
|
|
[name] = re_stat_first.findall(lines[0])
|
|
|
|
re_stat_flag = re.compile("'(.*?)'")
|
|
flags = []
|
|
for i, line in enumerate(lines[2:-1]):
|
|
[l] = re_stat_flag.findall(line)
|
|
if l:
|
|
flags += [Flag(i, l)]
|
|
|
|
return Record("STAT", name, flags)
|
|
|
|
|
|
def find_concrete_wbRefRecords(data):
|
|
re_wbRefRecord = re.compile("wbRefRecord\(\w{4},.*?\n.*?wbFlagsList\(\[.*?\n(?:.*?\n)+?.*?\]")
|
|
re_wbRefRecord_first = re.compile("wbRefRecord\((\w{4}).*?'(.+?)'.*?")
|
|
return find_records(data, re_wbRefRecord, re_wbRefRecord_first)
|
|
|
|
|
|
def find_ReferenceRecords(data):
|
|
re_ReferenceRecordDef = re.compile("wbRefRecord\(aSignature, .*?\n(?:.*?\n)+?.*?]")
|
|
re_ReferenceRecordDef_first = re.compile("wbRefRecord\((\w+?), (\w+?),")
|
|
[d] = find_records(data, re_ReferenceRecordDef, re_ReferenceRecordDef_first)
|
|
|
|
re_ReferenceRecord = re.compile("ReferenceRecord\((\w{4}), '(.*?)'\);")
|
|
rr = re_ReferenceRecord.findall(data)
|
|
|
|
records = [Record(r[0], r[1], d.flags) for r in rr]
|
|
return records
|
|
|
|
|
|
def find_wbRefRecords(data):
|
|
records = find_concrete_wbRefRecords(data)
|
|
records = find_ReferenceRecords(data)
|
|
return records
|
|
|
|
|
|
fdir = os.path.dirname(__file__)
|
|
with open(os.path.join(fdir, "wbDefinitionsTES5.pas"), "r") as f:
|
|
inp = f.read()
|
|
|
|
records = find_wbRecords(inp) + [find_stat(inp)] + find_wbRefRecords(inp)
|
|
records.sort(key = lambda x: x.fourcc)
|
|
print(len(records))
|
|
|
|
class Encoder(json.JSONEncoder):
|
|
def default(self, obj):
|
|
if isinstance(obj, Jsonify):
|
|
return obj.encode()
|
|
else:
|
|
return json.JSONEncoder.default(self, obj)
|
|
|
|
with open(os.path.join(fdir, "flags.json"), "w") as f:
|
|
json.dump(records, f, cls=Encoder, indent=4)
|