173 lines
6.0 KiB
Python
173 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Replace printf with DEBUG_ macros in test files.
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
def add_debug_include(content):
|
|
"""Add #include \"../lib/debug_config.h\" if not present."""
|
|
if '#include "../lib/debug_config.h"' in content:
|
|
return content
|
|
# Find position after last #include
|
|
lines = content.split('\n')
|
|
new_lines = []
|
|
include_added = False
|
|
for line in lines:
|
|
new_lines.append(line)
|
|
if line.strip().startswith('#include') and not include_added:
|
|
# Add our include after the last #include block
|
|
# Check if next line is not #include
|
|
pass
|
|
# Simpler: insert after first #include line that includes something from ../lib or ../src
|
|
# Actually, just insert after the first #include line
|
|
for i, line in enumerate(lines):
|
|
if line.strip().startswith('#include'):
|
|
# Insert after this line
|
|
lines.insert(i + 1, '#include "../lib/debug_config.h"')
|
|
break
|
|
return '\n'.join(lines)
|
|
|
|
def add_debug_init(content):
|
|
"""Add debug initialization at the beginning of main()."""
|
|
if 'debug_config_init();' in content:
|
|
return content
|
|
# Find int main() {
|
|
pattern = r'int main\s*\(\s*\)\s*\{'
|
|
match = re.search(pattern, content)
|
|
if not match:
|
|
return content
|
|
start = match.end()
|
|
# Insert after the opening brace
|
|
# Find the next newline after brace
|
|
newline_pos = content.find('\n', start)
|
|
if newline_pos == -1:
|
|
return content
|
|
insertion_point = newline_pos + 1
|
|
init_code = '\n debug_config_init();\n debug_set_level(DEBUG_LEVEL_TRACE);\n debug_set_categories(DEBUG_CATEGORY_ALL);\n'
|
|
content = content[:insertion_point] + init_code + content[insertion_point:]
|
|
return content
|
|
|
|
def determine_category(filename, line):
|
|
"""Determine debug category based on filename and line content."""
|
|
filename_lower = filename.lower()
|
|
if 'crypto' in filename_lower:
|
|
return 'DEBUG_CATEGORY_CRYPTO'
|
|
elif 'etcp' in filename_lower:
|
|
return 'DEBUG_CATEGORY_ETCP'
|
|
elif 'memory' in filename_lower:
|
|
return 'DEBUG_CATEGORY_MEMORY'
|
|
elif 'u_async' in filename_lower:
|
|
return 'DEBUG_CATEGORY_UASYNC'
|
|
elif 'll_queue' in filename_lower:
|
|
return 'DEBUG_CATEGORY_LL_QUEUE'
|
|
elif 'config' in filename_lower:
|
|
return 'DEBUG_CATEGORY_CONFIG'
|
|
else:
|
|
return 'DEBUG_CATEGORY_ALL'
|
|
|
|
def determine_level(line):
|
|
"""Determine debug level based on line content."""
|
|
line_lower = line.lower()
|
|
if '❌' in line or 'error' in line_lower or 'failed' in line_lower:
|
|
return 'DEBUG_ERROR'
|
|
elif 'warn' in line_lower:
|
|
return 'DEBUG_WARN'
|
|
elif '✅' in line_lower or 'success' in line_lower or 'passed' in line_lower:
|
|
return 'DEBUG_INFO'
|
|
elif '[debug]' in line_lower:
|
|
return 'DEBUG_DEBUG'
|
|
elif 'info' in line_lower:
|
|
return 'DEBUG_INFO'
|
|
else:
|
|
return 'DEBUG_INFO'
|
|
|
|
def replace_printf(content, filename):
|
|
"""Replace printf calls with DEBUG_ macros."""
|
|
# Pattern to match printf("...", ...);
|
|
# Simple approach: replace line by line
|
|
lines = content.split('\n')
|
|
new_lines = []
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i]
|
|
stripped = line.strip()
|
|
|
|
# Check for printf
|
|
if stripped.startswith('printf('):
|
|
# Extract format string and arguments
|
|
# Simple regex to capture printf("format", args);
|
|
match = re.match(r'printf\("([^"]*)"\s*,?(.*)\);', stripped)
|
|
if match:
|
|
fmt = match.group(1)
|
|
args = match.group(2).strip()
|
|
# Remove ❌ and ✅ symbols
|
|
fmt = fmt.replace('❌', '').replace('✅', '').strip()
|
|
# Determine category and level
|
|
category = determine_category(filename, line)
|
|
level = determine_level(line)
|
|
# Build new macro call
|
|
if args:
|
|
new_line = line.replace(stripped, f'{level}({category}, "{fmt}", {args});')
|
|
else:
|
|
new_line = line.replace(stripped, f'{level}({category}, "{fmt}");')
|
|
new_lines.append(new_line)
|
|
# Check if next line is fflush(stdout);
|
|
if i + 1 < len(lines) and 'fflush(stdout);' in lines[i + 1]:
|
|
i += 1 # Skip fflush line
|
|
else:
|
|
# Keep original if pattern doesn't match
|
|
new_lines.append(line)
|
|
elif stripped.startswith('fprintf(') and 'stderr' in stripped:
|
|
# Replace fprintf(stderr, ...) with DEBUG_ERROR
|
|
match = re.match(r'fprintf\s*\(\s*stderr\s*,\s*"([^"]*)"\s*,?(.*)\);', stripped)
|
|
if match:
|
|
fmt = match.group(1)
|
|
args = match.group(2).strip()
|
|
category = determine_category(filename, line)
|
|
new_line = line.replace(stripped, f'DEBUG_ERROR({category}, "{fmt}", {args});')
|
|
new_lines.append(new_line)
|
|
else:
|
|
new_lines.append(line)
|
|
else:
|
|
new_lines.append(line)
|
|
i += 1
|
|
|
|
return '\n'.join(new_lines)
|
|
|
|
def process_file(filepath):
|
|
"""Process a single file."""
|
|
print(f"Processing {filepath}")
|
|
with open(filepath, 'r') as f:
|
|
content = f.read()
|
|
|
|
original = content
|
|
|
|
# Step 1: Add debug include
|
|
content = add_debug_include(content)
|
|
|
|
# Step 2: Add debug initialization in main()
|
|
content = add_debug_init(content)
|
|
|
|
# Step 3: Replace printf calls
|
|
content = replace_printf(content, os.path.basename(filepath))
|
|
|
|
if content != original:
|
|
with open(filepath, 'w') as f:
|
|
f.write(content)
|
|
print(f" Updated {filepath}")
|
|
else:
|
|
print(f" No changes needed")
|
|
|
|
def main():
|
|
test_dir = 'tests'
|
|
for root, dirs, files in os.walk(test_dir):
|
|
for file in files:
|
|
if file.endswith('.c'):
|
|
filepath = os.path.join(root, file)
|
|
process_file(filepath)
|
|
|
|
if __name__ == '__main__':
|
|
main() |