pokeemerald-jp/update_config.py
2019-09-27 01:42:56 -04:00

68 lines
2.5 KiB
Python

""" Renames functions in the config when they are renamed in the .s"""
import re
import os
import glob
from collections import defaultdict
from contextlib import ExitStack
from itertools import chain
config_path = 'pokeemerald_jp.cfg'
asm_path = os.path.join('asm', '*.s')
def update_config(asm_glob, config_path): # Find and replace all renamed functions
addresses = {} # Maps integer addresses to function names
asm_exp = re.compile(r'(?!sub_)(\w+): @ (0x[\da-fA-F]+)') # Ignore unknown functions
cfg_exp = re.compile(r'(thumb_func|arm_func) (0x[\da-fA-F]+)\r?\n')
with ExitStack() as stack:
files = [stack.enter_context(open(path, 'r')) for path in glob.iglob(asm_glob)]
f = chain(*files)
count = 0
print('Found 0 named functions.', end='', flush=True)
for i, line in enumerate(f, 1):
m = asm_exp.match(line)
if m:
addresses[int(m.group(2), 16)] = m.group(1)
count += 1
if count % 100 == 0:
print(f'\rFound {count} named functions', end='')
print(f'\rFound {count} named functions')
with open(config_path, 'r') as f_in, open(config_path+'.new', 'w') as f_out:
replaced = 0
print('New:')
for i, line in enumerate(f_in, 1): # Replace functions in config
m = cfg_exp.fullmatch(line)
if m:
func, addr = m.group(1), int(m.group(2), 16)
if addr in addresses:
line = f'{func} {m.group(2)} {addresses[addr]}\n'
print(line[:-1])
replaced += 1
f_out.write(line)
os.replace(config_path+'.new', config_path)
def check_dups(config_path): # Find duplicate names
func_exp = re.compile(r'(thumb_func|arm_func) (0x[\da-fA-F]+)\s+(\w+)\r?\n')
symbols = {} # Maps names to addresses
dups = defaultdict(set)
with open(config_path, 'r') as f:
for line in f:
m = func_exp.match(line)
if m is None:
continue
addr, name = int(m.group(2), 16), m.group(3)
if name in symbols:
dups[name].add(addr)
dups[name].add(symbols[name])
symbols[name] = addr
for name, addrs in dups.items():
print(f'{name} at {{{", ".join("%08x" % x for x in addrs)}}}')
if __name__ == '__main__':
#update_config(asm_path, config_path)
print('Find duplicates:')
check_dups(config_path)