diff --git a/.claude/skills/t27f/SKILL.md b/.claude/skills/t27f/SKILL.md index 112356ce12..f793efc1c1 100644 --- a/.claude/skills/t27f/SKILL.md +++ b/.claude/skills/t27f/SKILL.md @@ -476,8 +476,72 @@ Traps: - **A one-byte-short fit test cannot tell `w > cap` from `w > cap + k`.** Both return `cap + 1` there. The original and the mutant only differ when the room is 2..k+1 bytes short, so the test that kills the mutant is three bytes short, not ten. -- **Bands are in edge-list order, so a hub shows `account/*` first.** That is the stated rule, - not a ranking; do not caption the first three as the most important. +- **Bands were in edge-list order, so a hub showed `account/*` first.** Since t27#10762 (below) + they are ranked by how many specs import each row. Even so, do not caption the first three as + the most important: "most imported" is the only measure the card has. + +#### Long names are abbreviated, not refused (t27#10728) + +A shown name of at most 58 bytes is drawn byte for byte. A longer one is drawn as its first +segment, `/...`, and the longest run of whole trailing segments that fits +(`port/.../rings/CR-CHAT-03/src/confirmation_tag_chain`). When no whole run fits, it is drawn as +`...` and its last 55 bytes. Only drawn bytes are checked, and the text size follows the drawn +length. `why_card` is unchanged and still refuses a name over 58 bytes. + +On 5440d35e1 the sweep compares the new binary with master's, card by card: + +- 30 cards are newly drawn, 783 are byte-identical to master, and 0 are lost or refused; +- 0 changed cards and 0 newly drawn cards have no `...`, and 0 identical cards have one; +- 29 abbreviated forms are drawn: 27 `/.../` and 2 `...`, the longest 58 bytes; +- the helpers card (29 importers), a `/.../` focus and a `...` focus passed every pixel check, + with 0 white pixels outside x 100..980. + +Lab traps from this run: + +- **`pkill -f dn_lab.sh` kills the fs-lab command that runs it**, because the pattern is in that + command's own line. Write `pkill -f '[d]n_lab.sh'`, in an fs-lab call that names the script + nowhere else (see #10762's traps). +- **An untracked seal in the lab checkout makes `git checkout` fail, and the script then tests the + old commit.** Have the script take the commit it must test and stop with `WRONG COMMIT` when + `HEAD` differs. Once the PR adding a seal merges, that seal is tracked, so `rm -f` of it deletes + a tracked file: restore it with `git checkout --` before sealing. +- **Count a kill only on `^ ?FAIL [a-z]`.** The `FAIL 0` summary line otherwise counts as a failing + test, and a surviving mutant reads `KILLED by 1: 0`. +- **A `<` mutant of a 58-byte bound needs an unquotable byte that only the whole-name check + sees.** A 58-byte name with `:` in the middle is `true` under the mutant, because the dots form + hides that byte, and `false` under the rule. + +#### Bands rank the most imported first (t27#10762) + +Each band draws its specs by how many distinct specs import each of them in the whole edge list, +highest first. A repeated edge line counts once, and equal scores keep the edge-list order, so a +band of equal scores draws exactly what it drew before. The subtitle says +`most imported first in each band`. The direct counts, the transitive counts and `+N more` do not +change: only which names are drawn, and in what order. "Most imported" is the only measure; the +ranking is quadratic in the edge list, and the hub is the largest band measured (539 ms, 378 importers). + +On 7853e2ef4 the sweep compares the new binary with the #10728 binary, card by card: + +- 124 cards are reordered, 689 are the same, and 0 are lost or refused; +- 0 cards have a count that differs, and 0 drawn rows score higher than the row above them + (1647 rows checked; 3 rows have abbreviated names, so their scores are unknown); +- the hub `base/types` now shows `compiler/lexer`, `compiler/parser` and `igla/race/bram_weights` + in place of three `account/*` specs, and both it and `analog/linear` passed every pixel check; +- 21 of 21 mutants fail a named test, including the tie order, the repeated line, out-degree in + place of in-degree, and the hidden-name check run in edge-list order. + +Traps from this run: + +- **ffmpeg splits drawtext on `:` and `,` even inside the quoted text.** A subtitle with `:` made + ffmpeg refuse the whole graph ("Both text and text file provided"), and every test still passed, + because the tests compare the graph text and do not run ffmpeg. Every fixed text now passes + `dcard_text_ok`, which has a test and a negative control. Only a render catches this class. +- **`pkill -f '[r]k.sh'` still kills the fs-lab command if that same command line also says + `/root/rk.sh`.** The bracket trick only hides the pattern from itself. Run the pkill in its own + fs-lab call, then send and start the script in the next one. +- **`seal --verify` does not check the closure.** After a master merge changes an imported spec, + `--verify` still says MATCH, and frontier refuses the seal (#10749). Re-save the seal after any merge + that touches the closure. #### Long names are abbreviated, not refused (t27#10728) diff --git a/.trinity/seals/t27f_t27f_deps_card.json b/.trinity/seals/t27f_t27f_deps_card.json index 2b40fbba0a..1c8ca6b375 100644 --- a/.trinity/seals/t27f_t27f_deps_card.json +++ b/.trinity/seals/t27f_t27f_deps_card.json @@ -27,23 +27,23 @@ } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:683eaa26f084480224ca235b1b3c8fd3b3054e8b40c21ba9cbda756746e1182f", - "gen_hash_rust": "sha256:2e5b5fa8665015b90bf5adc6868fc719b0017e11b94639791a306cbf0bffbf9e", - "gen_hash_verilog": "sha256:a3778e7e0be41b04d8f4e4bcd5a8584394a1a6f78595832b4292a8aaf781373d", - "gen_hash_zig": "sha256:59fe61003bfe57fce363d3b6072112d96309dfe0a3819486afb7e518d80d1352", + "gen_hash_c": "sha256:3d48add519bafd236c700adf369f4108d1f3dfff3a2f5536f307cae64f684603", + "gen_hash_rust": "sha256:abdd5b77e5c07df08a243704b57ad0051d5b3cce0a8271c321778ca7e6525382", + "gen_hash_verilog": "sha256:5b18c1b146174b46ebcaa57c19cc15f62d27e05243662082a3c3bbc86d309232", + "gen_hash_zig": "sha256:671dcd2e8b4f2c0e56bad3c9b787c7c75971d3984dbb7ca097680dda81f2fba8", "module": "t27f_deps_card", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-19T01:13:38Z", + "sealed_at": "2026-10-19T01:35:52Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:96b9f08f0229d5408e2b44e9ced7519f68e898a9d3e8bc7a3c055bd72a93c893", + "spec_hash": "sha256:2668cf097b59a43a77bef448c2aef5cf575e437f97b5544250c6dcffbc0b9757", "spec_path": "specs/t27f/deps_card.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 17, - "total": 17, + "passed": 22, + "total": 22, "vacuous": 0 }, "toolchain": { diff --git a/specs/t27f/deps_card.t27 b/specs/t27f/deps_card.t27 index 0738aa9950..955045e25f 100644 --- a/specs/t27f/deps_card.t27 +++ b/specs/t27f/deps_card.t27 @@ -6,12 +6,16 @@ ; madge's image and dependency-cruiser's focus filter answer: what uses it, and what does it use. ; -- ; The card, 1080x1350, top to bottom: the specs that import the focus directly, the focus, the specs -; it imports directly, each band in edge-list order and joined to the focus by a `uses` connector, -; so the card reads downward as "X uses Y". The footer gives the transitive counts both ways. +; it imports directly, each band joined to the focus by a `uses` connector, so the card reads +; downward as "X uses Y". The footer gives the transitive counts both ways. ; -- ; The rules, each with a test below: -; - each band shows its first DCARD_ROWS specs. Its label gives the direct count, and `+N more` -; appears exactly when the band holds more specs than it shows, N the ones not shown; +; - each band shows DCARD_ROWS of its specs, the most imported first (gHashTag/t27#10762): a +; spec's score is how many distinct specs import it in the whole edge list, a repeated line +; counted once, and equal scores keep the band's edge-list order. The subtitle says so, and like +; every fixed text it holds no ':' or ',', which ffmpeg would split the graph on. Its +; label gives the direct count, and `+N more` appears exactly when the band holds more specs +; than it shows, N the ones not shown; ; - the counts are deps_walk's (specs/t27f/spec_deps.t27): direct is layer 1, transitive every ; layer past 0, so a spec reached two ways is counted once; ; - every box and connector is in the exact style (spec_graph_view's green stroke on its dark @@ -35,8 +39,10 @@ ; Then ffmpeg -filter_complex_script graph.txt -map '[v]' -frames:v 1 card.png. ; -- ; The honest limits: -; - a band shows DCARD_ROWS specs in edge-list order, not the "most important" ones: the card has -; no measure of importance, and does not pretend to; +; - "most imported" is the only measure: a spec many specs import is not thereby the most +; important neighbour, and the card does not claim it is. The ranking scans the edge list once +; per candidate per row, so it is quadratic; the corpus hub (378 importers, 2483 lines) is the +; largest band it has been measured on; ; - a `use` line t27c does not resolve is in neither band (deps_unknown, #10702, lists those); ; - two long names can abbreviate to the same text. The abbreviation says a name was cut; it ; does not say which spec it is, and the card does not claim it does; @@ -71,7 +77,7 @@ pub const DCARD_DOWN_ROW_Y : usize = 820; pub const DCARD_DOWN_MORE_Y : usize = 1068; pub const DCARD_HEAD : str = "WHO USES IT$"; -pub const DCARD_SUB : str = "imports and importers t27c resolved$"; +pub const DCARD_SUB : str = "most imported first in each band$"; pub const DCARD_CYCLE : str = "ON AN IMPORT CYCLE$"; pub const DCARD_UP : str = "IMPORTED BY $"; pub const DCARD_DOWN : str = "IMPORTS $"; @@ -140,6 +146,19 @@ pub fn dcard_dots_from(b: usize) -> usize { return b - (CARD_NAME_MAX - lit_len(DCARD_DOTS)); } +/// Can the fixed text s be drawn: every byte quotable or a space. ffmpeg reads a ':' or ',' inside +/// drawtext's quoted text as an option or filter separator and refuses the whole graph. +pub fn dcard_text_ok(s: []const u8) -> bool { + const k : usize = lit_len(s); + if (k == 0) { return false; } + var i : usize = 0; + while (i < k) { + if (card_quotable(s[i]) == false and s[i] != ' ') { return false; } + i += 1; + } + return true; +} + /// Is every byte of s[x..y] quotable. pub fn dcard_quotable_span(s: []const u8, x: usize, y: usize) -> bool { var i : usize = x; @@ -189,25 +208,73 @@ pub fn dcard_put_name(out: []u8, w: usize, cap: usize, s: []const u8, f: usize, return deps_put_span(out, q, cap, s, dcard_dots_from(b), b); } +// ---- ranking a band ---- + +/// Is the line buf[s..x] the same as some earlier line of buf[0..s]. +pub fn dcard_seen_before(buf: []const u8, s: usize, x: usize) -> bool { + var j : usize = 0; + while (j < s) { + const e : usize = line_end(buf, j, s); + if (same(buf, j, text_end(buf, j, e), buf, s, x)) { return true; } + j = e + 1; + } + return false; +} + +/// How many distinct specs the edge list buf[0..n] says import s[f..t]: lines whose second field is +/// s[f..t], a line repeated word for word counted once. +pub fn dcard_used_by(buf: []const u8, n: usize, s: []const u8, f: usize, t: usize) -> usize { + var c : usize = 0; + var i : usize = 0; + while (i < n) { + const e : usize = line_end(buf, i, n); + const x : usize = text_end(buf, i, e); + const p : usize = first_tab(buf, i, x); + if (p < x and p > i and same(buf, p + 1, x, s, f, t) and dcard_seen_before(buf, i, x) == false) { c += 1; } + i = e + 1; + } + return c; +} + +/// The line of set[lo..hi] drawn after the line at pp, whose score was ps: the highest score among +/// the lines ranked after it (a lower score, or the same score later in the set), the earliest on a +/// tie. hi when none is left. The first row passes ps = n + 1, above every score. +pub fn dcard_after(buf: []const u8, n: usize, set: []const u8, lo: usize, hi: usize, ps: usize, pp: usize) -> usize { + var best : usize = hi; + var bs : usize = 0; + var i : usize = lo; + while (i < hi) { + const e : usize = line_end(set, i, hi); + const sc : usize = dcard_used_by(buf, n, set, i, e); + if ((sc < ps or (sc == ps and i > pp)) and (best == hi or sc > bs)) { + best = i; + bs = sc; + } + i = e + 1; + } + return best; +} + // ---- reading the walks ---- -/// Can the first DCARD_ROWS lines of set[lo..hi] be drawn. -pub fn dcard_band_ok(set: []const u8, lo: usize, hi: usize) -> bool { +/// Can the DCARD_ROWS lines of set[lo..hi] that the band shows be drawn. +pub fn dcard_band_ok(buf: []const u8, n: usize, set: []const u8, lo: usize, hi: usize) -> bool { var r : usize = 0; - var i : usize = lo; + var i : usize = dcard_after(buf, n, set, lo, hi, n + 1, lo); while (i < hi and r < DCARD_ROWS) { const e : usize = line_end(set, i, hi); if (dcard_name_ok(set, i, e) == false) { return false; } r += 1; - i = e + 1; + i = dcard_after(buf, n, set, lo, hi, dcard_used_by(buf, n, set, i, e), i); } return true; } // ---- writing the graph ---- -/// One band: its label with the direct count d, its first rows of set[lo..hi], and `+N more`. -pub fn dcard_put_band(out: []u8, w: usize, cap: usize, font: []const u8, fnl: usize, set: []const u8, lo: usize, hi: usize, d: usize, label: []const u8, label_y: usize, row_y: usize, more_y: usize) -> usize { +/// One band: its label with the direct count d, its most imported rows of set[lo..hi] ranked over +/// the edge list buf[0..n], and `+N more`. +pub fn dcard_put_band(out: []u8, w: usize, cap: usize, font: []const u8, fnl: usize, buf: []const u8, n: usize, set: []const u8, lo: usize, hi: usize, d: usize, label: []const u8, label_y: usize, row_y: usize, more_y: usize) -> usize { const ok : u32 = VIEW_LABEL_STROKE[0]; const tint : u32 = VIEW_LABEL_FILL[0]; const muted : u32 = VIEW_LABEL_STROKE[3]; @@ -216,7 +283,7 @@ pub fn dcard_put_band(out: []u8, w: usize, cap: usize, font: []const u8, fnl: us p = deps_put_dec(out, p, cap, d); p = card_text_close(out, p, cap, muted, CARD_BOX_X, label_y); var r : usize = 0; - var i : usize = lo; + var i : usize = dcard_after(buf, n, set, lo, hi, n + 1, lo); while (i < hi and r < DCARD_ROWS) { const e : usize = line_end(set, i, hi); const y : usize = row_y + r * dcard_row_step(); @@ -226,7 +293,7 @@ pub fn dcard_put_band(out: []u8, w: usize, cap: usize, font: []const u8, fnl: us p = dcard_put_name(out, p, cap, set, i, e); p = card_text_close(out, p, cap, VIEW_TEXT, 0, y + DCARD_ROW_H / 2); r += 1; - i = e + 1; + i = dcard_after(buf, n, set, lo, hi, dcard_used_by(buf, n, set, i, e), i); } if (d > DCARD_ROWS) { p = card_text_open(out, p, cap, font, fnl, DCARD_BAND_FONT); @@ -269,7 +336,7 @@ pub fn dcard_graph(buf: []const u8, n: usize, focus: []const u8, ff: usize, ft: if (ti == 0 and tr == 0) { return 0; } const di : usize = deps_count(imp, ib[1], ib[2]); const dr : usize = deps_count(rev, rb[1], rb[2]); - if (dcard_band_ok(imp, ib[1], ib[2]) == false or dcard_band_ok(rev, rb[1], rb[2]) == false) { return 0; } + if (dcard_band_ok(buf, n, imp, ib[1], ib[2]) == false or dcard_band_ok(buf, n, rev, rb[1], rb[2]) == false) { return 0; } const ok : u32 = VIEW_LABEL_STROKE[0]; const gold : u32 = VIEW_LABEL_STROKE[1]; const tint : u32 = VIEW_LABEL_FILL[0]; @@ -292,7 +359,7 @@ pub fn dcard_graph(buf: []const u8, n: usize, focus: []const u8, ff: usize, ft: w = deps_put_lit(out, w, cap, DCARD_SUB); w = card_text_close(out, w, cap, muted, 0, CARD_SUB_Y); } - w = dcard_put_band(out, w, cap, font, fnl, rev, rb[1], rb[2], dr, DCARD_UP, DCARD_UP_LABEL_Y, DCARD_UP_ROW_Y, DCARD_UP_MORE_Y); + w = dcard_put_band(out, w, cap, font, fnl, buf, n, rev, rb[1], rb[2], dr, DCARD_UP, DCARD_UP_LABEL_Y, DCARD_UP_ROW_Y, DCARD_UP_MORE_Y); if (dr > 0) { w = dcard_put_uses(out, w, cap, font, fnl, dcard_band_bottom(DCARD_UP_ROW_Y, dcard_shown(dr)), DCARD_FOCUS_Y); } @@ -304,7 +371,7 @@ pub fn dcard_graph(buf: []const u8, n: usize, focus: []const u8, ff: usize, ft: if (di > 0) { w = dcard_put_uses(out, w, cap, font, fnl, DCARD_FOCUS_Y + DCARD_FOCUS_H, DCARD_DOWN_ROW_Y); } - w = dcard_put_band(out, w, cap, font, fnl, imp, ib[1], ib[2], di, DCARD_DOWN, DCARD_DOWN_LABEL_Y, DCARD_DOWN_ROW_Y, DCARD_DOWN_MORE_Y); + w = dcard_put_band(out, w, cap, font, fnl, buf, n, imp, ib[1], ib[2], di, DCARD_DOWN, DCARD_DOWN_LABEL_Y, DCARD_DOWN_ROW_Y, DCARD_DOWN_MORE_Y); w = card_text_open(out, w, cap, font, fnl, CARD_FOOT_FONT); w = deps_put_lit(out, w, cap, DCARD_REACHES); w = deps_put_dec(out, w, cap, ti); @@ -398,7 +465,7 @@ test dcard_draws_both_bands_and_the_focus { assert card_count(&out, w, "text='IMPORTED BY 1'$") == 1; assert card_count(&out, w, "text='IMPORTS 2'$") == 1; assert card_count(&out, w, "text='reaches 3 / reached by 2 / every edge exact'$") == 1; - assert card_count(&out, w, "text='imports and importers t27c resolved'$") == 1; + assert card_count(&out, w, "text='most imported first in each band'$") == 1; assert card_count(&out, w, "CYCLE$") == 0; assert card_count(&out, w, " more'$") == 0; assert card_count(&out, w, ":color=0x00FF88:t=8$") == 1; @@ -408,7 +475,7 @@ test dcard_draws_both_bands_and_the_focus { assert card_count(&out, w, "[v]\n$") == 1; } -test dcard_bands_follow_the_edge_list_order { +test dcard_equal_scores_keep_the_edge_list_order { var imp : [256]u8 = undefined; var rev : [256]u8 = undefined; var ib : [35]usize = undefined; @@ -479,7 +546,7 @@ test dcard_flags_a_focus_on_an_import_cycle { const w : usize = dcard_graph(c, lit_len(c), "p$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 256, &ib, &rev, 256, &rb, &out, 8192); assert w > 0; assert card_count(&out, w, "text='ON AN IMPORT CYCLE':fontcolor=0xFFD700$") == 1; - assert card_count(&out, w, "text='imports and importers t27c resolved'$") == 0; + assert card_count(&out, w, "text='most imported first in each band'$") == 0; assert card_count(&out, w, "text='q'$") == 2; const r : usize = dcard_graph(c, lit_len(c), "r$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 256, &ib, &rev, 256, &rb, &out, 8192); assert r > 0; @@ -513,6 +580,8 @@ test dcard_every_band_fits_the_card_without_overlap { } const foot : usize = lit_len(DCARD_REACHES) + 4 + lit_len(DCARD_REACHED) + 4 + lit_len(DCARD_FOOT); assert foot * CARD_FOOT_FONT * 3 <= CARD_W * 5; + assert lit_len(DCARD_SUB) * CARD_SUB_FONT * 3 <= CARD_BOX_W * 5; + assert lit_len(DCARD_CYCLE) * CARD_SUB_FONT * 3 <= CARD_BOX_W * 5; } test negative_control_a_spec_not_in_the_list_is_not_drawn { @@ -694,3 +763,84 @@ test negative_control_a_long_name_whose_drawn_bytes_cannot_be_quoted_is_not_draw const h : str = "port/tr:os/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_inter_arrival_autocorrelation_guard\tx\n$"; assert dcard_graph(h, lit_len(h), "x$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 512, &ib, &rev, 512, &rb, &out, 8192) > 0; } + +pub const DCARD_RANK : str = "h\tm1\nh\tm2\nh\tm3\nh\tm4\nx\tm4\ny\tm4\nx\tm3\nu1\th\nu2\th\nk\tu2\n$"; + +test dcard_a_band_shows_its_most_imported_specs_first { + var imp : [256]u8 = undefined; + var rev : [256]u8 = undefined; + var ib : [35]usize = undefined; + var rb : [35]usize = undefined; + var out : [8192]u8 = undefined; + const g : str = DCARD_RANK; + const w : usize = dcard_graph(g, lit_len(g), "h$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 256, &ib, &rev, 256, &rb, &out, 8192); + assert w > 0; + assert card_count(&out, w, "text='m4':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=852-text_h/2$") == 1; + assert card_count(&out, w, "text='m3':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=928-text_h/2$") == 1; + assert card_count(&out, w, "text='m1':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=1004-text_h/2$") == 1; + assert card_count(&out, w, "text='m2'$") == 0; + assert card_count(&out, w, "text='+1 more'$") == 1; + assert card_count(&out, w, "text='IMPORTS 4'$") == 1; + assert card_count(&out, w, "text='u2':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=312-text_h/2$") == 1; + assert card_count(&out, w, "text='u1':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=388-text_h/2$") == 1; + assert card_count(&out, w, "text='IMPORTED BY 2'$") == 1; + assert card_count(&out, w, "text='reaches 4 / reached by 3 / every edge exact'$") == 1; +} + +test dcard_a_repeated_edge_line_counts_one_importer { + const g : str = "h\tq\nh\tp\nz\tq\na\tp\na\tp\na\tp\r\n$"; + const n : usize = lit_len(g); + assert dcard_used_by(g, n, "p$", 0, 1) == 2; + assert dcard_used_by(g, n, "q$", 0, 1) == 2; + assert dcard_used_by(g, n, "h$", 0, 1) == 0; + assert dcard_used_by(g, n, "zz$", 0, 2) == 0; + assert dcard_used_by(g, 0, "p$", 0, 1) == 0; + var imp : [256]u8 = undefined; + var rev : [256]u8 = undefined; + var ib : [35]usize = undefined; + var rb : [35]usize = undefined; + var out : [8192]u8 = undefined; + const w : usize = dcard_graph(g, n, "h$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 256, &ib, &rev, 256, &rb, &out, 8192); + assert w > 0; + assert card_count(&out, w, "text='q':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=852-text_h/2$") == 1; + assert card_count(&out, w, "text='p':fontcolor=0xFFFFFF:x=(w-text_w)/2:y=928-text_h/2$") == 1; +} + +test negative_control_the_name_check_follows_the_ranking { + var imp : [256]u8 = undefined; + var rev : [256]u8 = undefined; + var ib : [35]usize = undefined; + var rb : [35]usize = undefined; + var out : [8192]u8 = undefined; + const up : str = "h\tm1\nh\tm2\nh\tm3\nh\tm:4\nx\tm:4\n$"; + assert dcard_graph(up, lit_len(up), "h$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 256, &ib, &rev, 256, &rb, &out, 8192) == 0; + const down : str = "h\tm1\nh\tm:2\nh\tm3\nh\tm4\nx\tm1\nx\tm3\nx\tm4\n$"; + const w : usize = dcard_graph(down, lit_len(down), "h$", 0, 1, CARD_TEST_FONT, lit_len(CARD_TEST_FONT), &imp, 256, &ib, &rev, 256, &rb, &out, 8192); + assert w > 0; + assert card_count(&out, w, "text='+1 more'$") == 1; + assert card_count(&out, w, "m:2$") == 0; +} + +test dcard_every_fixed_text_can_be_drawn { + assert dcard_text_ok(DCARD_HEAD); + assert dcard_text_ok(DCARD_SUB); + assert dcard_text_ok(DCARD_CYCLE); + assert dcard_text_ok(DCARD_UP); + assert dcard_text_ok(DCARD_DOWN); + assert dcard_text_ok(DCARD_MORE); + assert dcard_text_ok(DCARD_REACHES); + assert dcard_text_ok(DCARD_REACHED); + assert dcard_text_ok(DCARD_FOOT); + assert dcard_text_ok(DCARD_CUT); + assert dcard_text_ok(DCARD_DOTS); + assert dcard_text_ok(CARD_USES); + assert dcard_text_ok(CARD_SITE); +} + +test negative_control_a_fixed_text_ffmpeg_would_split_is_refused { + assert dcard_text_ok("each band: most imported first$") == false; + assert dcard_text_ok("a, b$") == false; + assert dcard_text_ok("it's$") == false; + assert dcard_text_ok("$") == false; + assert dcard_text_ok("a b-c/d.e_f$"); +} diff --git a/tools/verilog_width_baseline.txt b/tools/verilog_width_baseline.txt index c9ab527525..e0e1ef5c6e 100644 --- a/tools/verilog_width_baseline.txt +++ b/tools/verilog_width_baseline.txt @@ -60,3 +60,17 @@ specs/claw/suggest_feed.t27 # renders 1080x1920 and 1920x1080 video on a host; it has no hardware form. # Same class as big_frame.t27 and suggest_feed.t27. specs/t27f/token_floor.t27 +# +# specs/t27f/why_card.t27 and specs/t27f/deps_card.t27 -- not buses: each +# main() reads the whole `t27c use-edges` text from stdin into one byte +# array, and the arithmetic is exact: +# +# edges : [262144]u8 = 262144*8 = 2,097,152 bits -> [2097151:0] +# +# The edge list of the corpus is 136,837 bytes today, already over the +# 131,071 bytes (2^20 bits) a smaller array could hold, so the array cannot +# shrink below the threshold without refusing the real corpus. Host-side text +# plumbing for a social-card renderer, with no hardware form. Same class as +# suggest_feed.t27 and token_floor.t27. +specs/t27f/why_card.t27 +specs/t27f/deps_card.t27