mirror of
https://github.com/pret/pmd-sky.git
synced 2026-03-21 17:25:15 -05:00
54 lines
2.2 KiB
Python
54 lines
2.2 KiB
Python
from typing import List
|
|
|
|
ARM_FUNC_START = '\tarm_func_start '
|
|
BRANCH_LINK_INSTRUCTION = '\tbl '
|
|
BRANCH_LINK_EXCHANGE_INSTRUCTION = '\tblx '
|
|
BRANCH_INSTRUCTION = '\tb '
|
|
WORD_KEY = '.word '
|
|
WORD_PLUS_OFFSET = ' + 0x'
|
|
"""
|
|
Searches through an ASM file's contents for all external symbols, then populates a .inc file with all the necessary .public definitions.
|
|
"""
|
|
def write_inc_file(lines: List[str], file_path: str):
|
|
defined_functions = set()
|
|
used_functions = set()
|
|
for line in lines:
|
|
if line.startswith(ARM_FUNC_START):
|
|
defined_functions.add(line[len(ARM_FUNC_START) : -1])
|
|
elif line.startswith(BRANCH_LINK_INSTRUCTION):
|
|
used_functions.add(line[len(BRANCH_LINK_INSTRUCTION) : -1])
|
|
elif line.startswith(BRANCH_INSTRUCTION):
|
|
function = line[len(BRANCH_INSTRUCTION) : -1]
|
|
if function[0] != '_':
|
|
semicolon_index = function.index(' ; ')
|
|
used_functions.add(function[:semicolon_index])
|
|
elif line.startswith(BRANCH_LINK_EXCHANGE_INSTRUCTION):
|
|
function = line[len(BRANCH_LINK_EXCHANGE_INSTRUCTION) : -1]
|
|
if function not in {'fp', 'ip', 'lr', 'sb', 'sl'} and not (
|
|
function.startswith('r') and function[1:].isdigit() # rN
|
|
):
|
|
used_functions.add(function)
|
|
else:
|
|
word_index = line.find(WORD_KEY)
|
|
if word_index >= 0 and f'{WORD_KEY}0x' not in line:
|
|
word_plus_offset_index = line.find(WORD_PLUS_OFFSET)
|
|
if word_plus_offset_index >= 0:
|
|
new_word = line[word_index + len(WORD_KEY) : word_plus_offset_index]
|
|
else:
|
|
new_word = line[word_index + len(WORD_KEY) : -1]
|
|
|
|
if new_word[0] < '0' or new_word > '9':
|
|
used_functions.add(new_word)
|
|
|
|
for function in defined_functions:
|
|
if function in used_functions:
|
|
used_functions.remove(function)
|
|
|
|
write_lines = ['#pragma once\n']
|
|
for function in sorted(used_functions):
|
|
if ' ' not in function:
|
|
write_lines.append(f'.public {function}\n')
|
|
|
|
with open(file_path, 'w') as inc_file:
|
|
inc_file.writelines(write_lines)
|