import re import json import pandas as pd from ExportData import * from ExpandDB import * def clean_line(line): """Clean line from BOM and extra spaces or quotes.""" # Remove UTF-8 BOM if exists and strip trailing/leading whitespace line = line.replace("\ufeff", "").strip() # Standardize TYPE and DATA_BLOCK definitions to ensure they're properly captured line = re.sub(r'\s*TYPE\s+"?', 'TYPE "', line) line = re.sub(r'\s*DATA_BLOCK\s+"?', 'DATA_BLOCK "', line) return line def extract_name(line): """Extract the name from TYPE or DATA_BLOCK definition line.""" # Attempt to find a quoted name first match = re.search(r'(TYPE|DATA_BLOCK)\s+"([^"]+)"', line) if match: return match.group(2).strip() # The name is within quotes # If no quoted name, find an unquoted name match = re.search(r"(TYPE|DATA_BLOCK)\s+(\S+)", line) if match: return match.group(2).strip() # The name is without quotes def parse_udts(lines): udt_json = {} udt_name = None nested_structs = [] current_struct = None is_within_struct = False for line in lines: line = clean_line(line) if "TYPE" in line and "END_TYPE" not in line: udt_name = extract_name(line) udt_json[udt_name] = {} current_struct = udt_json[udt_name] print(f"Created UDT: {udt_name}") elif "END_TYPE" in line: print(f"Completed UDT: {udt_name}") udt_name = None nested_structs = [] current_struct = None is_within_struct = False elif "STRUCT" in line and "END_STRUCT" not in line and udt_name is not None: struct_name = ( "Struct" if "STRUCT" == line.strip() else line.split(":")[0].strip() ) new_struct = {} current_struct[struct_name] = new_struct nested_structs.append(current_struct) current_struct = new_struct is_within_struct = True print(f"Created STRUCT: {struct_name}") elif "END_STRUCT" in line and udt_name is not None: current_struct = nested_structs.pop() if nested_structs else None is_within_struct = bool(nested_structs) print(f"Closed STRUCT in UDT '{udt_name}'") elif udt_name and ":" in line and is_within_struct: parts = line.split(":") field_name = parts[0].strip() field_details = parts[1].strip().split("//") field_type = ( field_details[0].replace(";", "").strip() ) # Removing ';' from field type field_comment = parts[1].split("//")[1].strip() if "//" in parts[1] else "" if "Struct" in field_type: new_struct = {} current_struct[field_name] = new_struct nested_structs.append(current_struct) current_struct = new_struct print(f"Opened inline STRUCT at field '{field_name}'") else: current_struct[field_name] = { "type": field_type, "comment": field_comment, } print( f"Added field '{field_name}' to STRUCT: Type={field_type}, Comment={field_comment}" ) return udt_json def parse_dbs(lines, udts): db_json = {} db_name = None nested_structs = [] current_struct = None is_within_struct = False for line in lines: line = clean_line(line) if "DATA_BLOCK" in line and "END_DATA_BLOCK" not in line: db_name = extract_name(line) db_json[db_name] = {} current_struct = db_json[db_name] print(f"Created DATA_BLOCK: {db_name}") elif "END_DATA_BLOCK" in line: print(f"Completed DATA_BLOCK: {db_name}") db_name = None nested_structs = [] current_struct = None is_within_struct = False elif "STRUCT" in line and "END_STRUCT" not in line and db_name is not None: struct_name = ( "Struct" if "STRUCT" == line.strip() else line.split(":")[0].strip() ) new_struct = {} current_struct[struct_name] = new_struct nested_structs.append(current_struct) current_struct = new_struct is_within_struct = True print(f"Created STRUCT in DB '{db_name}': {struct_name}") elif "END_STRUCT" in line and db_name is not None: current_struct = nested_structs.pop() if nested_structs else None is_within_struct = bool(nested_structs) print(f"Closed STRUCT in DB '{db_name}'") elif db_name and ":" in line and is_within_struct: parts = line.split(":") field_name = parts[0].strip() field_details = parts[1].strip().split("//") field_type = ( field_details[0].replace(";", "").strip() ) # Removing ';' from field type field_comment = parts[1].split("//")[1].strip() if "//" in parts[1] else "" if "Struct" in field_type: new_struct = {} current_struct[field_name] = new_struct nested_structs.append(current_struct) current_struct = new_struct print(f"Opened inline STRUCT at field '{field_name}' in DB '{db_name}'") else: current_struct[field_name] = { "type": field_type, "comment": field_comment, } print( f"Added field '{field_name}' to STRUCT in DB '{db_name}': Type={field_type}, Comment={field_comment}" ) return db_json if __name__ == "__main__": file_path = "DB SIPA Supervision.db" with open(file_path, "r", encoding="utf-8-sig") as file: lines = file.readlines() udt_json = parse_udts(lines) db_json = parse_dbs(lines, udt_json) expand_dbs(udt_json, db_json) # Expand DBs with UDT definitions # Display the expanded DBs as a table df = display_as_table(db_json) save_dataframe_to_file(df) # Save the DataFrame to a CSV file save_dataframe_to_excel(df) # Optionally, save the DataFrame to an Excel file # Save JSON data to an XML file save_json_to_xml(db_json)