#!/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)>', # - 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']}")