code wiki / _hdl_build / nx_organ_callers.nx
nx_organ_callers.nx source
↩ module page · 149 lines · 9185 B
1// nx_organ_callers.nx -- SOVEREIGN caller-finder: given an organ basename, walk the .nx tree and list every
2// file that REFERENCES it (by name, import, or path). This is the missing tool that makes a rename SAFE -- you
3// can SEE all callers before touching a name, instead of a blind rename (#19 contract stability) or a grep that
4// times out on this tree. It is the prerequisite for resolving the 22 shadow collisions nx_janitor_dupname found.
5// Bounded BFS getdents walk; reads each .nx into a REUSED buffer + sys_munmap (no 4GB-per-call reserve, no leak,
6// no timeout) -- the proven nx_janitor_sprawl walk shape. Match = substring of the needle with a LEFT word
7// boundary so "nx_grep" is not matched inside "nx_grep_test" (over-reporting a caller is safe; this avoids it).
8// READ-ONLY (never-brick). Sovereign. license_tier: ORIGINAL
9import "nx_syscalls.nx"
10
11const OC_PATH_SLOT: i64 = 768
12const OC_QUEUE_CAP: i64 = 16384
13const OC_DENT_BUF: i64 = 65536
14const OC_FILE_CAP: i64 = 4194304
15const OC_MAX_HITS: i64 = 4096
16const OC_HIT_ARENA: i64 = 3145728 // bytes for the caller-path list
17
18func oc_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
19func oc_eq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i]{return 0} i=i+1 } if b[i]!=(0 as u8){return 0} return 1 }
20func oc_ends(path: *u8, pl: i64, ext: *u8) -> i64 { let el: i64=oc_slen(ext); if el>pl { return 0 } var i: i64=0; while i<el { if path[pl-el+i]!=ext[i] { return 0 } i=i+1 } return 1 }
21func oc_is_ident(c: i64) -> i64 { if c>=48 { if c<=57 { return 1 } } if c>=65 { if c<=90 { return 1 } } if c>=97 { if c<=122 { return 1 } } if c==95 { return 1 } return 0 }
22// is `pat` referenced in buf[0..n) with a LEFT word boundary?
23func oc_referenced(buf: *u8, n: i64, pat: *u8) -> i64 {
24 let pl: i64=oc_slen(pat); if pl==0 { return 0 }
25 var i: i64=0
26 while i+pl<=n {
27 var j: i64=0; var ok: i64=1
28 while j<pl { if buf[i+j]!=pat[j] { ok=0; j=pl } else { j=j+1 } }
29 if ok==1 { var b: i64=1; if i>0 { if oc_is_ident(buf[i-1] as i64)==1 { b=0 } } if b==1 { return 1 } }
30 i=i+1
31 }
32 return 0
33}
34func oc_join(dst: *u8, dir: *u8, name: *u8) -> i64 { var o: i64=0; var i: i64=0; while dir[i]!=(0 as u8){ dst[o]=dir[i]; o=o+1; i=i+1 } dst[o]=47 as u8; o=o+1; i=0; while name[i]!=(0 as u8){ dst[o]=name[i]; o=o+1; i=i+1 } dst[o]=0 as u8; return o }
35func oc_getdents(fd: i64, buf: *u8, count: i64) -> i64 { return __syscall(SYS_GETDENTS64, fd, buf, count, 0, 0, 0) }
36func oc_isdir(path: *u8, st: *u8) -> i64 { let r: i64=__syscall(262, 0-100, path, st, 0, 0, 0); if r<0 { return 0-1 } let mode: i64=(st[24] as i64)|((st[25] as i64)<<8)|((st[26] as i64)<<16)|((st[27] as i64)<<24); if (mode & 0xF000)==0x4000 { return 1 } return 0 }
37func oc_read(path: *u8, buf: *u8, cap: i64) -> i64 { let fd: i64=sys_openat_rd(path); if fd<0 { return 0-1 } var total: i64=0; var nrd: i64=sys_read(fd, buf, cap); while nrd>0 { total=total+nrd; if total>=cap { nrd=0 } else { nrd=sys_read(fd, ((buf as i64)+total) as *u8, cap-total) } } sys_close(fd); return total }
38
39// SOVEREIGN GREP: find `needle` in EVERY file under `root` (any extension, not just .nx), skipping files larger
40// than `maxsize` (build scripts/configs are small; this avoids slurping huge binaries). The ecosystem's answer
41// to the 3rd-party grep that times out on this tree. Records each matching path into hits/hitoff; returns count.
42func oc_grep(root: *u8, needle: *u8, maxsize: i64, hits: *u8, hitoff: *i64, maxh: i64) -> i64 {
43 let qbuf: *u8=sys_mmap(OC_PATH_SLOT*OC_QUEUE_CAP)
44 let gbuf: *u8=sys_mmap(OC_DENT_BUF)
45 let stbuf: *u8=sys_mmap(256)
46 let fbuf: *u8=sys_mmap(OC_FILE_CAP)
47 let child: *u8=sys_mmap(OC_PATH_SLOT)
48 var qh: i64=0; var qt: i64=0
49 var ri: i64=0; while root[ri]!=(0 as u8){ qbuf[ri]=root[ri]; ri=ri+1 } qbuf[ri]=0 as u8; qt=1
50 var nh: i64=0; hitoff[0]=0
51 while qh<qt {
52 let dir: *u8=((qbuf as i64)+qh*OC_PATH_SLOT) as *u8; qh=qh+1
53 let fd: i64=sys_openat_rd(dir)
54 if fd<0 { } else {
55 var nread: i64=oc_getdents(fd, gbuf, OC_DENT_BUF)
56 while nread>0 {
57 var off: i64=0
58 while off<nread {
59 let reclen: i64=(gbuf[off+16] as i64)|((gbuf[off+17] as i64)<<8)
60 if reclen<=0 { off=nread } else {
61 let name: *u8=((gbuf as i64)+off+19) as *u8
62 var skip: i64=0
63 if oc_eq(name, "." as *u8)==1 { skip=1 }
64 if oc_eq(name, ".." as *u8)==1 { skip=1 }
65 if skip==0 {
66 oc_join(child, dir, name)
67 let isd: i64=oc_isdir(child, stbuf)
68 if isd==1 {
69 var vend: i64=0
70 if oc_eq(name, "node_modules" as *u8)==1 { vend=1 }
71 if oc_eq(name, ".git" as *u8)==1 { vend=1 }
72 if oc_eq(name, ".alelane" as *u8)==1 { vend=1 }
73 if vend==0 { if qt<OC_QUEUE_CAP { let dst: *u8=((qbuf as i64)+qt*OC_PATH_SLOT) as *u8; var c: i64=0; while child[c]!=(0 as u8){ dst[c]=child[c]; c=c+1 } dst[c]=0 as u8; qt=qt+1 } }
74 } else { if isd==0 {
75 let fn: i64=oc_read(child, fbuf, OC_FILE_CAP)
76 if fn>0 { if fn<=maxsize { if oc_referenced(fbuf, fn, needle)==1 { if nh<maxh {
77 let st: i64=hitoff[nh]; var k: i64=0; while child[k]!=(0 as u8){ hits[st+k]=child[k]; k=k+1 } hits[st+k]=0 as u8; hitoff[nh+1]=st+k+1; nh=nh+1
78 } } } }
79 } }
80 }
81 off=off+reclen
82 }
83 }
84 nread=oc_getdents(fd, gbuf, OC_DENT_BUF)
85 }
86 sys_close(fd)
87 }
88 }
89 sys_munmap(qbuf, OC_PATH_SLOT*OC_QUEUE_CAP); sys_munmap(gbuf, OC_DENT_BUF); sys_munmap(fbuf, OC_FILE_CAP)
90 return nh
91}
92
93// FIND callers of `needle` under `root` (skip the file whose basename == self_skip, e.g. the organ itself).
94// records each caller path into hits/hitoff; returns caller count.
95func oc_find(root: *u8, needle: *u8, self_skip: *u8, hits: *u8, hitoff: *i64, maxh: i64) -> i64 {
96 let qbuf: *u8=sys_mmap(OC_PATH_SLOT*OC_QUEUE_CAP)
97 let gbuf: *u8=sys_mmap(OC_DENT_BUF)
98 let stbuf: *u8=sys_mmap(256)
99 let fbuf: *u8=sys_mmap(OC_FILE_CAP)
100 let child: *u8=sys_mmap(OC_PATH_SLOT)
101 var qh: i64=0; var qt: i64=0
102 var ri: i64=0; while root[ri]!=(0 as u8){ qbuf[ri]=root[ri]; ri=ri+1 } qbuf[ri]=0 as u8; qt=1
103 var nh: i64=0; hitoff[0]=0
104 while qh<qt {
105 let dir: *u8=((qbuf as i64)+qh*OC_PATH_SLOT) as *u8; qh=qh+1
106 let fd: i64=sys_openat_rd(dir)
107 if fd<0 { } else {
108 var nread: i64=oc_getdents(fd, gbuf, OC_DENT_BUF)
109 while nread>0 {
110 var off: i64=0
111 while off<nread {
112 let reclen: i64=(gbuf[off+16] as i64)|((gbuf[off+17] as i64)<<8)
113 if reclen<=0 { off=nread } else {
114 let name: *u8=((gbuf as i64)+off+19) as *u8
115 var skip: i64=0
116 if oc_eq(name, "." as *u8)==1 { skip=1 }
117 if oc_eq(name, ".." as *u8)==1 { skip=1 }
118 if skip==0 {
119 oc_join(child, dir, name)
120 let isd: i64=oc_isdir(child, stbuf)
121 if isd==1 {
122 var vend: i64=0
123 if oc_eq(name, "node_modules" as *u8)==1 { vend=1 }
124 if oc_eq(name, ".git" as *u8)==1 { vend=1 }
125 if oc_eq(name, ".alelane" as *u8)==1 { vend=1 }
126 if vend==0 { if qt<OC_QUEUE_CAP { let dst: *u8=((qbuf as i64)+qt*OC_PATH_SLOT) as *u8; var c: i64=0; while child[c]!=(0 as u8){ dst[c]=child[c]; c=c+1 } dst[c]=0 as u8; qt=qt+1 } }
127 } else { if isd==0 {
128 let pl: i64=oc_slen(child)
129 if oc_ends(child, pl, ".nx" as *u8)==1 { if oc_eq(name, self_skip)==0 {
130 let fn: i64=oc_read(child, fbuf, OC_FILE_CAP)
131 if fn>0 { if oc_referenced(fbuf, fn, needle)==1 { if nh<maxh {
132 let st: i64=hitoff[nh]; var k: i64=0; while child[k]!=(0 as u8){ hits[st+k]=child[k]; k=k+1 } hits[st+k]=0 as u8; hitoff[nh+1]=st+k+1; nh=nh+1
133 } } }
134 } }
135 } }
136 }
137 off=off+reclen
138 }
139 }
140 nread=oc_getdents(fd, gbuf, OC_DENT_BUF)
141 }
142 sys_close(fd)
143 }
144 }
145 sys_munmap(qbuf, OC_PATH_SLOT*OC_QUEUE_CAP)
146 sys_munmap(gbuf, OC_DENT_BUF)
147 sys_munmap(fbuf, OC_FILE_CAP)
148 return nh
149}