From 3552e25e4919eab5aaae2c60bf6506871c58deb4 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Fri, 2 Oct 2026 23:59:44 -0500 Subject: [PATCH] Build with the Zig 0.17.0 release Take the overlay's "0.17.0" release package rather than nixpkgs' Zig, which has no 0.17, and require 0.17.0 in build.zig.zon. The port itself is small: b.args gives way to addPassthruArgs, the array repetition operator is gone from the benchmark's filler, and zig fmt rewrites @intFromEnum to @backingInt. The README points 0.16 users at v0.2.1 and the zig-0.16 branch. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01425BduET4coqFEidGn2i51 --- README.md | 24 +++++++++++++++------- build.zig | 4 ++-- build.zig.zon | 2 +- flake.lock | 46 +++++++++++++++++++++++++++++++++++++++++- flake.nix | 9 ++++++++- test/csv_tokenizer.zig | 2 +- tools/bench.zig | 4 ++-- tools/fuzz.zig | 6 ++---- 8 files changed, 78 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index b595a6e..1d2b76c 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,18 @@ git clone https://github.com/jcollie/zig-csv.git ## Requirements -Zig 0.16.0 or later. The 0.16 release reworked readers and writers, so earlier -versions will not build this. +Zig 0.17.0 for `main`. The development shell takes the official release +binary from [zig-overlay](https://git.jcollie.dev/jeff/zig-overlay). + +For Zig 0.16.0, use the `v0.2.1` tag or the `zig-0.16` branch, which hold the +last of zig-csv to build with it: + +```console +zig fetch --save git+https://git.jcollie.dev/jeff/zig-csv.git#zig-0.16 +``` + +The 0.16 release reworked readers and writers, so nothing earlier builds +either line. ## Installation @@ -38,7 +48,7 @@ zig fetch --save git+https://git.jcollie.dev/jeff/zig-csv.git#v0.2.1 ``` That records the resolved commit and hash in your `build.zig.zon` under the -name `zig_csv`. Naming a tag pins the release; leaving the `#v0.1.0` off +name `zig_csv`. Naming a tag pins the release; leaving the `#v0.2.1` off pins whatever `main` happened to point at when you ran the command, which is rarely what you want in a committed manifest. @@ -97,7 +107,7 @@ tokenizer, and that the trailing empty field is reported as a zero-length ### Reading from a file The tokenizer only wants a `*std.Io.Reader`, so a file reader is the same code -with a different source. In 0.16 file access goes through an `Io`: +with a different source. File access goes through an `Io`: ```zig var threaded: std.Io.Threaded = .init(gpa, .{}); @@ -298,8 +308,8 @@ zig build fuzz -- --iterations 100000 --seed 1 zig build bench -- --seconds 2 ``` -Zig 0.16.0 cannot build a test executable in fuzz mode, so `tools/fuzz.zig` -drives the targets in `test/fuzz.zig` itself, mutating a corpus of real CSV. +`tools/fuzz.zig` drives the targets in `test/fuzz.zig` itself, mutating a +corpus of real CSV. Besides checking that nothing crashes, the targets assert that the field buffer cannot change what is parsed, that a token stream survives being re-encoded and read back, that the streaming tokenizer agrees with a naive @@ -341,7 +351,7 @@ Original author: [beho](https://github.com/beho), whose repository at tokenizer design and the test suite are theirs. Later upstream contributions came from Roman Frołow, Nitin Prakash, xdBronch, and Deins. -This fork carries the library forward across Zig releases — currently 0.16 — +This fork carries the library forward across Zig releases — currently 0.17 — and adds the Nix flake, the Forgejo workflow, and REUSE licensing metadata. ## License diff --git a/build.zig b/build.zig index 5bc2a15..bd09290 100644 --- a/build.zig +++ b/build.zig @@ -58,7 +58,7 @@ pub fn build(b: *std.Build) void { fuzz_driver.root_module.addImport("fuzz", fuzz_module); const run_fuzz = b.addRunArtifact(fuzz_driver); - if (b.args) |args| run_fuzz.addArgs(args); + run_fuzz.addPassthruArgs(); run_fuzz.stdio = .inherit; const fuzz_step = b.step("fuzz", "Run the fuzzing loop (-- --iterations N --seed N --target NAME)"); @@ -80,7 +80,7 @@ pub fn build(b: *std.Build) void { const bench = b.addExecutable(.{ .name = "bench", .root_module = bench_module }); const run_bench = b.addRunArtifact(bench); - if (b.args) |args| run_bench.addArgs(args); + run_bench.addPassthruArgs(); run_bench.stdio = .inherit; const bench_step = b.step("bench", "Run the throughput benchmarks (-- --seconds N --buffer N --case NAME)"); diff --git a/build.zig.zon b/build.zig.zon index 7cb3ca2..9550b72 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .zig_csv, .version = "0.3.0", .fingerprint = 0xb51631650614d5d2, - .minimum_zig_version = "0.16.0", + .minimum_zig_version = "0.17.0", .dependencies = .{}, .paths = .{ "build.zig", diff --git a/flake.lock b/flake.lock index d623e31..0756457 100644 --- a/flake.lock +++ b/flake.lock @@ -15,7 +15,51 @@ }, "root": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "zig": "zig" + } + }, + "zig": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "zon2nix": "zon2nix" + }, + "locked": { + "lastModified": 1790983248, + "narHash": "sha256-fjtjxWEofW5cbzXm3SqvjC2QZIbtp3lij2k8e1Jmj0w=", + "ref": "refs/heads/main", + "rev": "1a73bc5e8ae4d0223fefbd00afc58fe0b7f7e718", + "revCount": 1734, + "type": "git", + "url": "https://git.jcollie.dev/jeff/zig-overlay.git" + }, + "original": { + "type": "git", + "url": "https://git.jcollie.dev/jeff/zig-overlay.git" + } + }, + "zon2nix": { + "inputs": { + "nixpkgs": [ + "zig", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1790583033, + "narHash": "sha256-Eo3hR521Yc2Gsqw7m/aqd5sn3/qi0XoSpJBIPPIYKkg=", + "owner": "jcollie", + "repo": "zon2nix", + "rev": "8e91c0d44aa49d0ac415f7e3046662e9aa754335", + "type": "github" + }, + "original": { + "owner": "jcollie", + "ref": "v0.9.0", + "repo": "zon2nix", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index 6c4252f..af357d2 100644 --- a/flake.nix +++ b/flake.nix @@ -7,12 +7,19 @@ inputs = { nixpkgs.url = "https://channels.nixos.org/nixos-unstable/nixexprs.tar.zst"; + # The toolchain is the official 0.17.0 release binary, packaged by the + # overlay, rather than nixpkgs' Zig. + zig = { + url = "git+https://git.jcollie.dev/jeff/zig-overlay.git"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = { self, nixpkgs, + zig, ... }: let @@ -29,7 +36,7 @@ default = pkgs.mkShell { nativeBuildInputs = [ pkgs.reuse - pkgs.zig_0_16 + zig.packages.${pkgs.stdenv.hostPlatform.system}."0.17.0" ]; }; }); diff --git a/test/csv_tokenizer.zig b/test/csv_tokenizer.zig index 8411983..05853bc 100644 --- a/test/csv_tokenizer.zig +++ b/test/csv_tokenizer.zig @@ -14,7 +14,7 @@ fn getTokenizer(reader: *std.Io.Reader, buffer: []u8, config: csv_mod.CsvConfig) fn expectToken(comptime expected: csv_mod.CsvToken, maybe_actual: ?csv_mod.CsvToken) !void { if (maybe_actual) |actual| { - if (@intFromEnum(expected) != @intFromEnum(actual)) { + if (@backingInt(expected) != @backingInt(actual)) { std.log.warn("Expected {t} but is {t}\n", .{ expected, actual }); return error.TestFailed; } diff --git a/tools/bench.zig b/tools/bench.zig index cb27dd6..05f81c4 100644 --- a/tools/bench.zig +++ b/tools/bench.zig @@ -177,9 +177,9 @@ fn genWide(gpa: Allocator, rows: usize) ![]u8 { fn genLongFields(gpa: Allocator, rows: usize) ![]u8 { var out: std.ArrayList(u8) = .empty; defer out.deinit(gpa); - const filler = "x" ** 200; + const filler: [200]u8 = @splat('x'); for (0..rows) |i| { - try out.print(gpa, "{d},{s},{s}\n", .{ i, filler, filler }); + try out.print(gpa, "{d},{s},{s}\n", .{ i, &filler, &filler }); } return out.toOwnedSlice(gpa); } diff --git a/tools/fuzz.zig b/tools/fuzz.zig index 83e3dfe..89cfe1a 100644 --- a/tools/fuzz.zig +++ b/tools/fuzz.zig @@ -3,10 +3,8 @@ //! A fuzzing loop for the CSV tokenizer. //! -//! Zig 0.16.0 cannot build a test executable in fuzz mode, and even patched it -//! populates no coverage table, so this drives the targets in `test/fuzz.zig` -//! itself: it mutates a corpus of real CSV inputs, hands each result to a -//! target, and reports what came back. +//! This drives the targets in `test/fuzz.zig` itself: it mutates a corpus of +//! real CSV inputs, hands each result to a target, and reports what came back. //! //! Usage: fuzz [--iterations N] [--seed N] [--target NAME] -- knotmirror 0.0.1