From 9c2707adc17e0be5291326bbf0256949c22be312 Mon Sep 17 00:00:00 2001 From: Lywx Date: Wed, 10 Jan 2024 10:09:10 -0600 Subject: [PATCH] Symbol scanner (#74) * Created tool to scan unused symbols * Removed unused comments * Removed unused function and readded fail * Fixed error while cleaning symbol * Fixed logic to show used files and added csv export * Added from where is the symbol * Swapped text to a shorter one --- tools/used_symbols.py | 146 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 tools/used_symbols.py diff --git a/tools/used_symbols.py b/tools/used_symbols.py new file mode 100644 index 00000000..2678a5f5 --- /dev/null +++ b/tools/used_symbols.py @@ -0,0 +1,146 @@ +#!/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() \ No newline at end of file