code wiki / _hdl_build / nx_codewiki.nx
nx_codewiki.nx source
↩ module page · 117 lines · 5462 B
1// nx_codewiki.nx -- CLI for the code wiki generator (logic in nx_codewiki_lib.nx,
2// split so the gate can import the lib -- a module owning main() cannot be
3// imported by a second entry point, per the nx_gatelib lesson).
4//
5// nx_codewiki [srcroot] [outdir] [noext]
6// defaults: srcroot=runtime outdir=_codewiki linkmode=.html
7// 3rd arg literal "noext" emits extensionless hrefs (the edge's canonical
8// clean-URL form; use for NAS deploys -- local file browsing wants .html)
9//
10// license_tier: ORIGINAL
11import "nx_syscalls.nx"
12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
13import "nx_eco_graph.nx"
14import "nx_gatelib.nx"
15import "nx_import_scan.nx"
16import "nx_codewiki_lib.nx"
17const K_MAGIC_1024: i64 = 1024
18
19func cwm_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
20// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
21// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
22// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
23// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
24func cwm_n(v: i64) -> i64 { nxi_out(v); return 0 }
25
26func main(argc: i64, argv: *i64) -> i64 {
27 // ---- ask mode: nx_codewiki ask <question words...> ----
28 if argc >= 3 {
29 let a1: *u8 = argv[1] as *u8
30 var isask: i64 = 0
31 if a1[0] == (97 as u8) { if a1[1] == (115 as u8) { if a1[2] == (107 as u8) { if a1[3] == (0 as u8) { isask = 1 } } } }
32 if isask == 1 {
33 let toks: *u8 = sys_mmap(K_MAGIC_1024)
34 let toff: *i64 = sys_mmap(CW_ASKQTOK * 8) as *i64
35 let tlen: *i64 = sys_mmap(CW_ASKQTOK * 8) as *i64
36 let nt: i64 = cw_qtok(argv, argc, 2, toks, toff, tlen)
37 if nt == 0 {
38 cwm_w("ASK-NO-TOKENS: question has no word of >= 3 characters.\n" as *u8)
39 sys_exit(1)
40 return 1
41 }
42 let hits: i64 = cw_ask("sites/nishifamily/code/askindex.tsv" as *u8, toks, toff, tlen, nt, "https://nishifamily.com/code/" as *u8, 0 as *u8)
43 if hits < 0 { sys_exit(2); return 2 }
44 sys_exit(0)
45 return 0
46 }
47 }
48
49 var root: *u8 = "runtime" as *u8
50 var outdir: *u8 = "_codewiki" as *u8
51 var noext: i64 = 0
52 if argc >= 2 { root = argv[1] as *u8 }
53 if argc >= 3 { outdir = argv[2] as *u8 }
54 if argc >= 4 {
55 let a3: *u8 = argv[3] as *u8
56 if a3[0] == (110 as u8) { if a3[1] == (111 as u8) { if a3[2] == (101 as u8) { noext = 1 } } }
57 }
58
59 cwm_w("=== NISHI CODE WIKI -- generated from the tree, never hand-written ===\n" as *u8)
60 cwm_w("root=" as *u8); cwm_w(root)
61 cwm_w(" out=" as *u8); cwm_w(outdir)
62 cwm_w(" caps(DECLARED): nodes=" as *u8); cwm_n(CW_MAXNODE)
63 cwm_w(" edges=" as *u8); cwm_n(CW_EDGECAP)
64 cwm_w(" page=" as *u8); cwm_n(CW_PAGECAP)
65 cwm_w("B\n" as *u8)
66
67 let st: *i64 = sys_mmap(24 * 8) as *i64
68 var i: i64 = 0
69 while i < 24 { st[i] = 0; i = i + 1 }
70 let rc: i64 = cw_generate2(root, outdir, noext, st, "tool_allowlist.conf" as *u8, "knowledge/tool_schemas.conf" as *u8, "knowledge/codewiki_atlas.conf" as *u8)
71 if rc == 2 { cwm_w("EMPTY-ROOT: no .nx files under root -- refusing to publish a green nothing. verdict=RED\n" as *u8); sys_exit(2); return 2 }
72 if rc != 0 { cwm_w("GENERATE-FAILED rc=" as *u8); cwm_n(rc); cwm_w("\n" as *u8); sys_exit(2); return 2 }
73
74 cwm_w("files=" as *u8); cwm_n(st[0])
75 cwm_w(" nodes=" as *u8); cwm_n(st[1])
76 cwm_w(" edges=" as *u8); cwm_n(st[2])
77 cwm_w(" funcs=" as *u8); cwm_n(st[3])
78 cwm_w(" structs=" as *u8); cwm_n(st[4])
79 cwm_w(" consts=" as *u8); cwm_n(st[5])
80 cwm_w("\ndirs=" as *u8); cwm_n(st[10])
81 cwm_w(" pages=" as *u8); cwm_n(st[7])
82 cwm_w(" truncated=" as *u8); cwm_n(st[11])
83 cwm_w(" unresolved-imports=" as *u8); cwm_n(st[6])
84 cwm_w(" cycle=" as *u8); cwm_n(st[9])
85 cwm_w(" stamp=" as *u8); cwm_n(st[8])
86 cwm_w(" mcp-exposed=" as *u8); cwm_n(st[19]); cwm_w(" deployed-dark=" as *u8); cwm_n(st[20]); cwm_w(" findings-filed=" as *u8); cwm_n(st[21]);
87 cwm_w(" orphan-libraries=" as *u8); cwm_n(st[18])
88 cwm_w("\naskindex: records=" as *u8); cwm_n(st[16])
89 cwm_w(" truncated=" as *u8); cwm_n(st[17])
90 cwm_w("\ncallgraph: defs=" as *u8); cwm_n(st[12])
91 cwm_w(" edges=" as *u8); cwm_n(st[13])
92 cwm_w(" ambiguous-or-unknown=" as *u8); cwm_n(st[14])
93 cwm_w("\n" as *u8)
94
95 // A truncated retrieval corpus answers questions from a fraction of the
96 // tree and looks identical to a healthy one. Refuse, loudly.
97 if st[17] != 0 {
98 cwm_w("ASK-INDEX-TRUNCATED at the declared cap -- retrieval would answer from a PARTIAL corpus. verdict=RED\n" as *u8)
99 sys_exit(4)
100 return 4
101 }
102
103 // pages = module pages + SOURCE pages (one per file) + dirs + topic pages
104 // (incl topics index, st[15]) + index + search + ask + lang + tools + pulse
105 // + arch + modindex.js + fnindex.js + toolindex.js + atlas
106 let expect: i64 = st[0] + st[0] + st[10] + st[15] + 19
107 if st[7] != expect {
108 cwm_w("PAGE-COUNT-MISMATCH expect=" as *u8); cwm_n(expect)
109 cwm_w(" got=" as *u8); cwm_n(st[7])
110 cwm_w(" verdict=RED\n" as *u8)
111 sys_exit(3)
112 return 3
113 }
114 cwm_w("verdict=GREEN\n" as *u8)
115 sys_exit(0)
116 return 0
117}