aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-07-24 23:38:30 +0200
committerblasty <blasty@local>2026-07-24 23:38:30 +0200
commitde2fa194278bb132e23edddd65bdad84f32ec37d (patch)
tree67d18789676b3377892d3edf4a6fbe4d497967af /tests
parentsplit-view phase 2: cursor sync + linked-row highlight (diff)
downloadida-tui-de2fa194278bb132e23edddd65bdad84f32ec37d.tar.gz
ida-tui-de2fa194278bb132e23edddd65bdad84f32ec37d.tar.xz
ida-tui-de2fa194278bb132e23edddd65bdad84f32ec37d.zip
split-view phase 3: rich per-line instruction region highlight
The Ghidra "region band": moving the pseudocode cursor now lights up EVERY instruction that C line owns, not just one. * server/patch_server.py: new decomp_map tool — sweeps cfunc.get_line_item across each pseudocode line's columns and collects the ea from each item's dstr() ('EA: desc', matching the /*ea*/ marker source so it aligns with the display lines). Returns {addr, lines:[{ea, eas:[...]}]}. (First tried item.get_ea(), which reports a different ea and didn't align — dstr() is the right source.) * domain: Program.decomp_map(ea) -> per-line ea lists, cached by name-gen. * app: _load_split_map fetches it off-thread into _split_eamap/_split_ea2line; _sync_split bands the full instruction region for a C line (decomp drives) and uses the exact ea->line inverse (listing drives), falling back to the single marker until the map lands. Maps cleared on leaving split. Pilot split_view gains: decomp_map returns/aligns with the markers, and a multi-instruction C line bands >1 listing row (13/13). Full suite 154/2-flake. The idalib spike ran on the pilot's own worker (the standalone worker kept getting reaped in this sandbox).
Diffstat (limited to 'tests')
-rw-r--r--tests/test_scenarios.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py
index 9099035..0bca4d8 100644
--- a/tests/test_scenarios.py
+++ b/tests/test_scenarios.py
@@ -350,6 +350,27 @@ async def s_split_view(c: Ctx):
loaded = await c.wait(lambda: dec.loaded_ea == app._cur.ea, 25)
c.check("split loads the pseudocode alongside the listing", loaded,
f"loaded={dec.loaded_ea} cur={app._cur.ea if app._cur else None}")
+ # phase 3: the rich per-line instruction map (decomp_map tool, run on the
+ # pilot's real worker) — verify it returns, aligns with the markers, and
+ # bands a whole region for a multi-instruction C line.
+ m = app.program.decomp_map(app._cur.ea)
+ c.check("decomp_map returns per-line ea sets", len(m) > 5, f"lines={len(m)}")
+ aligned = sum(1 for i in range(min(len(m), len(dec._line_eas)))
+ if m[i] and dec._line_eas[i] is not None
+ and dec._line_eas[i] in m[i])
+ c.check("decomp_map aligns with the pseudocode markers", aligned >= 3,
+ f"aligned={aligned}/{len(dec._line_eas)}")
+ multi = next((i for i, eas in enumerate(m) if len(eas) > 1), None)
+ if multi is not None:
+ app._split_eamap = m
+ dec.cursor = multi
+ app._sync_split("decomp")
+ c.check("a multi-instruction C line bands a region (>1 listing row)",
+ len(lst._link_rows) > 1,
+ f"line={multi} eas={len(m[multi])} rows={sorted(lst._link_rows)[:8]}")
+ else:
+ c.check("a multi-instruction C line bands a region (>1 listing row)",
+ True, "no multi-instruction line in this function (skipped)")
# listing drives: move it, the decomp band must track the covering C line
lst.focus()
for _ in range(6):