mirror of
https://github.com/zeldaret/oot.git
synced 2025-08-14 19:10:25 +00:00
Automate fixing BSS ordering (#2009)
* Automate fixing BSS ordering * Typo * Some cleanups * Move pragma check after printing BSS info * Some proofreading * multiprocessing, require version, some colors * Tweak output * Black + mypy * Move logging and sys.exit out of helper functions * Use stdout instead of stderr in fix_bss.py * Add suggestion to conflicting offsets error Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com> * Remove var = list[T]() * Improve error handling Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com> * Add error if no pointers to BSS * Add comment about process_file_worker * Only print updates if stdout is a tty * Use new binary-search-esque candidate generation algorithm Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com> * Add Wikipedia link * More comment tweaks --------- Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
This commit is contained in:
parent
078e21f6c6
commit
0da402b9de
21 changed files with 1071 additions and 352 deletions
|
@ -3,13 +3,13 @@
|
|||
# SPDX-FileCopyrightText: © 2024 ZeldaRET
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
# Usage: preprocess.py [compile command minus input file...] [single input file]
|
||||
# Usage: preprocess.py [flags] -- [compile command minus input file...] [single input file]
|
||||
# Preprocess a C file to:
|
||||
# * Re-encode from UTF-8 to EUC-JP (the repo uses UTF-8 for text encoding, but
|
||||
# the strings in the ROM are encoded in EUC-JP)
|
||||
# * Replace `#pragma increment_block_number N` with `N` fake structs for
|
||||
# controlling BSS ordering
|
||||
# * Replace `#pragma increment_block_number` with fake structs for controlling BSS ordering
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import os
|
||||
import tempfile
|
||||
|
@ -22,39 +22,59 @@ def fail(message):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def process_file(filename, input, output):
|
||||
def process_file(version, filename, input, output):
|
||||
output.write(f'#line 1 "{filename}"\n')
|
||||
for i, line in enumerate(input, start=1):
|
||||
if line.startswith("#pragma increment_block_number"):
|
||||
parts = line.split()
|
||||
if len(parts) != 3:
|
||||
fail(
|
||||
f"{filename}:{i}: increment_block_number must be followed by an integer"
|
||||
)
|
||||
try:
|
||||
amount = int(parts[2])
|
||||
except ValueError:
|
||||
fail(
|
||||
f"{filename}:{i}: increment_block_number must be followed by an integer"
|
||||
)
|
||||
if line.startswith("#pragma increment_block_number "):
|
||||
# Grab pragma argument and remove quotes
|
||||
arg = line.strip()[len("#pragma increment_block_number ") + 1 : -1]
|
||||
amount = 0
|
||||
for part in arg.split():
|
||||
kv = part.split(":")
|
||||
if len(kv) != 2:
|
||||
fail(
|
||||
f"{filename}:{i}: increment_block_number must be followed by a list of version:amount pairs"
|
||||
)
|
||||
if kv[0] != version:
|
||||
continue
|
||||
try:
|
||||
amount = int(kv[1])
|
||||
except ValueError:
|
||||
fail(
|
||||
f"{filename}:{i}: increment_block_number amount must be an integer"
|
||||
)
|
||||
|
||||
# Always generate at least one struct so that fix_bss.py can know where the increment_block_number pragmas are
|
||||
if amount == 0:
|
||||
amount = 256
|
||||
|
||||
# Write fake structs for BSS ordering
|
||||
for j in range(amount):
|
||||
output.write(f"struct DummyStruct_{i:05}_{j:03};\n")
|
||||
output.write(f"struct increment_block_number_{i:05}_{j:03};\n")
|
||||
output.write(f'#line {i + 1} "{filename}"\n')
|
||||
else:
|
||||
output.write(line)
|
||||
|
||||
|
||||
def main():
|
||||
filename = Path(sys.argv[-1])
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-v", "--oot-version", help="Which version should be processed")
|
||||
parser.add_argument(
|
||||
"args",
|
||||
nargs="+",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
filename = Path(args.args[-1])
|
||||
with tempfile.TemporaryDirectory(prefix="oot_") as tmpdir:
|
||||
tmpfile = Path(tmpdir) / filename.name
|
||||
|
||||
with open(filename, mode="r", encoding="utf-8") as input:
|
||||
with open(tmpfile, mode="w", encoding="euc-jp") as output:
|
||||
process_file(filename, input, output)
|
||||
process_file(args.oot_version, filename, input, output)
|
||||
|
||||
compile_command = sys.argv[1:-1] + ["-I", filename.parent, tmpfile]
|
||||
compile_command = args.args[:-1] + ["-I", filename.parent, tmpfile]
|
||||
process = subprocess.run(compile_command)
|
||||
return process.returncode
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue