# -*- 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 # Example: 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): """Generates the standard footer with a placeholder get_processor_info.""" 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., 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, copying the entire function body until the next top-level definition. """ 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 os.makedirs(PROCESSORS_DIR, exist_ok=True) print(f"Ensuring '{PROCESSORS_DIR}' directory exists.") print("Searching for processor functions (def process_...):") processor_functions = [] # Store tuples of (name, start_line_index, end_line_index) current_func_start = -1 current_func_name = None # Pattern to find ANY top-level function definition any_func_def_pattern = re.compile(r"^def\s+(\w+)\s*\(") # Pattern specific to processor functions process_func_def_pattern = re.compile(r"^def\s+(process_\w+)\s*\(") # First pass: Identify start and end lines of all top-level functions for i, line in enumerate(lines): match = any_func_def_pattern.match(line) if match: # Found a new top-level function definition if current_func_name is not None: # Mark the end of the *previous* function # Only add if it was a 'process_' function if current_func_name.startswith("process_"): processor_functions.append((current_func_name, current_func_start, i)) # Start tracking the new function current_func_name = match.group(1) current_func_start = i # Add the last function found in the file (if it was a process_ function) if current_func_name is not None and current_func_name.startswith("process_"): processor_functions.append((current_func_name, current_func_start, len(lines))) # Second pass: Create files using the identified line ranges processor_count = 0 if not processor_functions: print("\nWarning: No functions starting with 'process_' found at the top level.") return print(f"Found {len(processor_functions)} potential processor functions.") for func_name, start_idx, end_idx in processor_functions: print(f" - Processing: {func_name} (lines {start_idx+1}-{end_idx})") func_lines = lines[start_idx:end_idx] # Extract lines for this function # Remove trailing blank lines from the extracted block, often happens before next def while func_lines and func_lines[-1].strip() == "": func_lines.pop() create_processor_file(func_name, func_lines) processor_count += 1 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) # Write the function lines, ensuring consistent newline endings for line in func_lines: f.write(line.rstrip() + '\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)