nx_file_result.nx source
↩ module page · 56 lines · 1934 B
1// nx_file_result.nx -- Result-wrapped file read.
2//
3// sys_read_file returns null on failure -- a sentinel. This wrapper
4// returns *NxResult so callers get a proper error code (NX_ERR_FILE_
5// NOT_FOUND) instead of "is this null?" inspection.
6//
7// Convention: result.value holds *u8 cast to nx_int (file buffer);
8// callers cast back via `as *u8`. Length stored in out parameter.
9
10// nx_safety_envelope:
11// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
12// sil_target: SIL1
13// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
14// verdict: NOT_YET_EVALUATED
15
16import "nx_syscalls.nx"
17import "nx_runtime.nx"
18import "nx_tier.nx"
19import "nx_result.nx"
20
21// Returns Result<i64-cast-of-*u8, NX_ERR_FILE_NOT_FOUND>. Writes the
22// byte count to out_len.
23func nx_read_file_result(path: *u8, out_len: *i64) -> *NxResult {
24 let buf: *u8 = sys_read_file(path, out_len)
25 if (buf as nx_int) == 0 { return nx_result_err(NX_ERR_FILE_NOT_FOUND) }
26 return nx_result_ok(buf as nx_int)
27}
28
29// Helper: count non-comment / non-blank lines in a file. Returns
30// Result<nx_int, NX_ERR_FILE_NOT_FOUND>.
31func nx_count_lines_result(path: *u8) -> *NxResult {
32 let len_p: *i64 = (sys_mmap(8)) as *i64
33 len_p[0] = 0
34 let r_read: *NxResult = nx_read_file_result(path, len_p)
35 if nx_result_is_err(r_read) == 1 { return r_read }
36 let buf: *u8 = nx_result_unwrap(r_read) as *u8
37 let n: nx_int = len_p[0]
38 var count: nx_int = 0
39 var i: nx_int = 0
40 while i < n {
41 var is_first: nx_int = 0
42 if i == 0 { is_first = 1 }
43 if i > 0 {
44 if buf[i - 1] == 10 { is_first = 1 }
45 }
46 if is_first == 1 {
47 if buf[i] != 35 {
48 if buf[i] != 10 {
49 if buf[i] != 0 { count = count + 1 }
50 }
51 }
52 }
53 i = i + 1
54 }
55 return nx_result_ok(count)
56}