nx_fmt.nx source
↩ module page · 34 lines · 1529 B
1// nx_fmt.nx -- shared LEAK-FREE integer/string formatters. Import this instead of copying the per-call
2// sys_mmap putn idiom (the propagating mmap leak). Uses a FRAME-LOCAL STACK ARRAY `var buf: [64]u8` (the
3// [N]T feature, live 2026-07-06): ZERO heap, per-call (NO data race even under threading), freed on return.
4// This is the clean successor to the lazy-static version -- composes the language's own stack-array primitive,
5// no mmap at all. KAT: nx_fmt_test (0 / 42 / -12345 / 1000000 / i64-max).
6import "nx_syscalls.nx"
7
8// write signed decimal `v` to fd. Leak-free + race-free (frame-local scratch).
9func fmt_putn_fd(fd: i64, v: i64) -> i64 {
10 if v == 0 { sys_write(fd, "0" as *u8, 1); return 0 }
11 var buf: [64]u8
12 var m: i64 = v
13 if m < 0 { sys_write(fd, "-" as *u8, 1); m = 0 - m }
14 var k: i64 = 0
15 while m > 0 { buf[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
16 // reverse buf[0..k) in place so the digits read most-significant first
17 var a: i64 = 0
18 var b: i64 = k - 1
19 while a < b {
20 let t: i64 = buf[a]
21 buf[a] = buf[b]
22 buf[b] = t as u8
23 a = a + 1
24 b = b - 1
25 }
26 sys_write(fd, buf, k)
27 return 0
28}
29
30func fmt_putn(v: i64) -> i64 { return fmt_putn_fd(1, v) }
31
32// write NUL-terminated string `s` to fd (no buffer needed; length-scan + one write).
33func fmt_puts_fd(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
34func fmt_puts(s: *u8) -> i64 { return fmt_puts_fd(1, s) }