code wiki / (root) / nx_zeroprint.nx

nx_zeroprint.nx source

↩ module page · 455 lines · 23342 B

1// nx_zeroprint.nx -- THE ZERO-PRINTS-AS-NUL DETECTOR AND REPAIRER. 2// 3// FOUND 2026-08-26 while adding a DNS diagnostic: a field printed "ancount= " with nothing after it. 4// The value was 0. The shape, repeated by hand across the estate, is a decimal printer that writes 5// its digits into one buffer and reverses them into another: 6// 7// if m == 0 { b[0] = 48 as u8; k = 1 } <-- '0' written to b 8// let t: *u8 = sys_mmap(24) 9// while m > 0 { t[k] = ...; k = k + 1 } <-- digits written to t 10// while i < k { b[i] = t[k-1-i]; i = i+1 } <-- reversal reads t, OVERWRITING b[0] 11// 12// With m == 0 the digit loop never runs, so t is untouched mmap memory (zero-filled) and the 13// reversal copies a NUL byte over the '0'. A zero therefore prints as an INVISIBLE BYTE. That is 14// the worst possible failure direction for a diagnostic: the field reads as ABSENT rather than as 15// the value zero, and "absent" and "zero" demand opposite conclusions from whoever is reading it. 16// 17// WHY THIS IS AN ORGAN AND NOT A ONE-OFF SWEEP: the first census of this was written in Python -- 18// shell-shaped work that counted, classified and judged, which is precisely the shape the estate 19// forbids, and it published a wrong number (28) because it could not see the safe else-form. The 20// count belongs in a NishiLang organ that can be re-run, gated, and pointed at either tree. 21// 22// THE CLASSIFICATION IS A PARTITION AND IT IS PRINTED, because three of the four buckets look 23// identical to a careless matcher: 24// EARLY-RETURN if m == 0 { b[0] = 48; sys_write(...); return 0 } -- prints and leaves. SAFE. 25// ELSE-FORM if m == 0 { ... } else { ...digit loop + reversal... } -- reversal is inside the 26// else and cannot run when m == 0. SAFE. This is the bucket the Python missed, and 27// missing it inflated the defect count by six. 28// SAME-BUFFER the zero branch writes the buffer the digit loop writes. The reversal reads back 29// a real '0'. SAFE -- this is the majority and the shared printer in nx_syscalls.nx. 30// DEFECTIVE zero branch writes X, digit loop writes Y, X != Y. The NUL case above. 31// 32// REPAIR is a pure statement reorder, not a rewrite: the declaration of Y already sits between the 33// zero branch and the digit loop, so moving the zero branch BELOW that declaration and retargeting 34// it at Y makes the reversal read a real '0'. Nothing else about the function changes. 35// 36// NO SEARCH WINDOW CONSTANT. A "look ahead N bytes" bound would be a guess and would silently 37// under-report on a long function. The digit loop is searched for only up to the START OF THE NEXT 38// FUNCTION, which is exact and needs no number. 39// 40// verbs: scan <root> census only, exit 1 if any DEFECTIVE remain (gate-friendly) 41// apply <root> repair every DEFECTIVE site, atomically per file, then re-census 42// license_tier: ORIGINAL 43import "nx_syscalls.nx" 44 45const ZP_EXIT_CLEAN: i64 = 0 46const ZP_EXIT_FOUND: i64 = 1 47const ZP_EXIT_USAGE: i64 = 3 48 49func zp_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 50func zp_putn(v: i64) -> i64 { 51 let t: *u8 = sys_mmap(24) 52 var m: i64 = v 53 if m < 0 { zp_puts("-" as *u8); m = 0 - m } 54 var k: i64 = 0 55 // Deliberately the EARLY-RETURN shape this organ classifies as safe -- a detector that carries 56 // the defect it hunts is the class of thing that reports zero findings forever. 57 if m == 0 { t[0] = 48 as u8; sys_write(1, t, 1); return 0 } 58 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 59 let b: *u8 = sys_mmap(24) 60 var i: i64 = 0 61 while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 62 sys_write(1, b, k) 63 return 0 64} 65func zp_is_ws(c: i64) -> i64 { if c == 32 { return 1 } if c == 9 { return 1 } if c == 10 { return 1 } if c == 13 { return 1 } return 0 } 66func zp_is_id(c: i64) -> i64 { 67 if c >= 97 { if c <= 122 { return 1 } } 68 if c >= 65 { if c <= 90 { return 1 } } 69 if c >= 48 { if c <= 57 { return 1 } } 70 if c == 95 { return 1 } 71 return 0 72} 73func zp_skip_ws(b: *u8, i: i64, n: i64) -> i64 { var j: i64 = i; while j < n { if zp_is_ws(b[j] & 0xff) == 1 { j = j + 1 } else { return j } } return j } 74// does b[i..] start with lit? 75func zp_lit(b: *u8, i: i64, n: i64, lit: *u8) -> i64 { 76 var k: i64 = 0 77 while lit[k] != (0 as u8) { 78 if i + k >= n { return 0 } 79 if (b[i + k] & 0xff) != (lit[k] & 0xff) { return 0 } 80 k = k + 1 81 } 82 return 1 83} 84// index of the next occurrence of lit at or after `from`, else -1 85func zp_find(b: *u8, from: i64, n: i64, lit: *u8) -> i64 { 86 var i: i64 = from 87 while i < n { if zp_lit(b, i, n, lit) == 1 { return i } i = i + 1 } 88 return 0 - 1 89} 90 91// Skip a line comment or a string literal starting at i; returns the index past it, else i. 92// 93// A SCANNER THAT DOES NOT SKIP COMMENTS MEASURES THE DOCUMENTATION, NOT THE CODE -- and this organ 94// proved it on ITSELF. Its first census of the estate named 18 defects, two of which were its own 95// source: the gate's runtime-assembled fixture (a string literal holding the defective shape) and 96// byte 345 of THIS file -- the header comment above that illustrates the bug. Applying the repair 97// would have rewritten its own documentation and destroyed the gate's fixture, so the gate's 98// anti-vacuity tooth would then have failed against a defect it could no longer plant. 99// Assembling fixtures at runtime is NOT enough when they are built from literals in the source. 100func zp_skip_noncode(b: *u8, i: i64, n: i64) -> i64 { 101 let c: i64 = b[i] & 0xff 102 if c == 47 { 103 if i + 1 < n { if (b[i+1] & 0xff) == 47 { 104 var j: i64 = i + 2 105 var go: i64 = 1 106 while go == 1 { 107 if j >= n { go = 0 } else { if (b[j] & 0xff) == 10 { go = 0 } else { j = j + 1 } } 108 } 109 return j 110 } } 111 } 112 if c == 34 { 113 var j2: i64 = i + 1 114 var go2: i64 = 1 115 while go2 == 1 { 116 if j2 >= n { go2 = 0 } 117 else { 118 let d: i64 = b[j2] & 0xff 119 if d == 92 { j2 = j2 + 2 } 120 else { if d == 34 { j2 = j2 + 1; go2 = 0 } else { j2 = j2 + 1 } } 121 } 122 } 123 return j2 124 } 125 return i 126} 127// ---- site recognition ------------------------------------------------------------------------- 128// A "site" is a zero-branch: `if m == 0 {` tolerating any spacing (real sources carry both 129// `if m == 0 { b[0] = 48 as u8; k = 1 }` and `if m==0{d[0]=48;k=1}`). Returns the index of the 130// opening brace, or -1. `st` is set to the index of the `if`. 131func zp_zero_at(b: *u8, i: i64, n: i64) -> i64 { 132 if zp_lit(b, i, n, "if" as *u8) == 0 { return 0 - 1 } 133 if i > 0 { if zp_is_id(b[i-1] & 0xff) == 1 { return 0 - 1 } } 134 var j: i64 = zp_skip_ws(b, i + 2, n) 135 if j >= n { return 0 - 1 } 136 if (b[j] & 0xff) != 109 { return 0 - 1 } // 'm' 137 if j + 1 < n { if zp_is_id(b[j+1] & 0xff) == 1 { return 0 - 1 } } 138 j = zp_skip_ws(b, j + 1, n) 139 if zp_lit(b, j, n, "==" as *u8) == 0 { return 0 - 1 } 140 j = zp_skip_ws(b, j + 2, n) 141 if j >= n { return 0 - 1 } 142 if (b[j] & 0xff) != 48 { return 0 - 1 } // '0' 143 if j + 1 < n { if zp_is_id(b[j+1] & 0xff) == 1 { return 0 - 1 } } 144 j = zp_skip_ws(b, j + 1, n) 145 if j >= n { return 0 - 1 } 146 if (b[j] & 0xff) != 123 { return 0 - 1 } // '{' 147 return j 148} 149// matching close brace for the block opening at `ob`, or -1 150func zp_close(b: *u8, ob: i64, n: i64) -> i64 { 151 var d: i64 = 1 152 var j: i64 = ob + 1 153 while j < n { 154 let c: i64 = b[j] & 0xff 155 if c == 123 { d = d + 1 } 156 if c == 125 { d = d - 1; if d == 0 { return j } } 157 j = j + 1 158 } 159 return 0 - 1 160} 161// Inside [ob,ce): find `IDENT[0]` immediately followed by `= 48`. Returns IDENT start, sets ide. 162func zp_zero_buf(b: *u8, ob: i64, ce: i64, ide: *i64) -> i64 { 163 var j: i64 = ob 164 while j < ce { 165 if zp_lit(b, j, ce, "[0]" as *u8) == 1 { 166 var k: i64 = zp_skip_ws(b, j + 3, ce) 167 if k < ce { if (b[k] & 0xff) == 61 { // '=' 168 k = zp_skip_ws(b, k + 1, ce) 169 if zp_lit(b, k, ce, "48" as *u8) == 1 { 170 // Walk back over the identifier with a FLAG. The first draft wrote `s = ob` to 171 // leave this loop, which destroys the very position being searched for -- the 172 // same cursor-clobber this organ's own zp_digit_at was fixed for one function 173 // earlier. Its symptom here was silent and total: every ident resolved to the 174 // brace, so the repair emitted `if m == 0 t[0] = ...` with the `{` eaten. Caught 175 // only because the fixture carried a SAME-BUFFER case that had to come back SAFE. 176 var s: i64 = j 177 var back: i64 = 1 178 while back == 1 { 179 if s <= ob { back = 0 } 180 else { if zp_is_id(b[s-1] & 0xff) == 1 { s = s - 1 } else { back = 0 } } 181 } 182 if s < j { ide[0] = j; return s } 183 } 184 } } 185 } 186 j = j + 1 187 } 188 ide[0] = 0 - 1 189 return 0 - 1 190} 191// `while m > 0 {` at i? returns the index of the ident that follows the brace (`Y` of `Y[k]`), else -1 192func zp_digit_at(b: *u8, i: i64, n: i64, ye: *i64) -> i64 { 193 if zp_lit(b, i, n, "while" as *u8) == 0 { return 0 - 1 } 194 var j: i64 = zp_skip_ws(b, i + 5, n) 195 if j >= n { return 0 - 1 } 196 if (b[j] & 0xff) != 109 { return 0 - 1 } 197 j = zp_skip_ws(b, j + 1, n) 198 if j >= n { return 0 - 1 } 199 if (b[j] & 0xff) != 62 { return 0 - 1 } // '>' 200 j = zp_skip_ws(b, j + 1, n) 201 if j >= n { return 0 - 1 } 202 if (b[j] & 0xff) != 48 { return 0 - 1 } 203 j = zp_skip_ws(b, j + 1, n) 204 if j >= n { return 0 - 1 } 205 if (b[j] & 0xff) != 123 { return 0 - 1 } 206 j = zp_skip_ws(b, j + 1, n) 207 let s: i64 = j 208 // Ident scan with an explicit FLAG, never by clobbering the cursor. Writing `e = n` to leave the 209 // loop destroys the very position the caller needs -- the estate has a linter for that idiom and 210 // the first draft of this function committed it. 211 var e: i64 = s 212 var scanning: i64 = 1 213 while scanning == 1 { 214 if e >= n { scanning = 0 } 215 else { if zp_is_id(b[e] & 0xff) == 1 { e = e + 1 } else { scanning = 0 } } 216 } 217 if e == s { return 0 - 1 } 218 if zp_lit(b, e, n, "[k]" as *u8) == 0 { return 0 - 1 } 219 ye[0] = e 220 return s 221} 222 223// ---- per-file classification + repair ---------------------------------------------------------- 224// counters: 0 sites, 1 early, 2 elsef, 3 same, 4 defect, 5 repaired 225// Returns the (possibly rewritten) length in nl[0]; nl[0] < 0 means "unchanged". 226// A COUNT WITHOUT A WORKLIST IS NOT ACTIONABLE -- so every DEFECTIVE site prints its file and byte 227// offset as it is found. The first version of this organ printed only totals, which is precisely the 228// shape this estate's own law forbids: the reader would have had to re-derive the list by hand. 229func zp_file(b: *u8, n: i64, ctr: *i64, doapply: i64, out: *u8, nl: *i64, path: *u8) -> i64 { 230 var i: i64 = 0 231 var wr: i64 = 0 // write cursor into out 232 var cp: i64 = 0 // copied-up-to index in b 233 var changed: i64 = 0 234 let ide: *i64 = sys_mmap(8) as *i64 235 let ye: *i64 = sys_mmap(8) as *i64 236 while i < n { 237 let skp: i64 = zp_skip_noncode(b, i, n) 238 if skp > i { i = skp } else { 239 let ob: i64 = zp_zero_at(b, i, n) 240 if ob < 0 { i = i + 1 } else { 241 let ce: i64 = zp_close(b, ob, n) 242 if ce < 0 { i = i + 1 } else { 243 let xs: i64 = zp_zero_buf(b, ob, ce, ide) 244 if xs < 0 { i = i + 1 } else { 245 ctr[0] = ctr[0] + 1 246 let xe: i64 = ide[0] 247 // EARLY-RETURN: the branch prints and leaves -- the reversal is never reached. 248 var early: i64 = 0 249 if zp_find(b, ob, ce, "sys_write" as *u8) >= 0 { early = 1 } 250 if zp_find(b, ob, ce, "return" as *u8) >= 0 { early = 1 } 251 if early == 1 { ctr[1] = ctr[1] + 1; i = ce + 1 } else { 252 // ELSE-FORM: reversal lives in the else, cannot run when m == 0. 253 var k2: i64 = zp_skip_ws(b, ce + 1, n) 254 if k2 < n { if (b[k2] & 0xff) == 59 { k2 = zp_skip_ws(b, k2 + 1, n) } } 255 if zp_lit(b, k2, n, "else" as *u8) == 1 { ctr[2] = ctr[2] + 1; i = ce + 1 } else { 256 // Search for the digit loop only as far as the NEXT FUNCTION -- exact, 257 // no guessed window. (\nfunc at column 0 is how every organ here starts.) 258 var lim: i64 = zp_find(b, ce, n, "\nfunc " as *u8) 259 if lim < 0 { lim = n } 260 var q: i64 = ce + 1 261 var ys: i64 = 0 - 1 262 while q < lim { 263 let cand: i64 = zp_digit_at(b, q, lim, ye) 264 if cand >= 0 { ys = cand; q = lim } else { q = q + 1 } 265 } 266 if ys < 0 { ctr[3] = ctr[3] + 1; i = ce + 1 } else { 267 var samebuf: i64 = 0 268 if ye[0] - ys == xe - xs { 269 var t2: i64 = 0 270 var eq: i64 = 1 271 while t2 < xe - xs { if (b[xs+t2] & 0xff) != (b[ys+t2] & 0xff) { eq = 0 } t2 = t2 + 1 } 272 samebuf = eq 273 } 274 if samebuf == 1 { ctr[3] = ctr[3] + 1; i = ce + 1 } else { 275 ctr[4] = ctr[4] + 1 276 zp_puts(" DEFECT " as *u8); zp_puts(path) 277 zp_puts(" at_byte=" as *u8); zp_putn(i) 278 zp_puts(" 279" as *u8) 280 // Locate `let|var Y : *u8 = sys_mmap(...)` between the zero branch 281 // and the digit loop -- the declaration the repair moves us below. 282 var ds: i64 = 0 - 1 283 var de: i64 = 0 - 1 284 var d2: i64 = ce + 1 285 while d2 < ys { 286 var isd: i64 = 0 287 if zp_lit(b, d2, ys, "let " as *u8) == 1 { isd = 1 } 288 if zp_lit(b, d2, ys, "var " as *u8) == 1 { isd = 1 } 289 if isd == 1 { 290 let ns2: i64 = zp_skip_ws(b, d2 + 3, ys) 291 if ns2 + (ye[0] - ys) <= ys { 292 var t3: i64 = 0 293 var eq3: i64 = 1 294 while t3 < ye[0] - ys { if (b[ns2+t3] & 0xff) != (b[ys+t3] & 0xff) { eq3 = 0 } t3 = t3 + 1 } 295 if eq3 == 1 { if zp_is_id(b[ns2 + (ye[0]-ys)] & 0xff) == 0 { 296 let mm: i64 = zp_find(b, ns2, ys, "sys_mmap" as *u8) 297 if mm >= 0 { 298 let cb2: i64 = zp_find(b, mm, ys, ")" as *u8) 299 if cb2 >= 0 { ds = d2; de = cb2 + 1; d2 = ys } 300 } 301 } } 302 } 303 } 304 if d2 < ys { d2 = d2 + 1 } 305 } 306 if doapply == 1 { if ds >= 0 { 307 // prefix | DECL | separator | zero-branch retargeted at Y | rest 308 var t4: i64 = cp 309 while t4 < i { out[wr] = b[t4]; wr = wr + 1; t4 = t4 + 1 } 310 t4 = ds 311 while t4 < de { out[wr] = b[t4]; wr = wr + 1; t4 = t4 + 1 } 312 t4 = ce + 1 313 while t4 < ds { out[wr] = b[t4]; wr = wr + 1; t4 = t4 + 1 } 314 t4 = i 315 while t4 < xs { out[wr] = b[t4]; wr = wr + 1; t4 = t4 + 1 } 316 t4 = ys 317 while t4 < ye[0] { out[wr] = b[t4]; wr = wr + 1; t4 = t4 + 1 } 318 t4 = xe 319 while t4 <= ce { out[wr] = b[t4]; wr = wr + 1; t4 = t4 + 1 } 320 cp = de 321 changed = 1 322 ctr[5] = ctr[5] + 1 323 } } 324 i = ce + 1 325 } 326 } 327 } 328 } 329 } 330 } 331 } 332 } 333 } 334 if changed == 1 { 335 var t5: i64 = cp 336 while t5 < n { out[wr] = b[t5]; wr = wr + 1; t5 = t5 + 1 } 337 nl[0] = wr 338 } else { nl[0] = 0 - 1 } 339 return 0 340} 341 342// ---- driver ------------------------------------------------------------------------------------ 343func zp_ends_nx(name: *u8) -> i64 { 344 var n: i64 = 0 345 while name[n] != (0 as u8) { n = n + 1 } 346 if n < 3 { return 0 } 347 if (name[n-3] & 0xff) != 46 { return 0 } 348 if (name[n-2] & 0xff) != 110 { return 0 } 349 if (name[n-1] & 0xff) != 120 { return 0 } 350 return 1 351} 352func zp_join(dir: *u8, name: *u8, out: *u8) -> i64 { 353 var i: i64 = 0 354 while dir[i] != (0 as u8) { out[i] = dir[i]; i = i + 1 } 355 if i > 0 { if (out[i-1] & 0xff) != 47 { out[i] = 47 as u8; i = i + 1 } } 356 var j: i64 = 0 357 while name[j] != (0 as u8) { out[i] = name[j]; i = i + 1; j = j + 1 } 358 out[i] = 0 as u8 359 return i 360} 361func zp_is_dot(name: *u8) -> i64 { 362 if (name[0] & 0xff) != 46 { return 0 } 363 if name[1] == (0 as u8) { return 1 } 364 if (name[1] & 0xff) == 46 { if name[2] == (0 as u8) { return 1 } } 365 return 0 366} 367func zp_write_atomic(path: *u8, buf: *u8, n: i64) -> i64 { 368 let tmp: *u8 = sys_mmap(4096) 369 var i: i64 = 0 370 while path[i] != (0 as u8) { tmp[i] = path[i]; i = i + 1 } 371 tmp[i] = 46 as u8; tmp[i+1] = 122 as u8; tmp[i+2] = 112 as u8; tmp[i+3] = 110 as u8; tmp[i+4] = 0 as u8 372 let fd: i64 = sys_openat_wr(tmp, MODE_0644) 373 if fd < 0 { return 0 - 1 } 374 let w: i64 = sys_write(fd, buf, n) 375 sys_close(fd) 376 if w != n { return 0 - 2 } 377 if sys_renameat(tmp, path) != 0 { return 0 - 3 } 378 return 0 379} 380func zp_walk(dir: *u8, ctr: *i64, doapply: i64) -> i64 { 381 let dfd: i64 = sys_openat_rd(dir) 382 if dfd < 0 { return 0 } 383 let dbuf: *u8 = sys_mmap(65536) 384 var go: i64 = 1 385 // LOOP until getdents64 returns 0. One call is a PREFIX, not a listing, and publishing a prefix 386 // as a population is exactly how a census reports a healthy system. 387 while go == 1 { 388 let nread: i64 = sys_getdents64(dfd, dbuf, 65536) 389 if nread <= 0 { go = 0 } else { 390 var off: i64 = 0 391 while off < nread { 392 let rec: *u8 = (dbuf as i64 + off) as *u8 393 let name: *u8 = dirent_name(rec) 394 let dtype: i64 = dirent_type(rec) 395 if zp_is_dot(name) == 0 { 396 let cp: *u8 = sys_mmap(4096) 397 zp_join(dir, name, cp) 398 if dtype == DT_DIR { zp_walk(cp, ctr, doapply) } 399 else { if zp_ends_nx(name) == 1 { 400 ctr[6] = ctr[6] + 1 401 let ln: *i64 = sys_mmap(8) as *i64 402 let src: *u8 = sys_read_file(cp, ln) 403 if (src as i64) != 0 { if ln[0] > 0 { 404 // Output reserve is DERIVED from the input: a repair only ever reorders 405 // bytes already present, so the result can never exceed the input length. 406 let out: *u8 = sys_mmap(ln[0] + 16) 407 let nl: *i64 = sys_mmap(8) as *i64 408 zp_file(src, ln[0], ctr, doapply, out, nl, cp) 409 if nl[0] > 0 { zp_write_atomic(cp, out, nl[0]) } 410 } } 411 } } 412 } 413 off = off + dirent_reclen(rec) 414 } 415 } 416 } 417 sys_close(dfd) 418 return 0 419} 420func main(argc: i64, argv: **u8) -> i64 { 421 if argc < 3 { 422 zp_puts("usage: nx_zeroprint scan|apply <root>\n" as *u8) 423 zp_puts(" scan census only; exit 1 if any DEFECTIVE site remains\n" as *u8) 424 zp_puts(" apply repair every DEFECTIVE site (atomic per file), then re-census\n" as *u8) 425 sys_exit(ZP_EXIT_USAGE) 426 return ZP_EXIT_USAGE 427 } 428 var doapply: i64 = 0 429 if zp_lit(argv[1], 0, 5, "apply" as *u8) == 1 { doapply = 1 } 430 let ctr: *i64 = sys_mmap(64) as *i64 431 var z: i64 = 0 432 while z < 8 { ctr[z] = 0; z = z + 1 } 433 zp_walk(argv[2], ctr, doapply) 434 zp_puts("files_scanned = " as *u8); zp_putn(ctr[6]); zp_puts("\n" as *u8) 435 zp_puts("zero_sites = " as *u8); zp_putn(ctr[0]); zp_puts("\n" as *u8) 436 zp_puts(" early_return = " as *u8); zp_putn(ctr[1]); zp_puts(" SAFE\n" as *u8) 437 zp_puts(" else_form = " as *u8); zp_putn(ctr[2]); zp_puts(" SAFE (reversal is inside the else)\n" as *u8) 438 zp_puts(" same_buffer = " as *u8); zp_putn(ctr[3]); zp_puts(" SAFE\n" as *u8) 439 zp_puts(" DEFECTIVE = " as *u8); zp_putn(ctr[4]); zp_puts(" zero prints as an invisible NUL\n" as *u8) 440 if doapply == 1 { zp_puts(" repaired = " as *u8); zp_putn(ctr[5]); zp_puts("\n" as *u8) } 441 // A partition is a CLAIM: print the sum and let the reader check it. 442 let sum: i64 = ctr[1] + ctr[2] + ctr[3] + ctr[4] 443 zp_puts("partition : " as *u8); zp_putn(ctr[0]); zp_puts(" = " as *u8); zp_putn(ctr[1]) 444 zp_puts(" + " as *u8); zp_putn(ctr[2]); zp_puts(" + " as *u8); zp_putn(ctr[3]) 445 zp_puts(" + " as *u8); zp_putn(ctr[4]); zp_puts(" -> " as *u8) 446 if sum == ctr[0] { zp_puts("RECONCILES\n" as *u8) } else { zp_puts("LEAK (does NOT sum)\n" as *u8); sys_exit(ZP_EXIT_FOUND); return ZP_EXIT_FOUND } 447 if doapply == 1 { if ctr[5] != ctr[4] { 448 zp_puts("REFUSED: " as *u8); zp_putn(ctr[4] - ctr[5]) 449 zp_puts(" defective site(s) had no movable declaration and were NOT repaired -- named as unrepaired rather than counted as done\n" as *u8) 450 sys_exit(ZP_EXIT_FOUND); return ZP_EXIT_FOUND 451 } } 452 if ctr[4] > 0 { if doapply == 0 { sys_exit(ZP_EXIT_FOUND); return ZP_EXIT_FOUND } } 453 sys_exit(ZP_EXIT_CLEAN) 454 return ZP_EXIT_CLEAN 455}