Files
qt6-migration-pipeline/fix_telegrams_v2.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

159 lines
6.1 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, 'getters': dict}"""
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 = []
getters = {} # member_name -> getter_name
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
# Getter name is member without m_ prefix
getter_name = member_name[2:]
getters[getter_name] = member_name
if members:
structs[struct_name] = {
'has_m_prefix': has_m_prefix,
'members': members,
'getters': getters
}
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']}, getters={info['getters']}")
# Fix fromJson functions
def fix_fromJson(content, structs):
"""Fix fromJson to assign to correct member (m_* or direct)"""
lines = content.split('\n')
new_lines = []
for line in lines:
# Pattern: get(obj, ..., ret.member);
match = re.search(r'get\(obj,\s*[^,]+,\s*ret\.(\w+)\);', line)
if match:
member_used = match.group(1)
# Check if this is a getter name that should be a member
for struct_name, info in structs.items():
if info['has_m_prefix'] and member_used in info['getters']:
# This is a getter name, should be member name
correct_member = info['getters'][member_used]
line = line.replace(f'ret.{member_used});', f'ret.{correct_member});')
print(f" fromJson fix: ret.{member_used} -> ret.{correct_member}")
break
new_lines.append(line)
return '\n'.join(new_lines)
# Fix toJson functions
def fix_toJson(content, structs):
"""Fix toJson to use Qt6-compatible QJsonObject{{}} syntax with correct member access"""
lines = content.split('\n')
new_lines = []
in_toJson = False
current_struct = None
brace_count = 0
for line in lines:
# Detect toJson function start
toJson_match = re.match(r'QJsonObject\s+(\w+)::toJson\(\)\s*const\s*\{', line)
if toJson_match:
in_toJson = True
current_struct = toJson_match.group(1)
brace_count = 1
new_lines.append(line)
continue
if in_toJson:
# Count braces
brace_count += line.count('{') - line.count('}')
# Fix member access in toJson (convert to method calls for m_* structs)
if current_struct and current_struct in structs:
info = structs[current_struct]
if info['has_m_prefix']:
# Need to convert member references to method calls
for getter_name, member_name in info['getters'].items():
# Match standalone member references (not already method calls)
# Be careful not to match inside strings or comments
pattern = rf'\b{getter_name}\b(?!\s*\()'
if re.search(pattern, line):
line = re.sub(pattern, f'{getter_name}()', line)
print(f" toJson fix: {getter_name} -> {getter_name}()")
# Fix QJsonObject initializer syntax: QJsonObject({{ -> QJsonObject{{
if 'QJsonObject({' in line:
line = line.replace('QJsonObject({', 'QJsonObject{{')
print(f" toJson syntax: QJsonObject({{ -> QJsonObject{{")
# Fix closing: }}); -> }});
if re.search(r'\}\}\);\s*$', line):
line = re.sub(r'\}\}\);\s*$', '}});', line)
if brace_count == 0:
in_toJson = False
current_struct = None
new_lines.append(line)
return '\n'.join(new_lines)
# Apply fixes
print("\n=== Fixing fromJson ===")
cpp_content = fix_fromJson(cpp_content, structs)
print("\n=== Fixing toJson ===")
cpp_content = fix_toJson(cpp_content, structs)
# Write back
with open(cpp_file, 'w') as f:
f.write(cpp_content)
print(f"\n✓ Fixed {cpp_file}")