code wiki / _hdl_build / nx_doc_mainscan.nx
nx_doc_mainscan.nx source
↩ module page · 59 lines · 3030 B
1// nx_doc_mainscan.nx -- DOCTOR diagnosis for a NEW failure class discovered live this session: nxasm exits rc=102
2// "UNDEFINED label: main" when a LIBRARY module (functions only, no `func main`) is built as a standalone
3// executable (the linker has no entry point). Seen real: `nx_sov_build_run nx_tls13` -> rc=102, because nx_tls13.nx
4// is the TLS-1.3 record-layer LIBRARY (consumed by nx_pub_tls_serve / the gates, which DO build green). This is a
5// DIFFERENT class from compiler-level CC-UNDEFFN ("call to undefined function: <name>"): it is an ASSEMBLER-level
6// missing entry-point. READ-ONLY BY CONSTRUCTION: it does NOT fabricate a `main` (that would be a fake program and
7// could mask a genuinely missing entry point) -- it DIAGNOSES "this source has no main; if it is a library, build it
8// through its consumer/gate, not standalone." Reuses kw_eq + dhl_isident/dhl_name_at from nx_doc_kwscan. ORIGINAL
9import "nx_syscalls.nx"
10import "nx_doc_kwscan.nx"
11
12// local substring search (kept self-contained; avoids pulling the seg-store in just for ki_substr).
13func ms_substr(hay: *u8, hlen: i64, needle: *u8, nlen: i64) -> i64 {
14 if nlen <= 0 { return 0-1 }
15 var i: i64 = 0
16 while i + nlen <= hlen {
17 var m: i64 = 1; var j: i64 = 0
18 while j < nlen { if hay[i+j] != needle[j] { m = 0; j = nlen } else { j = j + 1 } }
19 if m == 1 { return i }
20 i = i + 1
21 }
22 return 0-1
23}
24// 1 iff the source defines `func main` (whole-word `func` then the identifier `main`).
25func ms_has_main(src: *u8, n: i64) -> i64 {
26 let nb: *u8 = sys_mmap(256)
27 let nb2: *u8 = sys_mmap(256)
28 var i: i64 = 0
29 while i < n {
30 var isstart: i64 = 0
31 if dhl_isident(src[i] as i64) == 1 {
32 if i == 0 { isstart = 1 } else { if dhl_isident(src[i-1] as i64) == 0 { isstart = 1 } }
33 }
34 if isstart == 1 {
35 let nl: i64 = dhl_name_at(src, n, i, nb)
36 if kw_eq(nb, nl, "func" as *u8) == 1 {
37 var k: i64 = i + nl
38 var sk: i64 = 0
39 while sk == 0 { if k < n { if src[k]==(32 as u8){k=k+1} else { if src[k]==(9 as u8){k=k+1} else {sk=1} } } else {sk=1} }
40 if k < n { if dhl_isident(src[k] as i64) == 1 {
41 let nl2: i64 = dhl_name_at(src, n, k, nb2)
42 if kw_eq(nb2, nl2, "main" as *u8) == 1 { return 1 }
43 } }
44 }
45 i = i + nl
46 } else {
47 i = i + 1
48 }
49 }
50 return 0
51}
52// 1 iff the diagnostic is the missing-entry-point assembler error AND the source has no main (= a library built
53// standalone). If the source DOES define main, the same diagnostic means a DIFFERENT problem (a genuinely
54// unresolved entry symbol) -> return 0 so we never misroute it to the library remedy.
55func ms_is_library_build_error(diag: *u8, dlen: i64, src: *u8, n: i64) -> i64 {
56 if ms_substr(diag, dlen, "UNDEFINED label: main" as *u8, 21) < 0 { return 0 }
57 if ms_has_main(src, n) == 1 { return 0 }
58 return 1
59}