Files
qt6-migration-pipeline/fix_telegrams.py
T
torstenandCopilot d6500157f1 Fix RTI detection: only call FIND_PACKAGE if manual config failed
- Wrap FIND_PACKAGE(RTI) in IF(NOT TARGET RTI::nddsc) condition
- Prevents placeholder targets from overwriting manually configured RTI:: targets
- Manual configuration creates RTI:: targets when BUILD_RTI=ON and RTI found
- FIND_PACKAGE only called as fallback when manual config doesn't create targets

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entire-Checkpoint: 01M1CT3XSQXCX9RQR6WM9DG3GH
2026-08-31 23:03:01 +02:00

133 lines
5.2 KiB
Python

#!/usr/bin/env python3
"""
Fix Qt6 API compatibility issues in training_area_telegrams.cpp
Handles two struct patterns:
- Pattern A: private m_* members with getter methods (Header, BatteryState)
- Pattern B: public direct members (most other structs)
"""
import re
from pathlib import Path
cpp_file = Path('/home/torsten/swy/sandbox/qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Proxies/TrainingAreaBase/training_area_telegrams.cpp')
h_file = Path('/home/torsten/swy/sandbox/qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Proxies/TrainingAreaBase/training_area_telegrams.h')
# Parse header to determine struct member patterns
def parse_struct_members(header_content):
"""Returns dict: struct_name -> {'has_m_prefix': bool, 'members': list}"""
structs = {}
# Match struct definitions
struct_pattern = r'^struct\s+(\w+)(?:\s*:[^{\n]+)?\s*\{(.*?)^\};'
for match in re.finditer(struct_pattern, header_content, re.MULTILINE | re.DOTALL):
struct_name = match.group(1)
body = match.group(2)
# Find member variables (lines with type and name, not functions)
members = []
has_m_prefix = False
for line in body.split('\n'):
line = line.strip()
# Skip empty lines, comments, functions, static, etc.
if not line or line.startswith('//') or line.startswith('static') or \
line.startswith('virtual') or '(' in line or line.startswith('}'):
continue
# Match member variable declarations
member_match = re.match(r'(?:mutable\s+)?(?:const\s+)?(\w+(?:\s*<[^>]+>)?)\s+(\w+)(?:\s*=\s*[^;]+)?;', line)
if member_match:
member_name = member_match.group(2)
members.append(member_name)
if member_name.startswith('m_'):
has_m_prefix = True
if members:
structs[struct_name] = {
'has_m_prefix': has_m_prefix,
'members': members
}
return structs
# Read files
with open(h_file, 'r') as f:
header_content = f.read()
with open(cpp_file, 'r') as f:
cpp_content = f.read()
# Parse struct patterns
structs = parse_struct_members(header_content)
print(f"Found {len(structs)} structs")
for name, info in list(structs.items())[:10]:
print(f" {name}: m_prefix={info['has_m_prefix']}, members={info['members'][:3]}...")
# Fix fromJson functions
def fix_fromJson(content, structs):
"""Fix fromJson to assign to correct member (m_* or direct)"""
for struct_name, info in structs.items():
# Pattern: get(obj, STRUCT::FIELD(), ret.field)
# Need to change ret.field to ret.m_field if struct has m_prefix
if info['has_m_prefix']:
# Pattern A: need to add m_ prefix
for member in info['members']:
# Match: ret.member) where member is the getter name
# Need to convert getter name to member name (e.g., equipmentNumber -> m_equipmentNumber)
getter_name = member[2:] if member.startswith('m_') else member
pattern = rf'(get\(obj,\s*\w+::\w+\(\),\s*ret\.){getter_name}(\))'
replacement = rf'\1{member}\2'
content = re.sub(pattern, replacement, content)
# Pattern B: direct members, no change needed for assignment
# But we should verify the member names match
return content
# Fix toJson functions - convert to Qt6 single-line QJsonObject{{}} syntax
def fix_toJson(content, structs):
"""Fix toJson to use Qt6-compatible QJsonObject{{}} syntax with correct member access"""
for struct_name, info in structs.items():
# Find toJson function for this struct
pattern = rf'(QJsonObject\s+{struct_name}::toJson\(\)\s*const\s*\{{\s*return\s*QJsonObject)(\{{[^}}]*\}})(\s*;)'
def replace_toJson(m):
prefix = m.group(1)
init_list = m.group(2)
suffix = m.group(3)
# Parse the initializer list entries
entries = re.findall(r'\{([^,]+),\s*([^}]+)\}', init_list)
new_entries = []
for key_expr, value_expr in entries:
key_expr = key_expr.strip()
value_expr = value_expr.strip()
# If struct has m_prefix, use getter methods
if info['has_m_prefix']:
# Convert member name to getter call
if value_expr.startswith('m_'):
getter = value_expr[2:] # Remove m_ prefix
value_expr = f'{getter}()'
# else: Pattern B uses direct members, no change
new_entries.append(f'{{{key_expr}, {value_expr}}}')
new_init = '{' + ', '.join(new_entries) + '}'
return f'{prefix}{new_init}{suffix}'
content = re.sub(pattern, replace_toJson, content)
return content
# Apply fixes
cpp_content = fix_fromJson(cpp_content, structs)
cpp_content = fix_toJson(cpp_content, structs)
# Write back
with open(cpp_file, 'w') as f:
f.write(cpp_content)
print(f"\nFixed {cpp_file}")