nx_lineconf_lib.nx source
↩ module page · 83 lines · 2933 B
1// nx_lineconf_lib.nx -- LINE-ANCHORED CONF READER, ONE OWNER (shared lib, 2026-08-24).
2//
3// "key=value" rows, matched only at the START of a line, so a number inside a comment can never be
4// read as a setting (the defect rg_conf / rm_conf / ba_conf each re-implemented privately to avoid).
5// Integer values: digits only, a missing or non-numeric row returns LCF_MISS -- callers REFUSE on it
6// rather than default silently. String values: the bytes after '=' up to end of line, CR trimmed.
7// license_tier: ORIGINAL
8import "nx_syscalls.nx"
9
10const LCF_MISS: i64 = 0 - 999999
11const LCF_NL: i64 = 10
12const LCF_CR: i64 = 13
13const LCF_EQ: i64 = 61
14const LCF_ZERO: i64 = 48
15const LCF_NINE: i64 = 57
16const LCF_DECIMAL: i64 = 10
17const LCF_WORD: i64 = 8
18
19// offset of the first value byte of "key=" at a line start, or -1
20func lcf_find(buf: *u8, n: i64, key: *u8) -> i64 {
21 var i: i64 = 0
22 var at_line_start: i64 = 1
23 while i < n {
24 if at_line_start == 1 {
25 var k: i64 = 0
26 var matched: i64 = 1
27 while key[k] != (0 as u8) {
28 if i + k >= n { matched = 0 }
29 if matched == 1 { if buf[i + k] != key[k] { matched = 0 } }
30 k = k + 1
31 }
32 if matched == 1 { if i + k < n { if buf[i + k] == (LCF_EQ as u8) { return i + k + 1 } } }
33 }
34 if buf[i] == (LCF_NL as u8) { at_line_start = 1 } else { at_line_start = 0 }
35 i = i + 1
36 }
37 return 0 - 1
38}
39func lcf_int(buf: *u8, n: i64, key: *u8) -> i64 {
40 let o0: i64 = lcf_find(buf, n, key)
41 if o0 < 0 { return LCF_MISS }
42 var o: i64 = o0
43 var v: i64 = 0
44 var digits: i64 = 0
45 while o < n {
46 let c: i64 = buf[o] as i64
47 if c < LCF_ZERO { break }
48 if c > LCF_NINE { break }
49 v = v * LCF_DECIMAL + (c - LCF_ZERO)
50 digits = digits + 1
51 o = o + 1
52 }
53 if digits == 0 { return LCF_MISS }
54 return v
55}
56// copies the value into out (cap bytes incl NUL); returns length, or -1 when the key is absent
57func lcf_str(buf: *u8, n: i64, key: *u8, out: *u8, cap: i64) -> i64 {
58 let o0: i64 = lcf_find(buf, n, key)
59 if o0 < 0 { out[0] = 0 as u8; return 0 - 1 }
60 var o: i64 = o0
61 var w: i64 = 0
62 while o < n {
63 let c: i64 = buf[o] as i64
64 if c == LCF_NL { break }
65 if c == LCF_CR { break }
66 if w < cap - 1 { out[w] = buf[o]; w = w + 1 }
67 o = o + 1
68 }
69 out[w] = 0 as u8
70 return w
71}
72func lcf_int_of(path: *u8, key: *u8) -> i64 {
73 let lp: *i64 = sys_mmap(LCF_WORD * 2) as *i64
74 let b: *u8 = sys_read_file(path, lp)
75 if (b as i64) == 0 { return LCF_MISS }
76 return lcf_int(b, lp[0], key)
77}
78func lcf_str_of(path: *u8, key: *u8, out: *u8, cap: i64) -> i64 {
79 let lp: *i64 = sys_mmap(LCF_WORD * 2) as *i64
80 let b: *u8 = sys_read_file(path, lp)
81 if (b as i64) == 0 { out[0] = 0 as u8; return 0 - 1 }
82 return lcf_str(b, lp[0], key, out, cap)
83}