From a608ecd335df46b7d13dfaef3372b1120b774921 Mon Sep 17 00:00:00 2001 From: fardragon Date: Sun, 31 May 2026 10:01:33 +0000 Subject: [PATCH 01/12] Fix config_header build.zig --- test/standalone/config_header/build.zig | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index 733a3969077046d95e2526d4455b4a0a400312ab..f24f6dbdb85bdd52da968c17c680744f97660615 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -1,6 +1,9 @@ const std = @import("std"); pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + const config_header = b.addConfigHeader( .{ .style = .{ .autoconf_undef = b.path("config.h.in") } }, .{ @@ -23,6 +26,24 @@ pub fn build(b: *std.Build) void { const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ .expected_exact = @embedFile("config.h") }); - const test_step = b.step("test", "Test it"); + const config_header_autoconf_at = b.addConfigHeader( + .{ .style = .{ + .autoconf_at = b.path("autoconf_at/autoconf_at.txt.in"), + } }, + .{ + .undefined = null, + .defined = {}, + .boolean_true = true, + .boolean_false = false, + .integer = 42, + .string = "text", + .string_at = "@string@", + }, + ); + const check_config_header_autoconf_at = b.addCheckFile(config_header_autoconf_at.getOutputFile(), .{ + .expected_exact = @embedFile("autoconf_at/autoconf_at.txt"), + }); + test_step.dependOn(&check_config_header.step); + test_step.dependOn(&check_config_header_autoconf_at.step); } -- 2.54.0 From 17093e1dd89497b76c97a83917f0d7e4513f7f88 Mon Sep 17 00:00:00 2001 From: fardragon Date: Sun, 31 May 2026 10:02:32 +0000 Subject: [PATCH 02/12] Port autoconf_at tests --- .../config_header/autoconf_at/autoconf_at.txt | 37 +++++++++++++++++++ .../autoconf_at/autoconf_at.txt.in | 36 ++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 test/standalone/config_header/autoconf_at/autoconf_at.txt create mode 100644 test/standalone/config_header/autoconf_at/autoconf_at.txt.in diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.txt b/test/standalone/config_header/autoconf_at/autoconf_at.txt new file mode 100644 index 0000000000000000000000000000000000000000..fccd1255f887c410c0f86a87d51e531685a4382b --- /dev/null +++ b/test/standalone/config_header/autoconf_at/autoconf_at.txt @@ -0,0 +1,37 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +// empty strings are preserved + +// line with misc content is preserved +no substitution +// empty @ sigils are preserved +@ +@@ +@@@ +@@@@ +// simple substitution + + +1 +0 +42 +text +// double packed substitution +texttext +// triple packed substitution +text42text +// double separated substitution +42.42 +// triple separated substitution +42.1.42 +// misc prefix is preserved +false is 0 +// misc suffix is preserved +1 is true +// surrounding content is preserved +what is 6*7? 42! +// incomplete key is preserved +@undefined +// @-vars resolved only when they wrap valid characters, otherwise considered literals +@text@ +// expanded variables are considered strings after expansion +@string@ diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.txt.in b/test/standalone/config_header/autoconf_at/autoconf_at.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..8dfbab96d7b4483305352787cc32e420f606f0db --- /dev/null +++ b/test/standalone/config_header/autoconf_at/autoconf_at.txt.in @@ -0,0 +1,36 @@ +// empty strings are preserved + +// line with misc content is preserved +no substitution +// empty @ sigils are preserved +@ +@@ +@@@ +@@@@ +// simple substitution +@undefined@ +@defined@ +@boolean_true@ +@boolean_false@ +@integer@ +@string@ +// double packed substitution +@string@@string@ +// triple packed substitution +@string@@integer@@string@ +// double separated substitution +@integer@.@integer@ +// triple separated substitution +@integer@.@boolean_true@.@integer@ +// misc prefix is preserved +false is @boolean_false@ +// misc suffix is preserved +@boolean_true@ is true +// surrounding content is preserved +what is 6*7? @integer@! +// incomplete key is preserved +@undefined +// @-vars resolved only when they wrap valid characters, otherwise considered literals +@@string@@ +// expanded variables are considered strings after expansion +@string_at@ -- 2.54.0 From 59bd8201dc0f5ed31146ae2c9cff06b89e94cfc8 Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 16:24:13 +0000 Subject: [PATCH 03/12] Restore cmake tests. Merge standalone/cmakedefine and standalone/config_header. --- test/standalone/build.zig.zon | 3 - test/standalone/cmakedefine/build.zig | 104 ------------- test/standalone/cmakedefine/check.zig | 26 ---- test/standalone/cmakedefine/expected_pwd.sh | 1 - test/standalone/cmakedefine/expected_sigil.h | 4 - .../{ => autoconf_undef}/config.h | 2 +- .../{ => autoconf_undef}/config.h.in | 1 + test/standalone/config_header/build.zig | 142 +++++++++++++++++- test/standalone/config_header/cmake/cmake.txt | 66 ++++++++ .../config_header/cmake/cmake.txt.in | 65 ++++++++ .../config_header/cmake/cmake_edge_cases.txt | 38 +++++ .../cmake/cmake_edge_cases.txt.in | 37 +++++ .../cmake}/config.h.in | 0 .../cmake}/expected_config.h | 1 + .../config_header/cmake/expected_pwd.sh | 2 + .../config_header/cmake/expected_sigil.h | 5 + .../cmake}/expected_stack.h | 1 + .../cmake}/expected_wrapper.h | 1 + .../cmake}/pwd.sh.in | 0 .../cmake}/sigil.h.in | 0 .../cmake}/stack.h.in | 0 .../cmake}/wrapper.h.in | 0 22 files changed, 357 insertions(+), 142 deletions(-) delete mode 100644 test/standalone/cmakedefine/build.zig delete mode 100644 test/standalone/cmakedefine/check.zig delete mode 100644 test/standalone/cmakedefine/expected_pwd.sh delete mode 100644 test/standalone/cmakedefine/expected_sigil.h rename test/standalone/config_header/{ => autoconf_undef}/config.h (90%) rename test/standalone/config_header/{ => autoconf_undef}/config.h.in (86%) create mode 100644 test/standalone/config_header/cmake/cmake.txt create mode 100644 test/standalone/config_header/cmake/cmake.txt.in create mode 100644 test/standalone/config_header/cmake/cmake_edge_cases.txt create mode 100644 test/standalone/config_header/cmake/cmake_edge_cases.txt.in rename test/standalone/{cmakedefine => config_header/cmake}/config.h.in (100%) rename test/standalone/{cmakedefine => config_header/cmake}/expected_config.h (93%) create mode 100644 test/standalone/config_header/cmake/expected_pwd.sh create mode 100644 test/standalone/config_header/cmake/expected_sigil.h rename test/standalone/{cmakedefine => config_header/cmake}/expected_stack.h (58%) rename test/standalone/{cmakedefine => config_header/cmake}/expected_wrapper.h (86%) rename test/standalone/{cmakedefine => config_header/cmake}/pwd.sh.in (100%) rename test/standalone/{cmakedefine => config_header/cmake}/sigil.h.in (100%) rename test/standalone/{cmakedefine => config_header/cmake}/stack.h.in (100%) rename test/standalone/{cmakedefine => config_header/cmake}/wrapper.h.in (100%) diff --git a/test/standalone/build.zig.zon b/test/standalone/build.zig.zon index 0314bc23ef96091c368cdcb20649c5567aedd92c..de1b97d60bdbe995992a69fe4eb9f55d99e7e3c8 100644 --- a/test/standalone/build.zig.zon +++ b/test/standalone/build.zig.zon @@ -141,9 +141,6 @@ .strip_struct_init = .{ .path = "strip_struct_init", }, - .cmakedefine = .{ - .path = "cmakedefine", - }, .zerolength_check = .{ .path = "zerolength_check", }, diff --git a/test/standalone/cmakedefine/build.zig b/test/standalone/cmakedefine/build.zig deleted file mode 100644 index 78fe1f1cbfc9b2ec07dba6dea6fe808190e37c7d..0000000000000000000000000000000000000000 --- a/test/standalone/cmakedefine/build.zig +++ /dev/null @@ -1,104 +0,0 @@ -const std = @import("std"); -const ConfigHeader = std.Build.Step.ConfigHeader; - -pub fn build(b: *std.Build) void { - const config_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("config.h.in") }, - .include_path = "config.h", - }, - .{ - .noval = null, - .trueval = true, - .falseval = false, - .zeroval = 0, - .oneval = 1, - .tenval = 10, - .stringval = "test", - - .boolnoval = {}, - .booltrueval = true, - .boolfalseval = false, - .boolzeroval = 0, - .booloneval = 1, - .booltenval = 10, - .boolstringval = "test", - }, - ); - - const pwd_sh = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("pwd.sh.in") }, - .include_path = "pwd.sh", - }, - .{ .DIR = "${PWD}" }, - ); - - const sigil_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("sigil.h.in") }, - .include_path = "sigil.h", - }, - .{}, - ); - - const stack_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("stack.h.in") }, - .include_path = "stack.h", - }, - .{ - .UNDERSCORE = "_", - .NEST_UNDERSCORE_PROXY = "UNDERSCORE", - .NEST_PROXY = "NEST_UNDERSCORE_PROXY", - }, - ); - - const wrapper_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("wrapper.h.in") }, - .include_path = "wrapper.h", - }, - .{ - .DOLLAR = "$", - .TEXT = "TRAP", - - .STRING = "TEXT", - .STRING_AT = "@STRING@", - .STRING_CURLY = "{STRING}", - .STRING_VAR = "${STRING}", - }, - ); - - const check_exe = b.addExecutable(.{ - .name = "check", - .root_module = b.createModule(.{ - .target = b.graph.host, - .root_source_file = b.path("check.zig"), - }), - }); - - const test_step = b.step("test", "Test it"); - b.default_step = test_step; - test_step.dependOn(addCheck(b, check_exe, config_header)); - test_step.dependOn(addCheck(b, check_exe, pwd_sh)); - test_step.dependOn(addCheck(b, check_exe, sigil_header)); - test_step.dependOn(addCheck(b, check_exe, stack_header)); - test_step.dependOn(addCheck(b, check_exe, wrapper_header)); -} - -fn addCheck( - b: *std.Build, - check_exe: *std.Build.Step.Compile, - ch: *ConfigHeader, -) *std.Build.Step { - // We expect `ch.include_path` to only be a basename to infer where the expected output is. - std.debug.assert(std.fs.path.dirname(ch.include_path) == null); - const expected_path = b.fmt("expected_{s}", .{ch.include_path}); - - const run_check = b.addRunArtifact(check_exe); - run_check.addFileArg(ch.getOutputFile()); - run_check.addFileArg(b.path(expected_path)); - - return &run_check.step; -} diff --git a/test/standalone/cmakedefine/check.zig b/test/standalone/cmakedefine/check.zig deleted file mode 100644 index 58a0762d111815637a86e385345adec1c618c81a..0000000000000000000000000000000000000000 --- a/test/standalone/cmakedefine/check.zig +++ /dev/null @@ -1,26 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); - -pub fn main(init: std.process.Init) !void { - const arena = init.arena.allocator(); - const io = init.io; - const args = try init.minimal.args.toSlice(arena); - - if (args.len != 3) return error.BadUsage; - const actual_path = args[1]; - const expected_path = args[2]; - - const actual = try std.Io.Dir.cwd().readFileAlloc(io, actual_path, arena, .limited(1024 * 1024)); - const expected = try std.Io.Dir.cwd().readFileAlloc(io, expected_path, arena, .limited(1024 * 1024)); - - // The actual output starts with a comment which we should strip out before comparing. - const comment_str = "/* This file was generated by ConfigHeader using the Zig Build System. */\n"; - if (!std.mem.startsWith(u8, actual, comment_str)) { - return error.MissingOrMalformedComment; - } - const actual_without_comment = actual[comment_str.len..]; - - if (builtin.os.tag == .windows) return; // https://codeberg.org/ziglang/zig/issues/30138 - - try std.testing.expectEqualStrings(expected, actual_without_comment); -} diff --git a/test/standalone/cmakedefine/expected_pwd.sh b/test/standalone/cmakedefine/expected_pwd.sh deleted file mode 100644 index 7e1d44c8eb0ee4b373be12c9e652653b6d228587..0000000000000000000000000000000000000000 --- a/test/standalone/cmakedefine/expected_pwd.sh +++ /dev/null @@ -1 +0,0 @@ -echo ${PWD} diff --git a/test/standalone/cmakedefine/expected_sigil.h b/test/standalone/cmakedefine/expected_sigil.h deleted file mode 100644 index 10108f4d1e2fdd3c4a685a8501596a77291b0c1f..0000000000000000000000000000000000000000 --- a/test/standalone/cmakedefine/expected_sigil.h +++ /dev/null @@ -1,4 +0,0 @@ -#define AT @ -#define ATAT @@ -#define ATATAT @@@ -#define ATATATAT @@@@ diff --git a/test/standalone/config_header/config.h b/test/standalone/config_header/autoconf_undef/config.h similarity index 90% rename from test/standalone/config_header/config.h rename to test/standalone/config_header/autoconf_undef/config.h index 22b5fb5697d5fa47ee4bc6a4b7d00d6360aac9f8..ef5b4abab30499feb5c82019ae8750e82b059512 100644 --- a/test/standalone/config_header/config.h +++ b/test/standalone/config_header/autoconf_undef/config.h @@ -20,4 +20,4 @@ int foo(); /* #undef PREFIX_TAB */ /* #undef POSTFIX_SPACE */ /* #undef POSTFIX_TAB */ - +// TODO: unexpected newline is being added here diff --git a/test/standalone/config_header/config.h.in b/test/standalone/config_header/autoconf_undef/config.h.in similarity index 86% rename from test/standalone/config_header/config.h.in rename to test/standalone/config_header/autoconf_undef/config.h.in index c1b8fe7236fb57384347fbeb972db2850d44edf3..fafc3587658162eaae0c918320df9752b779086d 100644 --- a/test/standalone/config_header/config.h.in +++ b/test/standalone/config_header/autoconf_undef/config.h.in @@ -19,3 +19,4 @@ int foo(); #undef PREFIX_TAB #undef POSTFIX_SPACE #undef POSTFIX_TAB +// TODO: unexpected newline is being added here \ No newline at end of file diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index f24f6dbdb85bdd52da968c17c680744f97660615..15ad4112bf91ef74d965b8c44fb469ec86d00bee 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -5,7 +5,9 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const config_header = b.addConfigHeader( - .{ .style = .{ .autoconf_undef = b.path("config.h.in") } }, + .{ .style = .{ + .autoconf_undef = b.path("autoconf_undef/config.h.in"), + } }, .{ .SOME_NO = null, .SOME_TRUE = true, @@ -23,8 +25,9 @@ pub fn build(b: *std.Build) void { .POSTFIX_TAB = null, }, ); - - const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ .expected_exact = @embedFile("config.h") }); + const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ + .expected_exact = @embedFile("autoconf_undef/config.h"), + }); const config_header_autoconf_at = b.addConfigHeader( .{ .style = .{ @@ -46,4 +49,137 @@ pub fn build(b: *std.Build) void { test_step.dependOn(&check_config_header.step); test_step.dependOn(&check_config_header_autoconf_at.step); + addCmakeChecks(b, test_step); +} + +fn addCmakeChecks(b: *std.Build, test_step: *std.Build.Step) void { + const config_header = b.addConfigHeader( + .{ + .style = .{ .cmake = b.path("cmake/config.h.in") }, + .include_path = "config.h", + }, + .{ + .noval = null, + .trueval = true, + .falseval = false, + .zeroval = 0, + .oneval = 1, + .tenval = 10, + .stringval = "test", + + .boolnoval = {}, + .booltrueval = true, + .boolfalseval = false, + .boolzeroval = 0, + .booloneval = 1, + .booltenval = 10, + .boolstringval = "test", + }, + ); + const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/expected_config.h"), + }); + test_step.dependOn(&check_config_header.step); + + const pwd_sh = b.addConfigHeader( + .{ + .style = .{ .cmake = b.path("cmake/pwd.sh.in") }, + .include_path = "pwd.sh", + }, + .{ .DIR = "${PWD}" }, + ); + const check_pwd_sh = b.addCheckFile(pwd_sh.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/expected_pwd.sh"), + }); + test_step.dependOn(&check_pwd_sh.step); + + const sigil_header = b.addConfigHeader( + .{ + .style = .{ .cmake = b.path("cmake/sigil.h.in") }, + .include_path = "sigil.h", + }, + .{}, + ); + const check_sigil_header = b.addCheckFile(sigil_header.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/expected_sigil.h"), + }); + test_step.dependOn(&check_sigil_header.step); + + const stack_header = b.addConfigHeader( + .{ + .style = .{ .cmake = b.path("cmake/stack.h.in") }, + .include_path = "stack.h", + }, + .{ + .UNDERSCORE = "_", + .NEST_UNDERSCORE_PROXY = "UNDERSCORE", + .NEST_PROXY = "NEST_UNDERSCORE_PROXY", + }, + ); + const check_stack_header = b.addCheckFile(stack_header.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/expected_stack.h"), + }); + test_step.dependOn(&check_stack_header.step); + + const wrapper_header = b.addConfigHeader( + .{ + .style = .{ .cmake = b.path("cmake/wrapper.h.in") }, + .include_path = "wrapper.h", + }, + .{ + .DOLLAR = "$", + .TEXT = "TRAP", + + .STRING = "TEXT", + .STRING_AT = "@STRING@", + .STRING_CURLY = "{STRING}", + .STRING_VAR = "${STRING}", + }, + ); + const check_wrapper_header = b.addCheckFile(wrapper_header.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/expected_wrapper.h"), + }); + test_step.dependOn(&check_wrapper_header.step); + + const config_header_cmake = b.addConfigHeader( + .{ .style = .{ + .cmake = b.path("cmake/cmake.txt.in"), + } }, + .{ + .undef = null, + .defined = {}, + .true = true, + .false = false, + .int = 42, + .ident = "value", + .string = "text", + }, + ); + const check_config_header_cmake = b.addCheckFile(config_header_cmake.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/cmake.txt"), + }); + test_step.dependOn(&check_config_header_cmake.step); + + const config_header_cmake_edge_cases = b.addConfigHeader( + .{ .style = .{ + .cmake = b.path("cmake/cmake_edge_cases.txt.in"), + } }, + .{ + // .at = "@", + // .trueval = true, + .dollar = "$", + .underscore = "_", + .string = "text", + .string_proxy = "string", + .string_at = "@string@", + .string_curly = "{string}", + .string_var = "${string}", + .nest_underscore_proxy = "underscore", + .nest_proxy = "nest_underscore_proxy", + }, + ); + const check_config_header_cmake_edge_cases = b.addCheckFile(config_header_cmake_edge_cases.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/cmake_edge_cases.txt"), + }); + test_step.dependOn(&check_config_header_cmake_edge_cases.step); } diff --git a/test/standalone/config_header/cmake/cmake.txt b/test/standalone/config_header/cmake/cmake.txt new file mode 100644 index 0000000000000000000000000000000000000000..782ab0f6d5e44b8b87547592c498388c04f19931 --- /dev/null +++ b/test/standalone/config_header/cmake/cmake.txt @@ -0,0 +1,66 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +// empty strings are preserved + +// line with misc content is preserved +no substitution + +// empty @ sigils are preserved +@ +@@ +@@@ +@@@@ + +// simple substitution + + + + +1 +1 +0 +0 +42 +42 +value +value +text +text + +// double packed substitution +texttext +texttext + +// triple packed substitution +text42text +text42text +text42text +text42text + +// double separated substitution +42.42 +42.42 + +// triple separated substitution +42.1.42 +42.1.42 +42.1.42 +42.1.42 + +// misc prefix is preserved +false is 0 +false is 0 + +// misc suffix is preserved +1 is true +1 is true + +// surrounding content is preserved +what is 6*7? 42! +what is 6*7? 42! + +// incomplete key is preserved +@undef +${undef +{undef} +undef@ +undef} diff --git a/test/standalone/config_header/cmake/cmake.txt.in b/test/standalone/config_header/cmake/cmake.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..bef9fb7a2b7eb74a3870bb80c3a22256bb6e9fa0 --- /dev/null +++ b/test/standalone/config_header/cmake/cmake.txt.in @@ -0,0 +1,65 @@ +// empty strings are preserved + +// line with misc content is preserved +no substitution + +// empty @ sigils are preserved +@ +@@ +@@@ +@@@@ + +// simple substitution +@undef@ +${undef} +@defined@ +${defined} +@true@ +${true} +@false@ +${false} +@int@ +${int} +@ident@ +${ident} +@string@ +${string} + +// double packed substitution +@string@@string@ +${string}${string} + +// triple packed substitution +@string@@int@@string@ +@string@${int}@string@ +${string}@int@${string} +${string}${int}${string} + +// double separated substitution +@int@.@int@ +${int}.${int} + +// triple separated substitution +@int@.@true@.@int@ +@int@.${true}.@int@ +${int}.@true@.${int} +${int}.${true}.${int} + +// misc prefix is preserved +false is @false@ +false is ${false} + +// misc suffix is preserved +@true@ is true +${true} is true + +// surrounding content is preserved +what is 6*7? @int@! +what is 6*7? ${int}! + +// incomplete key is preserved +@undef +${undef +{undef} +undef@ +undef} diff --git a/test/standalone/config_header/cmake/cmake_edge_cases.txt b/test/standalone/config_header/cmake/cmake_edge_cases.txt new file mode 100644 index 0000000000000000000000000000000000000000..e88fa5faeac3e473bd44062ca17d88522f233240 --- /dev/null +++ b/test/standalone/config_header/cmake/cmake_edge_cases.txt @@ -0,0 +1,38 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +// empty lines are preserved + +// @-substition tests +// @-vars resolved only when they wrap valid characters, otherwise considered literals +@text@ +@text@ + +// at-vars are resolved inside curly-vars +text + +// expanded variables are considered strings after expansion +@string@ +@string@ +${string} +${string} +${string} +${string} +${text} +${text} +${text} + +// nested expanded variables are expanded from the inside out +string +string + +// nested vars are only expanded when curly braces are closed +nest_underscore_proxy +nest_underscore_proxy + +// backslash is an invalid character for @ lookup +\@string\@ + +// backslash is preserved, but doesn't affect $curly-braces variable expansion +\text + +// backslash breaks $curly-braces opening bracket identification +$\{string} diff --git a/test/standalone/config_header/cmake/cmake_edge_cases.txt.in b/test/standalone/config_header/cmake/cmake_edge_cases.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..21ef8d68052c8d0c1bf1fdb0595ebf9eec75e6c1 --- /dev/null +++ b/test/standalone/config_header/cmake/cmake_edge_cases.txt.in @@ -0,0 +1,37 @@ +// empty lines are preserved + +// @-substition tests +// @-vars resolved only when they wrap valid characters, otherwise considered literals +@@string@@ +@${string}@ + +// at-vars are resolved inside curly-vars +${@string_proxy@} + +// expanded variables are considered strings after expansion +@string_at@ +${string_at} +$@string_curly@ +$${string_curly} +${string_var} +@string_var@ +${dollar}{${string}} +@dollar@{${string}} +@dollar@{@string@} + +// nested expanded variables are expanded from the inside out +${string${underscore}proxy} +${string@underscore@proxy} + +// nested vars are only expanded when curly braces are closed +${nest${underscore}proxy} +${nest${${nest_underscore${underscore}proxy}}proxy} + +// backslash is an invalid character for @ lookup +\@string\@ + +// backslash is preserved, but doesn't affect $curly-braces variable expansion +\${string} + +// backslash breaks $curly-braces opening bracket identification +$\{string} diff --git a/test/standalone/cmakedefine/config.h.in b/test/standalone/config_header/cmake/config.h.in similarity index 100% rename from test/standalone/cmakedefine/config.h.in rename to test/standalone/config_header/cmake/config.h.in diff --git a/test/standalone/cmakedefine/expected_config.h b/test/standalone/config_header/cmake/expected_config.h similarity index 93% rename from test/standalone/cmakedefine/expected_config.h rename to test/standalone/config_header/cmake/expected_config.h index 9ebe80956e3264d6c33aaa2dbc06f735a30dce33..c38418b6df3021a671c431e071c7caa374bbf5cd 100644 --- a/test/standalone/cmakedefine/expected_config.h +++ b/test/standalone/config_header/cmake/expected_config.h @@ -1,3 +1,4 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ // cmakedefine // undefined /* #undef noval */ diff --git a/test/standalone/config_header/cmake/expected_pwd.sh b/test/standalone/config_header/cmake/expected_pwd.sh new file mode 100644 index 0000000000000000000000000000000000000000..929ee58b393a1173c4d3e2740d034ff6e5d1101f --- /dev/null +++ b/test/standalone/config_header/cmake/expected_pwd.sh @@ -0,0 +1,2 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +echo ${PWD} diff --git a/test/standalone/config_header/cmake/expected_sigil.h b/test/standalone/config_header/cmake/expected_sigil.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0f5c0e329dabbc3d6b8ae245c69a91b18b9eaa --- /dev/null +++ b/test/standalone/config_header/cmake/expected_sigil.h @@ -0,0 +1,5 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +#define AT @ +#define ATAT @@ +#define ATATAT @@@ +#define ATATATAT @@@@ diff --git a/test/standalone/cmakedefine/expected_stack.h b/test/standalone/config_header/cmake/expected_stack.h similarity index 58% rename from test/standalone/cmakedefine/expected_stack.h rename to test/standalone/config_header/cmake/expected_stack.h index 940d68d13e2f6d98ea518ae031a42c3944d4cf7a..598bc0a310ada8f00d0b8bf64ce0562e4e5681b7 100644 --- a/test/standalone/cmakedefine/expected_stack.h +++ b/test/standalone/config_header/cmake/expected_stack.h @@ -1,3 +1,4 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ #define NEST_UNDERSCORE_PROXY NEST_UNDERSCORE_PROXY #define NEST_UNDERSCORE_PROXY NEST_UNDERSCORE_PROXY diff --git a/test/standalone/cmakedefine/expected_wrapper.h b/test/standalone/config_header/cmake/expected_wrapper.h similarity index 86% rename from test/standalone/cmakedefine/expected_wrapper.h rename to test/standalone/config_header/cmake/expected_wrapper.h index cbd6aabdcae959adef77256dc958999a41f07d0f..1f78d22ee9ae778e833c98e784f284c04ac47dfb 100644 --- a/test/standalone/cmakedefine/expected_wrapper.h +++ b/test/standalone/config_header/cmake/expected_wrapper.h @@ -1,3 +1,4 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ // becomes TEXT #define TEXT #define TEXT diff --git a/test/standalone/cmakedefine/pwd.sh.in b/test/standalone/config_header/cmake/pwd.sh.in similarity index 100% rename from test/standalone/cmakedefine/pwd.sh.in rename to test/standalone/config_header/cmake/pwd.sh.in diff --git a/test/standalone/cmakedefine/sigil.h.in b/test/standalone/config_header/cmake/sigil.h.in similarity index 100% rename from test/standalone/cmakedefine/sigil.h.in rename to test/standalone/config_header/cmake/sigil.h.in diff --git a/test/standalone/cmakedefine/stack.h.in b/test/standalone/config_header/cmake/stack.h.in similarity index 100% rename from test/standalone/cmakedefine/stack.h.in rename to test/standalone/config_header/cmake/stack.h.in diff --git a/test/standalone/cmakedefine/wrapper.h.in b/test/standalone/config_header/cmake/wrapper.h.in similarity index 100% rename from test/standalone/cmakedefine/wrapper.h.in rename to test/standalone/config_header/cmake/wrapper.h.in -- 2.54.0 From 0804feac00ce4aff2ae746f4246d1675b6b4e491 Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 17:37:11 +0000 Subject: [PATCH 04/12] Deduplicate and cleanup cmake tests --- test/standalone/config_header/build.zig | 157 +++++--------- test/standalone/config_header/cmake/cmake.txt | 66 ------ .../config_header/cmake/cmake.txt.in | 65 ------ .../config_header/cmake/cmake_edge_cases.txt | 38 ---- .../cmake/cmake_edge_cases.txt.in | 37 ---- .../cmake/cmakedefine_edge_cases.h | 43 ++++ .../cmake/cmakedefine_edge_cases.h.in | 42 ++++ test/standalone/config_header/cmake/config.h | 144 +++++++++++++ .../config_header/cmake/config.h.in | 194 +++++++++--------- .../config_header/cmake/edge_cases.h | 43 ++++ .../config_header/cmake/edge_cases.h.in | 42 ++++ .../config_header/cmake/expected_config.h | 148 ------------- .../config_header/cmake/expected_sigil.h | 5 - .../config_header/cmake/expected_stack.h | 4 - .../config_header/cmake/expected_wrapper.h | 31 --- .../cmake/{expected_pwd.sh => pwd.sh} | 0 .../standalone/config_header/cmake/sigil.h.in | 4 - .../standalone/config_header/cmake/stack.h.in | 3 - .../config_header/cmake/wrapper.h.in | 30 --- 19 files changed, 462 insertions(+), 634 deletions(-) delete mode 100644 test/standalone/config_header/cmake/cmake.txt delete mode 100644 test/standalone/config_header/cmake/cmake.txt.in delete mode 100644 test/standalone/config_header/cmake/cmake_edge_cases.txt delete mode 100644 test/standalone/config_header/cmake/cmake_edge_cases.txt.in create mode 100644 test/standalone/config_header/cmake/cmakedefine_edge_cases.h create mode 100644 test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in create mode 100644 test/standalone/config_header/cmake/config.h create mode 100644 test/standalone/config_header/cmake/edge_cases.h create mode 100644 test/standalone/config_header/cmake/edge_cases.h.in delete mode 100644 test/standalone/config_header/cmake/expected_config.h delete mode 100644 test/standalone/config_header/cmake/expected_sigil.h delete mode 100644 test/standalone/config_header/cmake/expected_stack.h delete mode 100644 test/standalone/config_header/cmake/expected_wrapper.h rename test/standalone/config_header/cmake/{expected_pwd.sh => pwd.sh} (100%) delete mode 100644 test/standalone/config_header/cmake/sigil.h.in delete mode 100644 test/standalone/config_header/cmake/stack.h.in delete mode 100644 test/standalone/config_header/cmake/wrapper.h.in diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index 15ad4112bf91ef74d965b8c44fb469ec86d00bee..e6d62557e223abb8e610cc945986ee82165fe14f 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -5,9 +5,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const config_header = b.addConfigHeader( - .{ .style = .{ - .autoconf_undef = b.path("autoconf_undef/config.h.in"), - } }, + .{ .style = .{ .autoconf_undef = b.path("autoconf_undef/config.h.in") } }, .{ .SOME_NO = null, .SOME_TRUE = true, @@ -30,9 +28,7 @@ pub fn build(b: *std.Build) void { }); const config_header_autoconf_at = b.addConfigHeader( - .{ .style = .{ - .autoconf_at = b.path("autoconf_at/autoconf_at.txt.in"), - } }, + .{ .style = .{ .autoconf_at = b.path("autoconf_at/autoconf_at.txt.in") } }, .{ .undefined = null, .defined = {}, @@ -54,132 +50,85 @@ pub fn build(b: *std.Build) void { fn addCmakeChecks(b: *std.Build, test_step: *std.Build.Step) void { const config_header = b.addConfigHeader( + .{ .style = .{ .cmake = b.path("cmake/config.h.in") } }, .{ - .style = .{ .cmake = b.path("cmake/config.h.in") }, - .include_path = "config.h", - }, - .{ - .noval = null, - .trueval = true, - .falseval = false, - .zeroval = 0, - .oneval = 1, - .tenval = 10, - .stringval = "test", + .NOVAL = null, + .TRUEVAL = true, + .FALSEVAL = false, + .ZEROVAL = 0, + .ONEVAL = 1, + .TENVAL = 10, + .STRINGVAL = "test", - .boolnoval = {}, - .booltrueval = true, - .boolfalseval = false, - .boolzeroval = 0, - .booloneval = 1, - .booltenval = 10, - .boolstringval = "test", + .BOOLNOVAL = {}, + .BOOLTRUEVAL = true, + .BOOLFALSEVAL = false, + .BOOLZEROVAL = 0, + .BOOLONEVAL = 1, + .BOOLTENVAL = 10, + .BOOLSTRINGVAL = "test", }, ); const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/expected_config.h"), + .expected_exact = @embedFile("cmake/config.h"), }); test_step.dependOn(&check_config_header.step); const pwd_sh = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("cmake/pwd.sh.in") }, - .include_path = "pwd.sh", - }, + .{ .style = .{ .cmake = b.path("cmake/pwd.sh.in") } }, .{ .DIR = "${PWD}" }, ); const check_pwd_sh = b.addCheckFile(pwd_sh.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/expected_pwd.sh"), + .expected_exact = @embedFile("cmake/pwd.sh"), }); test_step.dependOn(&check_pwd_sh.step); - const sigil_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("cmake/sigil.h.in") }, - .include_path = "sigil.h", - }, - .{}, - ); - const check_sigil_header = b.addCheckFile(sigil_header.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/expected_sigil.h"), - }); - test_step.dependOn(&check_sigil_header.step); - - const stack_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("cmake/stack.h.in") }, - .include_path = "stack.h", - }, - .{ - .UNDERSCORE = "_", - .NEST_UNDERSCORE_PROXY = "UNDERSCORE", - .NEST_PROXY = "NEST_UNDERSCORE_PROXY", - }, - ); - const check_stack_header = b.addCheckFile(stack_header.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/expected_stack.h"), - }); - test_step.dependOn(&check_stack_header.step); - - const wrapper_header = b.addConfigHeader( - .{ - .style = .{ .cmake = b.path("cmake/wrapper.h.in") }, - .include_path = "wrapper.h", - }, + const config_header_edge_cases = b.addConfigHeader( + .{ .style = .{ .cmake = b.path("cmake/edge_cases.h.in") } }, .{ .DOLLAR = "$", - .TEXT = "TRAP", - - .STRING = "TEXT", + .UNDERSCORE = "_", + .STRING = "text", + .STRING_PROXY = "STRING", .STRING_AT = "@STRING@", .STRING_CURLY = "{STRING}", .STRING_VAR = "${STRING}", + .NEST_UNDERSCORE_PROXY = "UNDERSCORE", + .NEST_PROXY = "NEST_UNDERSCORE_PROXY", }, ); - const check_wrapper_header = b.addCheckFile(wrapper_header.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/expected_wrapper.h"), + const check_config_header_edge_cases = b.addCheckFile(config_header_edge_cases.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/edge_cases.h"), }); - test_step.dependOn(&check_wrapper_header.step); + test_step.dependOn(&check_config_header_edge_cases.step); - const config_header_cmake = b.addConfigHeader( - .{ .style = .{ - .cmake = b.path("cmake/cmake.txt.in"), - } }, + const config_header_cmakedefine_edge_cases = b.addConfigHeader( .{ - .undef = null, - .defined = {}, - .true = true, - .false = false, - .int = 42, - .ident = "value", - .string = "text", + .style = .{ .cmake = b.path("cmake/cmakedefine_edge_cases.h.in") }, + .include_path = "cmakedefine_edge_cases_renamed.h", }, - ); - const check_config_header_cmake = b.addCheckFile(config_header_cmake.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/cmake.txt"), - }); - test_step.dependOn(&check_config_header_cmake.step); - - const config_header_cmake_edge_cases = b.addConfigHeader( - .{ .style = .{ - .cmake = b.path("cmake/cmake_edge_cases.txt.in"), - } }, .{ - // .at = "@", - // .trueval = true, - .dollar = "$", - .underscore = "_", - .string = "text", - .string_proxy = "string", - .string_at = "@string@", - .string_curly = "{string}", - .string_var = "${string}", - .nest_underscore_proxy = "underscore", - .nest_proxy = "nest_underscore_proxy", + .MULTI_WORD = true, + .MULTI_WORD_FALSE = false, + .NO_VALUE = true, + .NO_VALUE_FALSE = false, + .WITH_UNDERSCORE_TRUE = true, + .WITH_UNDERSCORE_FALSE = false, + ._LEADING = true, + .TRAILING_ = true, + ._UNDER_01 = true, + .UNDER_01_ = true, + .SUBST_VAL = true, + .SUBST_VAL_FALSE = false, + .STRING = "text", + .VAR_NAME = "ACTUAL_VAR", + .ACTUAL_VAR = true, + .AT_SIGN = "@", + .DOLLAR_SIGN = "$", }, ); - const check_config_header_cmake_edge_cases = b.addCheckFile(config_header_cmake_edge_cases.getOutputFile(), .{ - .expected_exact = @embedFile("cmake/cmake_edge_cases.txt"), + const check_config_header_cmakedefine_edge_cases = b.addCheckFile(config_header_cmakedefine_edge_cases.getOutputFile(), .{ + .expected_exact = @embedFile("cmake/cmakedefine_edge_cases.h"), }); - test_step.dependOn(&check_config_header_cmake_edge_cases.step); + test_step.dependOn(&check_config_header_cmakedefine_edge_cases.step); } diff --git a/test/standalone/config_header/cmake/cmake.txt b/test/standalone/config_header/cmake/cmake.txt deleted file mode 100644 index 782ab0f6d5e44b8b87547592c498388c04f19931..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/cmake.txt +++ /dev/null @@ -1,66 +0,0 @@ -/* This file was generated by ConfigHeader using the Zig Build System. */ -// empty strings are preserved - -// line with misc content is preserved -no substitution - -// empty @ sigils are preserved -@ -@@ -@@@ -@@@@ - -// simple substitution - - - - -1 -1 -0 -0 -42 -42 -value -value -text -text - -// double packed substitution -texttext -texttext - -// triple packed substitution -text42text -text42text -text42text -text42text - -// double separated substitution -42.42 -42.42 - -// triple separated substitution -42.1.42 -42.1.42 -42.1.42 -42.1.42 - -// misc prefix is preserved -false is 0 -false is 0 - -// misc suffix is preserved -1 is true -1 is true - -// surrounding content is preserved -what is 6*7? 42! -what is 6*7? 42! - -// incomplete key is preserved -@undef -${undef -{undef} -undef@ -undef} diff --git a/test/standalone/config_header/cmake/cmake.txt.in b/test/standalone/config_header/cmake/cmake.txt.in deleted file mode 100644 index bef9fb7a2b7eb74a3870bb80c3a22256bb6e9fa0..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/cmake.txt.in +++ /dev/null @@ -1,65 +0,0 @@ -// empty strings are preserved - -// line with misc content is preserved -no substitution - -// empty @ sigils are preserved -@ -@@ -@@@ -@@@@ - -// simple substitution -@undef@ -${undef} -@defined@ -${defined} -@true@ -${true} -@false@ -${false} -@int@ -${int} -@ident@ -${ident} -@string@ -${string} - -// double packed substitution -@string@@string@ -${string}${string} - -// triple packed substitution -@string@@int@@string@ -@string@${int}@string@ -${string}@int@${string} -${string}${int}${string} - -// double separated substitution -@int@.@int@ -${int}.${int} - -// triple separated substitution -@int@.@true@.@int@ -@int@.${true}.@int@ -${int}.@true@.${int} -${int}.${true}.${int} - -// misc prefix is preserved -false is @false@ -false is ${false} - -// misc suffix is preserved -@true@ is true -${true} is true - -// surrounding content is preserved -what is 6*7? @int@! -what is 6*7? ${int}! - -// incomplete key is preserved -@undef -${undef -{undef} -undef@ -undef} diff --git a/test/standalone/config_header/cmake/cmake_edge_cases.txt b/test/standalone/config_header/cmake/cmake_edge_cases.txt deleted file mode 100644 index e88fa5faeac3e473bd44062ca17d88522f233240..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/cmake_edge_cases.txt +++ /dev/null @@ -1,38 +0,0 @@ -/* This file was generated by ConfigHeader using the Zig Build System. */ -// empty lines are preserved - -// @-substition tests -// @-vars resolved only when they wrap valid characters, otherwise considered literals -@text@ -@text@ - -// at-vars are resolved inside curly-vars -text - -// expanded variables are considered strings after expansion -@string@ -@string@ -${string} -${string} -${string} -${string} -${text} -${text} -${text} - -// nested expanded variables are expanded from the inside out -string -string - -// nested vars are only expanded when curly braces are closed -nest_underscore_proxy -nest_underscore_proxy - -// backslash is an invalid character for @ lookup -\@string\@ - -// backslash is preserved, but doesn't affect $curly-braces variable expansion -\text - -// backslash breaks $curly-braces opening bracket identification -$\{string} diff --git a/test/standalone/config_header/cmake/cmake_edge_cases.txt.in b/test/standalone/config_header/cmake/cmake_edge_cases.txt.in deleted file mode 100644 index 21ef8d68052c8d0c1bf1fdb0595ebf9eec75e6c1..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/cmake_edge_cases.txt.in +++ /dev/null @@ -1,37 +0,0 @@ -// empty lines are preserved - -// @-substition tests -// @-vars resolved only when they wrap valid characters, otherwise considered literals -@@string@@ -@${string}@ - -// at-vars are resolved inside curly-vars -${@string_proxy@} - -// expanded variables are considered strings after expansion -@string_at@ -${string_at} -$@string_curly@ -$${string_curly} -${string_var} -@string_var@ -${dollar}{${string}} -@dollar@{${string}} -@dollar@{@string@} - -// nested expanded variables are expanded from the inside out -${string${underscore}proxy} -${string@underscore@proxy} - -// nested vars are only expanded when curly braces are closed -${nest${underscore}proxy} -${nest${${nest_underscore${underscore}proxy}}proxy} - -// backslash is an invalid character for @ lookup -\@string\@ - -// backslash is preserved, but doesn't affect $curly-braces variable expansion -\${string} - -// backslash breaks $curly-braces opening bracket identification -$\{string} diff --git a/test/standalone/config_header/cmake/cmakedefine_edge_cases.h b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h new file mode 100644 index 0000000000000000000000000000000000000000..e05567a40332e2bb46a67376bd283a4e341cd46a --- /dev/null +++ b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h @@ -0,0 +1,43 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +// cmakedefine with multi-word string value (truthy) +#define MULTI_WORD "hello world" + +// cmakedefine with multi-word string value (falsy) +/* #undef MULTI_WORD_FALSE */ + +// cmakedefine with no replacement value (truthy) +// TODO: unexpected whitespace is being added here +#define NO_VALUE + +// cmakedefine with no replacement value (falsy) +/* #undef NO_VALUE_FALSE */ + +// cmakedefine01 with underscored variable names (truthy) +#define WITH_UNDERSCORE_TRUE 1 + +// cmakedefine01 with underscored variable names (falsy) +#define WITH_UNDERSCORE_FALSE 0 + +// cmakedefine with leading/trailing underscores (truthy) +#define _LEADING 1 +#define TRAILING_ 1 + +// cmakedefine01 with leading/trailing underscores (truthy) +#define _UNDER_01 1 +#define UNDER_01_ 1 + +// cmakedefine with @ substitution in the replacement value (truthy) +#define SUBST_VAL text + +// cmakedefine with @ substitution in the replacement value (falsy) +/* #undef SUBST_VAL_FALSE */ + +// cmakedefine with @ substitution as the variable name +#define ACTUAL_VAR custom_val + +// cmakedefine with dollar-curly substitution as the variable name +#define ACTUAL_VAR custom_val + +// @ and $ as literal config values +@ +$ diff --git a/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in new file mode 100644 index 0000000000000000000000000000000000000000..e46d114ca0a814436282d0f5ed895f146a1a4b12 --- /dev/null +++ b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in @@ -0,0 +1,42 @@ +// cmakedefine with multi-word string value (truthy) +#cmakedefine MULTI_WORD "hello world" + +// cmakedefine with multi-word string value (falsy) +#cmakedefine MULTI_WORD_FALSE "hello world" + +// cmakedefine with no replacement value (truthy) +// TODO: unexpected whitespace is being added here +#cmakedefine NO_VALUE + +// cmakedefine with no replacement value (falsy) +#cmakedefine NO_VALUE_FALSE + +// cmakedefine01 with underscored variable names (truthy) +#cmakedefine01 WITH_UNDERSCORE_TRUE + +// cmakedefine01 with underscored variable names (falsy) +#cmakedefine01 WITH_UNDERSCORE_FALSE + +// cmakedefine with leading/trailing underscores (truthy) +#cmakedefine _LEADING 1 +#cmakedefine TRAILING_ 1 + +// cmakedefine01 with leading/trailing underscores (truthy) +#cmakedefine01 _UNDER_01 +#cmakedefine01 UNDER_01_ + +// cmakedefine with @ substitution in the replacement value (truthy) +#cmakedefine SUBST_VAL @STRING@ + +// cmakedefine with @ substitution in the replacement value (falsy) +#cmakedefine SUBST_VAL_FALSE @STRING@ + +// cmakedefine with @ substitution as the variable name +#cmakedefine @VAR_NAME@ custom_val + +// cmakedefine with dollar-curly substitution as the variable name +#cmakedefine ${VAR_NAME} custom_val + +// @ and $ as literal config values +@AT_SIGN@ +${DOLLAR_SIGN} diff --git a/test/standalone/config_header/cmake/config.h b/test/standalone/config_header/cmake/config.h new file mode 100644 index 0000000000000000000000000000000000000000..757c4f11f14bc11ff1bb9b3cfc912eec11adb46a --- /dev/null +++ b/test/standalone/config_header/cmake/config.h @@ -0,0 +1,144 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +// cmakedefine — value is null (undefined) → /* #undef */ +/* #undef NOVAL */ + +// cmakedefine — value is true → #define ... 1 +#define TRUEVAL 1 + +// cmakedefine — value is false → /* #undef */ +/* #undef FALSEVAL */ + +// cmakedefine — value is 0 (falsy) → /* #undef */ +/* #undef ZEROVAL */ + +// cmakedefine — value is 1 (truthy) → #define ... 1 +#define ONEVAL 1 + +// cmakedefine — value is 10 (truthy) → #define ... 1 +#define TENVAL 1 + +// cmakedefine — value is non-empty string (truthy) → #define ... 1 +#define STRINGVAL 1 + +// cmakedefine — leading whitespace preserved in output + #define STRINGVAL 1 + #define STRINGVAL 1 + + +// cmakedefine01 — value is {} (defined, no value) → 0 +#define BOOLNOVAL 0 + +// cmakedefine01 — value is true → 1 +#define BOOLTRUEVAL 1 + +// cmakedefine01 — value is false → 0 +#define BOOLFALSEVAL 0 + +// cmakedefine01 — value is 0 (falsy) → 0 +#define BOOLZEROVAL 0 + +// cmakedefine01 — value is 1 (truthy) → 1 +#define BOOLONEVAL 1 + +// cmakedefine01 — value is 10 (truthy) → 1 +#define BOOLTENVAL 1 + +// cmakedefine01 — value is non-empty string (truthy) → 1 +#define BOOLSTRINGVAL 1 + + +// @-substitution — value is null → empty string +// + +// @-substitution — null values produce nothing even when packed +// + +// @-substitution — null values produce nothing even when separated +// . + +// @-substitution — value is true → "1" +// 1 + +// @-substitution — value is false → "0" +// 0 + +// @-substitution — true + false packed → "10" +// 10 + +// @-substitution — false + true separated → "0.1" +// 0.1 + +// @-substitution — value is 0 → "0" +// 0 + +// @-substitution — value is 1 → "1" +// 1 + +// @-substitution — value is 10 → "10" +// 10 + +// @-substitution — 0 + 1 packed → "01" +// 01 + +// @-substitution — 0 + 10 separated → "0.10" +// 0.10 + +// @-substitution — value is string "test" → "test" +// test + +// @-substitution — strings packed → "testtest" +// testtest + +// @-substitution — strings separated → "test.test" +// test.test + +// @-substitution — mixed null/string/true/zero → "test10" +// test10 + +// dollar-curly substitution — value is null → empty string +// + +// dollar-curly substitution — null values produce nothing even when packed +// + +// dollar-curly substitution — null values produce nothing even when separated +// . + +// dollar-curly substitution — value is true → "1" +// 1 + +// dollar-curly substitution — value is false → "0" +// 0 + +// dollar-curly substitution — true + false packed → "10" +// 10 + +// dollar-curly substitution — false + true separated → "0.1" +// 0.1 + +// dollar-curly substitution — value is 0 → "0" +// 0 + +// dollar-curly substitution — value is 1 → "1" +// 1 + +// dollar-curly substitution — value is 10 → "10" +// 10 + +// dollar-curly substitution — 0 + 1 packed → "01" +// 01 + +// dollar-curly substitution — 0 + 10 separated → "0.10" +// 0.10 + +// dollar-curly substitution — value is string "test" → "test" +// test + +// dollar-curly substitution — strings packed → "testtest" +// testtest + +// dollar-curly substitution — strings separated → "test.test" +// test.test + +// dollar-curly substitution — mixed null/string/true/zero → "test10" +// test10 diff --git a/test/standalone/config_header/cmake/config.h.in b/test/standalone/config_header/cmake/config.h.in index 3f9c60c7523362e952c736a1ba69fbdf9abb3fe2..7bd23030835e92b703c7ff68d1e4e4d8e30142a1 100644 --- a/test/standalone/config_header/cmake/config.h.in +++ b/test/standalone/config_header/cmake/config.h.in @@ -1,147 +1,143 @@ -// cmakedefine -// undefined -#cmakedefine noval unreachable +// cmakedefine — value is null (undefined) → /* #undef */ +#cmakedefine NOVAL unreachable -// 1 -#cmakedefine trueval 1 +// cmakedefine — value is true → #define ... 1 +#cmakedefine TRUEVAL 1 -// undefined -#cmakedefine falseval unreachable +// cmakedefine — value is false → /* #undef */ +#cmakedefine FALSEVAL unreachable -// undefined -#cmakedefine zeroval unreachable +// cmakedefine — value is 0 (falsy) → /* #undef */ +#cmakedefine ZEROVAL unreachable -// 1 -#cmakedefine oneval 1 +// cmakedefine — value is 1 (truthy) → #define ... 1 +#cmakedefine ONEVAL 1 -// 1 -#cmakedefine tenval 1 +// cmakedefine — value is 10 (truthy) → #define ... 1 +#cmakedefine TENVAL 1 -// 1 -#cmakedefine stringval 1 +// cmakedefine — value is non-empty string (truthy) → #define ... 1 +#cmakedefine STRINGVAL 1 -// whitespace test - #cmakedefine stringval 1 - #cmakedefine stringval 1 +// cmakedefine — leading whitespace preserved in output + #cmakedefine STRINGVAL 1 + #cmakedefine STRINGVAL 1 -// cmakedefine01 -// 0 -#cmakedefine01 boolnoval +// cmakedefine01 — value is {} (defined, no value) → 0 +#cmakedefine01 BOOLNOVAL -// 1 -#cmakedefine01 booltrueval +// cmakedefine01 — value is true → 1 +#cmakedefine01 BOOLTRUEVAL -// 0 -#cmakedefine01 boolfalseval +// cmakedefine01 — value is false → 0 +#cmakedefine01 BOOLFALSEVAL -// 0 -#cmakedefine01 boolzeroval +// cmakedefine01 — value is 0 (falsy) → 0 +#cmakedefine01 BOOLZEROVAL -// 1 -#cmakedefine01 booloneval +// cmakedefine01 — value is 1 (truthy) → 1 +#cmakedefine01 BOOLONEVAL -// 1 -#cmakedefine01 booltenval +// cmakedefine01 — value is 10 (truthy) → 1 +#cmakedefine01 BOOLTENVAL -// 1 -#cmakedefine01 boolstringval +// cmakedefine01 — value is non-empty string (truthy) → 1 +#cmakedefine01 BOOLSTRINGVAL -// @ substition +// @-substitution — value is null → empty string +// @NOVAL@ -// no substition -// @noval@ +// @-substitution — null values produce nothing even when packed +// @NOVAL@@NOVAL@ -// no substition -// @noval@@noval@ +// @-substitution — null values produce nothing even when separated +// @NOVAL@.@NOVAL@ -// no substition -// @noval@.@noval@ +// @-substitution — value is true → "1" +// @TRUEVAL@ -// 1 -// @trueval@ +// @-substitution — value is false → "0" +// @FALSEVAL@ -// 0 -// @falseval@ +// @-substitution — true + false packed → "10" +// @TRUEVAL@@FALSEVAL@ -// 10 -// @trueval@@falseval@ +// @-substitution — false + true separated → "0.1" +// @FALSEVAL@.@TRUEVAL@ -// 0.1 -// @falseval@.@trueval@ +// @-substitution — value is 0 → "0" +// @ZEROVAL@ -// 0 -// @zeroval@ +// @-substitution — value is 1 → "1" +// @ONEVAL@ -// 1 -// @oneval@ +// @-substitution — value is 10 → "10" +// @TENVAL@ -// 10 -// @tenval@ +// @-substitution — 0 + 1 packed → "01" +// @ZEROVAL@@ONEVAL@ -// 01 -// @zeroval@@oneval@ +// @-substitution — 0 + 10 separated → "0.10" +// @ZEROVAL@.@TENVAL@ -// 0.10 -// @zeroval@.@tenval@ +// @-substitution — value is string "test" → "test" +// @STRINGVAL@ -// test -// @stringval@ +// @-substitution — strings packed → "testtest" +// @STRINGVAL@@STRINGVAL@ -// testtest -// @stringval@@stringval@ +// @-substitution — strings separated → "test.test" +// @STRINGVAL@.@STRINGVAL@ -// test.test -// @stringval@.@stringval@ +// @-substitution — mixed null/string/true/zero → "test10" +// @NOVAL@@STRINGVAL@@TRUEVAL@@ZEROVAL@ -// test10 -// @noval@@stringval@@trueval@@zeroval@ +// dollar-curly substitution — value is null → empty string +// ${NOVAL} -// no substition -// ${noval} +// dollar-curly substitution — null values produce nothing even when packed +// ${NOVAL}${NOVAL} -// no substition -// ${noval}${noval} +// dollar-curly substitution — null values produce nothing even when separated +// ${NOVAL}.${NOVAL} -// no substition -// ${noval}.${noval} +// dollar-curly substitution — value is true → "1" +// ${TRUEVAL} -// 1 -// ${trueval} +// dollar-curly substitution — value is false → "0" +// ${FALSEVAL} -// 0 -// ${falseval} +// dollar-curly substitution — true + false packed → "10" +// ${TRUEVAL}${FALSEVAL} -// 10 -// ${trueval}${falseval} +// dollar-curly substitution — false + true separated → "0.1" +// ${FALSEVAL}.${TRUEVAL} -// 0.1 -// ${falseval}.${trueval} +// dollar-curly substitution — value is 0 → "0" +// ${ZEROVAL} -// 0 -// ${zeroval} +// dollar-curly substitution — value is 1 → "1" +// ${ONEVAL} -// 1 -// ${oneval} +// dollar-curly substitution — value is 10 → "10" +// ${TENVAL} -// 10 -// ${tenval} +// dollar-curly substitution — 0 + 1 packed → "01" +// ${ZEROVAL}${ONEVAL} -// 01 -// ${zeroval}${oneval} +// dollar-curly substitution — 0 + 10 separated → "0.10" +// ${ZEROVAL}.${TENVAL} -// 0.10 -// ${zeroval}.${tenval} +// dollar-curly substitution — value is string "test" → "test" +// ${STRINGVAL} -// test -// ${stringval} +// dollar-curly substitution — strings packed → "testtest" +// ${STRINGVAL}${STRINGVAL} -// testtest -// ${stringval}${stringval} +// dollar-curly substitution — strings separated → "test.test" +// ${STRINGVAL}.${STRINGVAL} -// test.test -// ${stringval}.${stringval} - -// test10 -// ${noval}${stringval}${trueval}${zeroval} +// dollar-curly substitution — mixed null/string/true/zero → "test10" +// ${NOVAL}${STRINGVAL}${TRUEVAL}${ZEROVAL} diff --git a/test/standalone/config_header/cmake/edge_cases.h b/test/standalone/config_header/cmake/edge_cases.h new file mode 100644 index 0000000000000000000000000000000000000000..e77ba031b7e87b905e38fa15083296375e387184 --- /dev/null +++ b/test/standalone/config_header/cmake/edge_cases.h @@ -0,0 +1,43 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +// empty lines are preserved + +// double-wrapped at-sigils work like single-wrapped +@text@ +@text@ + +// at-var lookup happens inside dollar-curly before dollar-curly lookup +text + +// expanded variables are treated as strings and can be re-substituted +@STRING@ +@STRING@ +${STRING} +${STRING} +${STRING} +${STRING} +${text} +${text} +${text} + +// nested dollar-curly expansion from the inside out +STRING +STRING + +// nested dollar-curly — only completed brace blocks are expanded +NEST_UNDERSCORE_PROXY +NEST_UNDERSCORE_PROXY + +// backslash is invalid in at-var names — preserved as literal +\@STRING\@ + +// backslash does not affect dollar-curly expansion +\text + +// backslash before opening brace breaks dollar-curly identification +$\{STRING} + +// bare at-sigils pass through unchanged with no variable map +#define AT @ +#define ATAT @@ +#define ATATAT @@@ +#define ATATATAT @@@@ diff --git a/test/standalone/config_header/cmake/edge_cases.h.in b/test/standalone/config_header/cmake/edge_cases.h.in new file mode 100644 index 0000000000000000000000000000000000000000..97ac91db24e4d1ecfe5632722b8d0e33924752f0 --- /dev/null +++ b/test/standalone/config_header/cmake/edge_cases.h.in @@ -0,0 +1,42 @@ +// empty lines are preserved + +// double-wrapped at-sigils work like single-wrapped +@@STRING@@ +@${STRING}@ + +// at-var lookup happens inside dollar-curly before dollar-curly lookup +${@STRING_PROXY@} + +// expanded variables are treated as strings and can be re-substituted +@STRING_AT@ +${STRING_AT} +$@STRING_CURLY@ +$${STRING_CURLY} +${STRING_VAR} +@STRING_VAR@ +${DOLLAR}{${STRING}} +@DOLLAR@{${STRING}} +@DOLLAR@{@STRING@} + +// nested dollar-curly expansion from the inside out +${STRING${UNDERSCORE}PROXY} +${STRING@UNDERSCORE@PROXY} + +// nested dollar-curly — only completed brace blocks are expanded +${NEST${UNDERSCORE}PROXY} +${NEST${${NEST_UNDERSCORE${UNDERSCORE}PROXY}}PROXY} + +// backslash is invalid in at-var names — preserved as literal +\@STRING\@ + +// backslash does not affect dollar-curly expansion +\${STRING} + +// backslash before opening brace breaks dollar-curly identification +$\{STRING} + +// bare at-sigils pass through unchanged with no variable map +#define AT @ +#define ATAT @@ +#define ATATAT @@@ +#define ATATATAT @@@@ diff --git a/test/standalone/config_header/cmake/expected_config.h b/test/standalone/config_header/cmake/expected_config.h deleted file mode 100644 index c38418b6df3021a671c431e071c7caa374bbf5cd..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/expected_config.h +++ /dev/null @@ -1,148 +0,0 @@ -/* This file was generated by ConfigHeader using the Zig Build System. */ -// cmakedefine -// undefined -/* #undef noval */ - -// 1 -#define trueval 1 - -// undefined -/* #undef falseval */ - -// undefined -/* #undef zeroval */ - -// 1 -#define oneval 1 - -// 1 -#define tenval 1 - -// 1 -#define stringval 1 - -// whitespace test - #define stringval 1 - #define stringval 1 - - -// cmakedefine01 -// 0 -#define boolnoval 0 - -// 1 -#define booltrueval 1 - -// 0 -#define boolfalseval 0 - -// 0 -#define boolzeroval 0 - -// 1 -#define booloneval 1 - -// 1 -#define booltenval 1 - -// 1 -#define boolstringval 1 - - -// @ substition - -// no substition -// - -// no substition -// - -// no substition -// . - -// 1 -// 1 - -// 0 -// 0 - -// 10 -// 10 - -// 0.1 -// 0.1 - -// 0 -// 0 - -// 1 -// 1 - -// 10 -// 10 - -// 01 -// 01 - -// 0.10 -// 0.10 - -// test -// test - -// testtest -// testtest - -// test.test -// test.test - -// test10 -// test10 - -// no substition -// - -// no substition -// - -// no substition -// . - -// 1 -// 1 - -// 0 -// 0 - -// 10 -// 10 - -// 0.1 -// 0.1 - -// 0 -// 0 - -// 1 -// 1 - -// 10 -// 10 - -// 01 -// 01 - -// 0.10 -// 0.10 - -// test -// test - -// testtest -// testtest - -// test.test -// test.test - -// test10 -// test10 diff --git a/test/standalone/config_header/cmake/expected_sigil.h b/test/standalone/config_header/cmake/expected_sigil.h deleted file mode 100644 index 1f0f5c0e329dabbc3d6b8ae245c69a91b18b9eaa..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/expected_sigil.h +++ /dev/null @@ -1,5 +0,0 @@ -/* This file was generated by ConfigHeader using the Zig Build System. */ -#define AT @ -#define ATAT @@ -#define ATATAT @@@ -#define ATATATAT @@@@ diff --git a/test/standalone/config_header/cmake/expected_stack.h b/test/standalone/config_header/cmake/expected_stack.h deleted file mode 100644 index 598bc0a310ada8f00d0b8bf64ce0562e4e5681b7..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/expected_stack.h +++ /dev/null @@ -1,4 +0,0 @@ -/* This file was generated by ConfigHeader using the Zig Build System. */ -#define NEST_UNDERSCORE_PROXY NEST_UNDERSCORE_PROXY - -#define NEST_UNDERSCORE_PROXY NEST_UNDERSCORE_PROXY diff --git a/test/standalone/config_header/cmake/expected_wrapper.h b/test/standalone/config_header/cmake/expected_wrapper.h deleted file mode 100644 index 1f78d22ee9ae778e833c98e784f284c04ac47dfb..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/expected_wrapper.h +++ /dev/null @@ -1,31 +0,0 @@ -/* This file was generated by ConfigHeader using the Zig Build System. */ -// becomes TEXT -#define TEXT -#define TEXT - -// becomes `at`TEXT`at` -#define @TEXT@ -#define @TEXT@ - -// becomes TRAP -#define TRAP - -// becomes `dollar sign`{STRING} -#define ${STRING} -#define ${STRING} - -// becomes `dollar sign`{STRING} -#define ${STRING} -#define ${STRING} - -// becomes `dollar sign`{TEXT} -#define ${TEXT} -#define ${TEXT} - -// becomes `at`STRING`at` -#define @STRING@ -#define @STRING@ - -#define \@STRING_VAR\@ -#define \${STRING} -#define $\{STRING_VAR} diff --git a/test/standalone/config_header/cmake/expected_pwd.sh b/test/standalone/config_header/cmake/pwd.sh similarity index 100% rename from test/standalone/config_header/cmake/expected_pwd.sh rename to test/standalone/config_header/cmake/pwd.sh diff --git a/test/standalone/config_header/cmake/sigil.h.in b/test/standalone/config_header/cmake/sigil.h.in deleted file mode 100644 index 10108f4d1e2fdd3c4a685a8501596a77291b0c1f..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/sigil.h.in +++ /dev/null @@ -1,4 +0,0 @@ -#define AT @ -#define ATAT @@ -#define ATATAT @@@ -#define ATATATAT @@@@ diff --git a/test/standalone/config_header/cmake/stack.h.in b/test/standalone/config_header/cmake/stack.h.in deleted file mode 100644 index 91fdd8a26516634e7cce1779c276ca5e30a0a2a9..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/stack.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#define NEST_UNDERSCORE_PROXY ${NEST${UNDERSCORE}PROXY} - -#define NEST_UNDERSCORE_PROXY ${NEST${${NEST_UNDERSCORE${UNDERSCORE}PROXY}}PROXY} diff --git a/test/standalone/config_header/cmake/wrapper.h.in b/test/standalone/config_header/cmake/wrapper.h.in deleted file mode 100644 index d2334fa9b79c624bfb72c4dcae19b38f57e2cc13..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/cmake/wrapper.h.in +++ /dev/null @@ -1,30 +0,0 @@ -// becomes TEXT -#define @STRING@ -#define ${STRING} - -// becomes `at`TEXT`at` -#define @${STRING}@ -#define @@STRING@@ - -// becomes TRAP -#define ${@STRING@} - -// becomes `dollar sign`{STRING} -#define $@STRING_CURLY@ -#define $${STRING_CURLY} - -// becomes `dollar sign`{STRING} -#define @STRING_VAR@ -#define ${STRING_VAR} - -// becomes `dollar sign`{TEXT} -#define ${DOLLAR}{${STRING}} -#define @DOLLAR@{${STRING}} - -// becomes `at`STRING`at` -#define ${STRING_AT} -#define @STRING_AT@ - -#define \@STRING_VAR\@ -#define \${STRING_VAR} -#define $\{STRING_VAR} -- 2.54.0 From d80b072bf29620753fb36b8053c6e81500526fb6 Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 18:26:14 +0000 Subject: [PATCH 05/12] add more coverage for autoconf style --- .../config_header/autoconf_at/autoconf_at.txt | 12 ++++++++++++ .../config_header/autoconf_at/autoconf_at.txt.in | 12 ++++++++++++ .../config_header/autoconf_undef/config.h | 11 +++++++++++ .../config_header/autoconf_undef/config.h.in | 16 +++++++++++++--- test/standalone/config_header/build.zig | 5 +++++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.txt b/test/standalone/config_header/autoconf_at/autoconf_at.txt index fccd1255f887c410c0f86a87d51e531685a4382b..e35cb5f822ab889e727d0fd13fe263fedb8b24cd 100644 --- a/test/standalone/config_header/autoconf_at/autoconf_at.txt +++ b/test/standalone/config_header/autoconf_at/autoconf_at.txt @@ -35,3 +35,15 @@ what is 6*7? 42! @text@ // expanded variables are considered strings after expansion @string@ + +// variable name with underscores +value + +// backslash before at-sigil does not prevent resolution +\text + +// value that is an at-sign itself +@ + +// incomplete key mid-line is preserved, trailing content kept +@incomplete trailing content diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.txt.in b/test/standalone/config_header/autoconf_at/autoconf_at.txt.in index 8dfbab96d7b4483305352787cc32e420f606f0db..77d15622e8223e3e51ccc66889deb2b0d79b563b 100644 --- a/test/standalone/config_header/autoconf_at/autoconf_at.txt.in +++ b/test/standalone/config_header/autoconf_at/autoconf_at.txt.in @@ -34,3 +34,15 @@ what is 6*7? @integer@! @@string@@ // expanded variables are considered strings after expansion @string_at@ + +// variable name with underscores +@underscored_var@ + +// backslash before at-sigil does not prevent resolution +\@string@ + +// value that is an at-sign itself +@at_sign@ + +// incomplete key mid-line is preserved, trailing content kept +@incomplete trailing content diff --git a/test/standalone/config_header/autoconf_undef/config.h b/test/standalone/config_header/autoconf_undef/config.h index ef5b4abab30499feb5c82019ae8750e82b059512..3a649b0aca5576d75099906310d28ef049d50f4a 100644 --- a/test/standalone/config_header/autoconf_undef/config.h +++ b/test/standalone/config_header/autoconf_undef/config.h @@ -20,4 +20,15 @@ int foo(); /* #undef PREFIX_TAB */ /* #undef POSTFIX_SPACE */ /* #undef POSTFIX_TAB */ + +// #undef with underscored variable name +#define SOME_UNDERSCORED 1 + +// #undef with extra tokens after variable name (ignored) +#define SOME_ONE 1 + +// non-#undef # lines pass through unchanged +#define KEPT_DEFINE value +#include // TODO: unexpected newline is being added here + diff --git a/test/standalone/config_header/autoconf_undef/config.h.in b/test/standalone/config_header/autoconf_undef/config.h.in index fafc3587658162eaae0c918320df9752b779086d..1a13ccf319a85432ff04916ac0145b23bf78a7d3 100644 --- a/test/standalone/config_header/autoconf_undef/config.h.in +++ b/test/standalone/config_header/autoconf_undef/config.h.in @@ -17,6 +17,16 @@ int foo(); #undef PREFIX_SPACE #undef PREFIX_TAB -#undef POSTFIX_SPACE -#undef POSTFIX_TAB -// TODO: unexpected newline is being added here \ No newline at end of file +#undef POSTFIX_SPACE +#undef POSTFIX_TAB + +// #undef with underscored variable name +#undef SOME_UNDERSCORED + +// #undef with extra tokens after variable name (ignored) +#undef SOME_ONE extra ignored tokens + +// non-#undef # lines pass through unchanged +#define KEPT_DEFINE value +#include +// TODO: unexpected newline is being added here diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index e6d62557e223abb8e610cc945986ee82165fe14f..42080a0996c2b330a73ff5ad721be8a3d120e15b 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -21,6 +21,8 @@ pub fn build(b: *std.Build) void { .PREFIX_TAB = null, .POSTFIX_SPACE = null, .POSTFIX_TAB = null, + + .SOME_UNDERSCORED = true, }, ); const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ @@ -37,6 +39,9 @@ pub fn build(b: *std.Build) void { .integer = 42, .string = "text", .string_at = "@string@", + + .underscored_var = "value", + .at_sign = "@", }, ); const check_config_header_autoconf_at = b.addCheckFile(config_header_autoconf_at.getOutputFile(), .{ -- 2.54.0 From cf741692f7c34b1bd3269fdd7437903bad64804d Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 18:33:59 +0000 Subject: [PATCH 06/12] Add coverage for blank and nasm styles --- test/standalone/config_header/blank/config.h | 13 ++++++ test/standalone/config_header/build.zig | 45 +++++++++++++++++++ test/standalone/config_header/nasm/config.asm | 10 +++++ 3 files changed, 68 insertions(+) create mode 100644 test/standalone/config_header/blank/config.h create mode 100644 test/standalone/config_header/nasm/config.asm diff --git a/test/standalone/config_header/blank/config.h b/test/standalone/config_header/blank/config.h new file mode 100644 index 0000000000000000000000000000000000000000..d5778c5bf642920877939cf1bd3fc3e4e606725d --- /dev/null +++ b/test/standalone/config_header/blank/config.h @@ -0,0 +1,13 @@ +/* This file was generated by ConfigHeader using the Zig Build System. */ +#ifndef CONFIG_H +#define CONFIG_H +/* #undef UNDEFINED */ +#define DEFINED +#define TRUE 1 +#define FALSE 0 +#define ZERO 0 +#define ONE 1 +#define TEN 10 +#define IDENT identifier +#define STRING "test" +#endif /* CONFIG_H */ diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index 42080a0996c2b330a73ff5ad721be8a3d120e15b..95daf60c28ea3aa5032377c7cb5c14f082a622a9 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -50,6 +50,51 @@ pub fn build(b: *std.Build) void { test_step.dependOn(&check_config_header.step); test_step.dependOn(&check_config_header_autoconf_at.step); + + const config_header_blank = b.addConfigHeader( + .{ + .style = .blank, + .include_path = "config.h", + }, + .{ + .UNDEFINED = null, + .DEFINED = {}, + .TRUE = true, + .FALSE = false, + .ZERO = 0, + .ONE = 1, + .TEN = 10, + .IDENT = @as(enum { identifier }, .identifier), + .STRING = "test", + }, + ); + const check_config_header_blank = b.addCheckFile(config_header_blank.getOutputFile(), .{ + .expected_exact = @embedFile("blank/config.h"), + }); + test_step.dependOn(&check_config_header_blank.step); + + const config_header_nasm = b.addConfigHeader( + .{ + .style = .nasm, + .include_path = "config.asm", + }, + .{ + .UNDEFINED = null, + .DEFINED = {}, + .TRUE = true, + .FALSE = false, + .ZERO = 0, + .ONE = 1, + .TEN = 10, + .IDENT = @as(enum { identifier }, .identifier), + .STRING = "test", + }, + ); + const check_config_header_nasm = b.addCheckFile(config_header_nasm.getOutputFile(), .{ + .expected_exact = @embedFile("nasm/config.asm"), + }); + test_step.dependOn(&check_config_header_nasm.step); + addCmakeChecks(b, test_step); } diff --git a/test/standalone/config_header/nasm/config.asm b/test/standalone/config_header/nasm/config.asm new file mode 100644 index 0000000000000000000000000000000000000000..ffc7acf6859435ab1124efa700c93a6781fb2032 --- /dev/null +++ b/test/standalone/config_header/nasm/config.asm @@ -0,0 +1,10 @@ +; This file was generated by ConfigHeader using the Zig Build System. +; %undef UNDEFINED +%define DEFINED +%define TRUE 1 +%define FALSE 0 +%define ZERO 0 +%define ONE 1 +%define TEN 10 +%define IDENT identifier +%define STRING "test" -- 2.54.0 From be18e17ce528f5e4a0cda5f694c8ad13a6b38662 Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 18:41:41 +0000 Subject: [PATCH 07/12] Fix unexpected trailing whitespace for cmakedefine with no replacement value --- lib/compiler/Maker/Step/ConfigHeader.zig | 7 ++++++- .../config_header/cmake/cmakedefine_edge_cases.h | 3 +-- .../config_header/cmake/cmakedefine_edge_cases.h.in | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/compiler/Maker/Step/ConfigHeader.zig b/lib/compiler/Maker/Step/ConfigHeader.zig index 8f4f677ee3bd4cef5f42541673823e9377185c86..5096c8e0e3340fc5d841b5ae1677297bfb40417f 100644 --- a/lib/compiler/Maker/Step/ConfigHeader.zig +++ b/lib/compiler/Maker/Step/ConfigHeader.zig @@ -418,7 +418,12 @@ fn renderValueC(conf: *const Configuration, w: *Writer, name: []const u8, value: } fn renderValueCIdent(w: *Writer, name: []const u8, ident: []const u8) Writer.Error!void { - return w.print("#define {s} {s}\n", .{ name, ident }); + try w.print("#define {s}", .{name}); + if (ident.len > 0) { + try w.writeByte(' '); + try w.writeAll(ident); + } + return w.writeByte('\n'); } fn renderValueCBool(w: *Writer, name: []const u8, b: bool) Writer.Error!void { diff --git a/test/standalone/config_header/cmake/cmakedefine_edge_cases.h b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h index e05567a40332e2bb46a67376bd283a4e341cd46a..abe4df8d94b5070ee4cba4cbc09a146688b3c96b 100644 --- a/test/standalone/config_header/cmake/cmakedefine_edge_cases.h +++ b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h @@ -6,8 +6,7 @@ /* #undef MULTI_WORD_FALSE */ // cmakedefine with no replacement value (truthy) -// TODO: unexpected whitespace is being added here -#define NO_VALUE +#define NO_VALUE // cmakedefine with no replacement value (falsy) /* #undef NO_VALUE_FALSE */ diff --git a/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in index e46d114ca0a814436282d0f5ed895f146a1a4b12..343e767043db563edff5adb9ebf13c98469854a0 100644 --- a/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in +++ b/test/standalone/config_header/cmake/cmakedefine_edge_cases.h.in @@ -5,7 +5,6 @@ #cmakedefine MULTI_WORD_FALSE "hello world" // cmakedefine with no replacement value (truthy) -// TODO: unexpected whitespace is being added here #cmakedefine NO_VALUE // cmakedefine with no replacement value (falsy) -- 2.54.0 From 6043fbb2b7f263c0bab308f46f4ef393fec4a678 Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 18:54:43 +0000 Subject: [PATCH 08/12] Fix unexpected trailing newline for autconf_undef --- lib/compiler/Maker/Step/ConfigHeader.zig | 6 ++++-- test/standalone/config_header/autoconf_undef/config.h | 2 -- test/standalone/config_header/autoconf_undef/config.h.in | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/compiler/Maker/Step/ConfigHeader.zig b/lib/compiler/Maker/Step/ConfigHeader.zig index 5096c8e0e3340fc5d841b5ae1677297bfb40417f..9444d3a6171c2157d042ef3ca2d1dd4b16ee5517 100644 --- a/lib/compiler/Maker/Step/ConfigHeader.zig +++ b/lib/compiler/Maker/Step/ConfigHeader.zig @@ -177,16 +177,18 @@ fn renderAutoConfUndef( var line_index: u32 = 0; var line_it = std.mem.splitScalar(u8, contents, '\n'); while (line_it.next()) |line| : (line_index += 1) { + const last_line = line_it.index == line_it.buffer.len; + if (!std.mem.startsWith(u8, line, "#")) { try w.writeAll(line); - try w.writeByte('\n'); + if (!last_line) try w.writeByte('\n'); continue; } var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); const undef = it.next().?; if (!std.mem.eql(u8, undef, "undef")) { try w.writeAll(line); - try w.writeByte('\n'); + if (!last_line) try w.writeByte('\n'); continue; } const name = it.next().?; diff --git a/test/standalone/config_header/autoconf_undef/config.h b/test/standalone/config_header/autoconf_undef/config.h index 3a649b0aca5576d75099906310d28ef049d50f4a..854cbfc9f7fe9e1ed1de0dbea6f25ea687ec4264 100644 --- a/test/standalone/config_header/autoconf_undef/config.h +++ b/test/standalone/config_header/autoconf_undef/config.h @@ -30,5 +30,3 @@ int foo(); // non-#undef # lines pass through unchanged #define KEPT_DEFINE value #include -// TODO: unexpected newline is being added here - diff --git a/test/standalone/config_header/autoconf_undef/config.h.in b/test/standalone/config_header/autoconf_undef/config.h.in index 1a13ccf319a85432ff04916ac0145b23bf78a7d3..39b0ec734ede142c24327af6038c288cd4fe161a 100644 --- a/test/standalone/config_header/autoconf_undef/config.h.in +++ b/test/standalone/config_header/autoconf_undef/config.h.in @@ -29,4 +29,3 @@ int foo(); // non-#undef # lines pass through unchanged #define KEPT_DEFINE value #include -// TODO: unexpected newline is being added here -- 2.54.0 From a6fded0810cdc9998101cc56804b1dc7274f9671 Mon Sep 17 00:00:00 2001 From: fardragon Date: Thu, 4 Jun 2026 19:26:32 +0000 Subject: [PATCH 09/12] Make ConfigHeader newline aware --- lib/compiler/Maker/Step/ConfigHeader.zig | 92 +++++++++++++++--------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/lib/compiler/Maker/Step/ConfigHeader.zig b/lib/compiler/Maker/Step/ConfigHeader.zig index 9444d3a6171c2157d042ef3ca2d1dd4b16ee5517..a483ef7bd5cb86cdd2215e6ddacae1a3be692aef 100644 --- a/lib/compiler/Maker/Step/ConfigHeader.zig +++ b/lib/compiler/Maker/Step/ConfigHeader.zig @@ -11,8 +11,10 @@ const Step = @import("../Step.zig"); const Maker = @import("../../Maker.zig"); const header_text = "This file was generated by ConfigHeader using the Zig Build System."; -const c_generated_line = "/* " ++ header_text ++ " */\n"; -const asm_generated_line = "; " ++ header_text ++ "\n"; +const c_generated_line = "/* " ++ header_text ++ " */"; +const asm_generated_line = "; " ++ header_text; + +const os_newline = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; /// Table value is whether the value is used. const ValueMap = std.array_hash_map.String(bool); @@ -160,6 +162,15 @@ fn ensureAllValuesUsed( if (any_errors) return error.MakeFailed; } +fn detectNewline(contents: []const u8) []const u8 { + return if (std.mem.endsWith(u8, contents, "\r\n")) + "\r\n" + else if (std.mem.endsWith(u8, contents, "\n")) + "\n" + else + os_newline; +} + fn renderAutoConfUndef( maker: *Maker, step: *Step, @@ -170,25 +181,28 @@ fn renderAutoConfUndef( src_path: Path, ) !void { const conf = &maker.scanned_config.configuration; + const newline = detectNewline(contents); try w.writeAll(c_generated_line); + try w.writeAll(newline); var any_errors = false; var line_index: u32 = 0; var line_it = std.mem.splitScalar(u8, contents, '\n'); - while (line_it.next()) |line| : (line_index += 1) { + while (line_it.next()) |raw_line| : (line_index += 1) { const last_line = line_it.index == line_it.buffer.len; + const line = std.mem.trimEnd(u8, raw_line, "\r"); if (!std.mem.startsWith(u8, line, "#")) { try w.writeAll(line); - if (!last_line) try w.writeByte('\n'); + if (!last_line) try w.writeAll(newline); continue; } var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); const undef = it.next().?; if (!std.mem.eql(u8, undef, "undef")) { try w.writeAll(line); - if (!last_line) try w.writeByte('\n'); + if (!last_line) try w.writeAll(newline); continue; } const name = it.next().?; @@ -200,7 +214,7 @@ fn renderAutoConfUndef( continue; }; value_map.values()[index] = true; // Set to used. - try renderValueC(conf, w, name, value_pairs[index].index); + try renderValueC(conf, w, newline, name, value_pairs[index].index); } try ensureAllValuesUsed(maker, step, value_map, src_path); @@ -218,14 +232,17 @@ fn renderAutoconfAt( ) !void { const w = &aw.writer; const conf = &maker.scanned_config.configuration; + const newline = detectNewline(contents); try w.writeAll(c_generated_line); + try w.writeAll(newline); var any_errors = false; var line_index: u32 = 0; var line_it = std.mem.splitScalar(u8, contents, '\n'); - while (line_it.next()) |line| : (line_index += 1) { + while (line_it.next()) |raw_line| : (line_index += 1) { const last_line = line_it.index == line_it.buffer.len; + const line = std.mem.trimEnd(u8, raw_line, "\r"); const old_len = aw.written().len; expandVariablesAutoconfAt(w, line, conf, value_pairs, value_map) catch |err| switch (err) { @@ -246,7 +263,7 @@ fn renderAutoconfAt( continue; }, }; - if (!last_line) try w.writeByte('\n'); + if (!last_line) try w.writeAll(newline); } try ensureAllValuesUsed(maker, step, value_map, src_path); @@ -264,16 +281,19 @@ fn renderCmake( src_path: Path, ) !void { const conf = &maker.scanned_config.configuration; + const newline = detectNewline(contents); try w.writeAll(c_generated_line); + try w.writeAll(newline); var any_errors = false; var line_index: u32 = 0; var line_it = std.mem.splitScalar(u8, contents, '\n'); while (line_it.next()) |raw_line| : (line_index += 1) { const last_line = line_it.index == line_it.buffer.len; + const stripped_line = std.mem.trimEnd(u8, raw_line, "\r"); - const line = expandVariablesCmake(arena, raw_line, conf, value_pairs, value_map) catch |err| switch (err) { + const line = expandVariablesCmake(arena, stripped_line, conf, value_pairs, value_map) catch |err| switch (err) { error.InvalidCharacter => { try step.addError(maker, "{f}:{d}: invalid character in a variable name", .{ src_path, line_index + 1, @@ -292,7 +312,7 @@ fn renderCmake( const line_start = std.mem.findNone(u8, line, " \t\r") orelse { try w.writeAll(line); - if (!last_line) try w.writeByte('\n'); + if (!last_line) try w.writeAll(newline); continue; }; const whitespace_prefix = line[0..line_start]; @@ -300,7 +320,7 @@ fn renderCmake( if (!std.mem.startsWith(u8, trimmed_line, "#")) { try w.writeAll(line); - if (!last_line) try w.writeByte('\n'); + if (!last_line) try w.writeAll(newline); continue; } @@ -313,7 +333,7 @@ fn renderCmake( false else { try w.writeAll(line); - if (!last_line) try w.writeByte('\n'); + if (!last_line) try w.writeAll(newline); continue; }; @@ -337,7 +357,7 @@ fn renderCmake( try w.writeAll(whitespace_prefix); if (booldefine) { - try renderValueCBool(w, name, switch (value.unpack(conf)) { + try renderValueCBool(w, newline, name, switch (value.unpack(conf)) { .undef, .defined => false, .bool => |b| b, inline .u64, .i64 => |i| i != 0, @@ -345,9 +365,9 @@ fn renderCmake( .ident => false, }); } else if (value != .undef) { - try renderValueCIdent(w, name, it.rest()); + try renderValueCIdent(w, newline, name, it.rest()); } else { - try renderValueC(conf, w, name, value); + try renderValueC(conf, w, newline, name, value); } } @@ -364,6 +384,7 @@ fn renderBlank( include_guard_override: ?[]const u8, ) !void { try w.writeAll(c_generated_line); + try w.writeAll(os_newline); const include_guard_fmt: IncludeGuardFmt = .{ .include_path = include_path, @@ -376,7 +397,7 @@ fn renderBlank( \\ , .{include_guard_fmt}); - for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, name, pair.index); + for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, os_newline, name, pair.index); try w.print( \\#endif /* {f} */ @@ -405,41 +426,42 @@ fn renderNasm( value_map: *const ValueMap, ) !void { try w.writeAll(asm_generated_line); - for (value_map.keys(), value_pairs) |name, pair| try renderValueNasm(conf, w, name, pair.index); + try w.writeAll(os_newline); + for (value_map.keys(), value_pairs) |name, pair| try renderValueNasm(conf, w, os_newline, name, pair.index); } -fn renderValueC(conf: *const Configuration, w: *Writer, name: []const u8, value: Value.Index) !void { +fn renderValueC(conf: *const Configuration, w: *Writer, newline: []const u8, name: []const u8, value: Value.Index) !void { switch (value.unpack(conf)) { - .undef => try w.print("/* #undef {s} */\n", .{name}), - .defined => try w.print("#define {s}\n", .{name}), - .bool => |b| return renderValueCBool(w, name, b), - inline .u64, .i64 => |i| try w.print("#define {s} {d}\n", .{ name, i }), - .ident => |ident| return renderValueCIdent(w, name, ident), - .string => |string| try w.print("#define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }), + .undef => try w.print("/* #undef {s} */{s}", .{ name, newline }), + .defined => try w.print("#define {s}{s}", .{ name, newline }), + .bool => |b| return renderValueCBool(w, newline, name, b), + inline .u64, .i64 => |i| try w.print("#define {s} {d}{s}", .{ name, i, newline }), + .ident => |ident| return renderValueCIdent(w, newline, name, ident), + .string => |string| try w.print("#define {s} \"{f}\"{s}", .{ name, std.zig.fmtString(string), newline }), } } -fn renderValueCIdent(w: *Writer, name: []const u8, ident: []const u8) Writer.Error!void { +fn renderValueCIdent(w: *Writer, newline: []const u8, name: []const u8, ident: []const u8) Writer.Error!void { try w.print("#define {s}", .{name}); if (ident.len > 0) { try w.writeByte(' '); try w.writeAll(ident); } - return w.writeByte('\n'); + return w.writeAll(newline); } -fn renderValueCBool(w: *Writer, name: []const u8, b: bool) Writer.Error!void { - return w.print("#define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }); +fn renderValueCBool(w: *Writer, newline: []const u8, name: []const u8, b: bool) Writer.Error!void { + return w.print("#define {s} {c}{s}", .{ name, @as(u8, '0') + @intFromBool(b), newline }); } -fn renderValueNasm(conf: *const Configuration, w: *Writer, name: []const u8, value: Value.Index) !void { +fn renderValueNasm(conf: *const Configuration, w: *Writer, newline: []const u8, name: []const u8, value: Value.Index) !void { switch (value.unpack(conf)) { - .undef => try w.print("; %undef {s}\n", .{name}), - .defined => try w.print("%define {s}\n", .{name}), - .bool => |b| try w.print("%define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }), - inline .u64, .i64 => |i| try w.print("%define {s} {d}\n", .{ name, i }), - .ident => |ident| try w.print("%define {s} {s}\n", .{ name, ident }), - .string => |string| try w.print("%define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }), + .undef => try w.print("; %undef {s}{s}", .{ name, newline }), + .defined => try w.print("%define {s}{s}", .{ name, newline }), + .bool => |b| try w.print("%define {s} {c}{s}", .{ name, @as(u8, '0') + @intFromBool(b), newline }), + inline .u64, .i64 => |i| try w.print("%define {s} {d}{s}", .{ name, i, newline }), + .ident => |ident| try w.print("%define {s} {s}{s}", .{ name, ident, newline }), + .string => |string| try w.print("%define {s} \"{f}\"{s}", .{ name, std.zig.fmtString(string), newline }), } } -- 2.54.0 From 1eb3c64ea4ae4badbb71c92245de194b7fe7e1c4 Mon Sep 17 00:00:00 2001 From: fardragon Date: Fri, 5 Jun 2026 17:24:29 +0200 Subject: [PATCH 10/12] cleanup autoconf_at --- .../{autoconf_at.txt => autoconf_at.h} | 62 ++++++++++++------- .../autoconf_at/autoconf_at.h.in | 62 +++++++++++++++++++ .../autoconf_at/autoconf_at.txt.in | 48 -------------- test/standalone/config_header/build.zig | 4 +- 4 files changed, 102 insertions(+), 74 deletions(-) rename test/standalone/config_header/autoconf_at/{autoconf_at.txt => autoconf_at.h} (50%) create mode 100644 test/standalone/config_header/autoconf_at/autoconf_at.h.in delete mode 100644 test/standalone/config_header/autoconf_at/autoconf_at.txt.in diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.txt b/test/standalone/config_header/autoconf_at/autoconf_at.h similarity index 50% rename from test/standalone/config_header/autoconf_at/autoconf_at.txt rename to test/standalone/config_header/autoconf_at/autoconf_at.h index e35cb5f822ab889e727d0fd13fe263fedb8b24cd..a4bdeff7af89c8b3c8b14d19abfae016692a2249 100644 --- a/test/standalone/config_header/autoconf_at/autoconf_at.txt +++ b/test/standalone/config_header/autoconf_at/autoconf_at.h @@ -1,49 +1,63 @@ /* This file was generated by ConfigHeader using the Zig Build System. */ +/* Some Comment */ +int foo(); // empty strings are preserved // line with misc content is preserved -no substitution +#define KEPT_VALUE no substitution + // empty @ sigils are preserved -@ -@@ -@@@ -@@@@ +#define AT_SIGIL_1 @ +#define AT_SIGIL_2 @@ +#define AT_SIGIL_3 @@@ +#define AT_SIGIL_4 @@@@ + // simple substitution +#define SIMPLE_UNDEFINED +#define SIMPLE_DEFINED +#define SIMPLE_BOOL_TRUE 1 +#define SIMPLE_BOOL_FALSE 0 +#define SIMPLE_INTEGER 42 +#define SIMPLE_STRING text - -1 -0 -42 -text // double packed substitution -texttext +#define DOUBLE_PACKED texttext + // triple packed substitution -text42text +#define TRIPLE_PACKED text42text + // double separated substitution -42.42 +#define DOUBLE_SEPARATED 42.42 + // triple separated substitution -42.1.42 +#define TRIPLE_SEPARATED 42.1.42 + // misc prefix is preserved -false is 0 +#define MISC_PREFIX false is 0 + // misc suffix is preserved -1 is true +#define MISC_SUFFIX 1 is true + // surrounding content is preserved -what is 6*7? 42! +#define SURROUNDING what is 6*7? 42! + // incomplete key is preserved -@undefined +#define INCOMPLETE_KEY @undefined + // @-vars resolved only when they wrap valid characters, otherwise considered literals -@text@ +#define DOUBLE_WRAPPED @text@ + // expanded variables are considered strings after expansion -@string@ +#define EXPANDED_STRING @string@ // variable name with underscores -value +#define UNDERSCORED_VAR value // backslash before at-sigil does not prevent resolution -\text +#define BACKSLASH_AT \text // value that is an at-sign itself -@ +#define AT_SIGN_VALUE @ // incomplete key mid-line is preserved, trailing content kept -@incomplete trailing content +#define INCOMPLETE_MID @incomplete trailing content diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.h.in b/test/standalone/config_header/autoconf_at/autoconf_at.h.in new file mode 100644 index 0000000000000000000000000000000000000000..3c7967a61eba0ba3e2276cd19eedf12bb466f118 --- /dev/null +++ b/test/standalone/config_header/autoconf_at/autoconf_at.h.in @@ -0,0 +1,62 @@ +/* Some Comment */ +int foo(); +// empty strings are preserved + +// line with misc content is preserved +#define KEPT_VALUE no substitution + +// empty @ sigils are preserved +#define AT_SIGIL_1 @ +#define AT_SIGIL_2 @@ +#define AT_SIGIL_3 @@@ +#define AT_SIGIL_4 @@@@ + +// simple substitution +#define SIMPLE_UNDEFINED @undefined@ +#define SIMPLE_DEFINED @defined@ +#define SIMPLE_BOOL_TRUE @boolean_true@ +#define SIMPLE_BOOL_FALSE @boolean_false@ +#define SIMPLE_INTEGER @integer@ +#define SIMPLE_STRING @string@ + +// double packed substitution +#define DOUBLE_PACKED @string@@string@ + +// triple packed substitution +#define TRIPLE_PACKED @string@@integer@@string@ + +// double separated substitution +#define DOUBLE_SEPARATED @integer@.@integer@ + +// triple separated substitution +#define TRIPLE_SEPARATED @integer@.@boolean_true@.@integer@ + +// misc prefix is preserved +#define MISC_PREFIX false is @boolean_false@ + +// misc suffix is preserved +#define MISC_SUFFIX @boolean_true@ is true + +// surrounding content is preserved +#define SURROUNDING what is 6*7? @integer@! + +// incomplete key is preserved +#define INCOMPLETE_KEY @undefined + +// @-vars resolved only when they wrap valid characters, otherwise considered literals +#define DOUBLE_WRAPPED @@string@@ + +// expanded variables are considered strings after expansion +#define EXPANDED_STRING @string_at@ + +// variable name with underscores +#define UNDERSCORED_VAR @underscored_var@ + +// backslash before at-sigil does not prevent resolution +#define BACKSLASH_AT \@string@ + +// value that is an at-sign itself +#define AT_SIGN_VALUE @at_sign@ + +// incomplete key mid-line is preserved, trailing content kept +#define INCOMPLETE_MID @incomplete trailing content diff --git a/test/standalone/config_header/autoconf_at/autoconf_at.txt.in b/test/standalone/config_header/autoconf_at/autoconf_at.txt.in deleted file mode 100644 index 77d15622e8223e3e51ccc66889deb2b0d79b563b..0000000000000000000000000000000000000000 --- a/test/standalone/config_header/autoconf_at/autoconf_at.txt.in +++ /dev/null @@ -1,48 +0,0 @@ -// empty strings are preserved - -// line with misc content is preserved -no substitution -// empty @ sigils are preserved -@ -@@ -@@@ -@@@@ -// simple substitution -@undefined@ -@defined@ -@boolean_true@ -@boolean_false@ -@integer@ -@string@ -// double packed substitution -@string@@string@ -// triple packed substitution -@string@@integer@@string@ -// double separated substitution -@integer@.@integer@ -// triple separated substitution -@integer@.@boolean_true@.@integer@ -// misc prefix is preserved -false is @boolean_false@ -// misc suffix is preserved -@boolean_true@ is true -// surrounding content is preserved -what is 6*7? @integer@! -// incomplete key is preserved -@undefined -// @-vars resolved only when they wrap valid characters, otherwise considered literals -@@string@@ -// expanded variables are considered strings after expansion -@string_at@ - -// variable name with underscores -@underscored_var@ - -// backslash before at-sigil does not prevent resolution -\@string@ - -// value that is an at-sign itself -@at_sign@ - -// incomplete key mid-line is preserved, trailing content kept -@incomplete trailing content diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index 95daf60c28ea3aa5032377c7cb5c14f082a622a9..84439ba34cd7d97ae6cef9c9df99e2e0e9df5cd3 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -30,7 +30,7 @@ pub fn build(b: *std.Build) void { }); const config_header_autoconf_at = b.addConfigHeader( - .{ .style = .{ .autoconf_at = b.path("autoconf_at/autoconf_at.txt.in") } }, + .{ .style = .{ .autoconf_at = b.path("autoconf_at/autoconf_at.h.in") } }, .{ .undefined = null, .defined = {}, @@ -45,7 +45,7 @@ pub fn build(b: *std.Build) void { }, ); const check_config_header_autoconf_at = b.addCheckFile(config_header_autoconf_at.getOutputFile(), .{ - .expected_exact = @embedFile("autoconf_at/autoconf_at.txt"), + .expected_exact = @embedFile("autoconf_at/autoconf_at.h"), }); test_step.dependOn(&check_config_header.step); -- 2.54.0 From cae8952548518c9504ca40f5212cafa79622f04b Mon Sep 17 00:00:00 2001 From: fardragon Date: Fri, 5 Jun 2026 23:06:41 +0200 Subject: [PATCH 11/12] Work around multiline string literals weirdness --- lib/compiler/Maker/Step/ConfigHeader.zig | 12 ++++-------- test/standalone/config_header/build.zig | 7 +------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/compiler/Maker/Step/ConfigHeader.zig b/lib/compiler/Maker/Step/ConfigHeader.zig index a483ef7bd5cb86cdd2215e6ddacae1a3be692aef..f0c2d27b371eb4fed9e701d6377b5206ba31773a 100644 --- a/lib/compiler/Maker/Step/ConfigHeader.zig +++ b/lib/compiler/Maker/Step/ConfigHeader.zig @@ -392,17 +392,13 @@ fn renderBlank( }; try w.print( - \\#ifndef {[0]f} - \\#define {[0]f} - \\ - , .{include_guard_fmt}); + "#ifndef {[0]f}{[1]s}#define {[0]f}{[1]s}", + .{ include_guard_fmt, os_newline }, + ); for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, os_newline, name, pair.index); - try w.print( - \\#endif /* {f} */ - \\ - , .{include_guard_fmt}); + try w.print("#endif /* {f} */{s}", .{ include_guard_fmt, os_newline }); } const IncludeGuardFmt = struct { diff --git a/test/standalone/config_header/build.zig b/test/standalone/config_header/build.zig index 84439ba34cd7d97ae6cef9c9df99e2e0e9df5cd3..88297e12d3fbe6c620128c68dbf9d0a1681e9e57 100644 --- a/test/standalone/config_header/build.zig +++ b/test/standalone/config_header/build.zig @@ -16,18 +16,17 @@ pub fn build(b: *std.Build) void { .SOME_ENUM = @as(enum { foo, bar }, .foo), .SOME_ENUM_LITERAL = .@"test", .SOME_STRING = "test", - .PREFIX_SPACE = null, .PREFIX_TAB = null, .POSTFIX_SPACE = null, .POSTFIX_TAB = null, - .SOME_UNDERSCORED = true, }, ); const check_config_header = b.addCheckFile(config_header.getOutputFile(), .{ .expected_exact = @embedFile("autoconf_undef/config.h"), }); + test_step.dependOn(&check_config_header.step); const config_header_autoconf_at = b.addConfigHeader( .{ .style = .{ .autoconf_at = b.path("autoconf_at/autoconf_at.h.in") } }, @@ -39,7 +38,6 @@ pub fn build(b: *std.Build) void { .integer = 42, .string = "text", .string_at = "@string@", - .underscored_var = "value", .at_sign = "@", }, @@ -47,8 +45,6 @@ pub fn build(b: *std.Build) void { const check_config_header_autoconf_at = b.addCheckFile(config_header_autoconf_at.getOutputFile(), .{ .expected_exact = @embedFile("autoconf_at/autoconf_at.h"), }); - - test_step.dependOn(&check_config_header.step); test_step.dependOn(&check_config_header_autoconf_at.step); const config_header_blank = b.addConfigHeader( @@ -109,7 +105,6 @@ fn addCmakeChecks(b: *std.Build, test_step: *std.Build.Step) void { .ONEVAL = 1, .TENVAL = 10, .STRINGVAL = "test", - .BOOLNOVAL = {}, .BOOLTRUEVAL = true, .BOOLFALSEVAL = false, -- 2.54.0 From 1467054baeaa05668129ef491be6ac1b3b82d80d Mon Sep 17 00:00:00 2001 From: fardragon Date: Sat, 27 Jun 2026 11:28:21 +0200 Subject: [PATCH 12/12] In newline detection handle files that contain newlines, but don't end in one --- lib/compiler/Maker/Step/ConfigHeader.zig | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/compiler/Maker/Step/ConfigHeader.zig b/lib/compiler/Maker/Step/ConfigHeader.zig index f0c2d27b371eb4fed9e701d6377b5206ba31773a..e0fde54d54b88297e7033627da8a39d3f895ae6a 100644 --- a/lib/compiler/Maker/Step/ConfigHeader.zig +++ b/lib/compiler/Maker/Step/ConfigHeader.zig @@ -163,12 +163,8 @@ fn ensureAllValuesUsed( } fn detectNewline(contents: []const u8) []const u8 { - return if (std.mem.endsWith(u8, contents, "\r\n")) - "\r\n" - else if (std.mem.endsWith(u8, contents, "\n")) - "\n" - else - os_newline; + const lf_index = std.mem.findScalar(u8, contents, '\n') orelse return os_newline; + return if (lf_index > 0 and contents[lf_index - 1] == '\r') "\r\n" else "\n"; } fn renderAutoConfUndef( -- 2.54.0