113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
import os
|
|
import time
|
|
from jinja2 import Environment, FileSystemLoader
|
|
import re
|
|
|
|
import filechecksum as fcs
|
|
|
|
# Pfad zur Eingabedatei und Ausgabedatei
|
|
input_file = "include/config.h"
|
|
output_sourcefile = "src/struct2json.cpp"
|
|
output_headerfile = "include/struct2json.h"
|
|
# Liste der zu suchenden Variablen/Structs
|
|
variable_names = ['LubeConfig', 'PersistenceData']
|
|
|
|
def get_types(file_content, variable_names):
|
|
result = {}
|
|
|
|
# Entferne Kommentare, um unerwünschte Störungen zu vermeiden
|
|
file_content = re.sub(r'\/\*.*?\*\/', '', file_content, flags=re.DOTALL)
|
|
file_content = re.sub(r'\/\/.*', '', file_content)
|
|
|
|
for var_name in variable_names:
|
|
# Erstelle ein reguläres Ausdrucksmuster, um den Typ der Variable zu extrahieren
|
|
pattern = re.compile(r'\b(?:extern\s+)?(\w+)\s+' + re.escape(var_name) + r'\s*;')
|
|
match = pattern.search(file_content)
|
|
|
|
if match:
|
|
# Extrahiere den Typ aus dem Treffer
|
|
type_match = match.group(1)
|
|
result[var_name] = type_match
|
|
|
|
return result
|
|
|
|
def extract_struct_fields(file_content, variable_types):
|
|
result = {}
|
|
|
|
# Entferne Kommentare, um unerwünschte Störungen zu vermeiden
|
|
file_content = re.sub(r'\/\*.*?\*\/', '', file_content, flags=re.DOTALL)
|
|
file_content = re.sub(r'\/\/.*', '', file_content)
|
|
|
|
for var_name, var_type in variable_types.items():
|
|
# Erstelle ein reguläres Ausdrucksmuster, um das Strukturfeld zu extrahieren
|
|
pattern = re.compile(r'typedef\s+struct\s*{([^}]*)}\s*' + re.escape(var_type) + r'\s*;')
|
|
match = pattern.search(file_content)
|
|
|
|
if match:
|
|
# Extrahiere die Felder aus dem Treffer
|
|
fields_match = re.findall(r'\b(\w+)\s+(\w+)(?:\[(\d+)\])?\s*;', match.group(1))
|
|
if fields_match:
|
|
result[var_name] = {'type': var_type, 'fields': {}}
|
|
for field_type, field_name, array_size in fields_match:
|
|
if array_size:
|
|
result[var_name]['fields'][field_name] = {'type': field_type, 'size': int(array_size)}
|
|
else:
|
|
result[var_name]['fields'][field_name] = {'type': field_type}
|
|
|
|
return result
|
|
|
|
def struct2json():
|
|
# Überprüfen, ob die Verzeichnisse existieren, andernfalls erstellen
|
|
output_dir_source = os.path.dirname(output_sourcefile)
|
|
if not os.path.exists(output_dir_source):
|
|
os.makedirs(output_dir_source)
|
|
output_dir_header = os.path.dirname(output_headerfile)
|
|
if not os.path.exists(output_dir_header):
|
|
os.makedirs(output_dir_header)
|
|
|
|
# Unix-Zeitstempel hinzufügen
|
|
timestamp = int(time.time())
|
|
|
|
# Parse structs
|
|
with open(input_file, 'r') as file:
|
|
content = file.read()
|
|
|
|
variable_types = get_types(content, variable_names)
|
|
structs = extract_struct_fields(content, variable_types)
|
|
checksum = fcs.calculate_checksum(structs)
|
|
|
|
env = Environment(loader=FileSystemLoader('codegen/templates', encoding='utf-8'))
|
|
# Lade das Jinja2-Template aus der Datei
|
|
template_c = env.get_template('struct2json.cpp.j2')
|
|
template_h = env.get_template('struct2json.h.j2')
|
|
|
|
# Erstelle ein Context-Dictionary mit den erforderlichen Daten
|
|
context = {
|
|
'timestamp_unix': timestamp,
|
|
'timestamp' : time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
|
|
'date' : time.strftime('%d.%m.%Y', time.localtime(timestamp)),
|
|
'structs': structs,
|
|
'checksum': checksum
|
|
}
|
|
|
|
# Überprüfe, ob die Checksummen übereinstimmen
|
|
if fcs.read_and_compare_checksum(output_sourcefile, checksum):
|
|
print("Keine Änderungen in der Source-Datei erforderlich.")
|
|
else:
|
|
# Rendere das Template mit den Werten und erhalte den Source-Text
|
|
source_text = template_c.render(context)
|
|
# Schreibe den generierten Source-Text in die Source-Datei
|
|
with open(output_sourcefile, "w", encoding='utf-8') as f:
|
|
f.write(source_text)
|
|
print(f"Source-Datei wurde erstellt: {output_sourcefile}")
|
|
|
|
# Überprüfe, ob die Checksummen übereinstimmen
|
|
if fcs.read_and_compare_checksum(output_headerfile, checksum):
|
|
print("Keine Änderungen in der Header-Datei erforderlich.")
|
|
else:
|
|
# Rendere das Template mit den Werten und erhalte den Header-Text
|
|
header_text = template_h.render(context)
|
|
# Schreibe den generierten Header-Text in die Header-Datei
|
|
with open(output_headerfile, "w", encoding='utf-8') as f:
|
|
f.write(header_text)
|
|
print(f"Header-Datei wurde erstellt: {output_headerfile}") |