diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fe9c783..ce6f821 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
- version: 0.16.0
+ version: 0.17.0
- name: Zig fmt check
shell: bash
@@ -36,7 +36,7 @@ jobs:
- name: Benchmark smoke
shell: bash
run: |
- zig build bench-only -Doptimize=ReleaseFast
+ zig build bench-only -Doptimize=fast
for mode in validated validated-trusted permissive; do
./zig-out/bin/zxml-bench parse "$mode" bench/smoke.xml 1 >/dev/null
./zig-out/bin/zxml-stream-bench parse "$mode" bench/smoke.xml 1 >/dev/null
@@ -45,8 +45,8 @@ jobs:
- name: Darwin compile and 32-bit public API
shell: bash
run: |
- zig build bench-only -Dtarget=x86_64-macos -Doptimize=ReleaseFast
- zig build test-public-api -Dtarget=x86-linux-musl -Dintlen=u64 -Doptimize=ReleaseSafe
+ zig build bench-only -Dtarget=x86_64-macos -Doptimize=fast
+ zig build test-public-api -Dtarget=x86-linux-musl -Dintlen=u64 -Doptimize=safe
- name: Conformance
run: zig build conformance
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1b235a3..5b2e8dd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
## Prerequisites
-- Zig `0.16.0`
+- Zig `0.17.0`
- Git
## Local Development Workflow
@@ -23,6 +23,8 @@ zig build bench-compare
zig build conformance
```
+Use `zig build test -j1 -Dtest-jobs=1` to bound both compilation and test-process concurrency.
+
## Style
- Format Zig code before pushing:
diff --git a/README.md b/README.md
index c34139b..80a1903 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ Fast XML parsing for Zig with comptime-generated DOM and streaming types.
The default parser is destructive and permissive. Attributes and text stay source-backed and are materialized lazily; the DOM does not build an attribute array or a separate open-element stack.
+Requires Zig `0.17.0`.
+
## Quick start
```zig
diff --git a/bench/runners/run_parse.zig b/bench/runners/run_parse.zig
index 70c5c5c..4878b2d 100644
--- a/bench/runners/run_parse.zig
+++ b/bench/runners/run_parse.zig
@@ -108,7 +108,7 @@ fn runStreamValidated(io: std.Io, alloc: std.mem.Allocator, input: []const u8, i
fn onNode(self: *@This(), node: *const StreamingEventType) bool {
self.count +%= 1;
- self.checksum +%= @as(u64, @intFromEnum(node.kind)) +% 1;
+ self.checksum +%= @as(u64, @backingInt(node.kind)) +% 1;
switch (node.kind) {
.element => {
self.checksum +%= @as(u64, node.name.end - node.name.start);
@@ -143,7 +143,7 @@ fn runStreamValidatedTrusted(io: std.Io, alloc: std.mem.Allocator, input: []cons
fn onNode(self: *@This(), node: *const StreamingEventType) bool {
self.count +%= 1;
- self.checksum +%= @as(u64, @intFromEnum(node.kind)) +% 1;
+ self.checksum +%= @as(u64, @backingInt(node.kind)) +% 1;
switch (node.kind) {
.element => {
self.checksum +%= @as(u64, node.name.end - node.name.start);
@@ -175,7 +175,7 @@ fn runStreamPermissive(io: std.Io, alloc: std.mem.Allocator, input: []const u8,
fn onNode(self: *@This(), node: *const StreamingEventType) bool {
self.count +%= 1;
- self.checksum +%= @as(u64, @intFromEnum(node.kind)) +% 1;
+ self.checksum +%= @as(u64, @backingInt(node.kind)) +% 1;
switch (node.kind) {
.element => {
self.checksum +%= @as(u64, node.name.end - node.name.start);
diff --git a/build.zig b/build.zig
index f41d44d..bc620ff 100644
--- a/build.zig
+++ b/build.zig
@@ -11,6 +11,7 @@ const IntLen = enum {
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
+ const test_jobs = b.option(usize, "test-jobs", "Maximum concurrent test processes");
const intlen = b.option(IntLen, "intlen", "Integer width used for DOM spans and node indexes") orelse .u32;
const config_options = b.addOptions();
@@ -117,20 +118,19 @@ pub fn build(b: *std.Build) void {
docs_check_cmd.step.dependOn(b.getInstallStep());
examples_check_cmd.step.dependOn(b.getInstallStep());
- if (b.args) |args| {
- tools_cmd.addArgs(args);
- compare_cmd.addArgs(args);
- interleaved_cmd.addArgs(args);
- conformance_cmd.addArgs(args);
- docs_check_cmd.addArgs(args);
- examples_check_cmd.addArgs(args);
- }
+ tools_cmd.addPassthruArgs();
+ compare_cmd.addPassthruArgs();
+ interleaved_cmd.addPassthruArgs();
+ conformance_cmd.addPassthruArgs();
+ docs_check_cmd.addPassthruArgs();
+ examples_check_cmd.addPassthruArgs();
const mod_tests = b.addTest(.{
.root_module = mod,
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_mod_tests = b.addRunArtifact(mod_tests);
+ if (test_jobs) |jobs| run_mod_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const example_tests = b.addTest(.{
.root_module = b.createModule(.{
@@ -144,6 +144,7 @@ pub fn build(b: *std.Build) void {
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_example_tests = b.addRunArtifact(example_tests);
+ if (test_jobs) |jobs| run_example_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const bench_tests = b.addTest(.{
.root_module = b.createModule(.{
@@ -157,6 +158,7 @@ pub fn build(b: *std.Build) void {
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_bench_tests = b.addRunArtifact(bench_tests);
+ if (test_jobs) |jobs| run_bench_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const tools_tests = b.addTest(.{
.root_module = b.createModule(.{
@@ -170,6 +172,7 @@ pub fn build(b: *std.Build) void {
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_tools_tests = b.addRunArtifact(tools_tests);
+ if (test_jobs) |jobs| run_tools_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const tools_common_tests = b.addTest(.{
.root_module = b.createModule(.{
@@ -180,6 +183,7 @@ pub fn build(b: *std.Build) void {
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_tools_common_tests = b.addRunArtifact(tools_common_tests);
+ if (test_jobs) |jobs| run_tools_common_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const conformance_tests = b.addTest(.{
.root_module = b.createModule(.{
@@ -193,6 +197,7 @@ pub fn build(b: *std.Build) void {
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_conformance_tests = b.addRunArtifact(conformance_tests);
+ if (test_jobs) |jobs| run_conformance_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const public_api_tests = b.addTest(.{
.root_module = b.createModule(.{
@@ -206,6 +211,7 @@ pub fn build(b: *std.Build) void {
.test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple },
});
const run_public_api_tests = b.addRunArtifact(public_api_tests);
+ if (test_jobs) |jobs| run_public_api_tests.addArgs(&.{ "--jobs", b.fmt("{d}", .{jobs}) });
const public_api_step = b.step("test-public-api", "Run exhaustive consumer-facing public API tests");
public_api_step.dependOn(&run_public_api_tests.step);
diff --git a/build.zig.zon b/build.zig.zon
index b641670..ae868a4 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -2,7 +2,7 @@
.name = .zxml,
.version = "0.1.0",
.fingerprint = 0xeb739e953d363ad3,
- .minimum_zig_version = "0.16.0",
+ .minimum_zig_version = "0.17.0",
.paths = .{
".gitignore",
"LICENSE",
diff --git a/src/attr.zig b/src/attr.zig
index 79727df..5dd84e5 100644
--- a/src/attr.zig
+++ b/src/attr.zig
@@ -206,7 +206,7 @@ pub fn materializeAttributes(
}
}
- source[write] = @intFromEnum(state);
+ source[write] = @backingInt(state);
write += 1;
const value_start: usize = @intCast(item.value.start);
std.mem.copyForwards(u8, source[write .. write + value_len], source[value_start .. value_start + value_len]);
diff --git a/src/document.zig b/src/document.zig
index ed0831a..da16ba9 100644
--- a/src/document.zig
+++ b/src/document.zig
@@ -1656,8 +1656,9 @@ fn consumeMixedContent(input: []const u8, i: *usize) ParseError!void {
fn consumeChildrenContent(allocator: std.mem.Allocator, input: []const u8, i: *usize) ParseError!void {
std.debug.assert(input[i.*] == '(');
- var stack_fallback = std.heap.stackFallback(512, allocator);
- const temp_allocator = stack_fallback.get();
+ var stack_buffer: [512]u8 align(@alignOf(ContentFrame)) = undefined;
+ var stack_fallback: std.heap.BufferFirstAllocator = .init(&stack_buffer, allocator);
+ const temp_allocator = stack_fallback.allocator();
var stack: std.ArrayList(ContentFrame) = .empty;
defer stack.deinit(temp_allocator);
@@ -2470,7 +2471,7 @@ pub fn GetDocument(comptime options: ParseOptions) type {
const end: usize = @intCast(span.end);
if (end >= self.source.len) return .raw;
return switch (self.source[end]) {
- @intFromEnum(TextMaterializationState.decoded) => .decoded,
+ @backingInt(TextMaterializationState.decoded) => .decoded,
else => .raw,
};
}
@@ -2478,7 +2479,7 @@ pub fn GetDocument(comptime options: ParseOptions) type {
inline fn markTextState(self: *Self, idx: IndexInt, state: TextMaterializationState) void {
if (comptime options.non_destructive) return;
const end: usize = @intCast(self.nodes[@intCast(idx)].valueSpan(idx).end);
- if (end < self.source.len) self.source[end] = @intFromEnum(state);
+ if (end < self.source.len) self.source[end] = @backingInt(state);
}
fn materializeText(self: *Self, idx: IndexInt, alloc: std.mem.Allocator) ValueError!common.SliceResult {
@@ -3253,7 +3254,7 @@ test "XML character vector exits never skip invalid controls or encodings" {
}
test "XML character validation crosses dense Unicode and ASCII windows" {
- const source = "é漢😀" ** 20 ++ " ASCII " ** 20 ++ "Ω漢é" ** 35;
+ const source = &(comptime repeatTestBytes("é漢😀", 20) ++ repeatTestBytes(" ASCII ", 20) ++ repeatTestBytes("Ω漢é", 35));
for (0..source.len + 1) |split| {
var expected = split;
while (!std.unicode.utf8ValidateSlice(source[0..expected])) : (expected -= 1) {}
@@ -3279,7 +3280,7 @@ test "vector UTF-8 validation rejects illegal sequences at every lane boundary"
try std.testing.expectError(error.InvalidXmlCharacter, xmlValidPrefixLenStreaming(&input));
}
}
- const valid = "é漢😀Ω" ** 12 ++ " \t\n\rASCII" ** 4;
+ const valid = &(comptime repeatTestBytes("é漢😀Ω", 12) ++ repeatTestBytes(" \t\n\rASCII", 4));
for (0..valid.len + 1) |end| {
var boundary = end;
while (!std.unicode.utf8ValidateSlice(valid[0..boundary])) : (boundary -= 1) {}
@@ -3441,3 +3442,9 @@ test "compact validated serialization preserves a required DOCTYPE" {
try std.testing.expectEqualStrings("&e;", reparsed.nodeAt(1).?.getAttributeValueRaw("a").?);
}
}
+
+fn repeatTestBytes(comptime bytes: []const u8, comptime count: usize) [bytes.len * count]u8 {
+ var result: [bytes.len * count]u8 = undefined;
+ for (0..count) |i| @memcpy(result[i * bytes.len ..][0..bytes.len], bytes);
+ return result;
+}
diff --git a/src/parser.zig b/src/parser.zig
index 14ecfa0..769bf03 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -2092,7 +2092,12 @@ test "inline node storage spills safely and releases every failed allocation" {
const Check = struct {
fn run(allocator: std.mem.Allocator) !void {
const options: ParseOptions = .{ .validate_well_formedness = true };
- var source = ("" ++ "value" ** 90 ++ "").*;
+ var source = comptime blk: {
+ const child = "value";
+ var children: [child.len * 90]u8 = undefined;
+ for (0..90) |i| @memcpy(children[i * child.len ..][0..child.len], child);
+ break :blk "".* ++ children ++ "".*;
+ };
var doc = try options.parse(allocator, &source);
defer doc.deinit();
try std.testing.expectEqual(@as(usize, 182), doc.nodes.len);
diff --git a/src/root.zig b/src/root.zig
index 7c15a98..75bad27 100644
--- a/src/root.zig
+++ b/src/root.zig
@@ -1564,11 +1564,11 @@ fn refAllDeclsRecursiveSeen(comptime T: type, comptime seen: []const type) void
// Recurse into namespace-style containers only; value-carrying types blow
// up the traversal without contributing additional declaration coverage.
inline for (comptime std.meta.declarations(T)) |decl| {
- const decl_value = @field(T, decl.name);
+ const decl_value = @field(T, decl);
if (@TypeOf(decl_value) != type) continue;
const Child = decl_value;
if (comptime switch (@typeInfo(Child)) {
- .@"struct" => |s| s.fields.len != 0,
+ .@"struct" => |s| s.field_names.len != 0,
.@"union", .@"enum", .@"opaque" => true,
else => true,
}) continue;
diff --git a/src/scanner.zig b/src/scanner.zig
index 1bb9ec0..3f4680f 100644
--- a/src/scanner.zig
+++ b/src/scanner.zig
@@ -11,7 +11,7 @@ const byte_scan_vector_len: comptime_int = switch (builtin.cpu.arch) {
pub noinline fn countByte(source: []const u8, value: u8) usize {
const Vec = @Vector(byte_scan_vector_len, u8);
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
const needle: Vec = @splat(value);
var i: usize = 0;
var count: usize = 0;
@@ -145,7 +145,7 @@ pub inline fn findTextEnd(noalias haystack: []const u8, start: usize) ?usize {
const Vec = @Vector(byte_scan_vector_len, u8);
if (haystack.len - start >= @sizeOf(Vec)) {
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
// Load the vector directly; array coercion can reconstruct it from scalar loads.
const bytes = @as(*align(1) const Vec, @ptrCast(haystack.ptr + start)).*;
const lt_vec: Vec = @splat('<');
@@ -170,7 +170,7 @@ pub noinline fn scanStartTagEnd(noalias input: []const u8, start: usize) ?StartT
const Vec = @Vector(byte_scan_vector_len, u8);
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
const gt_vec: Vec = @splat('>');
const sq_vec: Vec = @splat('\'');
const dq_vec: Vec = @splat('"');
@@ -250,7 +250,7 @@ pub noinline fn scanStartTagEndFast(noalias input: []const u8, start: usize) usi
if (start >= input.len) return 0;
const Vec = @Vector(byte_scan_vector_len, u8);
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
if (input.len - start < @sizeOf(Vec)) return scanStartTagEndFastLong(input, start, start, 0, false);
const bytes: Vec = input[start..][0..@sizeOf(Vec)].*;
@@ -277,7 +277,7 @@ noinline fn scanStartTagEndFastLong(
) usize {
const Vec = @Vector(byte_scan_vector_len, u8);
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
var seen_quotes = initial_seen_quotes;
var odd = initial_odd;
var i = initial_i;
@@ -490,7 +490,7 @@ pub inline fn scanQuotedValueSpecials(noalias hay: []const u8, start: usize, quo
const Vec = @Vector(byte_scan_vector_len, u8);
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
const quote_vec: Vec = @splat(quote);
const lt_vec: Vec = @splat('<');
const amp_vec: Vec = @splat('&');
@@ -730,7 +730,7 @@ pub inline fn scanTextSpecials(noalias hay: []const u8, start: usize) TextSpecia
const Vec = @Vector(byte_scan_vector_len, u8);
const Bits = @Vector(byte_scan_vector_len, u1);
- const Mask = std.meta.Int(.unsigned, byte_scan_vector_len);
+ const Mask = @Int(.unsigned, byte_scan_vector_len);
const lt_vec: Vec = @splat('<');
const close_vec: Vec = @splat(']');
const amp_vec: Vec = @splat('&');
@@ -1110,7 +1110,7 @@ test "bytePairPresence finds either sentinel in short and vector-sized inputs" {
try std.testing.expect(both.first);
try std.testing.expect(both.second);
- var long = [_]u8{'x'} ** (byte_scan_vector_len * 2 + 3);
+ var long: [byte_scan_vector_len * 2 + 3]u8 = @splat('x');
long[byte_scan_vector_len - 1] = ']';
long[byte_scan_vector_len * 2 + 1] = '&';
const vector = bytePairPresence(&long, ']', '&');
diff --git a/src/streaming.zig b/src/streaming.zig
index 345e4e6..e6213c3 100644
--- a/src/streaming.zig
+++ b/src/streaming.zig
@@ -1651,13 +1651,13 @@ const CallbackKind = enum {
fn callbackKind(comptime callback: anytype, comptime Node: type) CallbackKind {
const cb_info = @typeInfo(@TypeOf(callback)).@"fn";
- return switch (cb_info.params.len) {
- 1 => switch (cb_info.params[0].type.?) {
+ return switch (cb_info.param_types.len) {
+ 1 => switch (cb_info.param_types[0].?) {
Node => .node,
*const Node => .node_ptr,
else => @compileError("streaming callback node parameter must be Node or *const Node"),
},
- 2 => switch (cb_info.params[1].type.?) {
+ 2 => switch (cb_info.param_types[1].?) {
Node => .ctx_node,
*const Node => .ctx_node_ptr,
else => @compileError("streaming callback node parameter must be Node or *const Node"),
diff --git a/src/tables.zig b/src/tables.zig
index fc38e96..bcde18c 100644
--- a/src/tables.zig
+++ b/src/tables.zig
@@ -1,7 +1,7 @@
const std = @import("std");
pub const WhitespaceTable = blk: {
- var t = [_]bool{false} ** 256;
+ var t: [256]bool = @splat(false);
t[' '] = true;
t['\t'] = true;
t['\n'] = true;
@@ -10,7 +10,7 @@ pub const WhitespaceTable = blk: {
};
pub const NameStartTable = blk: {
- var t = [_]bool{false} ** 256;
+ var t: [256]bool = @splat(false);
for ('A'..('Z' + 1)) |c| t[c] = true;
for ('a'..('z' + 1)) |c| t[c] = true;
for (0x80..256) |c| t[c] = true;
@@ -20,7 +20,7 @@ pub const NameStartTable = blk: {
};
pub const NameCharTable = blk: {
- var t = [_]bool{false} ** 256;
+ var t: [256]bool = @splat(false);
for ('A'..('Z' + 1)) |c| t[c] = true;
for ('a'..('z' + 1)) |c| t[c] = true;
for ('0'..('9' + 1)) |c| t[c] = true;
@@ -33,7 +33,7 @@ pub const NameCharTable = blk: {
};
pub const AttrUnquotedValueCharTable = blk: {
- var t = [_]bool{true} ** 256;
+ var t: [256]bool = @splat(true);
t['<'] = false;
t['>'] = false;
t['&'] = false;
diff --git a/test_runner.zig b/test_runner.zig
index 54861c4..3f5f073 100644
--- a/test_runner.zig
+++ b/test_runner.zig
@@ -515,7 +515,7 @@ fn printTestOutput(name: []const u8, res: ChildResult) void {
switch (res.term) {
.exited => |code| if (code != 0) print(" | exit {d}", .{code}),
- .signal => |sig| print(" | signal {d} ({s})", .{ @intFromEnum(sig), @tagName(sig) }),
+ .signal => |sig| print(" | signal {d} ({s})", .{ @backingInt(sig), @tagName(sig) }),
.stopped => |code| print(" | stopped {d}", .{code}),
.unknown => |code| print(" | unknown {d}", .{code}),
}
@@ -544,11 +544,11 @@ fn runSingleTest(name: []const u8, seed: ?u32) void {
std.process.exit(1);
};
- std.testing.allocator_instance = .{};
+ std.testing.allocator_instance = .init(std.heap.page_allocator, .{ .check_write_after_free = true });
const result = test_fn.func();
const leak_status = std.testing.allocator_instance.deinit();
- if (leak_status == .leak) {
+ if (leak_status != 0) {
print("memory leak\n", .{});
std.process.exit(3);
}
diff --git a/tests/public_api.zig b/tests/public_api.zig
index 76b0da8..fc24380 100644
--- a/tests/public_api.zig
+++ b/tests/public_api.zig
@@ -10,8 +10,8 @@ fn assertDeclCoverage(comptime T: type, comptime expected: []const []const u8) v
comptime {
const decls = std.meta.declarations(T);
for (decls) |decl| {
- if (!contains(expected, decl.name)) {
- @compileError("public API declaration is not covered: " ++ @typeName(T) ++ "." ++ decl.name);
+ if (!contains(expected, decl)) {
+ @compileError("public API declaration is not covered: " ++ @typeName(T) ++ "." ++ decl);
}
}
if (decls.len != expected.len) @compileError("public API declaration coverage list contains a missing declaration for " ++ @typeName(T));
@@ -22,11 +22,11 @@ fn assertFnCoverage(comptime T: type, comptime expected: []const []const u8) voi
comptime {
var actual: usize = 0;
for (std.meta.declarations(T)) |decl| {
- const value = @field(T, decl.name);
+ const value = @field(T, decl);
if (@typeInfo(@TypeOf(value)) != .@"fn") continue;
actual += 1;
- if (!contains(expected, decl.name)) {
- @compileError("public API function is not exercised: " ++ @typeName(T) ++ "." ++ decl.name);
+ if (!contains(expected, decl)) {
+ @compileError("public API function is not exercised: " ++ @typeName(T) ++ "." ++ decl);
}
}
if (actual != expected.len) @compileError("public API coverage list contains a missing/non-function declaration for " ++ @typeName(T));
diff --git a/tools/scripts.zig b/tools/scripts.zig
index 68395e9..91825f9 100644
--- a/tools/scripts.zig
+++ b/tools/scripts.zig
@@ -104,8 +104,8 @@ const BenchmarkEnvironment = struct {
cxx_driver: []const u8,
fn deinit(self: BenchmarkEnvironment, alloc: std.mem.Allocator) void {
- inline for (std.meta.fields(BenchmarkEnvironment)) |field| {
- alloc.free(@field(self, field.name));
+ inline for (comptime std.meta.fieldNames(BenchmarkEnvironment)) |field_name| {
+ alloc.free(@field(self, field_name));
}
}
};
@@ -862,7 +862,7 @@ fn buildRunners(io: std.Io, alloc: std.mem.Allocator, force_external_rebuild: bo
// Match zhtml: build the installed benchmark binary directly. The tools
// executable is already running, so bench-only avoids recursive tool builds.
- const zig_build = [_][]const u8{ "zig", "build", "bench-only", "-Doptimize=ReleaseFast", "-Dcpu=native" };
+ const zig_build = [_][]const u8{ "zig", "build", "bench-only", "-Doptimize=fast", "-Dcpu=native" };
try runInheritWithBenchTmp(io, alloc, &zig_build, REPO_ROOT);
const pugixml_sources = [_][]const u8{
@@ -1576,7 +1576,7 @@ fn writeBenchmarkEnvironmentTable(w: anytype, heading: []const u8, environment:
try w.print("| CPU | {s} |\n", .{environment.cpu_model});
try w.print("| CPU frequency scaling | {s} |\n", .{environment.cpu_scaling});
try w.print("| CPU MHz range | {s}–{s} |\n", .{ environment.cpu_min_mhz, environment.cpu_max_mhz });
- try w.print("| Zig | {s} (`ReleaseFast -Dcpu=native`) |\n", .{environment.zig_version});
+ try w.print("| Zig | {s} (`fast -Dcpu=native`) |\n", .{environment.zig_version});
try w.print("| C++ driver | {s} (`-O3 -DNDEBUG -march=native`) |\n\n", .{environment.cxx_driver});
}
@@ -2840,7 +2840,7 @@ fn compareWorktrees(io: std.Io, alloc: std.mem.Allocator, args: []const []const
const seed_text = try std.fmt.allocPrint(alloc, "{d}", .{seed});
defer alloc.free(seed_text);
try common.runInherit(io, alloc, &.{
- "zig", "build", "bench-only", "-Doptimize=ReleaseFast", "-Dcpu=native", "--seed", seed_text,
+ "zig", "build", "bench-only", "-Doptimize=fast", "-Dcpu=native", "--seed", seed_text,
}, worktree);
}