# -*- coding: utf-8 -*- import os import sys import re import argparse # Directorio donde se crearán los archivos de procesador PROCESSORS_DIR = "processors" # Cabecera estándar para añadir a cada nuevo archivo FILE_HEADER = """# -*- coding: utf-8 -*- # TODO: Import necessary functions from processor_utils # from .processor_utils import get_scl_representation, format_variable_name, ... # Or: import processors.processor_utils as utils # TODO: Define constants if needed (e.g., SCL_SUFFIX) or import them SCL_SUFFIX = "_scl" # --- Function code starts --- """ # Pie de página estándar con la función get_processor_info de plantilla def get_file_footer(func_name): # Intenta adivinar el type_name quitando 'process_' # Necesitará ajustes manuales para casos como 'call', 'edge_detector', 'comparison', 'math' type_name_guess = func_name.replace('process_', '') return f""" # --- Function code ends --- # --- Processor Information Function --- def get_processor_info(): \"\"\"Returns the type name and processing function for this module.\"\"\" # TODO: Adjust the type_name if needed (e.g., for call, edge_detector, comparison, math) # TODO: Return a list if this module handles multiple types (e.g., PBox/NBox, FC/FB) type_name = "{type_name_guess}" # Basic guess return {{'type_name': type_name, 'processor_func': {func_name}}} """ def extract_and_create_processors(source_py_file): """ Extracts top-level functions starting with 'process_' from the source file and creates individual processor files in the PROCESSORS_DIR. """ if not os.path.exists(source_py_file): print(f"Error: Source file not found: '{source_py_file}'") return print(f"Reading source file: '{source_py_file}'") try: with open(source_py_file, 'r', encoding='utf-8') as f: lines = f.readlines() except Exception as e: print(f"Error reading source file: {e}") return # Crear directorio de procesadores si no existe os.makedirs(PROCESSORS_DIR, exist_ok=True) print(f"Ensuring '{PROCESSORS_DIR}' directory exists.") current_func_name = None current_func_lines = [] processor_count = 0 print("Searching for processor functions (def process_...):") # Usamos una expresión regular para encontrar definiciones de función de nivel superior # que empiecen por 'process_' func_def_pattern = re.compile(r"^def\s+(process_\w+)\s*\(") for i, line in enumerate(lines): match = func_def_pattern.match(line) if match: # Encontrada una nueva definición de función 'process_' new_func_name = match.group(1) # Si estábamos procesando una función anterior, guardarla ahora if current_func_name: create_processor_file(current_func_name, current_func_lines) processor_count += 1 # Empezar a recolectar para la nueva función print(f" - Found: {new_func_name}") current_func_name = new_func_name current_func_lines = [line] # Empezar con la línea 'def' elif line.strip() == "" and not current_func_lines: # Ignorar líneas en blanco antes de la primera función continue elif current_func_name and not line.startswith(' '): # Si estamos dentro de una función y encontramos una línea # que NO empieza con espacio (y no es un 'def process_'), # podría ser el fin de la función (o una definición de otra cosa). # Por simplicidad, asumimos que marca el fin. Guardamos la actual. # (Esto funciona si las 'def process_' están una tras otra o separadas # por comentarios o definiciones de funciones NO 'process_') create_processor_file(current_func_name, current_func_lines) processor_count += 1 current_func_name = None current_func_lines = [] elif current_func_name: # Si estamos recolectando líneas para una función, añadir la línea actual current_func_lines.append(line) # Guardar la última función encontrada después de salir del bucle if current_func_name: create_processor_file(current_func_name, current_func_lines) processor_count += 1 if processor_count == 0: print("\nWarning: No functions starting with 'process_' found at the top level.") else: print(f"\nFinished processing. Attempted to create/check {processor_count} processor files in '{PROCESSORS_DIR}'.") def create_processor_file(func_name, func_lines): """Creates the individual processor file if it doesn't exist.""" target_filename = f"{func_name}.py" target_filepath = os.path.join(PROCESSORS_DIR, target_filename) if os.path.exists(target_filepath): print(f" * Skipping: '{target_filename}' already exists.") return print(f" * Creating: '{target_filename}'...") try: with open(target_filepath, 'w', encoding='utf-8') as f: f.write(FILE_HEADER) f.writelines(func_lines) # Escribir las líneas de la función f.write(get_file_footer(func_name)) except Exception as e: print(f" Error writing file '{target_filename}': {e}") if __name__ == "__main__": parser = argparse.ArgumentParser( description="Extracts 'process_*' functions from a source Python file " "and creates individual processor files." ) parser.add_argument( "source_file", default="x2_process.py", # Valor por defecto nargs='?', # Hacerlo opcional para que use el default help="Path to the source Python file (default: x2_process.py)" ) args = parser.parse_args() extract_and_create_processors(args.source_file)