code wiki / _hdl_build / nx_gated_edit_multi.nx

nx_gated_edit_multi.nx source

↩ module page · 106 lines · 5471 B

1// nx_gated_edit_multi.nx -- MULTI-EDIT gated applier: apply N exact old->new edits ATOMICALLY, keep iff a 2// verify command's output is byte-identical before/after (else restore ALL + refuse). The multi-edit 3// generalisation of nx_gated_edit -- needed for delegation that adds an IMPORT line AND replaces a body 4// as ONE unit, so the g_check-bulk organs (which don't import the base) consolidate onto a shared lib. 5// argv: <srcfile> <manifestfile> <verifyelf> <verifyarg> 6// manifest: one edit per line, oldfile<TAB>newfile (paths -> no argv escaping). Edits applied in order; 7// each old must occur EXACTLY once in the evolving working copy, else REFUSE-ALL (no partial writes). 8// exit: 0 CONSOLIDATED | 1 REFUSED (restored) | 2 usage/edit-contract (untouched) | 3 verify-before-empty 9// license_tier: ORIGINAL No hw writes (Rule 26). 10import "nx_seat_drive_lib.nx" 11import "nx_deploy_lib.nx" 12import "nx_ge_str_lib.nx" 13import "nx_syscalls.nx" 14 15const GM_CAP: i64 = 1048576 16const GM_ECAP: i64 = 2097152 17const GM_MANIFEST: i64 = 65536 18const GM_PATH: i64 = 1024 19 20func main(argc: i64, argv: *i64) -> i64 { 21 if argc < 5 { sd_w("usage: nx_gated_edit_multi <srcfile> <manifestfile> <verifyelf> <verifyarg>\n" as *u8); sys_exit(2); return 2 } 22 let srcp: *u8 = argv[1] as *u8 23 let manp: *u8 = argv[2] as *u8 24 let velf: *u8 = argv[3] as *u8 25 let varg: *u8 = argv[4] as *u8 26 let src: *u8 = sys_mmap(GM_CAP) 27 let sn: i64 = dp_read(srcp, src, GM_CAP) 28 if sn <= 0 { sd_w("NX-GEM verdict=SRC-ABSENT " as *u8); sd_w(srcp); sd_w(" . FIX: confirm with `nx_fs ls <dir>`.\n" as *u8); sys_exit(2); return 2 } 29 let man: *u8 = sys_mmap(GM_MANIFEST) 30 let mn: i64 = dp_read(manp, man, GM_MANIFEST) 31 if mn <= 0 { sd_w("NX-GEM verdict=MANIFEST-ABSENT " as *u8); sd_w(manp); sd_w(" . FIX: one oldfile<TAB>newfile per line.\n" as *u8); sys_exit(2); return 2 } 32 let work: *u8 = sys_mmap(GM_ECAP) 33 var wn: i64 = 0 34 var ci: i64 = 0 35 while ci < sn { work[wn] = src[ci]; wn = wn + 1; ci = ci + 1 } 36 let tmp: *u8 = sys_mmap(GM_ECAP) 37 let oldb: *u8 = sys_mmap(GM_CAP) 38 let newb: *u8 = sys_mmap(GM_CAP) 39 let of: *u8 = sys_mmap(GM_PATH) 40 let nf: *u8 = sys_mmap(GM_PATH) 41 var applied: i64 = 0 42 var i: i64 = 0 43 while i < mn { 44 var le: i64 = i 45 var f: i64 = 1 46 while f == 1 { if le >= mn { f = 0 } else { if man[le] == (10 as u8) { f = 0 } else { le = le + 1 } } } 47 var tab: i64 = 0 - 1 48 var j: i64 = i 49 while j < le { if man[j] == (9 as u8) { tab = j; j = le } else { j = j + 1 } } 50 if tab > i { 51 var a: i64 = 0 52 var p: i64 = i 53 while p < tab { of[a] = man[p]; a = a + 1; p = p + 1 } 54 of[a] = 0 as u8 55 var b: i64 = 0 56 var q: i64 = tab + 1 57 while q < le { nf[b] = man[q]; b = b + 1; q = q + 1 } 58 nf[b] = 0 as u8 59 let on: i64 = dp_read(of, oldb, GM_CAP) 60 let nn: i64 = dp_read(nf, newb, GM_CAP) 61 if on <= 0 { sd_w("NX-GEM verdict=OLDFILE-EMPTY " as *u8); sd_w(of); sd_w(" (all untouched)\n" as *u8); sys_exit(2); return 2 } 62 let cnt: i64 = ge_count(work, wn, oldb, on) 63 if cnt == 0 { sd_w("NX-GEM verdict=NOMATCH old=" as *u8); sd_w(of); sd_w(" not in working copy (all untouched). FIX: check old-string or edit order.\n" as *u8); sys_exit(2); return 2 } 64 if cnt > 1 { sd_w("NX-GEM verdict=AMBIGUOUS old=" as *u8); sd_w(of); sd_w(" occurs >1 (all untouched). FIX: longer unique context.\n" as *u8); sys_exit(2); return 2 } 65 let pos: i64 = ge_find(work, wn, oldb, on, 0) 66 var to: i64 = 0 67 var x: i64 = 0 68 while x < pos { tmp[to] = work[x]; to = to + 1; x = x + 1 } 69 var y: i64 = 0 70 while y < nn { tmp[to] = newb[y]; to = to + 1; y = y + 1 } 71 var z: i64 = pos + on 72 while z < wn { tmp[to] = work[z]; to = to + 1; z = z + 1 } 73 wn = to 74 var w2: i64 = 0 75 while w2 < wn { work[w2] = tmp[w2]; w2 = w2 + 1 } 76 applied = applied + 1 77 } 78 i = le 79 if i < mn { i = i + 1 } 80 } 81 if applied == 0 { sd_w("NX-GEM verdict=NO-EDITS (manifest had no oldfile<TAB>newfile rows) (untouched)\n" as *u8); sys_exit(2); return 2 } 82 let av: *i64 = sys_mmap(32) as *i64 83 av[0] = varg as i64 84 dep_run_capture(velf, av, 1, "/tmp/gem_before.out" as *u8) 85 let before: *u8 = sys_mmap(GM_CAP) 86 let bn: i64 = dp_read("/tmp/gem_before.out" as *u8, before, GM_CAP) 87 if bn <= 0 { sd_w("NX-GEM verdict=VERIFY-BEFORE-EMPTY (untouched). FIX: verifyelf must emit deterministic output.\n" as *u8); sys_exit(3); return 3 } 88 dp_writefile(srcp, work, wn) 89 dep_run_capture(velf, av, 1, "/tmp/gem_after.out" as *u8) 90 let after: *u8 = sys_mmap(GM_CAP) 91 let an: i64 = dp_read("/tmp/gem_after.out" as *u8, after, GM_CAP) 92 if an > 0 { if ge_eq(before, bn, after, an) == 1 { 93 sd_w("NX-GEM verdict=CONSOLIDATED edits=" as *u8) 94 let eb: *u8 = sys_mmap(24) 95 sd_num(eb, 0, applied) 96 sd_w(eb) 97 sd_w(" (verify byte-identical) src=" as *u8); sd_w(srcp); sd_w("\n" as *u8) 98 sys_exit(0) 99 return 0 100 } } 101 dp_writefile(srcp, src, sn) 102 dep_run_capture(velf, av, 1, "/tmp/gem_restore.out" as *u8) 103 sd_w("NX-GEM verdict=REFUSED (verify changed -> edits are live) restored src=" as *u8); sd_w(srcp); sd_w("\n" as *u8) 104 sys_exit(1) 105 return 1 106}