code wiki / _hdl_build / nx_wirecensus_lib.nx
nx_wirecensus_lib.nx source
↩ module page · 538 lines · 24058 B
1// nx_wirecensus_lib.nx -- S4 OF THE WIRING CENSUS: REGISTERED BUT NEVER CALLED.
2//
3// WHY THIS AND NOT MORE CALL-GRAPH (July-2026 external SOTA, debt id=1785451391): the field's largest
4// dead-surface win came from RUNTIME evidence, not static analysis -- an Express codebase shed 16,000
5// lines (35 pct) by cross-referencing ACCESS LOGS against REGISTERED ROUTES, and the write-up states
6// plainly that static tools "only detect unreachable code, not the absence of live traffic".
7// nx_adopt already answers the static question (S1: defined, zero external callers). It structurally
8// CANNOT see a tool that is registered, callable, advertised -- and that nobody has ever invoked.
9// That tool is worse than dead code: it occupies the capability surface and reads as a feature.
10//
11// THE TWO WITNESSES, and why one is strong and one is weak (stated so the verdict is not oversold):
12// W1 cap_consent.log "CAPMINT ... allow=<csv> ..." -- STRONG. A capability is MANDATORY to invoke
13// a tool over /mcp, so a tool that never appears in any allow= list was never callable in
14// practice. Absence here is close to proof.
15// W2 actlog.jrnl TAB field 2 = the tool actually invoked -- WEAK BUT POSITIVE. Seats log
16// VOLUNTARILY, so absence proves nothing; PRESENCE proves use. Used only to rescue tools from
17// the dark list, never to condemn them.
18// A tool is DARK only if BOTH witnesses are silent. Union, not intersection -- the conservative side.
19//
20// KNOWN BLIND SPOT, REPORTED NOT HIDDEN: caps minted before this log existed, or minted with the
21// root nx_cap_mint on the NAS rather than POST /api/cap/mint, never reach cap_consent.log. So DARK is
22// an UPPER BOUND on unused surface, exactly as nx_adopt's raw count was an upper bound before the
23// public/local split. Anyone quoting this number must quote the bound with it.
24// license_tier: ORIGINAL Read-only. No hw writes (Rule 26).
25import "nx_syscalls.nx"
26const WC_MAGIC_262144: i64 = 262144
27const WC_MAGIC_1048576: i64 = 1048576
28
29const WC_BUF: i64 = 4194304
30const WC_MAXT: i64 = 2048
31const WC_NAMEMAX: i64 = 64
32const WC_TAB: i64 = 9
33const WC_NL: i64 = 10
34const WC_HASH: i64 = 35
35const WC_COMMA: i64 = 44
36const WC_SP: i64 = 32
37
38func wc_read(path: *u8, buf: *u8, cap: i64) -> i64 {
39 let fd: i64 = sys_openat_rd(path)
40 if fd < 0 { return 0 - 1 }
41 var n: i64 = 0
42 var go: i64 = 1
43 while go == 1 {
44 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n)
45 if r <= 0 { go = 0 } else { n = n + r; if n >= cap { go = 0 } }
46 }
47 sys_close(fd)
48 return n
49}
50
51func wc_name_ch(c: i64) -> i64 {
52 if c >= 97 { if c <= 122 { return 1 } }
53 if c >= 65 { if c <= 90 { return 1 } }
54 if c >= 48 { if c <= 57 { return 1 } }
55 if c == 95 { return 1 }
56 return 0
57}
58
59func wc_has(names: *u8, lens: *i64, cnt: i64, p: *u8, l: i64) -> i64 {
60 var i: i64 = 0
61 while i < cnt {
62 if lens[i] == l {
63 let base: i64 = i * WC_NAMEMAX
64 var k: i64 = 0
65 var same: i64 = 1
66 while k < l { if names[base + k] != p[k] { same = 0; k = l } else { k = k + 1 } }
67 if same == 1 { return 1 }
68 }
69 i = i + 1
70 }
71 return 0
72}
73
74// CANONICAL NAME LENGTH: drop a trailing ".elf" so the three sets are comparable. Required because
75// organ_kind.conf is INCONSISTENT -- it carries "sites.elf daemon" AND "nx_mgmt_api daemon" -- while
76// the allowlist stores full ELF paths and the directory listing stores filenames. Comparing those
77// without canonicalising silently mismatches every row and the census reports confident nonsense.
78func wc_elflen(p: *u8, l: i64) -> i64 {
79 if l > 4 {
80 if p[l-4] == (46 as u8) { if p[l-3] == (101 as u8) {
81 if p[l-2] == (108 as u8) { if p[l-1] == (102 as u8) { return l - 4 } } } }
82 }
83 return l
84}
85
86// add if absent. returns new count. trunc incremented when the table is full.
87func wc_add(names: *u8, lens: *i64, cnt: i64, p: *u8, l: i64, trunc: *i64) -> i64 {
88 if l <= 0 { return cnt }
89 if l >= WC_NAMEMAX { return cnt }
90 if wc_has(names, lens, cnt, p, l) == 1 { return cnt }
91 if cnt >= WC_MAXT { trunc[0] = trunc[0] + 1; return cnt }
92 let base: i64 = cnt * WC_NAMEMAX
93 var k: i64 = 0
94 while k < l { names[base + k] = p[k]; k = k + 1 }
95 names[base + l] = 0 as u8
96 lens[cnt] = l
97 return cnt + 1
98}
99
100// DECLARED SURFACE: field 0 of every non-comment, non-blank line of tool_allowlist.conf.
101func wc_parse_registered(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 {
102 var cnt: i64 = 0
103 var ls: i64 = 0
104 var i: i64 = 0
105 while i <= n {
106 var eol: i64 = 0
107 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } }
108 if eol == 1 {
109 if i > ls {
110 if buf[ls] != (WC_HASH as u8) {
111 var e: i64 = ls
112 var go: i64 = 1
113 while go == 1 {
114 if e >= i { go = 0 } else {
115 if buf[e] == (WC_TAB as u8) { go = 0 } else { e = e + 1 }
116 }
117 }
118 cnt = wc_add(names, lens, cnt, (buf as i64 + ls) as *u8, e - ls, trunc)
119 }
120 }
121 ls = i + 1
122 }
123 i = i + 1
124 }
125 return cnt
126}
127
128// W1 AUTHORISED: every name in every "allow=" CSV in cap_consent.log. Terminates each name at a
129// comma or any non-name byte, so "allow=a,b exp=..." yields exactly a and b.
130func wc_parse_authorised(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 {
131 var cnt: i64 = 0
132 var i: i64 = 0
133 let last: i64 = n - 6
134 while i <= last {
135 var hit: i64 = 0
136 if buf[i] == (97 as u8) { if buf[i+1] == (108 as u8) { if buf[i+2] == (108 as u8) {
137 if buf[i+3] == (111 as u8) { if buf[i+4] == (119 as u8) { if buf[i+5] == (61 as u8) { hit = 1 } } } } } }
138 if hit == 1 {
139 var p: i64 = i + 6
140 var run: i64 = 1
141 while run == 1 {
142 var e: i64 = p
143 var go: i64 = 1
144 while go == 1 {
145 if e >= n { go = 0 } else {
146 if wc_name_ch(buf[e] as i64) == 1 { e = e + 1 } else { go = 0 }
147 }
148 }
149 cnt = wc_add(names, lens, cnt, (buf as i64 + p) as *u8, e - p, trunc)
150 if e < n {
151 if buf[e] == (WC_COMMA as u8) { p = e + 1 } else { run = 0 }
152 } else { run = 0 }
153 }
154 i = p
155 } else { i = i + 1 }
156 }
157 return cnt
158}
159
160// W2 INVOKED: TAB field 2 of actlog.jrnl (epoch \t ws \t TOOL \t verb \t outcome \t note).
161// PRESENCE ONLY -- seats log voluntarily, so this can rescue a tool from the dark list but must
162// never be used to condemn one.
163func wc_parse_invoked(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 {
164 var cnt: i64 = 0
165 var ls: i64 = 0
166 var i: i64 = 0
167 while i <= n {
168 var eol: i64 = 0
169 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } }
170 if eol == 1 {
171 if i > ls {
172 var tabs: i64 = 0
173 var fs: i64 = 0 - 1
174 var fe: i64 = 0 - 1
175 var p: i64 = ls
176 while p < i {
177 if buf[p] == (WC_TAB as u8) {
178 tabs = tabs + 1
179 if tabs == 2 { fs = p + 1 } else { if tabs == 3 { if fe < 0 { fe = p } } }
180 }
181 p = p + 1
182 }
183 if fs >= 0 {
184 if fe < 0 { fe = i }
185 cnt = wc_add(names, lens, cnt, (buf as i64 + fs) as *u8, fe - fs, trunc)
186 }
187 }
188 ls = i + 1
189 }
190 i = i + 1
191 }
192 return cnt
193}
194
195// ---- S3: BUILT + PROMOTED BUT NEVER REGISTERED --------------------------------------------------
196// The class that bit this session twice: an artifact is compiled, promoted to live, and then nothing
197// exposes it, so it is callable by nobody and invisible to every consumer. nx_srcdiverge_gate is the
198// canonical instance -- promoted, unregistered, and it is the detector for a different stranding class.
199//
200// FALSE-POSITIVE CONTROL, and without it this check is unusable: nishihost holds DAEMONS (sites.elf,
201// nx_mgmt_api.elf) and LIBS which are correctly NOT tools. organ_kind.conf already declares what each
202// organ IS, so daemons and libs are excluded by DECLARATION rather than by a name heuristic. An organ
203// that is neither registered nor declared is the real finding: nobody said what it is OR wired it.
204
205// field 1 of an allowlist row is the ABS ELF PATH; collect its BASENAME so it can be compared to a
206// directory listing.
207func wc_parse_registered_elfs(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 {
208 var cnt: i64 = 0
209 var ls: i64 = 0
210 var i: i64 = 0
211 while i <= n {
212 var eol: i64 = 0
213 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } }
214 if eol == 1 {
215 if i > ls { if buf[ls] != (WC_HASH as u8) {
216 var tabs: i64 = 0
217 var fs: i64 = 0 - 1
218 var fe: i64 = i
219 var p: i64 = ls
220 while p < i {
221 if buf[p] == (WC_TAB as u8) {
222 tabs = tabs + 1
223 if tabs == 1 { fs = p + 1 } else { if tabs == 2 { if fe == i { fe = p } } }
224 }
225 p = p + 1
226 }
227 if fs >= 0 {
228 var bs: i64 = fs
229 var q: i64 = fs
230 while q < fe { if buf[q] == (47 as u8) { bs = q + 1 } q = q + 1 }
231 let bp: *u8 = (buf as i64 + bs) as *u8
232 cnt = wc_add(names, lens, cnt, bp, wc_elflen(bp, fe - bs), trunc)
233 }
234 } }
235 ls = i + 1
236 }
237 i = i + 1
238 }
239 return cnt
240}
241
242// names in organ_kind.conf whose declared kind is daemon or lib -- correctly NOT tools.
243func wc_parse_nontools(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 {
244 var cnt: i64 = 0
245 var ls: i64 = 0
246 var i: i64 = 0
247 while i <= n {
248 var eol: i64 = 0
249 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } }
250 if eol == 1 {
251 if i > ls { if buf[ls] != (WC_HASH as u8) {
252 var e: i64 = ls
253 var go: i64 = 1
254 while go == 1 {
255 if e >= i { go = 0 } else {
256 if buf[e] == (WC_SP as u8) { go = 0 } else { e = e + 1 }
257 }
258 }
259 if e < i {
260 let k: i64 = e + 1
261 var isnt: i64 = 0
262 if k + 5 < i { if buf[k] == (100 as u8) { isnt = 1 } } // daemon
263 if k + 2 < i { if buf[k] == (108 as u8) { isnt = 1 } } // lib
264 if isnt == 1 {
265 let np: *u8 = (buf as i64 + ls) as *u8
266 cnt = wc_add(names, lens, cnt, np, wc_elflen(np, e - ls), trunc)
267 }
268 }
269 } }
270 ls = i + 1
271 }
272 i = i + 1
273 }
274 return cnt
275}
276
277// every *.elf in a directory (exact suffix, so .elf.prev / .elf.new / .bak-* never match).
278func wc_scan_elfs(dir: *u8, names: *u8, lens: *i64, trunc: *i64) -> i64 {
279 var cnt: i64 = 0
280 let dfd: i64 = __syscall(257, 0 - 100, dir, 0x10000, 0, 0, 0)
281 if dfd < 0 { return 0 }
282 let db: *u8 = sys_mmap(WC_MAGIC_262144)
283 var more: i64 = 1
284 while more == 1 {
285 let got: i64 = sys_getdents64(dfd, db, WC_MAGIC_262144)
286 if got <= 0 { more = 0 } else {
287 var p: i64 = 0
288 while p < got {
289 let rec: *u8 = (db as i64 + p) as *u8
290 let rl: i64 = dirent_reclen(rec)
291 if rl <= 0 { p = got } else {
292 if dirent_type(rec) == DT_REG {
293 let nm: *u8 = dirent_name(rec)
294 var l: i64 = 0
295 while nm[l] != (0 as u8) { l = l + 1 }
296 if l > 4 {
297 if nm[l-4] == (46 as u8) { if nm[l-3] == (101 as u8) {
298 if nm[l-2] == (108 as u8) { if nm[l-1] == (102 as u8) {
299 cnt = wc_add(names, lens, cnt, nm, wc_elflen(nm, l), trunc)
300 } } } }
301 }
302 }
303 p = p + rl
304 }
305 }
306 }
307 }
308 sys_close(dfd)
309 return cnt
310}
311
312// ---- S3 TRIAGE: split UNEXPOSED into convention-inferred buckets vs the real residue -------------
313// WHY: the first S3 run returned 253 "unexposed" and the list was dominated by RUNNING DAEMONS
314// (nx_siteedit_daemon, nx_analyst_serve, redirect...). They only looked stranded because
315// organ_kind.conf declares 32 of 743 promoted artifacts -- 4 pct coverage -- so the number MIXED
316// "correctly a daemon" with "genuinely stranded". That is the same category-mixing trap already
317// banked twice today (nx_adopt's DARK, nx_dupfunc's 3.3k), and a mixed number is a headline.
318//
319// THE FIX IS NOT TO HAND-WRITE 711 DECLARATIONS -- organ_kind.conf says "add a row, do NOT guess",
320// and a wrong row there lets /api/promote swap a live daemon with no health probe (rule-26 hazard).
321// So: DERIVE what evidence can classify, and report only what it cannot.
322// CRITICAL DISTINCTION: these suffix rules are CONVENTION-INFERRED and are for REPORTING ONLY. They
323// must never feed a promote decision -- organ_kind.conf stays the sole authority for that. A census
324// may guess out loud; a deploy verb may not.
325// ORACLE-shaped: _gate / _test / _kat (mirrors the /api/gate_run bound, which is itself a rule)
326// DAEMON-shaped: _daemon / _serve / _gw / _gateway
327// residue : UNCLASSIFIED -- the honest S3 number and the only rows worth a human backfill.
328func wc_suffix_is(p: *u8, l: i64, suf: *u8, sl: i64) -> i64 {
329 if l <= sl { return 0 }
330 var i: i64 = 0
331 while i < sl { if p[l - sl + i] != suf[i] { return 0 } i = i + 1 }
332 return 1
333}
334func wc_looks_oracle(p: *u8, l: i64) -> i64 {
335 if wc_suffix_is(p, l, "_gate" as *u8, 5) == 1 { return 1 }
336 if wc_suffix_is(p, l, "_test" as *u8, 5) == 1 { return 1 }
337 if wc_suffix_is(p, l, "_kat" as *u8, 4) == 1 { return 1 }
338 return 0
339}
340func wc_looks_daemon(p: *u8, l: i64) -> i64 {
341 if wc_suffix_is(p, l, "_daemon" as *u8, 7) == 1 { return 1 }
342 if wc_suffix_is(p, l, "_serve" as *u8, 6) == 1 { return 1 }
343 if wc_suffix_is(p, l, "_gateway" as *u8, 8) == 1 { return 1 }
344 if wc_suffix_is(p, l, "_gw" as *u8, 3) == 1 { return 1 }
345 return 0
346}
347
348// ---- S7: PROMOTED, UNREGISTERED, BUT INVOKED BY A PLAN OR CRON ----------------------------------
349// WHY THIS CLASS EXISTS: S3 sees REGISTRY exposure only, so an organ invoked by a PLAN or a CRON row
350// reads as unexposed even though it runs on a schedule. A census whose residue cannot be acted on is
351// a census nobody runs, and retiring a cron-invoked organ because the registry never saw it is the
352// specific damage this class prevents.
353//
354// ⚠THE FIRST EVIDENCE SOURCE I PICKED WAS WRONG, AND THE ORGAN MEASURED IT: log stems. The theory was
355// that a promoted artifact writing logs/X.log or knowledge/status/X.log has run. Live result: 224 log
356// stems seen, 0 rescues. Logs here are named after the JOB (surfsentinel.log), never after the ORGAN
357// (nx_link_sentinel), so stem-matching can never join them. Kept only as a weak positive.
358//
359// I ALSO ASSERTED A WIRING THAT DOES NOT EXIST and the plane refuted it: I claimed
360// nx_link_sentinel/nx_nav_sentinel were invoked by plan-surfsentinel-. Dumping that plane shows it is
361// TEN nx_https_get steps against ten URLs and NOTHING ELSE. Those two organs are NOT in it. So S3's
362// UNCLASSIFIED label may have been right about them all along, and my "correction" was the error.
363//
364// THE CORRECT WITNESS, now measured: the plan planes themselves. knowledge/store/plan-*/ rows carry
365// the invoked tool in COLUMN 1 (e.g. "10 <TAB> nx_https_get <TAB> <url>"). That is a direct, positive
366// record of what actually gets called on a schedule. Column 1 of every plan- plane is the S7 source;
367// log stems are not. This function is retained for the weak signal but must not be read as S7.
368func wc_strip_logsuffix(p: *u8, l: i64) -> i64 {
369 // ".cron.log" (9) then ".log" (4) -- longest first, or "x.cron" survives as a bogus name.
370 if l > 9 {
371 if wc_suffix_is(p, l, ".cron.log" as *u8, 9) == 1 { return l - 9 }
372 }
373 if l > 4 {
374 if wc_suffix_is(p, l, ".log" as *u8, 4) == 1 { return l - 4 }
375 }
376 return 0
377}
378
379// collect the STEM of every *.log / *.cron.log in a directory, ACCUMULATING onto cnt0 and returning
380// the new total. Takes a starting count on purpose: log evidence lives in more than one directory
381// (logs/ and knowledge/status/), and a version that reset to 0 per call would have each scan CLOBBER
382// the previous one from index 0 and silently under-count the rescue set.
383func wc_scan_logs(dir: *u8, names: *u8, lens: *i64, cnt0: i64, trunc: *i64) -> i64 {
384 var cnt: i64 = cnt0
385 let dfd: i64 = __syscall(257, 0 - 100, dir, 0x10000, 0, 0, 0)
386 if dfd < 0 { return 0 }
387 let db: *u8 = sys_mmap(WC_MAGIC_262144)
388 var more: i64 = 1
389 while more == 1 {
390 let got: i64 = sys_getdents64(dfd, db, WC_MAGIC_262144)
391 if got <= 0 { more = 0 } else {
392 var p: i64 = 0
393 while p < got {
394 let rec: *u8 = (db as i64 + p) as *u8
395 let rl: i64 = dirent_reclen(rec)
396 if rl <= 0 { p = got } else {
397 if dirent_type(rec) == DT_REG {
398 let nm: *u8 = dirent_name(rec)
399 var l: i64 = 0
400 while nm[l] != (0 as u8) { l = l + 1 }
401 let stem: i64 = wc_strip_logsuffix(nm, l)
402 if stem > 0 { cnt = wc_add(names, lens, cnt, nm, stem, trunc) }
403 }
404 p = p + rl
405 }
406 }
407 }
408 }
409 sys_close(dfd)
410 return cnt
411}
412
413// ---- S7, CORRECT WITNESS: the tool named in COLUMN 1 of every plan- plane row -------------------
414// Measured, not assumed: dumping plan-surfsentinel- gives rows shaped
415// "<seq> TAB nx_https_get TAB https://... TAB 127.0.0.1:8443"
416// and the seg-store .docs file carries that text verbatim (with q:<n> framing between rows). So a
417// tool INVOKED BY A SCHEDULED PLAN is exactly an identifier that is TAB-delimited on BOTH sides.
418// URLs and paths cannot collide with it because ':' and '/' are not name bytes.
419//
420// POSITIVE-ONLY, like every other rescue witness here: an over-broad match (a bare-identifier ARG
421// caught alongside a real tool) can only RESCUE a name from the residue, never condemn one. That
422// asymmetry is what makes a slightly loose extractor safe -- the failure mode is a smaller residue,
423// not a wrongly-retired organ.
424func wc_scan_plan_tools(dir: *u8, names: *u8, lens: *i64, cnt0: i64, trunc: *i64) -> i64 {
425 var cnt: i64 = cnt0
426 let dfd: i64 = __syscall(257, 0 - 100, dir, 0x10000, 0, 0, 0)
427 if dfd < 0 { return cnt }
428 let db: *u8 = sys_mmap(WC_MAGIC_262144)
429 let fb: *u8 = sys_mmap(WC_MAGIC_1048576)
430 let path: *u8 = sys_mmap(512)
431 var dl: i64 = 0
432 while dir[dl] != (0 as u8) { dl = dl + 1 }
433 var more: i64 = 1
434 while more == 1 {
435 let got: i64 = sys_getdents64(dfd, db, WC_MAGIC_262144)
436 if got <= 0 { more = 0 } else {
437 var p: i64 = 0
438 while p < got {
439 let rec: *u8 = (db as i64 + p) as *u8
440 let rl: i64 = dirent_reclen(rec)
441 if rl <= 0 { p = got } else {
442 if dirent_type(rec) == DT_REG {
443 let nm: *u8 = dirent_name(rec)
444 var l: i64 = 0
445 while nm[l] != (0 as u8) { l = l + 1 }
446 // plan-*.docs only: the plan planes, not their hist- twins or manifests
447 var isplan: i64 = 0
448 if l > 10 {
449 if nm[0] == (112 as u8) { if nm[1] == (108 as u8) {
450 if nm[2] == (97 as u8) { if nm[3] == (110 as u8) {
451 if nm[4] == (45 as u8) {
452 if wc_suffix_is(nm, l, ".docs" as *u8, 5) == 1 { isplan = 1 }
453 } } } } }
454 }
455 if isplan == 1 {
456 var w: i64 = 0
457 while w < dl { path[w] = dir[w]; w = w + 1 }
458 path[w] = 47 as u8
459 w = w + 1
460 var k: i64 = 0
461 while k < l { if w + 2 < 512 { path[w] = nm[k]; w = w + 1 } k = k + 1 }
462 path[w] = 0 as u8
463 let n: i64 = wc_read(path, fb, WC_MAGIC_1048576)
464 if n > 0 {
465 var i: i64 = 1
466 while i < n {
467 if fb[i - 1] == (WC_TAB as u8) {
468 var e: i64 = i
469 var go: i64 = 1
470 while go == 1 {
471 if e >= n { go = 0 } else {
472 if wc_name_ch(fb[e] as i64) == 1 { e = e + 1 } else { go = 0 }
473 }
474 }
475 if e > i { if e < n { if fb[e] == (WC_TAB as u8) {
476 cnt = wc_add(names, lens, cnt, (fb as i64 + i) as *u8, e - i, trunc)
477 } } }
478 if e > i { i = e } else { i = i + 1 }
479 } else { i = i + 1 }
480 }
481 }
482 }
483 }
484 p = p + rl
485 }
486 }
487 }
488 }
489 sys_close(dfd)
490 return cnt
491}
492
493// Is `name` present in buf as a WHOLE line-leading token? Used to skip already-declared organs when
494// emitting. Line-leading + boundary-checked so nx_adopt never satisfies nx_adopt_lib and a partial
495// name can never suppress a real emission.
496func wc_contains_name(buf: *u8, n: i64, p: *u8, l: i64) -> i64 {
497 if l <= 0 { return 0 }
498 var ls: i64 = 0
499 var i: i64 = 0
500 while i <= n {
501 var eol: i64 = 0
502 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } }
503 if eol == 1 {
504 if i - ls > l {
505 var same: i64 = 1
506 var k: i64 = 0
507 while k < l { if buf[ls + k] != p[k] { same = 0; k = l } else { k = k + 1 } }
508 if same == 1 { if buf[ls + l] == (WC_SP as u8) { return 1 } }
509 }
510 ls = i + 1
511 }
512 i = i + 1
513 }
514 return 0
515}
516
517// THE VERDICT: registered names present in NEITHER witness. Writes their indices into dark[].
518func wc_dark(rnames: *u8, rlens: *i64, rcnt: i64,
519 anames: *u8, alens: *i64, acnt: i64,
520 inames: *u8, ilens: *i64, icnt: i64,
521 dark: *i64, darkcap: i64) -> i64 {
522 var d: i64 = 0
523 var i: i64 = 0
524 while i < rcnt {
525 let base: i64 = i * WC_NAMEMAX
526 let p: *u8 = (rnames as i64 + base) as *u8
527 let l: i64 = rlens[i]
528 var seen: i64 = 0
529 if wc_has(anames, alens, acnt, p, l) == 1 { seen = 1 }
530 if seen == 0 { if wc_has(inames, ilens, icnt, p, l) == 1 { seen = 1 } }
531 if seen == 0 {
532 if d < darkcap { dark[d] = i }
533 d = d + 1
534 }
535 i = i + 1
536 }
537 return d
538}