mm/tools/progress.py
Tharo c55e9eeee5
pragma variant for GLOBAL_ASM (#49)
* pragma GLOBAL_ASM

* Revert split_asm.py arg description change
2021-02-23 23:15:58 -05:00

103 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
import os, struct, sys, ast, argparse
def read_all_lines(file_name):
lines = list()
try:
with open(file_name) as f:
lines = f.readlines()
except IOError:
print('failed to read file ' + file_name)
sys.exit(1)
return lines
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--file', help='File to print progress off. If excluded, defaults to all files.')
args = parser.parse_args()
map_lines = read_all_lines('build/mm.map')
current_section = ''
in_section_list = False
asm_amounts = dict()
src_amounts = dict()
src_files = dict()
for line in map_lines:
if in_section_list:
if line.startswith('OUTPUT(build/code.elf elf32-tradbigmips)'):
break
line_split = list(filter(None, line.split()))
if (len(line_split) > 0 and not line.startswith(' ')):
current_section = line_split[0]
src_amounts[current_section] = 0
asm_amounts[current_section] = 0
src_files[current_section] = []
if (len(line_split) == 4 and line_split[0].startswith(".")):
section = line_split[0]
size = int(line_split[2], 16)
obj_file = line_split[3]
if (section == ".text" and not current_section + '_data' in obj_file and not current_section + '_rodata' in obj_file):
if (obj_file.startswith("build/src")):
src_amounts[current_section] += size
formatted_name = obj_file[len('build/'):] # remove build/ prefix
formatted_name = formatted_name[:-1] + 'c' # replace .o preface with .c
src_files[current_section].append(formatted_name)
elif (obj_file.startswith("build/asm")):
asm_amounts[current_section] += size
else:
in_section_list = line.startswith('Linker script and memory map')
for section in src_files:
for file in src_files[section]:
file_lines = read_all_lines(file)
for line in file_lines:
if line.startswith('#pragma GLOBAL_ASM'):
line_split = list(filter(None, line.split('\"')))
asm_lines = read_all_lines(line_split[1])
for asm_line in asm_lines:
if asm_line.startswith('/*'):
asm_amounts[section] += 4
src_amounts[section] -= 4
src = 0
asm = 0
if args.file == None:
for section in src_amounts:
src += src_amounts[section]
for section in asm_amounts:
asm += asm_amounts[section]
else:
if args.file not in src_amounts or args.file not in asm_amounts:
sys.exit('{} not found in map file'.format(args.file))
src += src_amounts[args.file]
asm += asm_amounts[args.file]
total = src + asm
src_percent = 100 * src / total
asm_percent = 100 * asm / total
print('{} total bytes of decompilable code\n'.format(total))
print('{} bytes of code in src {}%'.format(src, src_percent))
print('{} bytes of code in asm {}%\n'.format(asm, asm_percent))
print("------------------------------------\n")
num_masks = 24
max_rupees = 500
bytes_per_mask = total / num_masks
bytes_per_rupee = bytes_per_mask / max_rupees
masks = int(src / bytes_per_mask)
rupees = int((src % bytes_per_mask) / bytes_per_rupee)
if (rupees > 0):
print('You have {}/{} masks and {}/{} rupee(s).\n'.format(masks, num_masks, rupees, max_rupees));
else:
print('You have {}/{} masks.\n'.format(masks, num_masks));