From 586a989ae98b0effc618956cf92d0ea30d4cdcf7 Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Fri, 19 Sep 2025 23:57:40 +0900 Subject: [PATCH 1/8] feat: update test-runner --- build.zig.zon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index f26abff..b271f1c 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -38,8 +38,8 @@ .dependencies = .{ // Custom test-runner: see tests output .runner = .{ - .url = "git+https://gist.github.com/karlseguin/c6bea5b35e4e8d26af6f81c22cb5d76b/#1f317ebc9cd09bc50fd5591d09c34255e15d1d85", - .hash = "N-V-__8AANwlAADW-4Yu_sYSZkL_6wcz13gOf9pkOLCjct-F", + .url = "git+https://gist.github.com/karlseguin/c6bea5b35e4e8d26af6f81c22cb5d76b#eb15512d6ae49663fa9df6c7a9725b20dab43edd", + .hash = "N-V-__8AAHMkAAC4CUVVTX0UMBJXtfOubskbF9EJ7X6qAGYR", }, }, .paths = .{ From e0c44c63d6baf61dc0816ccb3bf1014b377d3ff3 Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 00:00:03 +0900 Subject: [PATCH 2/8] feat: update for Zig 0.15.1 --- build.zig | 10 +++++++--- runall.zig | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/build.zig b/build.zig index e143b9a..c056365 100644 --- a/build.zig +++ b/build.zig @@ -235,11 +235,15 @@ fn buildAlgorithm(b: *std.Build, info: BInfo) void { const runner = b.dependency("runner", .{}).path("test_runner.zig"); - const exe_tests = b.addTest(.{ - .name = info.name, + const mod = b.addModule(info.name, .{ + .root_source_file = b.path(src), .target = info.target, .optimize = info.optimize, - .root_source_file = b.path(src), + }); + + const exe_tests = b.addTest(.{ + .name = info.name, + .root_module = mod, .test_runner = .{ .path = runner, .mode = .simple }, }); diff --git a/runall.zig b/runall.zig index f97c802..ffe4ee3 100644 --- a/runall.zig +++ b/runall.zig @@ -61,8 +61,8 @@ fn runTest(allocator: std.mem.Allocator, comptime algorithm: []const u8) !void { "-Dalgorithm=" ++ algorithm, } ++ args, allocator); - child.stderr = std.io.getStdErr(); - child.stdout = std.io.getStdOut(); + child.stderr = std.fs.File.stderr(); + child.stdout = std.fs.File.stdout(); _ = try child.spawnAndWait(); } From 718c039fceaac8b79cd013f948550ce3f2b2609c Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 01:19:04 +0900 Subject: [PATCH 3/8] fix: ArrayList usage --- .../longestIncreasingSubsequence.zig | 6 +- search/binarySearchTree.zig | 57 ++++++++++--------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/dynamicProgramming/longestIncreasingSubsequence.zig b/dynamicProgramming/longestIncreasingSubsequence.zig index d7e4f32..d765d74 100644 --- a/dynamicProgramming/longestIncreasingSubsequence.zig +++ b/dynamicProgramming/longestIncreasingSubsequence.zig @@ -30,15 +30,15 @@ pub fn lowerBound(arr: []const i32, key: i32) usize { // arr: the passed array // allocator: Any std.heap type allocator pub fn lis(arr: []const i32, allocator: anytype) usize { - var v = ArrayList(i32).init(allocator); - defer v.deinit(); + var v: ArrayList(i32) = .empty; + defer v.deinit(allocator); const n = arr.len; for (0..n) |i| { const it = lowerBound(v.items, arr[i]); if (it == v.items.len) { - _ = v.append(arr[i]) catch return 0; + _ = v.append(allocator, arr[i]) catch return 0; } else { v.items[it] = arr[i]; } diff --git a/search/binarySearchTree.zig b/search/binarySearchTree.zig index 6ab93e8..cd75ec0 100644 --- a/search/binarySearchTree.zig +++ b/search/binarySearchTree.zig @@ -1,6 +1,7 @@ const std = @import("std"); const print = std.debug.print; const ArrayList = std.ArrayList; +const Allocator = std.mem.Allocator; const testing = std.testing; // Returns a binary search tree instance. @@ -22,7 +23,7 @@ pub fn BinarySearchTree(comptime T: type) type { left: ?*node = null, }; - allocator: *std.mem.Allocator, + allocator: *Allocator, root: ?*node = null, size: usize = 0, @@ -56,27 +57,27 @@ pub fn BinarySearchTree(comptime T: type) type { } // Function that performs inorder traversal of the tree - pub fn inorder(self: *Self, path: *ArrayList(T)) !void { + pub fn inorder(self: *Self, allocator: Allocator, path: *ArrayList(T)) !void { if (self.root == null) { return; } - try self._inorder(self.root, path); + try self._inorder(allocator, self.root, path); } // Function that performs preorder traversal of the tree - pub fn preorder(self: *Self, path: *ArrayList(T)) !void { + pub fn preorder(self: *Self, allocator: Allocator, path: *ArrayList(T)) !void { if (self.root == null) { return; } - try self._preorder(self.root, path); + try self._preorder(allocator, self.root, path); } // Function that performs postorder traversal of the tree - pub fn postorder(self: *Self, path: *ArrayList(T)) !void { + pub fn postorder(self: *Self, allocator: Allocator, path: *ArrayList(T)) !void { if (self.root == null) { return; } - try self._postorder(self.root, path); + try self._postorder(allocator, self.root, path); } // Function that destroys the allocated memory of the whole tree @@ -159,27 +160,27 @@ pub fn BinarySearchTree(comptime T: type) type { return false; } - fn _inorder(self: *Self, root: ?*node, path: *ArrayList(T)) !void { + fn _inorder(self: *Self, allocator: Allocator, root: ?*node, path: *ArrayList(T)) !void { if (root != null) { - try self._inorder(root.?.left, path); - try path.append(root.?.info); - try self._inorder(root.?.right, path); + try self._inorder(allocator, root.?.left, path); + try path.append(allocator, root.?.info); + try self._inorder(allocator, root.?.right, path); } } - fn _preorder(self: *Self, root: ?*node, path: *ArrayList(T)) !void { + fn _preorder(self: *Self, allocator: Allocator, root: ?*node, path: *ArrayList(T)) !void { if (root != null) { - try path.append(root.?.info); - try self._preorder(root.?.left, path); - try self._preorder(root.?.right, path); + try path.append(allocator, root.?.info); + try self._preorder(allocator, root.?.left, path); + try self._preorder(allocator, root.?.right, path); } } - fn _postorder(self: *Self, root: ?*node, path: *ArrayList(T)) !void { + fn _postorder(self: *Self, allocator: Allocator, root: ?*node, path: *ArrayList(T)) !void { if (root != null) { - try self._postorder(root.?.left, path); - try self._postorder(root.?.right, path); - try path.append(root.?.info); + try self._postorder(allocator, root.?.left, path); + try self._postorder(allocator, root.?.right, path); + try path.append(allocator, root.?.info); } } @@ -244,26 +245,26 @@ test "Testing traversal methods" { try t.insert(12); try t.insert(15); - var ino = ArrayList(i32).init(allocator); - defer ino.deinit(); + var ino: ArrayList(i32) = .empty; + defer ino.deinit(allocator); const check_ino = [_]i32{ 3, 5, 12, 15, 25 }; - try t.inorder(&ino); + try t.inorder(allocator, &ino); try testing.expect(std.mem.eql(i32, ino.items, &check_ino)); - var pre = ArrayList(i32).init(allocator); - defer pre.deinit(); + var pre: ArrayList(i32) = .empty; + defer pre.deinit(allocator); const check_pre = [_]i32{ 5, 3, 25, 12, 15 }; - try t.preorder(&pre); + try t.preorder(allocator, &pre); try testing.expect(std.mem.eql(i32, pre.items, &check_pre)); - var post = ArrayList(i32).init(allocator); - defer post.deinit(); + var post: ArrayList(i32) = .empty; + defer post.deinit(allocator); const check_post = [_]i32{ 3, 15, 12, 25, 5 }; - try t.postorder(&post); + try t.postorder(allocator, &post); try testing.expect(std.mem.eql(i32, post.items, &check_post)); } From 12a949e9880c33513f558c25eda4937855ee1af2 Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 01:23:41 +0900 Subject: [PATCH 4/8] feat: migrate to Zig 0.15 HTTP client/server APIs --- web/http/client.zig | 14 ++++++-------- web/http/server.zig | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/web/http/client.zig b/web/http/client.zig index 585a521..04c536b 100644 --- a/web/http/client.zig +++ b/web/http/client.zig @@ -6,15 +6,13 @@ test "Status == 200" { .allocator = std.testing.allocator, }; defer client.deinit(); - var buffer: [4 * 1024]u8 = undefined; - var req = try client.open(.GET, uri, .{ - .server_header_buffer = &buffer, - }); + + var req = try client.request(.GET, uri, .{}); defer req.deinit(); - try req.send(); - try req.wait(); + try req.sendBodiless(); + const response = try req.receiveHead(&.{}); - try std.testing.expectEqual(req.response.status, .ok); - try std.testing.expectEqual(req.response.version, .@"HTTP/1.1"); + try std.testing.expectEqual(response.head.status, .ok); + try std.testing.expectEqual(response.head.version, .@"HTTP/1.1"); } diff --git a/web/http/server.zig b/web/http/server.zig index 74466b0..573ab7d 100644 --- a/web/http/server.zig +++ b/web/http/server.zig @@ -1,5 +1,5 @@ //! ref: https://github.com/ziglang/zig/blob/master/lib/std/http/test.zig -//! ref: https://ziglang.org/download/0.12.0/release-notes.html#Reworked-HTTP +//! ref: https://ziglang.org/download/0.15.1/release-notes.html#HTTP-Client-and-Server const std = @import("std"); const expect = std.testing.expect; @@ -7,6 +7,8 @@ const expect = std.testing.expect; test "client requests server" { const builtin = @import("builtin"); + const allocator = std.testing.allocator; + // This test requires spawning threads. if (builtin.single_threaded) { return error.SkipZigTest; @@ -24,7 +26,7 @@ test "client requests server" { const address = try std.net.Address.parseIp4("127.0.0.1", 0); var http_server = try address.listen(.{ - .reuse_port = true, + .reuse_address = true, }); const server_port = http_server.listen_address.getPort(); defer http_server.deinit(); @@ -34,16 +36,20 @@ test "client requests server" { const connection = try s.accept(); defer connection.stream.close(); - var read_buffer: [8000]u8 = undefined; - var server = std.http.Server.init(connection, &read_buffer); + var recv_buffer: [4000]u8 = undefined; + var sead_buffer: [4000]u8 = undefined; + var conn_reader = connection.stream.reader(&recv_buffer); + var conn_writer = connection.stream.writer(&sead_buffer); + var server = std.http.Server.init(conn_reader.interface(), &conn_writer.interface); var request = try server.receiveHead(); // Accept request - const reader = try request.reader(); - var buffer: [100]u8 = undefined; - const read_num = try reader.readAll(&buffer); - try std.testing.expectEqualStrings(buffer[0..read_num], "Hello, World!\n"); + var reader = try request.readerExpectContinue(&.{}); + const body = try reader.allocRemaining(allocator, .unlimited); + defer allocator.free(body); + + try std.testing.expectEqualStrings(body, "Hello, World!\n"); // Respond const server_body: []const u8 = "message from server!\n"; @@ -60,7 +66,7 @@ test "client requests server" { // Make requests to server var client = std.http.Client{ - .allocator = std.testing.allocator, + .allocator = allocator, }; defer client.deinit(); const uri = uri: { @@ -70,22 +76,19 @@ test "client requests server" { break :uri uri; }; - var buffer: [4 * 1024]u8 = undefined; - var req = try client.open(.POST, uri, .{ - .server_header_buffer = &buffer, - }); + var req = try client.request(.POST, uri, .{}); req.transfer_encoding = .{ .content_length = 14 }; defer req.deinit(); - try req.send(); - try req.writeAll("Hello, "); - try req.writeAll("World!\n"); - try req.finish(); + var body_writer = try req.sendBody(&.{}); - try req.wait(); + try body_writer.writer.writeAll("Hello, "); + try body_writer.writer.writeAll("World!\n"); + try body_writer.end(); - var read_buffer: [100]u8 = undefined; - const read_num = try req.readAll(&read_buffer); + var response = try req.receiveHead(&.{}); + const body = try response.reader(&.{}).allocRemaining(allocator, .unlimited); + defer allocator.free(body); - try std.testing.expectEqualStrings(read_buffer[0..read_num], "message from server!\n"); + try std.testing.expectEqualStrings(body, "message from server!\n"); } From 66453a38ed7841109d9cb150661be69cd6c95b16 Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 01:25:26 +0900 Subject: [PATCH 5/8] feat: migrate to Zig 0.15 HTTP client/server APIs --- web/tls/X25519+Kyber768Draft00.zig | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/web/tls/X25519+Kyber768Draft00.zig b/web/tls/X25519+Kyber768Draft00.zig index 4b86843..7594a8a 100644 --- a/web/tls/X25519+Kyber768Draft00.zig +++ b/web/tls/X25519+Kyber768Draft00.zig @@ -2,23 +2,28 @@ //! by: https://github.com/bwesterb test "HTTPS Client - X25519+Kyber768Draft00" { - var buf: [1000]u8 = undefined; - var header_buf: [8192]u8 = undefined; const uri = try std.Uri.parse("https://cloudflare.com/cdn-cgi/trace"); var client = std.http.Client{ .allocator = testing.allocator, }; defer client.deinit(); - var req = try client.open(.POST, uri, .{ - .server_header_buffer = &header_buf, + var req = try client.request(.GET, uri, .{ + .headers = .{ + .accept_encoding = .{ .override = "text/plain" }, + }, }); defer req.deinit(); - try req.send(); - try req.wait(); - const read = try req.read(&buf); - var strings = std.mem.splitAny(u8, buf[0..read], "\n"); + try req.sendBodiless(); + var response = try req.receiveHead(&.{}); + + var reader_buffer: [1000]u8 = undefined; + const body_reader = response.reader(&reader_buffer); + const body = try body_reader.allocRemaining(testing.allocator, .unlimited); + defer testing.allocator.free(body); + + var strings = std.mem.splitAny(u8, body, "\n"); var index = strings.index.?; while (index < strings.rest().len) : (index += 1) { const content = strings.next().?; @@ -29,8 +34,7 @@ test "HTTPS Client - X25519+Kyber768Draft00" { if (startW(u8, content, "http=")) try testing.expectEqualStrings("http=http/1.1", content); if (startW(u8, content, "uag=")) - try testing.expectEqualStrings("uag=zig/0.14.0 (std.http)", content); - // zig master/nightly change per build (e.g.: zig/0.11.0-dev.2868+1a455b2dd (std.http)) + try testing.expectEqualStrings("uag=zig/" ++ zig_version_string ++ " (std.http)", content); if (startW(u8, content, "tls=")) try testing.expectEqualStrings("tls=TLSv1.3", content); } @@ -39,3 +43,4 @@ test "HTTPS Client - X25519+Kyber768Draft00" { const std = @import("std"); const testing = std.testing; const startW = std.mem.startsWith; +const zig_version_string = @import("builtin").zig_version_string; From 46f2da001150db7cb6e925a8d9305ab910a2893e Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 01:28:00 +0900 Subject: [PATCH 6/8] fix: make build.zig match runall.zig for numerical_methods/newton_raphson (remove "_root") --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index c056365..392af3e 100644 --- a/build.zig +++ b/build.zig @@ -217,7 +217,7 @@ pub fn build(b: *std.Build) void { .category = "machine_learning", }); // Numerical Methods - if (std.mem.eql(u8, op, "numerical_methods/newton_raphson_root")) + if (std.mem.eql(u8, op, "numerical_methods/newton_raphson")) buildAlgorithm(b, .{ .optimize = optimize, .target = target, From 644dbc48d38598555bde25cd70cf9f2e5dfcec4b Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 01:29:58 +0900 Subject: [PATCH 7/8] zig update - v0.15.1 --- build.zig.zon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig.zon b/build.zig.zon index b271f1c..f9be43a 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -28,7 +28,7 @@ // Tracks the earliest Zig version that the package considers to be a // supported use case. - .minimum_zig_version = "0.14.0", + .minimum_zig_version = "0.15.1", // This field is optional. // Each dependency must either provide a `url` and `hash`, or a `path`. From ebd3506e38302802dcc9d51d23ce3461b75b2ec4 Mon Sep 17 00:00:00 2001 From: Ryoga-exe Date: Sat, 20 Sep 2025 01:31:30 +0900 Subject: [PATCH 8/8] docs: update zig version to 0.15.1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fc85e6..1a83969 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ ### How to build **Require:** -- [Zig v0.14 or higher](https://ziglang.org/download), self-hosting (stage3) compiler. +- [Zig v0.15.1 or higher](https://ziglang.org/download), self-hosting (stage3) compiler. ### Test all