import xml.etree.ElementTree as ET # === Словарь соответствия типов XML → DebugVarType_t === type_map = dict([ *[(k, 'pt_int8') for k in ('signed char', 'char')], *[(k, 'pt_int16') for k in ('int', 'int16', 'short')], *[(k, 'pt_int32') for k in ('long', 'int32', '_iqx')], *[(k, 'pt_int64') for k in ('long long', 'int64')], *[(k, 'pt_uint8') for k in ('unsigned char',)], *[(k, 'pt_uint16') for k in ('unsigned int', 'unsigned short', 'Uint16')], *[(k, 'pt_uint32') for k in ('unsigned long', 'Uint32')], *[(k, 'pt_uint64') for k in ('unsigned long long', 'Uint64')], *[(k, 'pt_ptr_int8') for k in ('signed char*',)], *[(k, 'pt_ptr_int16') for k in ('int*', 'short*')], *[(k, 'pt_ptr_int32') for k in ('long*',)], *[(k, 'pt_ptr_uint8') for k in ('unsigned char*',)], *[(k, 'pt_ptr_uint16') for k in ('unsigned int*', 'unsigned short*')], *[(k, 'pt_ptr_uint32') for k in ('unsigned long*',)], ('unsigned long long*', 'pt_int64'), *[(k, 'pt_arr_int8') for k in ('signed char[]',)], *[(k, 'pt_arr_int16') for k in ('int[]', 'short[]')], *[(k, 'pt_arr_int32') for k in ('long[]',)], *[(k, 'pt_arr_uint8') for k in ('unsigned char[]',)], *[(k, 'pt_arr_uint16') for k in ('unsigned int[]', 'unsigned short[]')], *[(k, 'pt_arr_uint32') for k in ('unsigned long[]',)], *[(k, 'pt_float') for k in ('float', 'float32')], ('struct', 'pt_struct'), ('union', 'pt_union'), ]) def is_anonymous(elem): typ = elem.attrib.get('type', '') return 'anonymous' in typ def get_array_sizes(elem): sizes = [] i = 0 while True: attr = 'size' if i == 0 else f'size{i}' if attr in elem.attrib: sizes.append(elem.attrib[attr]) i += 1 else: break return ''.join(f'[{size}]' for size in sizes) def collect_externs_and_vars(element, prefix, extern_vars, variables): kind = element.attrib.get('kind', '') name = element.attrib.get('name', prefix) vtype = element.attrib.get('type', 'unknown') # Пропускаем анонимные типы полностью if is_anonymous(element): return # Для массивов учитываем все размеры size, size1, size2... if kind == 'array': array_dims = get_array_sizes(element) extern_type = vtype # тип без размеров extern_vars[name] = (extern_type, array_dims) variables.append((name, vtype)) # В массив макросов кладём сам массив (без элементов) return # Для обычных структур (не анонимных) и переменных if kind in ('struct', 'union'): extern_vars[name] = (vtype, '') variables.append((name, vtype)) return # Простые переменные extern_vars[name] = (vtype, '') variables.append((name, vtype)) def parse_variables(xml_path): tree = ET.parse(xml_path) root = tree.getroot() extern_vars = dict() variables = [] for var in root.findall('variable'): collect_externs_and_vars(var, var.attrib['name'], extern_vars, variables) return variables, extern_vars def format_extern_declaration(varname, vartype, dims): base_type = vartype.replace('[]', '') # убираем [] из типа return f"extern {base_type} {varname}{dims};" def to_macro_entry(varname, vartype): # pt_ и t_iq_none — пример, замените на вашу логику или словарь ptr_type = type_map.get(vartype) if ptr_type is None: ptr_type = 'char *' iq_type = "t_iq_none" return f"\t{{(char *)&{varname:<40}, {ptr_type:<20}, {iq_type:<20}, \"{varname}\"}}," def generate_code(variables, extern_vars): # extern-блок extern_lines = [] for var, (vtype, dims) in sorted(extern_vars.items()): # фильтр анонимных структур по имени (пример) if "anonymous" in var: continue extern_lines.append(format_extern_declaration(var, vtype, dims)) # define DebugVar_Numb debugvar_numb = len(variables) defines = [f"#define DebugVar_Numb\t{debugvar_numb}"] # define DebugVar_Init defines.append("#define DebugVar_Init\t\\") defines.append("{\\") for varname, vartype in variables: defines.append(to_macro_entry(varname, vartype)) defines.append("}") return "\n".join(extern_lines) + "\n\n" + "\n".join(defines) if __name__ == "__main__": xml_file = "F:/Work/Projects/TMS/TMS_new_bus/bin/New_bus_allVars.xml" variables, extern_vars = parse_variables(xml_file) code = generate_code(variables, extern_vars) with open("debug_vars.h", "w") as f: f.write(code) print("Сгенерировано в debug_vars.h")