Files
qt-migration-legatus/add_logger_members.py
T

148 lines
4.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Add m_logger member variables to Qt6 class definitions.
Matches Qt5 and Qt6 headers by file path, then checks for m_logger.
"""
import os
import re
import sys
from pathlib import Path
# Paths
SCRIPT_DIR = Path(__file__).parent
QT5_BASE = SCRIPT_DIR / "qt5-before/qt5-legatus-legacy"
QT6_BASE = SCRIPT_DIR / "qt6-after/qt6-migrated-legatus"
def find_qt5_headers_with_logger():
"""Find all Qt5 headers with m_logger members"""
qt5_headers = []
for header in QT5_BASE.rglob("*.h"):
try:
content = header.read_text(encoding='utf-8', errors='ignore')
if 'm_logger' in content:
rel_path = header.relative_to(QT5_BASE)
qt5_headers.append(rel_path)
except Exception as e:
pass
print(f"Found {len(qt5_headers)} Qt5 headers with m_logger")
return qt5_headers
def find_qt6_header(rel_path):
"""Find corresponding Qt6 header by relative path"""
qt6_header = QT6_BASE / rel_path
if qt6_header.exists():
return qt6_header
# Try .hpp extension
qt6_header_hpp = QT6_BASE / rel_path.with_suffix('.hpp')
if qt6_header_hpp.exists():
return qt6_header_hpp
# Try lowercase path
qt6_header_lower = QT6_BASE / str(rel_path).lower()
if qt6_header_lower.exists():
return qt6_header_lower
# Try snake_case conversion for filename
filename = rel_path.name
snake_name = ''.join(['_' + c.lower() if c.isupper() else c for c in filename.split('.')[0]]).lstrip('_')
snake_path = rel_path.parent / f"{snake_name}{rel_path.suffix}"
qt6_header_snake = QT6_BASE / snake_path
if qt6_header_snake.exists():
return qt6_header_snake
return None
def add_logger_to_header(header_path):
"""Add m_logger member to class definition"""
try:
content = header_path.read_text(encoding='utf-8')
# Check if already has m_logger
if 'm_logger' in content:
return False, "Already has m_logger"
# Find private: or protected: section (handle comments after colon)
pattern = r'^(\s*)(private|protected):\s*(?:\/\/.*)?\s*\n'
match = re.search(pattern, content, re.MULTILINE)
if not match:
# Try finding end of class with just closing brace
lines = content.split('\n')
for i in range(len(lines) - 1, 0, -1):
if re.match(r'^\s*};\s*$', lines[i]):
indent = re.match(r'^(\s*)', lines[i]).group(1)
lines.insert(i, f"{indent}NGL::INGLLogger &m_logger;")
new_content = '\n'.join(lines)
header_path.write_text(new_content, encoding='utf-8')
return True, "Added (fallback)"
return False, "No private/protected section found"
# Insert m_logger after the access specifier line
indent = match.group(1)
insert_pos = match.end()
new_content = content[:insert_pos] + indent + "NGL::INGLLogger &m_logger;\n" + content[insert_pos:]
header_path.write_text(new_content, encoding='utf-8')
return True, "Added"
except Exception as e:
return False, f"Error: {str(e)}"
def main():
print("=" * 80)
print("Adding m_logger members to Qt6 headers")
print("=" * 80)
# Find Qt5 headers with m_logger
qt5_headers = find_qt5_headers_with_logger()
# Track results
added = 0
skipped = 0
skip_reasons = {}
not_found_examples = []
for rel_path in qt5_headers:
# Find corresponding Qt6 header
qt6_header = find_qt6_header(rel_path)
if not qt6_header:
skipped += 1
reason = "Header not found"
skip_reasons[reason] = skip_reasons.get(reason, 0) + 1
if len(not_found_examples) < 10:
not_found_examples.append(str(rel_path))
continue
# Try to add logger
success, message = add_logger_to_header(qt6_header)
if success:
added += 1
if added <= 10:
print(f"ADDED: {rel_path} -> {message}")
else:
skipped += 1
reason = message if not message.startswith("Already") else "Already has m_logger"
skip_reasons[reason] = skip_reasons.get(reason, 0) + 1
print("\n" + "=" * 80)
print(f"Results: {added} headers updated, {skipped} skipped")
print("\nSkip reasons:")
for reason, count in sorted(skip_reasons.items(), key=lambda x: -x[1]):
print(f" {reason}: {count}")
if not_found_examples:
print("\nHeader not found examples (first 10):")
for example in not_found_examples:
print(f" - {example}")
print("=" * 80)
if __name__ == "__main__":
main()