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}