Files
Navmesher/reference/flag_filter.py
2022-10-14 16:23:24 +11:00

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)