150 lines
5.7 KiB
Python
150 lines
5.7 KiB
Python
# -*- 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) |