Files
qt6-migration-pipeline/fix_export_headers_v2.py
T
torstenandCopilot 342ffd3e5c Update submodule to latest BUILD_RTI fixes
- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten
- svcTabCommon: Export-Header-Fix via Fallback-Target
- TrainingAreaBase: Stub-Header für BUILD_RTI=OFF
- ddsfts: Include-Pfad und Dependency-Fixes
- BUILD_RTI=OFF Compilation vollständig unterstützt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
2026-08-21 19:30:20 +02:00

147 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Repariert falsche Export-Header-Includes in Qt6-migrierten Dateien.
Dieses Skript:
1. Findet alle .h/.hpp Dateien mit falschen Export-Header-Includes
2. Liest den Target-Namen aus dem CMakeLists.txt im gleichen Verzeichnis
3. Ersetzt falsche Includes durch korrekte: "targetname_export.h"
"""
import os
import re
import sys
from pathlib import Path
# Patterns für falsche Export-Header-Includes
WRONG_PATTERNS = [
r'#include\s+<([^>]+_export\.h)>', # <name_export.h> - falsche angle brackets
r'#include\s+"([^"]+)_export\.h"', # "name_export.h" - aber falscher Name
]
# Pattern für korrektes Include
CORRECT_PATTERN = r'#include\s+"(\w+_export\.h)"'
def find_cmake_target(cmake_path):
"""Extrahiert Target-Namen aus NGL_ADD_LIBRARY2 Aufruf."""
if not os.path.exists(cmake_path):
return None
with open(cmake_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# NGL_ADD_LIBRARY2(ALL target_name SHARED ...)
match = re.search(r'NGL_ADD_LIBRARY2\s*\([^)]*\s+(\w+)\s+(SHARED|MODULE)', content, re.IGNORECASE)
if match:
return match.group(1)
# Alternative: add_library(target_name SHARED ...)
match = re.search(r'add_library\s*\(\s*(\w+)\s+(SHARED|MODULE)', content, re.IGNORECASE)
if match:
return match.group(1)
return None
def get_expected_export_header(target_name):
"""Generiert erwarteten Export-Header-Namen aus Target-Namen."""
if not target_name:
return None
return f"{target_name.lower()}_export.h"
def find_wrong_export_include(file_path):
"""Findet falsches Export-Header-Include in einer Datei."""
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
for pattern in WRONG_PATTERNS:
match = re.search(pattern, content)
if match:
return match.group(0), match.group(1)
return None, None
def is_correct_export_header(include_line, expected_header):
"""Prüft ob Include bereits korrekt ist."""
match = re.search(CORRECT_PATTERN, include_line)
if match:
return match.group(1) == expected_header
return False
def fix_export_header(file_path, expected_header):
"""Ersetzt falsches Export-Header-Include durch korrektes."""
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
original_content = content
# Ersetze alle falschen Patterns
for pattern in WRONG_PATTERNS:
content = re.sub(pattern, f'#include "{expected_header}"', content)
if content != original_content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
def process_directory(base_path):
"""Verarbeitet alle Header-Dateien im Verzeichnis."""
stats = {'fixed': 0, 'skipped': 0, 'errors': 0}
for root, dirs, files in os.walk(base_path):
# Skip build directories
if 'build' in root or '.git' in root:
continue
cmake_path = os.path.join(root, 'CMakeLists.txt')
target_name = find_cmake_target(cmake_path)
if not target_name:
continue
expected_header = get_expected_export_header(target_name)
if not expected_header:
continue
# Process header files
for file in files:
if not file.endswith(('.h', '.hpp')):
continue
file_path = os.path.join(root, file)
include_line, current_header = find_wrong_export_include(file_path)
if not include_line:
continue
# Check if already correct
if is_correct_export_header(include_line, expected_header):
stats['skipped'] += 1
continue
# Fix the include
try:
if fix_export_header(file_path, expected_header):
stats['fixed'] += 1
print(f"Fixed: {file_path}")
print(f" Target: {target_name} -> {expected_header}")
except Exception as e:
stats['errors'] += 1
print(f"Error processing {file_path}: {e}")
return stats
if __name__ == '__main__':
base_path = sys.argv[1] if len(sys.argv) > 1 else '.'
print(f"Scanning directory: {base_path}")
print("=" * 60)
stats = process_directory(base_path)
print("\n" + "=" * 60)
print(f"Summary:")
print(f" Fixed: {stats['fixed']}")
print(f" Skipped: {stats['skipped']}")
print(f" Errors: {stats['errors']}")