diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 438805508f..f1d03d2361 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -633,6 +633,10 @@ fn expand_variables_cmake( continue :loop; }, + '\\' => { + // backslash is not considered a special character + continue :loop; + }, else => {}, } @@ -811,3 +815,23 @@ test "expand_variables_cmake edge cases" { try std.testing.expectError(error.InvalidCharacter, testReplaceVariables(allocator, "${str$ing}", "", values)); try std.testing.expectError(error.InvalidCharacter, testReplaceVariables(allocator, "${str@ing}", "", values)); } + +test "expand_variables_cmake escaped characters" { + const allocator = std.testing.allocator; + var values = std.StringArrayHashMap(Value).init(allocator); + defer values.deinit(); + + try values.putNoClobber("string", Value{ .string = "text" }); + + // backslash is an invalid character for @ lookup + try testReplaceVariables(allocator, "\\@string\\@", "\\@string\\@", values); + + // backslash is preserved, but doesn't affect ${} variable expansion + try testReplaceVariables(allocator, "\\${string}", "\\text", values); + + // backslash breaks ${} opening bracket identification + try testReplaceVariables(allocator, "$\\{string}", "$\\{string}", values); + + // backslash is skipped when checking for invalid characters, yet it mangles the key + try testReplaceVariables(allocator, "${string\\}", "", values); +} diff --git a/test/standalone/cmakedefine/expected_wrapper.h b/test/standalone/cmakedefine/expected_wrapper.h index ad052b20fd..0fa39ba64e 100644 --- a/test/standalone/cmakedefine/expected_wrapper.h +++ b/test/standalone/cmakedefine/expected_wrapper.h @@ -28,3 +28,8 @@ // becomes `empty` #define #define + +#define \@STRING_VAR\@ +#define \${STRING} +#define $\{STRING_VAR} +#define diff --git a/test/standalone/cmakedefine/wrapper.h.in b/test/standalone/cmakedefine/wrapper.h.in index 8985186c19..c7323867e1 100644 --- a/test/standalone/cmakedefine/wrapper.h.in +++ b/test/standalone/cmakedefine/wrapper.h.in @@ -28,3 +28,8 @@ // becomes `empty` #define ${${STRING_VAR}} #define ${@STRING_VAR@} + +#define \@STRING_VAR\@ +#define \${STRING_VAR} +#define $\{STRING_VAR} +#define ${STRING_VAR\}