- 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
159 lines
6.1 KiB
Python
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}") |