#!/usr/bin/env python3 from pathlib import Path import re import os import colorama colorama.init() files = {} fail = False pattern = r'\b\w+\s+\w+(.*?)?\s*=\s*(?:;|{)?' def clean_symbol(s): s = s.strip() if(s.startswith('static')): s = ' '.join(s.split(' ')[1:]) if(s.startswith('/* static */')): s = ' '.join(s.split(' ')[3:]) if(s.startswith('const')): s = ' '.join(s.split(' ')[1:]) if(s.startswith('extern')): s = ' '.join(s.split(' ')[1:]) if('[' in s): s = s.split('[')[0] return re.sub(r'[\[\];]', '', s).split(' ')[1] def search_c(file, path): with open(path, 'r') as f: lines = f.readlines() for line in lines: search = re.findall(pattern, line) if search and not line.startswith('#') and not line.startswith(' ') and not '//' in line and len(line.strip()) > 0: files[file].append({ 'name': clean_symbol(line), 'used': [], 'global': False, }) def search_asm(file, path): with open(path, 'r') as f: lines = f.readlines() for line in lines: if line.startswith('dlabel'): files[file].append({ 'name': line.split(' ')[1].strip(), 'used': [], 'global': False, }) def init_file(file): if file not in files: files[file] = [] def parse_symbols(): for path in Path('src').rglob('*.c'): file = str(path).split('/')[-1].split('.')[0] init_file(file) search_c(file, path) for path in Path('asm').rglob('*.s'): file = str(path).split('/')[-1].split('.')[0] if file not in files: continue search_asm(file, path) def scan_code(): for path in Path('src').rglob('*.c'): with open(path, 'r') as f: print(f' - Scanning symbols on {colorama.Fore.YELLOW}{str(path).split("/")[-1]}{colorama.Fore.LIGHTWHITE_EX}') buffer = f.readlines() for line in buffer: for file in files: for symbol in files[file]: if symbol['name'] in line: if not line.strip().startswith('extern'): found = str(path).split('/')[-1].split('.')[0] if found not in symbol['used']: symbol['used'].append(found) def scan_variables(): with open('include/variables.h', 'r') as f: buffer = f.readlines() for line in buffer: if line.strip().startswith('extern'): symbol = clean_symbol(line.strip()) for file in files: for s in files[file]: if s['name'] == symbol: s['global'] = True def print_results(): global fail output = {} for file in files: for symbol in files[file]: for used in symbol['used']: if used != file and symbol['global']: if used not in output: output[used] = [] print(f' - Symbol {colorama.Fore.LIGHTBLUE_EX}{symbol["name"]} {colorama.Fore.LIGHTWHITE_EX}from {colorama.Fore.LIGHTGREEN_EX}{file} {colorama.Fore.LIGHTWHITE_EX}is used on {colorama.Fore.LIGHTMAGENTA_EX}{used} {colorama.Fore.LIGHTWHITE_EX}' + f'{colorama.Fore.LIGHTWHITE_EX}and its global' if symbol['global'] else '') output[used].append({ 'name': symbol['name'], 'file': file, }) fail = True print(f'{colorama.Fore.LIGHTWHITE_EX} - Writing to file...') # Write to file with open('symbols.csv', 'w') as f: max = 0 for file in output: f.write(f'{file},') max = max + len(output[file]) f.write('\n') keys = list(output.keys()) for i in range(0, max): for key in keys: if len(output[key]) > i: f.write(f'{output[key][i]["file"]}: {output[key][i]["name"]},') else: f.write(',') f.write('\n') print(f'{colorama.Fore.GREEN} - Done, Good luck!') def print_error(): print(colorama.Fore.LIGHTWHITE_EX + "\n BSS could be REORDERED!!\n" " Oh! MY GOD!!", file=os.sys.stderr) print("", file=os.sys.stderr) if __name__ == '__main__': print(colorama.Fore.LIGHTWHITE_EX, end='') print('Parsing .bss.s files...'); parse_symbols() print('Searching for used symbols...'); scan_code() scan_variables() print_results() if fail: print_error()