from dataclasses import dataclass from pprint import pprint import sys import csv from generate import renderer _field_types = { "parameter_control_word": "uint32_t", "user_clip_": "uint32_t", "object_pointer": "uint32_t", "bounding_box_": "uint32_t", "isp_tsp_instruction_word": "uint32_t", "tsp_instruction_word": "uint32_t", "texture_control_word": "uint32_t", "data_size_for_sort_dma": "uint32_t", "next_address_for_sort_dma": "uint32_t", "face_color_": "float", "face_offset_color_": "float", "x": "float", "y": "float", "z": "float", "base_color_": "float", "base_intensity_": "float", "u": "float", "v": "float", "u_v": "uint32_t", "base_color": "uint32_t", "offset_color": "uint32_t", "offset_color_": "float", "base_intensity": "float", "offset_intensity": "float", "a_": "float", "b_": "float", "c_": "float", "d_": "float", "a_u_a_v": "uint32_t", "b_u_b_v": "uint32_t", "c_u_c_v": "uint32_t", } def get_type(field_name: str): match = None match_len = 0 for name, type in _field_types.items(): if field_name.startswith(type) and len(name) >= match_len: match = type assert match_len != len(name), (name, match) match_len = len(name) assert match != None, field_name return match class EndOfInput(Exception): pass def next_row(ix, rows, advance): if ix >= len(rows): raise EndOfInput if advance: while rows[ix][0] == "": ix += 1 if ix >= len(rows): raise EndOfInput row = rows[ix] ix += 1 return ix, row @dataclass class FieldDeclaration: offset: int name: str @dataclass class StructDeclaration: name: str fields: list[FieldDeclaration] def parse_type_declaration(ix, rows): ix, row = next_row(ix, rows, advance=True) assert len(row) == 2, row struct_name, empty = row assert empty == "", row fields = [] last_offset = -4 while True: ix, row = next_row(ix, rows, advance=False) if row[0] == "": assert last_offset + 4 == 32 or last_offset + 4 == 64, last_offset + 4 return ix, StructDeclaration( struct_name, fields ) else: assert len(row) == 2, row _offset, name = row offset = int(_offset, 16) assert offset == last_offset + 4, (hex(offset), hex(last_offset)) last_offset = offset fields.append(FieldDeclaration(offset, name)) def parse(rows): ix = 0 declarations = [] while True: try: ix, declaration = parse_type_declaration(ix, rows) except EndOfInput: break declarations.append(declaration) return declarations def render_declaration(declaration): yield f"struct {declaration.name} {{" for field in declaration.fields: yield f"" yield "};" def render_declarations(namespace, declarations): yield f"namespace {namespace} {{" for declaration in declarations: yield from render_declaration(declaration) yield "" yield "}" def read_input(filename): with open(filename) as f: reader = csv.reader(f, delimiter=",", quotechar='"') rows = [ [s.strip() for s in row] for row in reader ] return rows if __name__ == "__main__": rows = read_input(sys.argv[1]) namespace = sys.argv[2] declarations = parse(rows) render, out = renderer() render(render_declarations(namespace, declarations)) print(out.getvalue())