Files
insightface/cpp-package/inspireface/tools/generate_error_tabel_to_python.py

110 lines
4.2 KiB
Python
Raw Normal View History

2025-08-08 13:26:10 +08:00
import click
import re
from datetime import datetime
# Function to calculate the actual error code value based on the expressions
def calculate_error_code_value(error_code_str, error_definitions):
try:
# Replace the hex values and error definitions with actual values
error_code_str = re.sub(r'0X([0-9A-F]+)', lambda m: str(int(m.group(1), 16)), error_code_str)
for error_name, error_value in error_definitions.items():
error_code_str = error_code_str.replace(error_name, str(error_value))
# Evaluate the expression to get the actual error code value
return eval(error_code_str)
except Exception as e:
# If there is an error in evaluation (like undefined reference), return the original string
return error_code_str
# Define a function to parse the error codes between anchors in a given C header file content
def parse_and_calculate_error_codes(header_content):
# Define the start and end anchor tags
start_anchor = '// [Anchor-Begin]'
end_anchor = '// [Anchor-End]'
# Find the index of start and end anchor tags
start_index = header_content.find(start_anchor)
end_index = header_content.find(end_anchor, start_index)
# Extract the content between anchors
anchor_content = header_content[start_index+len(start_anchor):end_index].strip()
# Split the content into lines
lines = anchor_content.split('\n')
# Dictionary to hold the error names and their evaluated values
error_definitions = {}
# List to hold the parsed error codes
error_codes = []
# Process each line
for line in lines:
line = line.strip()
# Skip empty lines and lines that don't start with #define
if not line or not line.startswith('#define'):
continue
# Split by comment marker and handle cases with no comment
parts = line.split('//')
define_part = parts[0].strip()
comment_part = parts[1].strip() if len(parts) > 1 else ''
# Extract the error name and code, handling parentheses
define_parts = define_part.split(None, 2) # Split into max 3 parts
if len(define_parts) >= 2: # Changed from == 3
error_name = define_parts[1]
error_code_str = define_parts[2].strip('()') if len(define_parts) > 2 else ''
# Calculate the actual error code value
error_code_value = calculate_error_code_value(error_code_str, error_definitions)
# Store the calculated error code value for later reference
error_definitions[error_name] = error_code_value
# Skip base offset definitions (ending with _BASE)
if error_name.endswith('_BASE'):
continue
# Append the extracted information to the error_codes list
error_codes.append((error_name, error_code_value, comment_part))
return error_codes
# Click command for processing the header file and outputting Python error table
@click.command()
@click.argument('header_path', type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True))
@click.argument('output_path', type=click.Path(file_okay=True, dir_okay=False, writable=True))
def process_header(header_path, output_path):
# Read the header file content
with open(header_path, 'r', encoding='utf-8') as file:
header_content = file.read()
# Parse and calculate the error codes from the header content
parsed_error_codes = parse_and_calculate_error_codes(header_content)
# Generate Python file content
python_content = f'''"""
InspireFace Error Codes
Auto-generated error code definitions from {header_path}
Generated on: {datetime.now().strftime("%Y-%m-%d")}
"""
'''
# Generate simple error code definitions
for name, code, comment in parsed_error_codes:
if comment:
python_content += f"{name} = {code} # {comment}\n"
else:
python_content += f"{name} = {code}\n"
# Write the Python file
with open(output_path, 'w', encoding='utf-8') as py_file:
py_file.write(python_content)
click.echo(f"Python error table has been written to {output_path}")
click.echo(f"Generated {len(parsed_error_codes)} error code definitions")
if __name__ == '__main__':
process_header()