- 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
133 lines
5.2 KiB
Python
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}") |