mirror of https://github.com/zeldaret/mm.git
				
				
				
			
		
			
				
	
	
		
			78 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
from pathlib import Path
 | 
						|
import argparse
 | 
						|
 | 
						|
parser = argparse.ArgumentParser(description="Script to sort forward-declared functions and extern'd symbols in actors")
 | 
						|
parser.add_argument("file", type=str, help="Path to c file to sort")
 | 
						|
args = parser.parse_args()
 | 
						|
 | 
						|
file_path = Path(args.file).resolve()
 | 
						|
 | 
						|
if not file_path.suffix == ".c":
 | 
						|
    print(f"Should only be run on a .c file!")
 | 
						|
    exit()
 | 
						|
if "/overlays/actors/" not in str(file_path):
 | 
						|
    print(f"This should only be run on actors, are you sure you gave it the right file?")
 | 
						|
    exit()
 | 
						|
 | 
						|
map_path = file_path.parent.parent.parent.parent.parent
 | 
						|
map_lines = (map_path / "build" / "mm.map").read_text().splitlines()[10000:]
 | 
						|
 | 
						|
i = 0
 | 
						|
while not f"{file_path.stem}.o(.text)" in map_lines[i]:
 | 
						|
    i += 1
 | 
						|
i += 2
 | 
						|
assert map_lines[i-1].startswith(" .text")
 | 
						|
 | 
						|
orig_funcs = set()
 | 
						|
while map_lines[i].startswith("  "):
 | 
						|
    func = map_lines[i].split(" ")[-1]
 | 
						|
    if not (func.endswith("_Init") or func.endswith("_Destroy") or func.endswith("_Update") or func.endswith("_Draw")):
 | 
						|
        orig_funcs.add(func)
 | 
						|
    i += 1
 | 
						|
 | 
						|
lines = file_path.read_text().splitlines()
 | 
						|
start_func_line = 0
 | 
						|
end_func_line = 0
 | 
						|
func_list = set()
 | 
						|
externs = []
 | 
						|
extern_set = set()
 | 
						|
 | 
						|
i = 0
 | 
						|
while (not (lines[i].startswith("const") or lines[i].startswith("static") or lines[i].startswith("typedef"))):
 | 
						|
    line = lines[i]
 | 
						|
    if line.startswith("extern"):
 | 
						|
        extern_type = line.rsplit(" ",1)[0]
 | 
						|
        extern_name = line.split(" ",2)[2][:-1]
 | 
						|
        if extern_name not in extern_set:
 | 
						|
            externs.append({"type":extern_type, "name":extern_name})
 | 
						|
            extern_set.add(extern_name)
 | 
						|
    i += 1
 | 
						|
 | 
						|
declares_needed = set()
 | 
						|
funcs_seen = set()
 | 
						|
funcs_types = []
 | 
						|
for count, line in enumerate(lines):
 | 
						|
    if not line.startswith(" ") and "(" in line and "{" in line and "static" not in line:
 | 
						|
        func_ret = line.split(" ",1)[0]
 | 
						|
        func_name = line.split(" ",1)[1].split("(",1)[0]
 | 
						|
        func_args = line.split("(",1)[1].split(")",1)[0]
 | 
						|
        funcs_seen.add(func_name)
 | 
						|
        funcs_types.append({"ret":func_ret, "name":func_name, "args":func_args})
 | 
						|
    else:
 | 
						|
        for func in orig_funcs:
 | 
						|
            if func in line and func not in funcs_seen:
 | 
						|
                declares_needed.add(func)
 | 
						|
 | 
						|
externs.sort(key=lambda x: x["name"])
 | 
						|
 | 
						|
declares = []
 | 
						|
for func in funcs_types:
 | 
						|
    if func["name"] in declares_needed:
 | 
						|
        declares.append(f"{func['ret']} {func['name']}({func['args']});")
 | 
						|
 | 
						|
print("\n".join(declares))
 | 
						|
print()
 | 
						|
print("\n".join([f"{x['type']} {x['name']};" for x in externs]))
 |