code wiki / _hdl_build / nx_resolve_lib.nx

nx_resolve_lib.nx source

↩ module page · 127 lines · 4985 B

1// nx_resolve_lib.nx -- shared primitives for the consolidation/de-collision organs (nx_split_resolve, 2// nx_decollide). Factored out so the two organs INHERIT one implementation instead of copy-pasting 3// (Rule 15 DRY / the OO-consolidation this session is about). Pure file+build helpers, no hw writes. 4// license_tier: ORIGINAL No hw writes (Rule 26). 5import "nx_seat_drive_lib.nx" 6import "nx_seg_store.nx" 7import "nx_deploy_lib.nx" 8import "nx_syscalls.nx" 9 10const RL_CAP: i64 = 4194304 11 12func rl_strlen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } 13func rl_read(path: *u8, buf: *u8, cap: i64) -> i64 { 14 let fd: i64 = sys_openat_rd(path) 15 if fd < 0 { return 0 - 1 } 16 var n: i64 = 0 17 var r: i64 = sys_read(fd, buf, cap - 1) 18 while r > 0 { n = n + r; if n >= cap - 1 { r = 0 } else { r = sys_read(fd, buf + n, cap - 1 - n) } } 19 sys_close(fd) 20 return n 21} 22func rl_eq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 { if an != bn { return 0 } var i: i64 = 0; while i < an { if a[i] != b[i] { return 0 } i = i + 1 } return 1 } 23func rl_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] == b[i] { if a[i] == (0 as u8) { return 1 } i = i + 1 } return 0 } 24// build the quoted import filename token: "<lib>.nx" (tag=0) or "<lib>_<tag>.nx". real quotes, byte-wise. 25func rl_mktok(out: *u8, lib: *u8, tag: *u8) -> i64 { 26 var o: i64 = 0 27 out[o] = 34 as u8; o = o + 1 28 let ll: i64 = rl_strlen(lib) 29 var i: i64 = 0 30 while i < ll { out[o] = lib[i]; o = o + 1; i = i + 1 } 31 if (tag as i64) != 0 { 32 out[o] = 95 as u8; o = o + 1 33 let tl: i64 = rl_strlen(tag) 34 i = 0 35 while i < tl { out[o] = tag[i]; o = o + 1; i = i + 1 } 36 } 37 out[o] = 46 as u8; o = o + 1 38 out[o] = 110 as u8; o = o + 1 39 out[o] = 120 as u8; o = o + 1 40 out[o] = 34 as u8; o = o + 1 41 out[o] = 0 as u8 42 return o 43} 44// build a bare quoted filename token: "<name>.nx" (name already includes any suffix). byte-wise. 45func rl_mktok_name(out: *u8, name: *u8) -> i64 { 46 var o: i64 = 0 47 out[o] = 34 as u8; o = o + 1 48 let ll: i64 = rl_strlen(name) 49 var i: i64 = 0 50 while i < ll { out[o] = name[i]; o = o + 1; i = i + 1 } 51 out[o] = 46 as u8; o = o + 1 52 out[o] = 110 as u8; o = o + 1 53 out[o] = 120 as u8; o = o + 1 54 out[o] = 34 as u8; o = o + 1 55 out[o] = 0 as u8 56 return o 57} 58// copy src->out, replacing EVERY occurrence of oldt with newt. return outlen, or -1 if oldt not present. 59func rl_replace(src: *u8, n: i64, oldt: *u8, ol: i64, newt: *u8, nl: i64, out: *u8) -> i64 { 60 var oi: i64 = 0 61 var i: i64 = 0 62 var found: i64 = 0 63 while i < n { 64 var mch: i64 = 0 65 if i + ol <= n { 66 mch = 1 67 var j: i64 = 0 68 while j < ol { if src[i + j] != oldt[j] { mch = 0; j = ol } else { j = j + 1 } } 69 } 70 if mch == 1 { 71 var k: i64 = 0 72 while k < nl { out[oi] = newt[k]; oi = oi + 1; k = k + 1 } 73 i = i + ol 74 found = found + 1 75 } else { out[oi] = src[i]; oi = oi + 1; i = i + 1 } 76 } 77 if found == 0 { return 0 - 1 } 78 return oi 79} 80func rl_contains(buf: *u8, n: i64, tok: *u8, tl: i64) -> i64 { 81 var i: i64 = 0 82 while i + tl <= n { 83 var m: i64 = 1 84 var j: i64 = 0 85 while j < tl { if buf[i + j] != tok[j] { m = 0; j = tl } else { j = j + 1 } } 86 if m == 1 { return 1 } 87 i = i + 1 88 } 89 return 0 90} 91// strip dir + trailing .nx -> basename (build target). out null-terminated. return len. 92func rl_basename(path: *u8, out: *u8) -> i64 { 93 let L: i64 = rl_strlen(path) 94 var st: i64 = 0 95 var i: i64 = 0 96 while i < L { if path[i] == (47 as u8) { st = i + 1 } i = i + 1 } 97 var en: i64 = L 98 if L >= 3 { if path[L - 1] == (120 as u8) { if path[L - 2] == (110 as u8) { if path[L - 3] == (46 as u8) { en = L - 3 } } } } 99 var o: i64 = 0 100 var k: i64 = st 101 while k < en { out[o] = path[k]; o = o + 1; k = k + 1 } 102 out[o] = 0 as u8 103 return o 104} 105// dir part of a path (everything before the last '/'). out null-terminated. return len. 106func rl_dirname(path: *u8, out: *u8) -> i64 { 107 let L: i64 = rl_strlen(path) 108 var cut: i64 = 0 109 var i: i64 = 0 110 while i < L { if path[i] == (47 as u8) { cut = i } i = i + 1 } 111 var o: i64 = 0 112 while o < cut { out[o] = path[o]; o = o + 1 } 113 out[o] = 0 as u8 114 return o 115} 116// build target tname (unlink artifact first so a failed build leaves no stale artifact). return bytes. 117func rl_build(buildelf: *u8, tname: *u8, artpath: *u8, buf: *u8) -> i64 { 118 sys_unlinkat(artpath) 119 let av: *i64 = sys_mmap(16) as *i64 120 av[0] = tname as i64 121 dep_run_capture(buildelf, av, 1, "/tmp/rl_build.log" as *u8) 122 return rl_read(artpath, buf, RL_CAP) 123} 124// write /tmp/<base>.<suffix> into out. return len. 125func rl_tmpp(out: *u8, base: *u8, suffix: *u8) -> i64 { 126 var q: i64 = sd_cat(out, 0, "/tmp/" as *u8); q = sd_cat(out, q, base); q = sd_cat(out, q, suffix); return q 127}