mirror of
https://github.com/sonicdcer/sf64.git
synced 2025-02-13 08:44:46 +00:00
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
This commit is contained in:
parent
7106c6a4c9
commit
9c2707adc1
146
tools/used_symbols.py
Normal file
146
tools/used_symbols.py
Normal file
@ -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()
|
Loading…
x
Reference in New Issue
Block a user