From be42267a59e1de6e03c3309352bc47d0bc2a2b12 Mon Sep 17 00:00:00 2001 From: Toni Date: Fri, 5 Jun 2026 09:47:59 +0200 Subject: [PATCH] io.snprintf --- examples/puzzles/aoc2024_07.zr | 12 ++----- examples/sqlite_todo.zr | 5 +-- src/std/net.zr | 1 + src/std/std.zr | 61 ++++++++++++++++++++++++++++++++++ test.zr | 6 +--- 5 files changed, 67 insertions(+), 18 deletions(-) diff --git a/examples/puzzles/aoc2024_07.zr b/examples/puzzles/aoc2024_07.zr index ca7ee90..35986df 100644 --- a/examples/puzzles/aoc2024_07.zr +++ b/examples/puzzles/aoc2024_07.zr @@ -1,13 +1,7 @@ func concat[a: i64, b: i64] : i64 - a_str := str.from_i64(a) - b_str := str.from_i64(b) - ab_str := str.concat(a_str, b_str) - out := str.parse_i64(ab_str) - // without freeing the program works but leaks 2GB of memory :p - mem.free(a_str) - mem.free(b_str) - mem.free(ab_str) - return out + ab_str := _stackalloc(50) + io.snprintf(ab_str, 50, "%d%d", a, b) + return str.parse_i64(ab_str) func solve[ops: Array, e: Array] : i64 e_1 : Array = array.nth(e, 1) diff --git a/examples/sqlite_todo.zr b/examples/sqlite_todo.zr index 7b0e2fd..ae619b0 100644 --- a/examples/sqlite_todo.zr +++ b/examples/sqlite_todo.zr @@ -41,10 +41,7 @@ func main[] : i64 while sqlite3_step(stmt) == 100 id := sqlite3_column_int(stmt, 0) task := sqlite3_column_text(stmt, 1) - - io.print_i64(id) - io.print(" - ") - io.println(task) + io.printf("%d - %s\n", id, task) io.println("============") else if choice == 2 diff --git a/src/std/net.zr b/src/std/net.zr index 99046f2..411080f 100644 --- a/src/std/net.zr +++ b/src/std/net.zr @@ -174,6 +174,7 @@ func net.resolve[domain: str] : i64, bool // TODO: this probably shouldnt be hardcoded ~s, ok := net.create_udp_client(net.pack_addr(1, 1, 1, 1), 53) if !ok + Blob.free(query) return -1, false net.udp_send_to(s, s->addr, query->data, query->size) diff --git a/src/std/std.zr b/src/std/std.zr index 19a38ea..625cacf 100644 --- a/src/std/std.zr +++ b/src/std/std.zr @@ -283,6 +283,67 @@ func io.printf[..] : void io.print_char(s[0]) s = s + 1 +func io.snprintf[..] : i64 + buf := _var_arg(0) as ptr + size := _var_arg(1) as i64 + if size <= 0 + return 0 + s := _var_arg(2) as ptr + i := 3 + n := 0 + + while s[0] + if s[0] == '%' + s = s + 1 + + if s[0] == 'd' + tmp := _stackalloc(21) + str.from_i64_buf(tmp, _var_arg(i) as i64) + tmp_len := str.len(tmp as str) + remaining := size - n - 1 + mem.copy(tmp, buf + n, math.min(tmp_len, remaining)) + n = n + tmp_len + i = i + 1 + else if s[0] == 'x' + tmp := _stackalloc(17) + str.hex_from_i64_buf(tmp, _var_arg(i) as i64) + tmp_len := str.len(tmp as str) + remaining := size - n - 1 + mem.copy(tmp, buf + n, math.min(tmp_len, remaining)) + n = n + tmp_len + i = i + 1 + else if s[0] == 's' + tmp_str := _var_arg(i) as str + tmp_len := str.len(tmp_str) + remaining := size - n - 1 + mem.copy(tmp_str as ptr, buf + n, math.min(tmp_len, remaining)) + n = n + tmp_len + i = i + 1 + else if s[0] == 'c' + if n < size - 1 + buf[n] = _var_arg(i) as u8 + n = n + 1 + i = i + 1 + else if s[0] == '%' + if n < size - 1 + buf[n] = '%' + n = n + 1 + else if s[0] == 0 + break + else + panic("io.snprintf: unrecognized format") + else + if n < size - 1 + buf[n] = s[0] + n = n + 1 + s = s + 1 + + if n < size + buf[n] = 0 + else if size > 0 + buf[size - 1] = 0 + return n + func io.print_sized[x: ptr, size: i64] : void _builtin_syscall(SYS_write, 1, x, size) diff --git a/test.zr b/test.zr index 5236320..ec0ae49 100644 --- a/test.zr +++ b/test.zr @@ -19,9 +19,7 @@ func run_test[x: str] : void for i in 0..run_blacklist->size if str.find(x, array.nth(run_blacklist, i)) != -1 - io.print("Skipping ") - io.print(x) - io.println("...") + io.printf("Skipping %s...\n", x) return 0 io.printf("Running %s...\n", x) @@ -45,8 +43,6 @@ func run_directory[dir: str] : void for i in 0..files->size run_test(str.concat(dir, array.nth(files, i))) - array.free(files) - func main[] : i64 ~status, ok := os.run_shell_command("cargo build --release") if !ok || status != 0