code wiki / _hdl_build / nx_book_links_gate.nx
nx_book_links_gate.nx source
↩ module page · 93 lines · 8740 B
1// nx_book_links_gate.nx -- liar-kill gate for ISSUE-3 server side: nx_epub_book must (1) EMIT in-book <a href>
2// as inline link markers (STX 0x02 url SOH 0x01 text ETX 0x03) the reader renders as clickable <a>, (2) expose
3// each chapter's source basename as chapters[].src so the reader resolves an internal href -> chapter idx, and
4// (3) keep capturing footnotes (chapters[].fn[]). Builds a real EPUB w/ an external link, an internal link, and a
5// footnote; runs the REAL nx_epub_book (self-rebuilt); asserts the emitted bytes + JSON. expect_exit: 0 license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_opc.nx"
8
9func 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 }
10func tg_n(v0: i64) -> i64 { var v: i64=v0; if v<0 { sys_write(1,"-" as *u8,1); v=0-v } let b: *u8=sys_mmap(24); var k: i64=0; if v==0 {b[0]=48 as u8;k=1} while v>0 {b[k]=(48+(v%10)) as u8; v=v/10; k=k+1} let o: *u8=sys_mmap(24); var j: i64=0; while j<k {o[j]=b[k-1-j];j=j+1} sys_write(1,o,k); return 0 }
11func tg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
12func ensure_dir(path: *u8) -> i64 { __syscall(258, 0-100, path, 0x1ed, 0, 0, 0); return 0 }
13func hassub(buf: *u8, n: i64, needle: *u8) -> i64 {
14 let nl: i64 = tg_slen(needle); if nl == 0 { return 0 }
15 var i: i64 = 0
16 while i + nl <= n { var k: i64=0; var hit: i64=1; while k<nl { if (buf[i+k]&0xff)!=(needle[k]&0xff){hit=0;k=nl}else{k=k+1} } if hit==1 {return 1} i=i+1 }
17 return 0
18}
19func has1(buf: *u8, n: i64, a: i64) -> i64 { var i: i64=0; while i < n { if (buf[i]&0xff)==a { return 1 } i=i+1 } return 0 }
20func run2(path: *u8, a0: *u8, a1: *u8, redir: *u8) -> i64 {
21 let pid: i64 = sys_fork()
22 if pid == 0 {
23 let fd: i64 = sys_openat_wr(redir, 420)
24 if fd >= 0 { sys_dup3(fd, 1, 0); sys_dup3(fd, 2, 0) }
25 let argv: *i64 = sys_mmap(64) as *i64
26 argv[0] = path as i64; argv[1] = a0 as i64; argv[2] = a1 as i64; argv[3] = 0
27 sys_execve(path, argv, 0 as *i64)
28 sys_exit(127)
29 }
30 let st: *i64 = sys_mmap(16) as *i64
31 sys_wait4(pid, st, 0)
32 return (st[0] >> 8) & 0xff
33}
34func chk(label: *u8, cond: i64, pf: *i64) -> i64 {
35 tg_p(" "); tg_p(label)
36 if cond == 1 { tg_p(" PASS\n"); pf[0]=pf[0]+1 } else { tg_p(" FAIL\n"); pf[1]=pf[1]+1 }
37 return 0
38}
39
40func main() -> i64 {
41 tg_p("=== nx_book_links_gate: in-book link markers + chapters[].src + footnotes ===\n" as *u8)
42 let pf: *i64 = sys_mmap(16) as *i64; pf[0]=0; pf[1]=0
43 ensure_dir("knowledge/fixtures" as *u8)
44
45 let names: *i64 = sys_mmap(8*8) as *i64
46 let datap: *i64 = sys_mmap(8*8) as *i64
47 let lens: *i64 = sys_mmap(8*8) as *i64
48 let mimetype: *u8 = "application/epub+zip" as *u8
49 let container: *u8 = "<?xml version=\"1.0\"?>\n<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n<rootfiles><rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/></rootfiles>\n</container>\n" as *u8
50 let opf: *u8 = "<?xml version=\"1.0\"?>\n<package xmlns=\"http://www.idpf.org/2007/opf\" version=\"3.0\" unique-identifier=\"bookid\">\n<metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n<dc:title>Links Fixture</dc:title>\n<dc:creator>Lewis Carroll</dc:creator>\n<dc:publisher>Sovereign Press</dc:publisher>\n<dc:identifier id=\"bookid\">links-1</dc:identifier>\n</metadata>\n<manifest>\n<item id=\"ch1\" href=\"ch1.xhtml\" media-type=\"application/xhtml+xml\"/>\n<item id=\"ch2\" href=\"ch2.xhtml\" media-type=\"application/xhtml+xml\"/>\n</manifest>\n<spine>\n<itemref idref=\"ch1\"/>\n<itemref idref=\"ch2\"/>\n</spine>\n</package>\n" as *u8
51 // ch1: an EXTERNAL link, an INTERNAL link (to ch2.xhtml), and a footnote (noteref + aside). + prose for the floor.
52 let ch1: *u8 = "<?xml version=\"1.0\"?>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\"><head><title>x</title></head><body>\n<h1>Chapter One</h1>\n<p>Visit <a href=\"https://example.com/ext\">External Site</a> for more, or jump to <a href=\"ch2.xhtml\">Go to Part Two</a> right now.<a epub:type=\"noteref\" href=\"#fn1\" id=\"r1\">1</a></p>\n<p>Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, and what is the use of a book, thought Alice, without pictures or conversations? So she was considering in her own mind whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her, and she ran across the field after it, and was just in time to see it pop down a large rabbit-hole under the hedge.</p>\n<aside epub:type=\"footnote\" id=\"fn1\"><p>A telescope here is the collapsible spyglass kind that folds shut.</p></aside>\n</body></html>\n" as *u8
53 let ch2: *u8 = "<?xml version=\"1.0\"?>\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>x</title></head><body>\n<h1>Part Two</h1>\n<p>In another moment down went Alice after the White Rabbit, never once considering how in the world she was to get out again. The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly down, so suddenly that Alice had not a moment to think about stopping herself before she found herself falling down what seemed to be a very deep well. Either the well was very deep, or she fell very slowly, for she had plenty of time as she went down to look about her, and to wonder what was going to happen next.</p>\n</body></html>\n" as *u8
54 names[0]=("mimetype" as *u8) as i64; datap[0]=mimetype as i64; lens[0]=tg_slen(mimetype)
55 names[1]=("META-INF/container.xml" as *u8) as i64; datap[1]=container as i64; lens[1]=tg_slen(container)
56 names[2]=("OEBPS/content.opf" as *u8) as i64; datap[2]=opf as i64; lens[2]=tg_slen(opf)
57 names[3]=("OEBPS/ch1.xhtml" as *u8) as i64; datap[3]=ch1 as i64; lens[3]=tg_slen(ch1)
58 names[4]=("OEBPS/ch2.xhtml" as *u8) as i64; datap[4]=ch2 as i64; lens[4]=tg_slen(ch2)
59 let w: i64 = opc_write("knowledge/fixtures/nishi_links.epub" as *u8, names, datap, lens, 5)
60 if w <= 0 { tg_p("LINKS-GATE verdict=RED reason=fixture-write\n" as *u8); sys_exit(1); return 1 }
61
62 run2("_offc/nx_sov_build_run.elf\x00" as *u8, "nx_epub_book\x00" as *u8, 0 as *u8, "knowledge/status/links_e2e_scratch.log\x00" as *u8)
63 let rc: i64 = run2("_offc/nx_epub_book.elf\x00" as *u8, "knowledge/fixtures/nishi_links.epub\x00" as *u8, "links_e2e\x00" as *u8, "knowledge/status/links_e2e_scratch.log\x00" as *u8)
64 tg_p(" nx_epub_book exit="); tg_n(rc); tg_p("\n" as *u8)
65
66 let lp: *i64 = sys_mmap(8) as *i64; lp[0]=0
67 let chap: *u8 = sys_read_file("knowledge/staging/media/reader/links_e2e/chap0.txt\x00" as *u8, lp)
68 if (chap as i64) == 0 { tg_p("LINKS-GATE verdict=RED reason=chap0-missing\n" as *u8); sys_exit(1); return 1 }
69 let cn: i64 = lp[0]
70 // link markers present (STX/SOH/ETX) + the external URL + its anchor text
71 chk("STX 0x02 link-open present" as *u8, has1(chap, cn, 0x02), pf)
72 chk("SOH 0x01 link-sep present" as *u8, has1(chap, cn, 0x01), pf)
73 chk("ETX 0x03 link-close present" as *u8, has1(chap, cn, 0x03), pf)
74 chk("external URL emitted" as *u8, hassub(chap, cn, "https://example.com/ext" as *u8), pf)
75 chk("link anchor text present" as *u8, hassub(chap, cn, "External Site" as *u8), pf)
76 chk("internal href ch2.xhtml emitted" as *u8, hassub(chap, cn, "ch2.xhtml" as *u8), pf)
77 // teeth: the raw <a tag must NOT survive as text
78 chk("no raw '<a href' tag in text" as *u8, 1 - hassub(chap, cn, "<a href" as *u8), pf)
79
80 let jp: *i64 = sys_mmap(8) as *i64; jp[0]=0
81 let jb: *u8 = sys_read_file("knowledge/staging/media/reader/links_e2e/book.json\x00" as *u8, jp)
82 if (jb as i64) == 0 { tg_p("LINKS-GATE verdict=RED reason=book.json-missing\n" as *u8); sys_exit(1); return 1 }
83 let jn: i64 = jp[0]
84 chk("chapters[].src ch1.xhtml" as *u8, hassub(jb, jn, "\"src\":\"ch1.xhtml\"" as *u8), pf)
85 chk("chapters[].src ch2.xhtml" as *u8, hassub(jb, jn, "\"src\":\"ch2.xhtml\"" as *u8), pf)
86 chk("footnote captured (fn text)" as *u8, hassub(jb, jn, "collapsible spyglass" as *u8), pf)
87 chk("epub publisher captured" as *u8, hassub(jb, jn, "Sovereign Press" as *u8), pf)
88 chk("rfix cache-heal marker present" as *u8, hassub(jb, jn, "\"rfix\":1" as *u8), pf)
89
90 tg_p("LINKS-GATE pass="); tg_n(pf[0]); tg_p(" fail="); tg_n(pf[1])
91 if pf[1] == 0 { tg_p(" verdict=GREEN\n"); sys_exit(0); return 0 }
92 tg_p(" verdict=RED\n"); sys_exit(1); return 1
93}