143 lines
4.8 KiB
Python
143 lines
4.8 KiB
Python
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") |