mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
fix(phase-26): scope_data_externs ANSI-brace fix + wire §8d into family_sweep --hseq; 780-class diagnosed
- _body_open_brace only matched a `{` on its own line (the K&R shape), so fix() SILENTLY NO-OP'D on
every ANSI draft — the same silent-skip disease as the four catalogued in §40/§8d, caught because
the h_seq re-sweep banked 0/780. Now brace-scans forward from the signature (ANSI same-line,
ANSI own-line, and K&R all work). Load-bearing for func_80178D40's upcoming ×134 bank.
- family_sweep --hseq now applies the §8d scoped stage at staging time.
- HONEST RESULT: still 0/780 — the substantial-band h_seq rejections are a DIFFERENT (sibling) class,
now fully diagnosed against the bytes:
gcc-2.7.2 decl-conflict semantics: a VISIBLE file-scope decl + a conflicting later decl (file OR
block) is a HARD ERROR; a limbo-only block decl (scope closed) + a conflicting later decl is a
warning. The h_seq drafts carry the EXEMPLAR TU's spellings; sibling TUs legitimately spell the
same symbol differently (loose typing), and the visible decl is often MACRO-INJECTED — a
DEFINE_func_* leading extern (§8c), invisible to any col-0 scan (e.g. D_80115158's `short` decl
enters ov_SC01_000.c via DEFINE_func_8014168C() @4637; the draft carries ov077's
`unsigned short` -> conflicting types at ANY scope).
Sub-class (a) no-visible-decl -> §8d demotion (the jr class, proven x133). Sub-class (b) visible
decl, different spelling -> needs reconcile-to-TU-VISIBLE (rewrite the draft decl to the TU-visible
spelling + byte-neutral access cast; oracle = col-0 decls above the stub + engine_core.h macro
externs for the DEFINE_ invocations above). Parked as a designed follow-up task; the 780 members
are mechanical-recovery fodder once the tool exists.
This commit is contained in:
@@ -20,6 +20,7 @@ import json, glob, re, subprocess, os, sys, shutil, collections, argparse
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import family_remap as FR
|
||||
import canon_sig_reconcile as CSR # v3.2 (Phase-25 T7-M2 per-sibling re-reconcile, Q5-proven)
|
||||
from scope_data_externs import fix as scope_data_fix # §8d (Phase-26 session 8)
|
||||
|
||||
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
PY = ".venv/bin/python"
|
||||
@@ -244,6 +245,19 @@ def hseq_sweep(a):
|
||||
skip[r[:24]] += 1; continue
|
||||
if re.search(r'__asm__\s*\(\s*"\$', draft): # hard-reg pin (§42e): ×1-only, cc1-crashes
|
||||
skip["pinned-exemplar"] += 1; continue # sibling TUs → skip the family, don't bisect-storm
|
||||
# §8d — place the carried DATA externs at a scope this sibling's TU can accept.
|
||||
# `remap_hseq` (via gather_externs) prepends them at FILE scope; for a per-location symbol the
|
||||
# sibling declares only at BLOCK scope inside its own later functions, that ESTABLISHES A GLOBAL
|
||||
# THE TU NEVER HAD and every later block-scope extern must now agree with it — loose typing ⇒ they
|
||||
# don't ⇒ `conflicting types for D_80115128`. Byte-proven to be the dominant gate-rejection class
|
||||
# here (as it was for the jr sweeps). Demoting is byte-neutral and never worse than raw, and the
|
||||
# whole-binary gate remains the sole arbiter (G3/P9).
|
||||
to_func = f"func_{to_addr:08X}"
|
||||
tu_path = os.path.join(REPO, src_rel)
|
||||
tu = open(tu_path).read()
|
||||
mstub = re.search(rf'INCLUDE_ASM\("[^"]*",\s*{to_func}\);', tu)
|
||||
if mstub:
|
||||
draft, _moved = scope_data_fix(draft, tu, mstub.start(), to_func)
|
||||
d = os.path.join(REPO, SWEEP, ov)
|
||||
os.makedirs(d, exist_ok=True)
|
||||
open(os.path.join(d, f"func_{to_addr:08X}.c"), "w").write(draft + "\n")
|
||||
|
||||
@@ -72,14 +72,20 @@ def _file_scope_data_syms(text):
|
||||
|
||||
|
||||
def _body_open_brace(body, func):
|
||||
"""Index of the newline ending the line that opens `func`'s body — i.e. where block-scope decls go.
|
||||
Handles both the ANSI form and the K&R form (mandatory whenever a zero-arg engine_core.h thunk calls
|
||||
the function), whose param decls sit between the signature and the `{`."""
|
||||
r"""Index just past the `{` that opens `func`'s body — i.e. where block-scope decls go. Scans forward
|
||||
from the signature to the first `{` at depth 0 of the *statement* (so it handles the ANSI form with
|
||||
the brace on the signature line, the ANSI form with the brace on its own line, AND the K&R form whose
|
||||
param decls sit between the signature and the `{`). The first cut of this used `^\s*\{\s*$` — own-line
|
||||
braces only — and silently no-op'd on every ANSI draft (the same silent-skip disease as the four
|
||||
catalogued in §40/§8d; caught because the h_seq re-sweep banked 0/780)."""
|
||||
sig = re.search(rf'^[^\n]*\b{re.escape(func)}\s*\(', body, re.M)
|
||||
if not sig:
|
||||
return None
|
||||
brace = re.compile(r'^\s*\{\s*$', re.M).search(body, sig.end())
|
||||
return brace.end() if brace else None
|
||||
i = body.find('{', sig.end())
|
||||
if i < 0:
|
||||
return None
|
||||
j = body.find('\n', i)
|
||||
return (j + 1) if j >= 0 else (i + 1)
|
||||
|
||||
|
||||
def fix(body, tu_text, insert_pos, func):
|
||||
|
||||
Reference in New Issue
Block a user