code wiki / _hdl_build / nx_assure.nx

nx_assure.nx source

↩ module page · 431 lines · 20810 B

1// nx_assure.nx -- WORLD-CLASS ASSURANCE RULER (worldclass-assurance lane, 2026-07-24). Operator: 2// "we need to get to the point our system is world class -- DARPA/NASA/Linux-level and above." That 3// is not a vibe, it is a CHECKABLE STANDARD. This organ scores the real .nx corpus against a subset 4// of the NASA/JPL "Power of Ten" rules for safety-critical code (Holzmann 2006) that are mechanically 5// decidable on NishiLang, emits per-rule violation counts, every violation LOCATABLE (file:fn), and an 6// honest corpus permille. CYNICAL BY CONSTRUCTION (the author-optimism law): a rule that cannot be 7// mechanically decided is declared NOT-CHECKED and counts as NEITHER pass nor fail -- the headline can 8// never inflate by claiming credit for what it did not measure. 9// 10// CHECKED (sound, non-gameable): 11// R1 no self-recursion -- fn body calls its own name (P10 rule 1: no recursion) 12// R2 bounded loops -- no `while true` / `while 1` (P10 rule 2) 13// R3 no dynamic alloc inside a loop -- no sys_mmap lexically inside a `while` (P10 rule 3; 14// THIS is the per-iteration-mmap OOM class banked across 15// sessions -- the single highest-value mechanical check) 16// R4 function length <= AS_MAXLEN lines -- (P10 rule 4: short functions) 17// G gate coverage -- every organ-with-main has a _gate/_test sibling (Nishi 18// assurance: fresh-compile-run is the only judge, so a 19// shippable organ WITHOUT a gate is unproven) 20// NOT-CHECKED (declared, never scored as pass): R5 assertion density, R6 minimal scope, R7 checked 21// returns, R8 preprocessor (NishiLang has none -- N/A), R9 single-deref pointers, R10 zero warnings 22// (nx_cc builds clean by construction -- reproducible-build ruler is a separate arc). 23// 24// verbs: audit [dir] (default runtime/_hdl_build) | selftest 25// license_tier: ORIGINAL No hw writes (Rule 26). 26import "nx_syscalls.nx" 27 28const AS_FCAP: i64 = 262144 29const AS_DCAP: i64 = 65536 30const AS_TCAP: i64 = 65536 // one extracted function (organs have big fns) 31const AS_PATHCAP: i64 = 256 32const AS_MAXLEN: i64 = 75 // P10-R4 line budget 33const AS_ZERO: i64 = 48 34const AS_NAMES: i64 = 4096 // main-organ base-name table 35const AS_NAMEBUF: i64 = 131072 36 37func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 38func wn(v: i64) -> i64 { 39 var m: i64 = v 40 if m < 0 { w("-" as *u8); m = 0 - m } 41 let t: *u8 = sys_mmap(24) 42 var k: i64 = 0 43 if m == 0 { t[0] = AS_ZERO as u8; k = 1 } 44 while m > 0 { t[k] = (AS_ZERO + (m % 10)) as u8; m = m / 10; k = k + 1 } 45 let o: *u8 = sys_mmap(24) 46 var i: i64 = 0 47 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 48 sys_write(1, o, k) 49 return 0 50} 51func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 52func sfind(hay: *u8, hn: i64, needle: *u8, from: i64) -> i64 { 53 let m: i64 = slen(needle) 54 if m == 0 { return 0 - 1 } 55 var i: i64 = from 56 while i + m <= hn { 57 var j: i64 = 0 58 var ok: i64 = 1 59 while j < m { if hay[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } } 60 if ok == 1 { return i } 61 i = i + 1 62 } 63 return 0 - 1 64} 65func scontains(h: *u8, hn: i64, n: *u8) -> i64 { if sfind(h, hn, n, 0) >= 0 { return 1 } return 0 } 66func as_read(path: *u8, buf: *u8, cap: i64) -> i64 { 67 let fd: i64 = sys_openat_rd(path) 68 if fd < 0 { return 0 - 1 } 69 var n: i64 = 0 70 var go: i64 = 1 71 while go == 1 { 72 if n >= cap { sys_close(fd); return 0 - 2 } 73 let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - n) 74 if r <= 0 { go = 0 } else { n = n + r } 75 } 76 sys_close(fd) 77 return n 78} 79 80// function boundary: from "func" at `at` through brace depth 0 -> end | -1 81func as_fnend(b: *u8, n: i64, at: i64) -> i64 { 82 var e: i64 = at 83 var depth: i64 = 0 84 var seen: i64 = 0 85 var go: i64 = 1 86 while go == 1 { 87 if e >= n { go = 0 } 88 else { 89 let c: i64 = b[e] as i64 90 if c == 123 { depth = depth + 1; seen = 1 } 91 if c == 125 { depth = depth - 1 } 92 e = e + 1 93 if seen == 1 { if depth == 0 { go = 0 } } 94 } 95 } 96 if seen == 0 { return 0 - 1 } 97 if depth != 0 { return 0 - 1 } 98 return e 99} 100// parse name into nb (null-terminated) from a fn text starting "func "; ret name len | 0 101func as_fnname(t: *u8, tn: i64, nb: *u8) -> i64 { 102 let po: i64 = sfind(t, tn, "(" as *u8, 0) 103 if po < 6 { return 0 } 104 var nl: i64 = 0 105 var i: i64 = 5 106 while i < po { if nl < 90 { nb[nl] = t[i]; nl = nl + 1 } i = i + 1 } 107 nb[nl] = 0 as u8 108 return nl 109} 110// body-start offset (first '{' after the signature) 111func as_bodystart(t: *u8, tn: i64) -> i64 { return sfind(t, tn, "{" as *u8, 0) } 112 113// R1: does the body call its own name? (name followed by '(' after the signature, prev char non-id) 114func as_recurses(t: *u8, tn: i64, name: *u8, nl: i64) -> i64 { 115 let bo: i64 = as_bodystart(t, tn) 116 if bo < 0 { return 0 } 117 let needle: *u8 = sys_mmap(128) 118 var i: i64 = 0 119 while i < nl { needle[i] = name[i]; i = i + 1 } 120 needle[nl] = 40 as u8 121 needle[nl + 1] = 0 as u8 122 var p: i64 = bo 123 var go: i64 = 1 124 while go == 1 { 125 let at: i64 = sfind(t, tn, needle, p) 126 if at < 0 { go = 0 } 127 else { 128 let prev: i64 = t[at - 1] as i64 129 var isid: i64 = 0 130 if prev >= 97 { if prev <= 122 { isid = 1 } } 131 if prev >= 65 { if prev <= 90 { isid = 1 } } 132 if prev >= 48 { if prev <= 57 { isid = 1 } } 133 if prev == 95 { isid = 1 } 134 if isid == 0 { return 1 } 135 p = at + nl + 1 136 } 137 } 138 return 0 139} 140// R2: unbounded loop smell 141func as_unbounded(t: *u8, tn: i64) -> i64 { 142 if scontains(t, tn, "while true" as *u8) == 1 { return 1 } 143 if scontains(t, tn, "while 1 " as *u8) == 1 { return 1 } 144 if scontains(t, tn, "while 1{" as *u8) == 1 { return 1 } 145 if scontains(t, tn, "while (1)" as *u8) == 1 { return 1 } 146 if scontains(t, tn, "while (true)" as *u8) == 1 { return 1 } 147 return 0 148} 149// R3: sys_mmap lexically INSIDE a while-block. Walk brace depth; track a stack bit "in a while" per 150// depth. mmap while any enclosing block was opened by a `while` header => per-iteration alloc. 151func as_mmap_in_loop(t: *u8, tn: i64) -> i64 { 152 // wl[d] = 1 if the block opened at depth d was a while-block 153 let wl: *i64 = sys_mmap(256 * 8) as *i64 154 var d: i64 = 0 155 var i: i64 = 0 156 // pending: a `while` seen since the last '{' at this level 157 var pend: i64 = 0 158 var inloop: i64 = 0 159 while i < tn { 160 // detect `while` keyword start (word-boundary) 161 if i + 5 <= tn { 162 if t[i] == (119 as u8) { if t[i+1] == (104 as u8) { if t[i+2] == (105 as u8) { if t[i+3] == (108 as u8) { if t[i+4] == (101 as u8) { 163 let pv: i64 = t[i-1] as i64 164 var idp: i64 = 0 165 if pv >= 97 { if pv <= 122 { idp = 1 } } 166 if pv >= 65 { if pv <= 90 { idp = 1 } } 167 if pv == 95 { idp = 1 } 168 if idp == 0 { pend = 1 } 169 } } } } } 170 } 171 let c: i64 = t[i] as i64 172 if c == 123 { 173 d = d + 1 174 if d < 256 { wl[d] = pend } 175 if pend == 1 { inloop = inloop + 1 } 176 pend = 0 177 } 178 if c == 125 { 179 if d < 256 { if wl[d] == 1 { if inloop > 0 { inloop = inloop - 1 } } } 180 d = d - 1 181 } 182 // mmap check when inside >=1 while-block 183 if inloop > 0 { 184 if i + 8 <= tn { if t[i] == (115 as u8) { if sfind(t, tn, "sys_mmap" as *u8, i) == i { return 1 } } } 185 } 186 i = i + 1 187 } 188 return 0 189} 190// count newlines in body -> logical line span 191func as_lines(t: *u8, tn: i64) -> i64 { 192 var c: i64 = 0 193 var i: i64 = 0 194 while i < tn { if t[i] == (10 as u8) { c = c + 1 } i = i + 1 } 195 return c + 1 196} 197 198// name-set for gate coverage 199static g_names: *u8 // packed null-terminated base names of organs-with-main 200static g_names_o: i64 201static g_gatebase: *u8 // packed base names that ARE a _gate/_test file 202static g_gatebase_o: i64 203static g_selfver: *u8 // base names whose OWN source self-verifies (contains VERDICT=) 204static g_selfver_o: i64 205static g_listmode: i64 // 1 = print each violation as `Rn file:fn` (actionable backlog) 206static g_curfile: *u8 // current file basename, for list output 207 208func as_pack(dst: *u8, o: i64, s: *u8, n: i64) -> i64 { 209 var i: i64 = 0 210 while i < n { dst[o] = s[i]; o = o + 1; i = i + 1 } 211 dst[o] = 0 as u8 212 return o + 1 213} 214func as_inpack(pk: *u8, pn: i64, s: *u8, sn: i64) -> i64 { 215 var p: i64 = 0 216 while p < pn { 217 var q: i64 = p 218 while pk[q] != (0 as u8) { q = q + 1 } 219 if q - p == sn { var eq: i64 = 1; var z: i64 = 0; while z < sn { if pk[p + z] != s[z] { eq = 0; z = sn } else { z = z + 1 } } if eq == 1 { return 1 } } 220 p = q + 1 221 } 222 return 0 223} 224// strip ".nx" and a trailing "_gate"/"_test" -> base name into nb; ret (0 normal | 1 was gate/test) 225func as_base(nm: *u8, nl: i64, nb: *u8) -> i64 { 226 var e: i64 = nl 227 if e >= 3 { if nm[e-3] == (46 as u8) { if nm[e-2] == (110 as u8) { if nm[e-1] == (120 as u8) { e = e - 3 } } } } 228 var isg: i64 = 0 229 if e >= 5 { if nm[e-5] == (95 as u8) { if nm[e-4] == (103 as u8) { if nm[e-3] == (97 as u8) { if nm[e-2] == (116 as u8) { if nm[e-1] == (101 as u8) { e = e - 5; isg = 1 } } } } } } 230 if isg == 0 { if e >= 5 { if nm[e-5] == (95 as u8) { if nm[e-4] == (116 as u8) { if nm[e-3] == (101 as u8) { if nm[e-2] == (115 as u8) { if nm[e-1] == (116 as u8) { e = e - 5; isg = 1 } } } } } } } 231 var z: i64 = 0 232 while z < e { nb[z] = nm[z]; z = z + 1 } 233 nb[e] = 0 as u8 234 return isg 235} 236func as_name_ok(nm: *u8, nl: i64) -> i64 { 237 if nl < 4 { return 0 } 238 if nm[nl-3] != (46 as u8) { return 0 } 239 if nm[nl-2] != (110 as u8) { return 0 } 240 if nm[nl-1] != (120 as u8) { return 0 } 241 if scontains(nm, nl, ".bak" as *u8) == 1 { return 0 } 242 if scontains(nm, nl, "premigrate" as *u8) == 1 { return 0 } 243 return 1 244} 245 246func as_audit(dir: *u8) -> i64 { 247 let fbuf: *u8 = sys_mmap(AS_FCAP) 248 let dbuf: *u8 = sys_mmap(AS_DCAP) 249 let tbuf: *u8 = sys_mmap(AS_TCAP) 250 let path: *u8 = sys_mmap(AS_PATHCAP) 251 let nb: *u8 = sys_mmap(96) 252 let base: *u8 = sys_mmap(96) 253 g_names = sys_mmap(AS_NAMEBUF) 254 g_gatebase = sys_mmap(AS_NAMEBUF) 255 g_selfver = sys_mmap(AS_NAMEBUF) 256 g_names_o = 0 257 g_gatebase_o = 0 258 g_selfver_o = 0 259 var files: i64 = 0 260 var fns: i64 = 0 261 var v_rec: i64 = 0 262 var v_unb: i64 = 0 263 var v_mmap: i64 = 0 264 var v_len: i64 = 0 265 var maxlen_seen: i64 = 0 266 var worst_name: *u8 = sys_mmap(96) 267 worst_name[0] = 0 as u8 268 269 let dfd: i64 = sys_openat_rd(dir) 270 if dfd < 0 { w("cannot open dir " as *u8); w(dir); w("\n" as *u8); return 1 } 271 var dgo: i64 = 1 272 while dgo == 1 { 273 let nr: i64 = sys_getdents64(dfd, dbuf, AS_DCAP) 274 if nr <= 0 { dgo = 0 } 275 else { 276 var off: i64 = 0 277 while off < nr { 278 let rl: i64 = (dbuf[off + 16] as i64) + ((dbuf[off + 17] as i64) * 256) 279 let nmp: *u8 = ((dbuf as i64) + off + 19) as *u8 280 let nml: i64 = slen(nmp) 281 if as_name_ok(nmp, nml) == 1 { 282 let isg: i64 = as_base(nmp, nml, base) 283 if isg == 1 { g_gatebase_o = as_pack(g_gatebase, g_gatebase_o, base, slen(base)) } 284 var po: i64 = 0 285 var di: i64 = 0 286 while dir[di] != (0 as u8) { path[po] = dir[di]; po = po + 1; di = di + 1 } 287 path[po] = 47 as u8 288 po = po + 1 289 var fi: i64 = 0 290 while nmp[fi] != (0 as u8) { path[po] = nmp[fi]; po = po + 1; fi = fi + 1 } 291 path[po] = 0 as u8 292 let fl: i64 = as_read(path, fbuf, AS_FCAP) 293 if fl > 0 { 294 files = files + 1 295 g_curfile = nmp 296 if scontains(fbuf, fl, "func main(" as *u8) == 1 { 297 if isg == 0 { g_names_o = as_pack(g_names, g_names_o, base, slen(base)) } 298 // self-verifying: an organ whose own source emits a VERDICT (selftest/gate 299 // convention) is assured even without a separate _gate file sibling. 300 if scontains(fbuf, fl, "VERDICT=" as *u8) == 1 { g_selfver_o = as_pack(g_selfver, g_selfver_o, base, slen(base)) } 301 } 302 var p: i64 = 0 303 var fgo: i64 = 1 304 while fgo == 1 { 305 let q: i64 = sfind(fbuf, fl, "func " as *u8, p) 306 if q < 0 { fgo = 0 } 307 else { 308 var atl: i64 = 0 309 if q == 0 { atl = 1 } 310 if q > 0 { if fbuf[q-1] == (10 as u8) { atl = 1 } } 311 var e: i64 = q + 5 312 if atl == 1 { 313 let fe: i64 = as_fnend(fbuf, fl, q) 314 if fe > q { 315 e = fe 316 let tn: i64 = fe - q 317 if tn < AS_TCAP - 1 { 318 var z: i64 = 0 319 while z < tn { tbuf[z] = fbuf[q + z]; z = z + 1 } 320 tbuf[tn] = 0 as u8 321 let nl2: i64 = as_fnname(tbuf, tn, nb) 322 if nl2 > 0 { 323 fns = fns + 1 324 if as_recurses(tbuf, tn, nb, nl2) == 1 { v_rec = v_rec + 1; if g_listmode == 1 { w("R1 recursion " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } } 325 if as_unbounded(tbuf, tn) == 1 { v_unb = v_unb + 1; if g_listmode == 1 { w("R2 unbounded " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } } 326 if as_mmap_in_loop(tbuf, tn) == 1 { v_mmap = v_mmap + 1; if g_listmode == 1 { w("R3 mmap-loop " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } } 327 let ln: i64 = as_lines(tbuf, tn) 328 if ln > AS_MAXLEN { v_len = v_len + 1; if g_listmode == 1 { w("R4 len=" as *u8); wn(ln); w(" " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } } 329 if ln > maxlen_seen { maxlen_seen = ln; var wz: i64 = 0; while wz < nl2 { worst_name[wz] = nb[wz]; wz = wz + 1 } worst_name[nl2] = 0 as u8 } 330 } 331 } 332 } 333 } 334 p = e 335 } 336 } 337 } 338 } 339 off = off + rl 340 } 341 } 342 } 343 sys_close(dfd) 344 // gate coverage: organs-with-main whose base is in the gatebase set 345 var organs: i64 = 0 346 var gated: i64 = 0 347 var p2: i64 = 0 348 while p2 < g_names_o { 349 var q2: i64 = p2 350 while g_names[q2] != (0 as u8) { q2 = q2 + 1 } 351 organs = organs + 1 352 var cov: i64 = as_inpack(g_gatebase, g_gatebase_o, ((g_names as i64) + p2) as *u8, q2 - p2) 353 if cov == 0 { cov = as_inpack(g_selfver, g_selfver_o, ((g_names as i64) + p2) as *u8, q2 - p2) } 354 if cov == 1 { gated = gated + 1 } 355 p2 = q2 + 1 356 } 357 // permille per rule = (fns clean of that violation) / fns 358 var pm_rec: i64 = 1000 359 var pm_unb: i64 = 1000 360 var pm_mmap: i64 = 1000 361 var pm_len: i64 = 1000 362 if fns > 0 { 363 pm_rec = ((fns - v_rec) * 1000) / fns 364 pm_unb = ((fns - v_unb) * 1000) / fns 365 pm_mmap = ((fns - v_mmap) * 1000) / fns 366 pm_len = ((fns - v_len) * 1000) / fns 367 } 368 var pm_gate: i64 = 1000 369 if organs > 0 { pm_gate = (gated * 1000) / organs } 370 // composite = mean of the 5 checked rules (each equally weighted; NOT-CHECKED rules excluded) 371 let comp: i64 = (pm_rec + pm_unb + pm_mmap + pm_len + pm_gate) / 5 372 w("=== NX-ASSURE Power-of-Ten-class ruler dir=" as *u8); w(dir); w(" ===\n" as *u8) 373 w("files=" as *u8); wn(files); w(" functions=" as *u8); wn(fns); w(" organs(main)=" as *u8); wn(organs); w("\n" as *u8) 374 w("R1 no-recursion " as *u8); wn(pm_rec); w(" permille (violations=" as *u8); wn(v_rec); w(")\n" as *u8) 375 w("R2 bounded-loops " as *u8); wn(pm_unb); w(" permille (violations=" as *u8); wn(v_unb); w(")\n" as *u8) 376 w("R3 no-alloc-in-loop " as *u8); wn(pm_mmap); w(" permille (violations=" as *u8); wn(v_mmap); w(") <- per-iteration sys_mmap OOM class\n" as *u8) 377 w("R4 fn-len<=" as *u8); wn(AS_MAXLEN); w(" " as *u8); wn(pm_len); w(" permille (violations=" as *u8); wn(v_len); w(", longest=" as *u8); wn(maxlen_seen); w(" @ " as *u8); w(worst_name); w(")\n" as *u8) 378 w("G assurance-cover " as *u8); wn(pm_gate); w(" permille (" as *u8); wn(gated); w("/" as *u8); wn(organs); w(" organs have a _gate/_test sibling OR self-verify via VERDICT=)\n" as *u8) 379 w("NOT-CHECKED (never scored as pass): R5 assert-density R6 minimal-scope R7 checked-returns R8 preprocessor(N/A) R9 single-deref R10 warnings(clean-by-construction)\n" as *u8) 380 w("NX-ASSURE composite=" as *u8); wn(comp); w(" permille over 5 mechanically-decided rules (HONEST: unmeasured rules excluded, not assumed-pass)\n" as *u8) 381 return 0 382} 383 384func as_selftest() -> i64 { 385 var passn: i64 = 0 386 // T1 recursion detected 387 let r1: *u8 = "func fac(n: i64) -> i64 { if n < 2 { return 1 } return n * fac(n - 1) }" as *u8 388 let nb: *u8 = sys_mmap(96) 389 let l1: i64 = as_fnname(r1, slen(r1), nb) 390 if as_recurses(r1, slen(r1), nb, l1) == 1 { passn = passn + 1; w("T1 recursion-detect PASS\n" as *u8) } else { w("T1 FAIL\n" as *u8) } 391 // T2 non-recursion clean (calls a DIFFERENT fn) 392 let r2: *u8 = "func g(n: i64) -> i64 { return h(n) + n }" as *u8 393 let l2: i64 = as_fnname(r2, slen(r2), nb) 394 if as_recurses(r2, slen(r2), nb, l2) == 0 { passn = passn + 1; w("T2 nonrecursion-clean PASS\n" as *u8) } else { w("T2 FAIL\n" as *u8) } 395 // T3 mmap-in-loop detected 396 let r3: *u8 = "func bad() -> i64 { var i: i64 = 0 while i < 10 { let p: *u8 = sys_mmap(16) i = i + 1 } return 0 }" as *u8 397 if as_mmap_in_loop(r3, slen(r3)) == 1 { passn = passn + 1; w("T3 mmap-in-loop-detect PASS\n" as *u8) } else { w("T3 FAIL\n" as *u8) } 398 // T4 mmap OUTSIDE loop is clean (init-time alloc) 399 let r4: *u8 = "func ok() -> i64 { let p: *u8 = sys_mmap(16) var i: i64 = 0 while i < 10 { i = i + 1 } return 0 }" as *u8 400 if as_mmap_in_loop(r4, slen(r4)) == 0 { passn = passn + 1; w("T4 mmap-init-clean PASS\n" as *u8) } else { w("T4 FAIL\n" as *u8) } 401 // T5 unbounded loop 402 let r5: *u8 = "func spin() -> i64 { while true { } return 0 }" as *u8 403 if as_unbounded(r5, slen(r5)) == 1 { passn = passn + 1; w("T5 unbounded-detect PASS\n" as *u8) } else { w("T5 FAIL\n" as *u8) } 404 // T6 base-name strip 405 let bn: *u8 = sys_mmap(96) 406 let isg: i64 = as_base("nx_foo_gate.nx" as *u8, 14, bn) 407 var ok6: i64 = 0 408 if isg == 1 { if sfind(bn, slen(bn), "nx_foo" as *u8, 0) == 0 { if slen(bn) == 6 { ok6 = 1 } } } 409 if ok6 == 1 { passn = passn + 1; w("T6 base-strip PASS\n" as *u8) } else { w("T6 FAIL base=" as *u8); w(bn); w("\n" as *u8) } 410 w("NX-ASSURE selftest " as *u8); wn(passn); w("/6 " as *u8) 411 if passn == 6 { w("VERDICT=GREEN\n" as *u8); return 0 } 412 w("VERDICT=RED\n" as *u8) 413 return 1 414} 415 416func main(argc: i64, argv: *i64) -> i64 { 417 var verb: *u8 = "selftest" as *u8 418 if argc > 1 { verb = argv[1] as *u8 } 419 if verb[0] == (97 as u8) { 420 var dir: *u8 = "runtime/_hdl_build" as *u8 421 if argc > 2 { dir = argv[2] as *u8 } 422 return as_audit(dir) 423 } 424 if verb[0] == (108 as u8) { // 'list' -> print every violation as `Rn file:fn` then the summary 425 g_listmode = 1 426 var dir: *u8 = "runtime/_hdl_build" as *u8 427 if argc > 2 { dir = argv[2] as *u8 } 428 return as_audit(dir) 429 } 430 return as_selftest() 431}