From c390f55e727c8f4ace2eb7992403bf8332a22126 Mon Sep 17 00:00:00 2001 From: Techatrix Date: Wed, 19 Feb 2025 09:34:25 +0100 Subject: [PATCH 1/4] add a standalone test for autoconf style addConfigHeader --- test/standalone/build.zig.zon | 3 +++ test/standalone/config_header/build.zig | 22 ++++++++++++++++++++++ test/standalone/config_header/config.h | 14 ++++++++++++++ test/standalone/config_header/config.h.in | 12 ++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 test/standalone/config_header/build.zig create mode 100644 test/standalone/config_header/config.h create mode 100644 test/standalone/config_header/config.h.in diff --git a/test/standalone/build.zig.zon b/test/standalone/build.zig.zon index 9863e7cc6d..db1c7125a7 100644 --- a/test/standalone/build.zig.zon +++ b/test/standalone/build.zig.zon @@ -186,6 +186,9 @@ .omit_cfi = .{ .path = "omit_cfi", }, + .config_header = .{ + .path = "config_header", + }, }, .paths = .{ "build.zig", diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig new file mode 100644 index 0000000000..0268b642a7 --- /dev/null +++ b/test/standalone/config_header/build.zig @@ -0,0 +1,22 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const config_header = b.addConfigHeader( + .{ .style = .{ .autoconf = b.path("config.h.in") } }, + .{ + .SOME_NO = null, + .SOME_TRUE = true, + .SOME_FALSE = false, + .SOME_ZERO = 0, + .SOME_ONE = 1, + .SOME_TEN = 10, + .SOME_ENUM_LITERAL = .@"test", + .SOME_STRING = "test", + }, + ); + + const check_config_header = b.addCheckFile(config_header.getOutput(), .{ .expected_exact = @embedFile("config.h") }); + + const test_step = b.step("test", "Test it"); + test_step.dependOn(&check_config_header.step); +} diff --git a/test/standalone/config_header/config.h b/test/standalone/config_header/config.h new file mode 100644 index 0000000000..961fdc564f --- /dev/null +++ b/test/standalone/config_header/config.h @@ -0,0 +1,14 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +/* Some Comment */ + +int foo(); + +/* #undef SOME_NO */ +#define SOME_TRUE 1 +#define SOME_FALSE 0 +#define SOME_ZERO 0 +#define SOME_ONE 1 +#define SOME_TEN 10 +#define SOME_ENUM_LITERAL test +#define SOME_STRING "test" + diff --git a/test/standalone/config_header/config.h.in b/test/standalone/config_header/config.h.in new file mode 100644 index 0000000000..0bb37a419c --- /dev/null +++ b/test/standalone/config_header/config.h.in @@ -0,0 +1,12 @@ +/* Some Comment */ + +int foo(); + +#undef SOME_NO +#undef SOME_TRUE +#undef SOME_FALSE +#undef SOME_ZERO +#undef SOME_ONE +#undef SOME_TEN +#undef SOME_ENUM_LITERAL +#undef SOME_STRING From 7e548af8b1527d2d04de1c12df9bf8afd1ad23ea Mon Sep 17 00:00:00 2001 From: Techatrix Date: Wed, 19 Feb 2025 09:03:56 +0100 Subject: [PATCH 2/4] std.Build.Step.ConfigHeader: allow using autoconf values multiple times --- lib/std/Build/Step/ConfigHeader.zig | 17 +++++++++++------ test/standalone/config_header/config.h | 3 +++ test/standalone/config_header/config.h.in | 3 +++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index f474c38ff0..e1a7e9f63f 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -264,8 +264,11 @@ fn render_autoconf( values: std.StringArrayHashMap(Value), src_path: []const u8, ) !void { - var values_copy = try values.clone(); - defer values_copy.deinit(); + const build = step.owner; + const allocator = build.allocator; + + var is_used: std.DynamicBitSetUnmanaged = try .initEmpty(allocator, values.count()); + defer is_used.deinit(allocator); var any_errors = false; var line_index: u32 = 0; @@ -284,18 +287,20 @@ fn render_autoconf( continue; } const name = it.rest(); - const kv = values_copy.fetchSwapRemove(name) orelse { + const index = values.getIndex(name) orelse { try step.addError("{s}:{d}: error: unspecified config header value: '{s}'", .{ src_path, line_index + 1, name, }); any_errors = true; continue; }; - try renderValueC(output, name, kv.value); + is_used.set(index); + try renderValueC(output, name, values.values()[index]); } - for (values_copy.keys()) |name| { - try step.addError("{s}: error: config header value unused: '{s}'", .{ src_path, name }); + var unused_value_it = is_used.iterator(.{ .kind = .unset }); + while (unused_value_it.next()) |index| { + try step.addError("{s}: error: config header value unused: '{s}'", .{ src_path, values.keys()[index] }); any_errors = true; } diff --git a/test/standalone/config_header/config.h b/test/standalone/config_header/config.h index 961fdc564f..aa9a9a707c 100644 --- a/test/standalone/config_header/config.h +++ b/test/standalone/config_header/config.h @@ -12,3 +12,6 @@ int foo(); #define SOME_ENUM_LITERAL test #define SOME_STRING "test" +// Used twice +#define SOME_TRUE 1 + diff --git a/test/standalone/config_header/config.h.in b/test/standalone/config_header/config.h.in index 0bb37a419c..4858d08794 100644 --- a/test/standalone/config_header/config.h.in +++ b/test/standalone/config_header/config.h.in @@ -10,3 +10,6 @@ int foo(); #undef SOME_TEN #undef SOME_ENUM_LITERAL #undef SOME_STRING + +// Used twice +#undef SOME_TRUE From 344db9e26bfb7a966cb99d73fa13c7d6845c2ce9 Mon Sep 17 00:00:00 2001 From: Techatrix Date: Wed, 19 Feb 2025 09:04:08 +0100 Subject: [PATCH 3/4] std.Build.Step.ConfigHeader: skip trailing whitespace in autoconf header --- lib/std/Build/Step/ConfigHeader.zig | 2 +- test/standalone/config_header/build.zig | 5 +++++ test/standalone/config_header/config.h | 5 +++++ test/standalone/config_header/config.h.in | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index e1a7e9f63f..4174d398b4 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -286,7 +286,7 @@ fn render_autoconf( try output.appendSlice("\n"); continue; } - const name = it.rest(); + const name = it.next().?; const index = values.getIndex(name) orelse { try step.addError("{s}:{d}: error: unspecified config header value: '{s}'", .{ src_path, line_index + 1, name, diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index 0268b642a7..fba2613c5a 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -12,6 +12,11 @@ pub fn build(b: *std.Build) void { .SOME_TEN = 10, .SOME_ENUM_LITERAL = .@"test", .SOME_STRING = "test", + + .PREFIX_SPACE = null, + .PREFIX_TAB = null, + .POSTFIX_SPACE = null, + .POSTFIX_TAB = null, }, ); diff --git a/test/standalone/config_header/config.h b/test/standalone/config_header/config.h index aa9a9a707c..298aeac344 100644 --- a/test/standalone/config_header/config.h +++ b/test/standalone/config_header/config.h @@ -15,3 +15,8 @@ int foo(); // Used twice #define SOME_TRUE 1 +/* #undef PREFIX_SPACE */ +/* #undef PREFIX_TAB */ +/* #undef POSTFIX_SPACE */ +/* #undef POSTFIX_TAB */ + diff --git a/test/standalone/config_header/config.h.in b/test/standalone/config_header/config.h.in index 4858d08794..b4cf3a47ea 100644 --- a/test/standalone/config_header/config.h.in +++ b/test/standalone/config_header/config.h.in @@ -13,3 +13,8 @@ int foo(); // Used twice #undef SOME_TRUE + +#undef PREFIX_SPACE +#undef PREFIX_TAB +#undef POSTFIX_SPACE +#undef POSTFIX_TAB From c1c6f082961a2735ff3c91167f0e1bcfcfcc2010 Mon Sep 17 00:00:00 2001 From: Techatrix Date: Wed, 19 Feb 2025 09:33:56 +0100 Subject: [PATCH 4/4] std.Build.Step.ConfigHeader: permit inserting enum values --- lib/std/Build/Step/ConfigHeader.zig | 2 +- test/standalone/config_header/build.zig | 1 + test/standalone/config_header/config.h | 1 + test/standalone/config_header/config.h.in | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 4174d398b4..72d5e99e3a 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -131,7 +131,7 @@ fn putValue(config_header: *ConfigHeader, field_name: []const u8, comptime T: ty .comptime_int => { try config_header.values.put(field_name, .{ .int = v }); }, - .enum_literal => { + .@"enum", .enum_literal => { try config_header.values.put(field_name, .{ .ident = @tagName(v) }); }, .optional => { diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index fba2613c5a..423e9d3823 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -10,6 +10,7 @@ pub fn build(b: *std.Build) void { .SOME_ZERO = 0, .SOME_ONE = 1, .SOME_TEN = 10, + .SOME_ENUM = @as(enum { foo, bar }, .foo), .SOME_ENUM_LITERAL = .@"test", .SOME_STRING = "test", diff --git a/test/standalone/config_header/config.h b/test/standalone/config_header/config.h index 298aeac344..22b5fb5697 100644 --- a/test/standalone/config_header/config.h +++ b/test/standalone/config_header/config.h @@ -9,6 +9,7 @@ int foo(); #define SOME_ZERO 0 #define SOME_ONE 1 #define SOME_TEN 10 +#define SOME_ENUM foo #define SOME_ENUM_LITERAL test #define SOME_STRING "test" diff --git a/test/standalone/config_header/config.h.in b/test/standalone/config_header/config.h.in index b4cf3a47ea..c1b8fe7236 100644 --- a/test/standalone/config_header/config.h.in +++ b/test/standalone/config_header/config.h.in @@ -8,6 +8,7 @@ int foo(); #undef SOME_ZERO #undef SOME_ONE #undef SOME_TEN +#undef SOME_ENUM #undef SOME_ENUM_LITERAL #undef SOME_STRING