From 120621daca9e9823689c3f5d1b43d42a33adad7d Mon Sep 17 00:00:00 2001 From: sim Date: Wed, 16 Sep 2026 20:07:19 +0200 Subject: [PATCH] fix(tools): every sylpheed.db reader honours $SYLPHEED_DB, and none needs a retired checkout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `SYLPHEED_DB` is the documented contract for the static-analysis database — `docker/decoder/sylph-decoder` sets it, and `docs/agents/CONTAINER-NOTES.md` and `decoder-loop.md` list it — but no reader honoured it: isl_cmdtab.py, name_block_bases.py hardcoded `/work/xenia-rs/sylpheed.db`, a path that has not existed anywhere since `/work` became a clone. Both failed on every machine, before and after the database moved. zq.py used `$SYLPH_XEXDB`, a name invented in #39 without grepping for the existing one. All three now resolve `$SYLPHEED_DB`, then `$SYLPH_XEXDB` (kept as an alias so nothing already written against it breaks), then `/sylpheed.db`, and refuse with exit 1 naming both variables and the build command otherwise. `grab_tutorial.sh` hardcoded its helpers into the retired `sylpheed-reborn` checkout. That copy's `skip_intro.sh` still calls the removed `vgamepad` and exits 0 having pressed nothing — the failure this repository's own copy was rewritten to make loud. So the script was already running a silently broken helper; it now resolves its helpers from its own directory. Nothing exists only in reborn's `tools/re-capture` (checked: 0 reborn-only files). Verified against the same database, output compared byte for byte with the ORIGINAL scripts (path-substituted copies, sibling imports resolvable): resolution path isl_cmdtab name_block_bases default (root) identical identical $SYLPHEED_DB identical identical $SYLPH_XEXDB identical identical bad path exit 1 exit 1 (zq.py: exit 1 too) and `isl_cmdtab`'s output is byte-identical to the body of the committed `docs/re/data/isl-command-table.txt`. ⚠️ `name_block_bases`'s output does NOT reproduce the committed `docs/re/data/name-block-bases.txt` (2,609 lines differ, `strings in the image: 7366` vs `7140`). That is the database, not this change: the artefact was generated from the agent box's older 586 MB database, and this machine's is the current generator's. Two databases are in circulation. Not regenerated here. ⚠️ Also not fixed, because it is a different bug: `name_block_bases.py` globs `/work/sylph_extract/**/*.pak`, another path that exists nowhere now; that part of its report is silently empty. It should read `$SYLPHEED_DISC`. Co-Authored-By: Claude Opus 5 (1M context) --- tools/re-capture/grab_tutorial.sh | 5 ++++- tools/re-capture/isl_cmdtab.py | 27 ++++++++++++++++++++++++++- tools/re-capture/name_block_bases.py | 26 ++++++++++++++++++++++++-- tools/zq.py | 21 ++++++++++++--------- 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/tools/re-capture/grab_tutorial.sh b/tools/re-capture/grab_tutorial.sh index d13798d4..0826c5e7 100755 --- a/tools/re-capture/grab_tutorial.sh +++ b/tools/re-capture/grab_tutorial.sh @@ -11,7 +11,10 @@ N="${1:?usage: grab_tutorial.sh }" OUT="${2:?}" export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98 SD="$(cd "$(dirname "$0")" && pwd)" -RC="/home/fabi/RE - Project Sylpheed/sylpheed-reborn/tools/re-capture" +# This script lives in the helpers' own directory. It used to hardcode the +# retired `sylpheed-reborn` checkout, whose `skip_intro.sh` still calls the +# removed `vgamepad` and exits 0 having pressed nothing. +RC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # The container entrypoint's Xvfb/openbox do NOT restart on their own, and a # dead Xvfb leaves a entry that still matches `pgrep` -- so test the diff --git a/tools/re-capture/isl_cmdtab.py b/tools/re-capture/isl_cmdtab.py index d272e7d9..13364a56 100644 --- a/tools/re-capture/isl_cmdtab.py +++ b/tools/re-capture/isl_cmdtab.py @@ -5,7 +5,32 @@ Each write is `stw rX, off(r1)` (a two-word stack pair) followed by `ld r9, off(r1)` and `std r9, N(r31)`, where slot = (N - 32) / 8. """ import duckdb, re, sys -con=duckdb.connect('/work/xenia-rs/sylpheed.db', read_only=True) + + +def _resolve_db(): + """`$SYLPHEED_DB`, else `$SYLPH_XEXDB`, else `/sylpheed.db`. + + `SYLPHEED_DB` is the documented contract -- `docker/decoder/sylph-decoder` sets + it and `docs/agents/CONTAINER-NOTES.md` lists it -- but no reader honoured it: + this script hardcoded `/work/xenia-rs/sylpheed.db`, a path that has not + existed anywhere since `/work` became a clone, so it failed on every machine. + """ + import os, pathlib + for var in ('SYLPHEED_DB', 'SYLPH_XEXDB'): + v = os.environ.get(var) + if v: + p = pathlib.Path(v).expanduser() + if not p.is_file(): + sys.exit(f'${var} is set but is not a file: {p}') + return str(p) + p = pathlib.Path(__file__).resolve().parents[2] / 'sylpheed.db' + if p.is_file(): + return str(p) + sys.exit(f'no database: set $SYLPHEED_DB, or build {p} with ' + 'sylph-xexdb dis --db sylpheed.db --analyze sql --quiet') + + +con=duckdb.connect(_resolve_db(), read_only=True) rows=con.execute("select address, coalesce(ext_disasm,disasm) from instructions " "where address>=? and address/sylpheed.db`. + + `SYLPHEED_DB` is the documented contract -- `docker/decoder/sylph-decoder` sets + it and `docs/agents/CONTAINER-NOTES.md` lists it -- but no reader honoured it: + this script hardcoded `/work/xenia-rs/sylpheed.db`, a path that has not + existed anywhere since `/work` became a clone, so it failed on every machine. + """ + import os, pathlib + for var in ('SYLPHEED_DB', 'SYLPH_XEXDB'): + v = os.environ.get(var) + if v: + p = pathlib.Path(v).expanduser() + if not p.is_file(): + sys.exit(f'${var} is set but is not a file: {p}') + return str(p) + p = pathlib.Path(__file__).resolve().parents[2] / 'sylpheed.db' + if p.is_file(): + return str(p) + sys.exit(f'no database: set $SYLPHEED_DB, or build {p} with ' + 'sylph-xexdb dis --db sylpheed.db --analyze sql --quiet') + + MIN_GROUP = 8 # displacements needed before a group is worth solving MIN_RESOLVED = 12 # report a function only if the base explains this many LOW, HIGH = 0x82000000, 0x82400000 def main(): import duckdb - con = duckdb.connect(DB, read_only=True) + con = duckdb.connect(_resolve_db(), read_only=True) S = set(a for (a,) in con.execute("SELECT address FROM strings").fetchall()) txt = dict(con.execute("SELECT address, content FROM strings").fetchall()) funcs = con.execute( diff --git a/tools/zq.py b/tools/zq.py index 81757f24..4697dfd9 100755 --- a/tools/zq.py +++ b/tools/zq.py @@ -39,7 +39,7 @@ Usage: A command that needs a table the current DB predates prints what to regenerate rather than a SQL error. -The database is found via `$SYLPH_XEXDB`, else `/sylpheed.db`. It is a +The database is found via `$SYLPHEED_DB` (alias `$SYLPH_XEXDB`), else `/sylpheed.db`. It is a build artefact, not a tracked file; if neither exists, zq.py says so and prints the command that builds one. """ @@ -53,7 +53,7 @@ REGEN = "sylph-xexdb dis --db sylpheed.db --analyze sql" def _resolve_db(): - """Locate the database: `$SYLPH_XEXDB`, else `/sylpheed.db`. + """Locate the database: `$SYLPHEED_DB` / `$SYLPH_XEXDB`, else `/sylpheed.db`. 🔴 This used to be one hardcoded absolute path, and it pointed *inside* `xenia-rs` -- a repository `docs/agents/CONSOLIDATION.md` archives in Phase 5 @@ -66,12 +66,15 @@ def _resolve_db(): one, say so and print how to build it. A default that silently resolves to the wrong database is worse than no default -- see issue #16. """ - env = os.environ.get('SYLPH_XEXDB') - if env: - p = pathlib.Path(env).expanduser() - if not p.is_file(): - sys.exit(f'$SYLPH_XEXDB is set but is not a file:\n {p}') - return p + # `SYLPHEED_DB` is the documented contract (the decoder container sets it); + # `SYLPH_XEXDB` was this script's own name for it and stays as an alias. + for var in ('SYLPHEED_DB', 'SYLPH_XEXDB'): + env = os.environ.get(var) + if env: + p = pathlib.Path(env).expanduser() + if not p.is_file(): + sys.exit(f'${var} is set but is not a file:\n {p}') + return p # Relative to this script, not to the caller's cwd: `zq.py` is run from # wherever the investigation happens to be. p = pathlib.Path(__file__).resolve().parent.parent / 'sylpheed.db' @@ -80,7 +83,7 @@ def _resolve_db(): sys.exit( f'no database found.\n' f' looked for: {p}\n' - f' set $SYLPH_XEXDB to an existing one, or build it with:\n' + f' set $SYLPHEED_DB to an existing one, or build it with:\n' f' {REGEN}' )