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}