code wiki / _hdl_build / nx_epub_toc_gate.nx
nx_epub_toc_gate.nx source
↩ module page · 61 lines · 6925 B
1// nx_epub_toc_gate.nx -- liar-kill gate for the EPUB navigation-document parser (Reader-arc R-TOC).
2// Proves nx_epub_nav parses BOTH EPUB3 nav.xhtml (nested <ol>) and EPUB2 toc.ncx (nested <navPoint>) into the
3// correct DEPTH-TAGGED {depth,label,href} entries, preserving hierarchy. Negative control: a nav with no
4// epub:type="toc" yields 0 entries (no fabricated TOC). Deterministic, sovereign, no network. expect_exit: 0
5import "nx_syscalls.nx"
6import "nx_epub_nav.nx"
7
8func tg_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
9func tg_n(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 }
10func tg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
11func tg_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i]{return 0} i=i+1 } if b[i]!=(0 as u8){return 0} return 1 }
12
13// global pass/fail
14func main() -> i64 {
15 let depths: *i64 = sys_mmap(8 * 128) as *i64
16 let loffs: *i64 = sys_mmap(8 * 128) as *i64
17 let hoffs: *i64 = sys_mmap(8 * 128) as *i64
18 let larena: *u8 = sys_mmap(16384)
19 let harena: *u8 = sys_mmap(16384)
20
21 var pass: i64 = 0
22 var fail: i64 = 0
23
24 tg_p("=== nx_epub_toc_gate: EPUB nav-document parser (R-TOC) ===\n" as *u8)
25
26 // ---------- EPUB3 nav.xhtml (nested <ol>) ----------
27 let nav3: *u8 = "<?xml version=\"1.0\"?>\n<html xmlns:epub=\"http://www.idpf.org/2007/ops\"><body>\n<nav epub:type=\"toc\"><h2>Contents</h2>\n<ol>\n<li><a href=\"cover.xhtml\">Cover</a></li>\n<li><a href=\"ch1.xhtml\">Chapter 1: Down the Rabbit-Hole</a></li>\n<li><a href=\"ch2.xhtml\">Part Two</a>\n<ol>\n<li><a href=\"ch2.xhtml#s1\">2.1 The Pool of Tears</a></li>\n<li><a href=\"ch3.xhtml\">2.2 A Caucus-Race</a></li>\n</ol>\n</li>\n<li><a href=\"ch4.xhtml\">Chapter 4</a></li>\n</ol>\n</nav>\n</body></html>\n" as *u8
28 let c3: i64 = nav_parse_xhtml(nav3, tg_slen(nav3), depths, larena, loffs, harena, hoffs, 128)
29 tg_p(" nav.xhtml entries=" as *u8); tg_n(c3); tg_p(" (expect 6)\n" as *u8)
30 if c3 == 6 { pass = pass + 1 } else { fail = fail + 1; tg_p(" FAIL nav3-count\n" as *u8) }
31
32 // entry 0: depth0 Cover cover.xhtml
33 if c3 > 0 { if depths[0]==0 { if tg_streq((larena as i64 + loffs[0]) as *u8, "Cover" as *u8)==1 { if tg_streq((harena as i64 + hoffs[0]) as *u8, "cover.xhtml" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL e0-href\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e0-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e0-depth\n" as *u8) } }
34 // entry 2: depth0 "Part Two" ch2.xhtml (the parent of the nested list)
35 if c3 > 2 { if depths[2]==0 { if tg_streq((larena as i64 + loffs[2]) as *u8, "Part Two" as *u8)==1 { if tg_streq((harena as i64 + hoffs[2]) as *u8, "ch2.xhtml" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL e2-href\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e2-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e2-depth\n" as *u8) } }
36 // entry 3: DEPTH 1 "2.1 The Pool of Tears" ch2.xhtml#s1 (the hierarchy proof + fragment kept)
37 if c3 > 3 { if depths[3]==1 { if tg_streq((larena as i64 + loffs[3]) as *u8, "2.1 The Pool of Tears" as *u8)==1 { if tg_streq((harena as i64 + hoffs[3]) as *u8, "ch2.xhtml#s1" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL e3-href\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e3-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e3-depth(expect1)\n" as *u8) } }
38 // entry 5: depth0 "Chapter 4" ch4.xhtml (correctly back to depth 0 after the nested </ol>)
39 if c3 > 5 { if depths[5]==0 { if tg_streq((larena as i64 + loffs[5]) as *u8, "Chapter 4" as *u8)==1 { if tg_streq((harena as i64 + hoffs[5]) as *u8, "ch4.xhtml" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL e5-href\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e5-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL e5-depth(expect0)\n" as *u8) } }
40
41 // ---------- EPUB2 toc.ncx (nested <navPoint>) ----------
42 let ncx: *u8 = "<?xml version=\"1.0\"?>\n<ncx version=\"2005-1\"><docTitle><text>Alice</text></docTitle>\n<navMap>\n<navPoint id=\"np1\" playOrder=\"1\"><navLabel><text>Chapter 1</text></navLabel><content src=\"ch1.xhtml\"/>\n<navPoint id=\"np1a\" playOrder=\"2\"><navLabel><text>Section 1.1</text></navLabel><content src=\"ch1.xhtml#s1\"/></navPoint>\n</navPoint>\n<navPoint id=\"np2\" playOrder=\"3\"><navLabel><text>Chapter 2</text></navLabel><content src=\"ch2.xhtml\"/></navPoint>\n</navMap>\n</ncx>\n" as *u8
43 let cn: i64 = ncx_parse(ncx, tg_slen(ncx), depths, larena, loffs, harena, hoffs, 128)
44 tg_p(" toc.ncx entries=" as *u8); tg_n(cn); tg_p(" (expect 3)\n" as *u8)
45 if cn == 3 { pass = pass + 1 } else { fail = fail + 1; tg_p(" FAIL ncx-count\n" as *u8) }
46 if cn > 0 { if depths[0]==0 { if tg_streq((larena as i64 + loffs[0]) as *u8, "Chapter 1" as *u8)==1 { if tg_streq((harena as i64 + hoffs[0]) as *u8, "ch1.xhtml" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL n0-href\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL n0-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL n0-depth\n" as *u8) } }
47 if cn > 1 { if depths[1]==1 { if tg_streq((larena as i64 + loffs[1]) as *u8, "Section 1.1" as *u8)==1 { if tg_streq((harena as i64 + hoffs[1]) as *u8, "ch1.xhtml#s1" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL n1-href\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL n1-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL n1-depth(expect1)\n" as *u8) } }
48 if cn > 2 { if depths[2]==0 { if tg_streq((larena as i64 + loffs[2]) as *u8, "Chapter 2" as *u8)==1 { pass=pass+1 } else { fail=fail+1; tg_p(" FAIL n2-label\n" as *u8) } } else { fail=fail+1; tg_p(" FAIL n2-depth(expect0)\n" as *u8) } }
49
50 // ---------- NEGATIVE CONTROL: a nav with NO epub:type="toc" must yield 0 (no fabricated TOC) ----------
51 let bad: *u8 = "<html><body><nav><ol><li><a href=\"x.xhtml\">X</a></li></ol></nav></body></html>" as *u8
52 let cb: i64 = nav_parse_xhtml(bad, tg_slen(bad), depths, larena, loffs, harena, hoffs, 128)
53 tg_p(" neg-control (no toc marker) entries=" as *u8); tg_n(cb); tg_p(" (expect 0)\n" as *u8)
54 if cb == 0 { pass = pass + 1 } else { fail = fail + 1; tg_p(" FAIL neg-control-fabricated\n" as *u8) }
55 // teeth: streq must discriminate (so a GREEN means something)
56 if tg_streq("Cover" as *u8, "Wrong" as *u8) == 0 { pass = pass + 1 } else { fail = fail + 1; tg_p(" FAIL streq-teeth\n" as *u8) }
57
58 tg_p("EPUB-TOC-GATE pass=" as *u8); tg_n(pass); tg_p(" fail=" as *u8); tg_n(fail)
59 if fail == 0 { tg_p(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
60 tg_p(" verdict=RED\n" as *u8); sys_exit(1); return 1
61}