authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-27 12:38:02-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-27 12:38:02-08:00
log608d5e6fb7d7ebca871207a151421e7b9016c3d2
tree3d8e46a9d571ee03df8c7581165f4fa3e8c400cd
parent87733171b60b0816e93c76419d10674ba10684e2
parentc84e086a2f3d7f45eade35de1bfb32c34c1d8ecf
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #18676 from MrDmitry/feat/improve_cmake_replace_values

std.Build.Step.ConfigHeader (cmake): rewrite variable expansion

14 files changed, 761 insertions(+), 352 deletions(-)

lib/std/Build/Step/ConfigHeader.zig+308-49
......@@ -7,7 +7,7 @@ pub const Style = union(enum) {
77 /// The configure format supported by autotools. It uses `#undef foo` to
88 /// mark lines that can be substituted with different values.
99 autoconf: std.Build.LazyPath,
10 /// The configure format supported by CMake. It uses `@@FOO@@` and
10 /// The configure format supported by CMake. It uses `@FOO@`, `${}` and
1111 /// `#cmakedefine` for template substitution.
1212 cmake: std.Build.LazyPath,
1313 /// Instead of starting with an input file, start with nothing.
......@@ -313,10 +313,22 @@ fn render_cmake(
313313 while (line_it.next()) |raw_line| : (line_index += 1) {
314314 const last_line = line_it.index == line_it.buffer.len;
315315
316 const first_pass = replace_variables(allocator, raw_line, values, "@", "@") catch @panic("Failed to substitute");
317 const line = replace_variables(allocator, first_pass, values, "${", "}") catch @panic("Failed to substitute");
318
319 allocator.free(first_pass);
316 const line = expand_variables_cmake(allocator, raw_line, values) catch |err| switch (err) {
317 error.InvalidCharacter => {
318 try step.addError("{s}:{d}: error: invalid character in a variable name", .{
319 src_path, line_index + 1,
320 });
321 any_errors = true;
322 continue;
323 },
324 else => {
325 try step.addError("{s}:{d}: unable to substitute variable: error: {s}", .{
326 src_path, line_index + 1, @errorName(err),
327 });
328 any_errors = true;
329 continue;
330 },
331 };
320332 defer allocator.free(line);
321333
322334 if (!std.mem.startsWith(u8, line, "#")) {
......@@ -514,64 +526,311 @@ fn renderValueNasm(output: *std.ArrayList(u8), name: []const u8, value: Value) !
514526 }
515527}
516528
517fn replace_variables(
529fn expand_variables_cmake(
518530 allocator: Allocator,
519531 contents: []const u8,
520532 values: std.StringArrayHashMap(Value),
521 prefix: []const u8,
522 suffix: []const u8,
523533) ![]const u8 {
524 var content_buf = allocator.dupe(u8, contents) catch @panic("OOM");
534 var result = std.ArrayList(u8).init(allocator);
535 errdefer result.deinit();
525536
526 var last_index: usize = 0;
527 while (std.mem.indexOfPos(u8, content_buf, last_index, prefix)) |prefix_index| {
528 const start_index = prefix_index + prefix.len;
529 if (std.mem.indexOfPos(u8, content_buf, start_index, suffix)) |suffix_index| {
530 const end_index = suffix_index + suffix.len;
537 const valid_varname_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/_.+-";
538 const open_var = "${";
531539
532 const beginline = content_buf[0..prefix_index];
533 const endline = content_buf[end_index..];
534 const key = content_buf[start_index..suffix_index];
535 const value = values.get(key) orelse .undef;
540 var curr: usize = 0;
541 var source_offset: usize = 0;
542 const Position = struct {
543 source: usize,
544 target: usize,
545 };
546 var var_stack = std.ArrayList(Position).init(allocator);
547 defer var_stack.deinit();
548 loop: while (curr < contents.len) : (curr += 1) {
549 switch (contents[curr]) {
550 '@' => blk: {
551 if (std.mem.indexOfScalarPos(u8, contents, curr + 1, '@')) |close_pos| {
552 if (close_pos == curr + 1) {
553 // closed immediately, preserve as a literal
554 break :blk;
555 }
556 const valid_varname_end = std.mem.indexOfNonePos(u8, contents, curr + 1, valid_varname_chars) orelse 0;
557 if (valid_varname_end != close_pos) {
558 // contains invalid characters, preserve as a literal
559 break :blk;
560 }
536561
537 switch (value) {
538 .boolean => |b| {
539 const buf = try std.fmt.allocPrint(allocator, "{s}{}{s}", .{ beginline, @intFromBool(b), endline });
540 last_index = prefix_index + 1;
562 const key = contents[curr + 1 .. close_pos];
563 const value = values.get(key) orelse .undef;
564 const missing = contents[source_offset..curr];
565 try result.appendSlice(missing);
566 switch (value) {
567 .undef, .defined => {},
568 .boolean => |b| {
569 try result.append(if (b) '1' else '0');
570 },
571 .int => |i| {
572 try result.writer().print("{d}", .{i});
573 },
574 .ident, .string => |s| {
575 try result.appendSlice(s);
576 },
577 }
541578
542 allocator.free(content_buf);
543 content_buf = buf;
544 },
545 .int => |i| {
546 const buf = try std.fmt.allocPrint(allocator, "{s}{}{s}", .{ beginline, i, endline });
547 const isNegative = i < 0;
548 const digits = (if (0 < i) std.math.log10(@abs(i)) else 0) + 1;
549 last_index = prefix_index + @intFromBool(isNegative) + digits;
579 curr = close_pos;
580 source_offset = close_pos + 1;
550581
551 allocator.free(content_buf);
552 content_buf = buf;
553 },
554 .string, .ident => |x| {
555 const buf = try std.fmt.allocPrint(allocator, "{s}{s}{s}", .{ beginline, x, endline });
556 last_index = prefix_index + x.len;
582 continue :loop;
583 }
584 },
585 '$' => blk: {
586 const next = curr + 1;
587 if (next == contents.len or contents[next] != '{') {
588 // no open bracket detected, preserve as a literal
589 break :blk;
590 }
591 const missing = contents[source_offset..curr];
592 try result.appendSlice(missing);
593 try result.appendSlice(open_var);
594
595 source_offset = curr + open_var.len;
596 curr = next;
597 try var_stack.append(Position{
598 .source = curr,
599 .target = result.items.len - open_var.len,
600 });
601
602 continue :loop;
603 },
604 '}' => blk: {
605 if (var_stack.items.len == 0) {
606 // no open bracket, preserve as a literal
607 break :blk;
608 }
609 const open_pos = var_stack.pop();
610 if (source_offset == open_pos.source) {
611 source_offset += open_var.len;
612 }
613 const missing = contents[source_offset..curr];
614 try result.appendSlice(missing);
557615
558 allocator.free(content_buf);
559 content_buf = buf;
560 },
616 const key_start = open_pos.target + open_var.len;
617 const key = result.items[key_start..];
618 const value = values.get(key) orelse .undef;
619 result.shrinkRetainingCapacity(result.items.len - key.len - open_var.len);
620 switch (value) {
621 .undef, .defined => {},
622 .boolean => |b| {
623 try result.append(if (b) '1' else '0');
624 },
625 .int => |i| {
626 try result.writer().print("{d}", .{i});
627 },
628 .ident, .string => |s| {
629 try result.appendSlice(s);
630 },
631 }
561632
562 else => {
563 const buf = try std.fmt.allocPrint(allocator, "{s}{s}", .{ beginline, endline });
564 last_index = prefix_index;
633 source_offset = curr + 1;
565634
566 allocator.free(content_buf);
567 content_buf = buf;
568 },
569 }
570 continue;
635 continue :loop;
636 },
637 '\\' => {
638 // backslash is not considered a special character
639 continue :loop;
640 },
641 else => {},
642 }
643
644 if (var_stack.items.len > 0 and std.mem.indexOfScalar(u8, valid_varname_chars, contents[curr]) == null) {
645 return error.InvalidCharacter;
571646 }
647 }
572648
573 last_index = start_index + 1;
649 if (source_offset != contents.len) {
650 const missing = contents[source_offset..];
651 try result.appendSlice(missing);
574652 }
575653
576 return content_buf;
654 return result.toOwnedSlice();
655}
656
657fn testReplaceVariables(
658 allocator: Allocator,
659 contents: []const u8,
660 expected: []const u8,
661 values: std.StringArrayHashMap(Value),
662) !void {
663 const actual = try expand_variables_cmake(allocator, contents, values);
664 defer allocator.free(actual);
665
666 try std.testing.expectEqualStrings(expected, actual);
667}
668
669test "expand_variables_cmake simple cases" {
670 const allocator = std.testing.allocator;
671 var values = std.StringArrayHashMap(Value).init(allocator);
672 defer values.deinit();
673
674 try values.putNoClobber("undef", .undef);
675 try values.putNoClobber("defined", .defined);
676 try values.putNoClobber("true", Value{ .boolean = true });
677 try values.putNoClobber("false", Value{ .boolean = false });
678 try values.putNoClobber("int", Value{ .int = 42 });
679 try values.putNoClobber("ident", Value{ .string = "value" });
680 try values.putNoClobber("string", Value{ .string = "text" });
681
682 // empty strings are preserved
683 try testReplaceVariables(allocator, "", "", values);
684
685 // line with misc content is preserved
686 try testReplaceVariables(allocator, "no substitution", "no substitution", values);
687
688 // empty ${} wrapper is removed
689 try testReplaceVariables(allocator, "${}", "", values);
690
691 // empty @ sigils are preserved
692 try testReplaceVariables(allocator, "@", "@", values);
693 try testReplaceVariables(allocator, "@@", "@@", values);
694 try testReplaceVariables(allocator, "@@@", "@@@", values);
695 try testReplaceVariables(allocator, "@@@@", "@@@@", values);
696
697 // simple substitution
698 try testReplaceVariables(allocator, "@undef@", "", values);
699 try testReplaceVariables(allocator, "${undef}", "", values);
700 try testReplaceVariables(allocator, "@defined@", "", values);
701 try testReplaceVariables(allocator, "${defined}", "", values);
702 try testReplaceVariables(allocator, "@true@", "1", values);
703 try testReplaceVariables(allocator, "${true}", "1", values);
704 try testReplaceVariables(allocator, "@false@", "0", values);
705 try testReplaceVariables(allocator, "${false}", "0", values);
706 try testReplaceVariables(allocator, "@int@", "42", values);
707 try testReplaceVariables(allocator, "${int}", "42", values);
708 try testReplaceVariables(allocator, "@ident@", "value", values);
709 try testReplaceVariables(allocator, "${ident}", "value", values);
710 try testReplaceVariables(allocator, "@string@", "text", values);
711 try testReplaceVariables(allocator, "${string}", "text", values);
712
713 // double packed substitution
714 try testReplaceVariables(allocator, "@string@@string@", "texttext", values);
715 try testReplaceVariables(allocator, "${string}${string}", "texttext", values);
716
717 // triple packed substitution
718 try testReplaceVariables(allocator, "@string@@int@@string@", "text42text", values);
719 try testReplaceVariables(allocator, "@string@${int}@string@", "text42text", values);
720 try testReplaceVariables(allocator, "${string}@int@${string}", "text42text", values);
721 try testReplaceVariables(allocator, "${string}${int}${string}", "text42text", values);
722
723 // double separated substitution
724 try testReplaceVariables(allocator, "@int@.@int@", "42.42", values);
725 try testReplaceVariables(allocator, "${int}.${int}", "42.42", values);
726
727 // triple separated substitution
728 try testReplaceVariables(allocator, "@int@.@true@.@int@", "42.1.42", values);
729 try testReplaceVariables(allocator, "@int@.${true}.@int@", "42.1.42", values);
730 try testReplaceVariables(allocator, "${int}.@true@.${int}", "42.1.42", values);
731 try testReplaceVariables(allocator, "${int}.${true}.${int}", "42.1.42", values);
732
733 // misc prefix is preserved
734 try testReplaceVariables(allocator, "false is @false@", "false is 0", values);
735 try testReplaceVariables(allocator, "false is ${false}", "false is 0", values);
736
737 // misc suffix is preserved
738 try testReplaceVariables(allocator, "@true@ is true", "1 is true", values);
739 try testReplaceVariables(allocator, "${true} is true", "1 is true", values);
740
741 // surrounding content is preserved
742 try testReplaceVariables(allocator, "what is 6*7? @int@!", "what is 6*7? 42!", values);
743 try testReplaceVariables(allocator, "what is 6*7? ${int}!", "what is 6*7? 42!", values);
744
745 // incomplete key is preserved
746 try testReplaceVariables(allocator, "@undef", "@undef", values);
747 try testReplaceVariables(allocator, "${undef", "${undef", values);
748 try testReplaceVariables(allocator, "{undef}", "{undef}", values);
749 try testReplaceVariables(allocator, "undef@", "undef@", values);
750 try testReplaceVariables(allocator, "undef}", "undef}", values);
751
752 // unknown key is removed
753 try testReplaceVariables(allocator, "@bad@", "", values);
754 try testReplaceVariables(allocator, "${bad}", "", values);
755}
756
757test "expand_variables_cmake edge cases" {
758 const allocator = std.testing.allocator;
759 var values = std.StringArrayHashMap(Value).init(allocator);
760 defer values.deinit();
761
762 // special symbols
763 try values.putNoClobber("at", Value{ .string = "@" });
764 try values.putNoClobber("dollar", Value{ .string = "$" });
765 try values.putNoClobber("underscore", Value{ .string = "_" });
766
767 // basic value
768 try values.putNoClobber("string", Value{ .string = "text" });
769
770 // proxy case values
771 try values.putNoClobber("string_proxy", Value{ .string = "string" });
772 try values.putNoClobber("string_at", Value{ .string = "@string@" });
773 try values.putNoClobber("string_curly", Value{ .string = "{string}" });
774 try values.putNoClobber("string_var", Value{ .string = "${string}" });
775
776 // stack case values
777 try values.putNoClobber("nest_underscore_proxy", Value{ .string = "underscore" });
778 try values.putNoClobber("nest_proxy", Value{ .string = "nest_underscore_proxy" });
779
780 // @-vars resolved only when they wrap valid characters, otherwise considered literals
781 try testReplaceVariables(allocator, "@@string@@", "@text@", values);
782 try testReplaceVariables(allocator, "@${string}@", "@text@", values);
783
784 // @-vars are resolved inside ${}-vars
785 try testReplaceVariables(allocator, "${@string_proxy@}", "text", values);
786
787 // expanded variables are considered strings after expansion
788 try testReplaceVariables(allocator, "@string_at@", "@string@", values);
789 try testReplaceVariables(allocator, "${string_at}", "@string@", values);
790 try testReplaceVariables(allocator, "$@string_curly@", "${string}", values);
791 try testReplaceVariables(allocator, "$${string_curly}", "${string}", values);
792 try testReplaceVariables(allocator, "${string_var}", "${string}", values);
793 try testReplaceVariables(allocator, "@string_var@", "${string}", values);
794 try testReplaceVariables(allocator, "${dollar}{${string}}", "${text}", values);
795 try testReplaceVariables(allocator, "@dollar@{${string}}", "${text}", values);
796 try testReplaceVariables(allocator, "@dollar@{@string@}", "${text}", values);
797
798 // when expanded variables contain invalid characters, they prevent further expansion
799 try testReplaceVariables(allocator, "${${string_var}}", "", values);
800 try testReplaceVariables(allocator, "${@string_var@}", "", values);
801
802 // nested expanded variables are expanded from the inside out
803 try testReplaceVariables(allocator, "${string${underscore}proxy}", "string", values);
804 try testReplaceVariables(allocator, "${string@underscore@proxy}", "string", values);
805
806 // nested vars are only expanded when ${} is closed
807 try testReplaceVariables(allocator, "@nest@underscore@proxy@", "underscore", values);
808 try testReplaceVariables(allocator, "${nest${underscore}proxy}", "nest_underscore_proxy", values);
809 try testReplaceVariables(allocator, "@nest@@nest_underscore@underscore@proxy@@proxy@", "underscore", values);
810 try testReplaceVariables(allocator, "${nest${${nest_underscore${underscore}proxy}}proxy}", "nest_underscore_proxy", values);
811
812 // invalid characters lead to an error
813 try std.testing.expectError(error.InvalidCharacter, testReplaceVariables(allocator, "${str*ing}", "", values));
814 try std.testing.expectError(error.InvalidCharacter, testReplaceVariables(allocator, "${str$ing}", "", values));
815 try std.testing.expectError(error.InvalidCharacter, testReplaceVariables(allocator, "${str@ing}", "", values));
816}
817
818test "expand_variables_cmake escaped characters" {
819 const allocator = std.testing.allocator;
820 var values = std.StringArrayHashMap(Value).init(allocator);
821 defer values.deinit();
822
823 try values.putNoClobber("string", Value{ .string = "text" });
824
825 // backslash is an invalid character for @ lookup
826 try testReplaceVariables(allocator, "\\@string\\@", "\\@string\\@", values);
827
828 // backslash is preserved, but doesn't affect ${} variable expansion
829 try testReplaceVariables(allocator, "\\${string}", "\\text", values);
830
831 // backslash breaks ${} opening bracket identification
832 try testReplaceVariables(allocator, "$\\{string}", "$\\{string}", values);
833
834 // backslash is skipped when checking for invalid characters, yet it mangles the key
835 try testReplaceVariables(allocator, "${string\\}", "", values);
577836}
test/standalone/cmakedefine/build.zig+67-13
......@@ -4,7 +4,8 @@ const ConfigHeader = std.Build.Step.ConfigHeader;
44pub fn build(b: *std.Build) void {
55 const config_header = b.addConfigHeader(
66 .{
7 .style = .{ .cmake = .{ .path = "config.h.cmake" } },
7 .style = .{ .cmake = .{ .path = "config.h.in" } },
8 .include_path = "config.h",
89 },
910 .{
1011 .noval = null,
......@@ -25,32 +26,85 @@ pub fn build(b: *std.Build) void {
2526 },
2627 );
2728
29 const pwd_sh = b.addConfigHeader(
30 .{
31 .style = .{ .cmake = .{ .path = "pwd.sh.in" } },
32 .include_path = "pwd.sh",
33 },
34 .{ .DIR = "${PWD}" },
35 );
36
37 const sigil_header = b.addConfigHeader(
38 .{
39 .style = .{ .cmake = .{ .path = "sigil.h.in" } },
40 .include_path = "sigil.h",
41 },
42 .{},
43 );
44
45 const stack_header = b.addConfigHeader(
46 .{
47 .style = .{ .cmake = .{ .path = "stack.h.in" } },
48 .include_path = "stack.h",
49 },
50 .{
51 .AT = "@",
52 .UNDERSCORE = "_",
53 .NEST_UNDERSCORE_PROXY = "UNDERSCORE",
54 .NEST_PROXY = "NEST_UNDERSCORE_PROXY",
55 },
56 );
57
58 const wrapper_header = b.addConfigHeader(
59 .{
60 .style = .{ .cmake = .{ .path = "wrapper.h.in" } },
61 .include_path = "wrapper.h",
62 },
63 .{
64 .DOLLAR = "$",
65 .TEXT = "TRAP",
66
67 .STRING = "TEXT",
68 .STRING_AT = "@STRING@",
69 .STRING_CURLY = "{STRING}",
70 .STRING_VAR = "${STRING}",
71 },
72 );
73
2874 const test_step = b.step("test", "Test it");
2975 test_step.makeFn = compare_headers;
3076 test_step.dependOn(&config_header.step);
77 test_step.dependOn(&pwd_sh.step);
78 test_step.dependOn(&sigil_header.step);
79 test_step.dependOn(&stack_header.step);
80 test_step.dependOn(&wrapper_header.step);
3181}
3282
3383fn compare_headers(step: *std.Build.Step, prog_node: *std.Progress.Node) !void {
3484 _ = prog_node;
3585 const allocator = step.owner.allocator;
36 const cmake_header_path = "expected.h";
86 const expected_fmt = "expected_{s}";
87
88 for (step.dependencies.items) |config_header_step| {
89 const config_header = @fieldParentPtr(ConfigHeader, "step", config_header_step);
3790
38 const config_header_step = step.dependencies.getLast();
39 const config_header = @fieldParentPtr(ConfigHeader, "step", config_header_step);
91 const zig_header_path = config_header.output_file.path orelse @panic("Could not locate header file");
4092
41 const zig_header_path = config_header.output_file.path orelse @panic("Could not locate header file");
93 const cwd = std.fs.cwd();
4294
43 const cwd = std.fs.cwd();
95 const cmake_header_path = try std.fmt.allocPrint(allocator, expected_fmt, .{std.fs.path.basename(zig_header_path)});
96 defer allocator.free(cmake_header_path);
4497
45 const cmake_header = try cwd.readFileAlloc(allocator, cmake_header_path, config_header.max_bytes);
46 defer allocator.free(cmake_header);
98 const cmake_header = try cwd.readFileAlloc(allocator, cmake_header_path, config_header.max_bytes);
99 defer allocator.free(cmake_header);
47100
48 const zig_header = try cwd.readFileAlloc(allocator, zig_header_path, config_header.max_bytes);
49 defer allocator.free(zig_header);
101 const zig_header = try cwd.readFileAlloc(allocator, zig_header_path, config_header.max_bytes);
102 defer allocator.free(zig_header);
50103
51 const header_text_index = std.mem.indexOf(u8, zig_header, "\n") orelse @panic("Could not find comment in header filer");
104 const header_text_index = std.mem.indexOf(u8, zig_header, "\n") orelse @panic("Could not find comment in header filer");
52105
53 if (!std.mem.eql(u8, zig_header[header_text_index + 1 ..], cmake_header)) {
54 @panic("processed cmakedefine header does not match expected output");
106 if (!std.mem.eql(u8, zig_header[header_text_index + 1 ..], cmake_header)) {
107 @panic("processed cmakedefine header does not match expected output");
108 }
55109 }
56110}
test/standalone/cmakedefine/config.h.cmake deleted-145
......@@ -1,145 +0,0 @@
1// cmakedefine
2// undefined
3#cmakedefine noval unreachable
4
5// 1
6#cmakedefine trueval 1
7
8// undefined
9#cmakedefine falseval unreachable
10
11// undefined
12#cmakedefine zeroval unreachable
13
14// 1
15#cmakedefine oneval 1
16
17// 1
18#cmakedefine tenval 1
19
20// 1
21#cmakedefine stringval 1
22
23
24// cmakedefine01
25// 0
26#cmakedefine01 boolnoval
27
28// 1
29#cmakedefine01 booltrueval
30
31// 0
32#cmakedefine01 boolfalseval
33
34// 0
35#cmakedefine01 boolzeroval
36
37// 1
38#cmakedefine01 booloneval
39
40// 1
41#cmakedefine01 booltenval
42
43// 1
44#cmakedefine01 boolstringval
45
46
47// @ substition
48
49// no substition
50// @noval@
51
52// no substition
53// @noval@@noval@
54
55// no substition
56// @noval@.@noval@
57
58// 1
59// @trueval@
60
61// 0
62// @falseval@
63
64// 10
65// @trueval@@falseval@
66
67// 0.1
68// @falseval@.@trueval@
69
70// 0
71// @zeroval@
72
73// 1
74// @oneval@
75
76// 10
77// @tenval@
78
79// 01
80// @zeroval@@oneval@
81
82// 0.10
83// @zeroval@.@tenval@
84
85// test
86// @stringval@
87
88// testtest
89// @stringval@@stringval@
90
91// test.test
92// @stringval@.@stringval@
93
94// test10
95// @noval@@stringval@@trueval@@zeroval@
96
97// ${} substition
98
99// no substition
100// ${noval}
101
102// no substition
103// ${noval}${noval}
104
105// no substition
106// ${noval}.${noval}
107
108// 1
109// ${trueval}
110
111// 0
112// ${falseval}
113
114// 10
115// ${trueval}${falseval}
116
117// 0.1
118// ${falseval}.${trueval}
119
120// 0
121// ${zeroval}
122
123// 1
124// ${oneval}
125
126// 10
127// ${tenval}
128
129// 01
130// ${zeroval}${oneval}
131
132// 0.10
133// ${zeroval}.${tenval}
134
135// test
136// ${stringval}
137
138// testtest
139// ${stringval}${stringval}
140
141// test.test
142// ${stringval}.${stringval}
143
144// test10
145// ${noval}${stringval}${trueval}${zeroval}
test/standalone/cmakedefine/config.h.in created+145
......@@ -0,0 +1,145 @@
1// cmakedefine
2// undefined
3#cmakedefine noval unreachable
4
5// 1
6#cmakedefine trueval 1
7
8// undefined
9#cmakedefine falseval unreachable
10
11// undefined
12#cmakedefine zeroval unreachable
13
14// 1
15#cmakedefine oneval 1
16
17// 1
18#cmakedefine tenval 1
19
20// 1
21#cmakedefine stringval 1
22
23
24// cmakedefine01
25// 0
26#cmakedefine01 boolnoval
27
28// 1
29#cmakedefine01 booltrueval
30
31// 0
32#cmakedefine01 boolfalseval
33
34// 0
35#cmakedefine01 boolzeroval
36
37// 1
38#cmakedefine01 booloneval
39
40// 1
41#cmakedefine01 booltenval
42
43// 1
44#cmakedefine01 boolstringval
45
46
47// @ substition
48
49// no substition
50// @noval@
51
52// no substition
53// @noval@@noval@
54
55// no substition
56// @noval@.@noval@
57
58// 1
59// @trueval@
60
61// 0
62// @falseval@
63
64// 10
65// @trueval@@falseval@
66
67// 0.1
68// @falseval@.@trueval@
69
70// 0
71// @zeroval@
72
73// 1
74// @oneval@
75
76// 10
77// @tenval@
78
79// 01
80// @zeroval@@oneval@
81
82// 0.10
83// @zeroval@.@tenval@
84
85// test
86// @stringval@
87
88// testtest
89// @stringval@@stringval@
90
91// test.test
92// @stringval@.@stringval@
93
94// test10
95// @noval@@stringval@@trueval@@zeroval@
96
97// ${} substition
98
99// no substition
100// ${noval}
101
102// no substition
103// ${noval}${noval}
104
105// no substition
106// ${noval}.${noval}
107
108// 1
109// ${trueval}
110
111// 0
112// ${falseval}
113
114// 10
115// ${trueval}${falseval}
116
117// 0.1
118// ${falseval}.${trueval}
119
120// 0
121// ${zeroval}
122
123// 1
124// ${oneval}
125
126// 10
127// ${tenval}
128
129// 01
130// ${zeroval}${oneval}
131
132// 0.10
133// ${zeroval}.${tenval}
134
135// test
136// ${stringval}
137
138// testtest
139// ${stringval}${stringval}
140
141// test.test
142// ${stringval}.${stringval}
143
144// test10
145// ${noval}${stringval}${trueval}${zeroval}
test/standalone/cmakedefine/expected.h deleted-145
......@@ -1,145 +0,0 @@
1// cmakedefine
2// undefined
3/* #undef noval */
4
5// 1
6#define trueval 1
7
8// undefined
9/* #undef falseval */
10
11// undefined
12/* #undef zeroval */
13
14// 1
15#define oneval 1
16
17// 1
18#define tenval 1
19
20// 1
21#define stringval 1
22
23
24// cmakedefine01
25// 0
26#define boolnoval 0
27
28// 1
29#define booltrueval 1
30
31// 0
32#define boolfalseval 0
33
34// 0
35#define boolzeroval 0
36
37// 1
38#define booloneval 1
39
40// 1
41#define booltenval 1
42
43// 1
44#define boolstringval 1
45
46
47// @ substition
48
49// no substition
50//
51
52// no substition
53//
54
55// no substition
56// .
57
58// 1
59// 1
60
61// 0
62// 0
63
64// 10
65// 10
66
67// 0.1
68// 0.1
69
70// 0
71// 0
72
73// 1
74// 1
75
76// 10
77// 10
78
79// 01
80// 01
81
82// 0.10
83// 0.10
84
85// test
86// test
87
88// testtest
89// testtest
90
91// test.test
92// test.test
93
94// test10
95// test10
96
97// substition
98
99// no substition
100//
101
102// no substition
103//
104
105// no substition
106// .
107
108// 1
109// 1
110
111// 0
112// 0
113
114// 10
115// 10
116
117// 0.1
118// 0.1
119
120// 0
121// 0
122
123// 1
124// 1
125
126// 10
127// 10
128
129// 01
130// 01
131
132// 0.10
133// 0.10
134
135// test
136// test
137
138// testtest
139// testtest
140
141// test.test
142// test.test
143
144// test10
145// test10
test/standalone/cmakedefine/expected_config.h created+145
......@@ -0,0 +1,145 @@
1// cmakedefine
2// undefined
3/* #undef noval */
4
5// 1
6#define trueval 1
7
8// undefined
9/* #undef falseval */
10
11// undefined
12/* #undef zeroval */
13
14// 1
15#define oneval 1
16
17// 1
18#define tenval 1
19
20// 1
21#define stringval 1
22
23
24// cmakedefine01
25// 0
26#define boolnoval 0
27
28// 1
29#define booltrueval 1
30
31// 0
32#define boolfalseval 0
33
34// 0
35#define boolzeroval 0
36
37// 1
38#define booloneval 1
39
40// 1
41#define booltenval 1
42
43// 1
44#define boolstringval 1
45
46
47// @ substition
48
49// no substition
50//
51
52// no substition
53//
54
55// no substition
56// .
57
58// 1
59// 1
60
61// 0
62// 0
63
64// 10
65// 10
66
67// 0.1
68// 0.1
69
70// 0
71// 0
72
73// 1
74// 1
75
76// 10
77// 10
78
79// 01
80// 01
81
82// 0.10
83// 0.10
84
85// test
86// test
87
88// testtest
89// testtest
90
91// test.test
92// test.test
93
94// test10
95// test10
96
97// substition
98
99// no substition
100//
101
102// no substition
103//
104
105// no substition
106// .
107
108// 1
109// 1
110
111// 0
112// 0
113
114// 10
115// 10
116
117// 0.1
118// 0.1
119
120// 0
121// 0
122
123// 1
124// 1
125
126// 10
127// 10
128
129// 01
130// 01
131
132// 0.10
133// 0.10
134
135// test
136// test
137
138// testtest
139// testtest
140
141// test.test
142// test.test
143
144// test10
145// test10
test/standalone/cmakedefine/expected_pwd.sh created+1
......@@ -0,0 +1 @@
1echo ${PWD}
test/standalone/cmakedefine/expected_sigil.h created+5
......@@ -0,0 +1,5 @@
1#define VAR
2#define AT @
3#define ATAT @@
4#define ATATAT @@@
5#define ATATATAT @@@@
test/standalone/cmakedefine/expected_stack.h created+7
......@@ -0,0 +1,7 @@
1#define NEST_UNDERSCORE_PROXY NEST_UNDERSCORE_PROXY
2#define UNDERSCORE UNDERSCORE
3
4#define NEST_UNDERSCORE_PROXY NEST_UNDERSCORE_PROXY
5#define UNDERSCORE UNDERSCORE
6
7#define (empty)
test/standalone/cmakedefine/expected_wrapper.h created+35
......@@ -0,0 +1,35 @@
1// becomes TEXT
2#define TEXT
3#define TEXT
4
5// becomes `at`TEXT`at`
6#define @TEXT@
7#define @TEXT@
8
9// becomes TRAP
10#define TRAP
11
12// becomes `dollar sign`{STRING}
13#define ${STRING}
14#define ${STRING}
15
16// becomes `dollar sign`{STRING}
17#define ${STRING}
18#define ${STRING}
19
20// becomes `dollar sign`{TEXT}
21#define ${TEXT}
22#define ${TEXT}
23
24// becomes `at`STRING`at`
25#define @STRING@
26#define @STRING@
27
28// becomes `empty`
29#define
30#define
31
32#define \@STRING_VAR\@
33#define \${STRING}
34#define $\{STRING_VAR}
35#define
test/standalone/cmakedefine/pwd.sh.in created+1
......@@ -0,0 +1 @@
1echo @DIR@
test/standalone/cmakedefine/sigil.h.in created+5
......@@ -0,0 +1,5 @@
1#define VAR ${}
2#define AT @
3#define ATAT @@
4#define ATATAT @@@
5#define ATATATAT @@@@
test/standalone/cmakedefine/stack.h.in created+7
......@@ -0,0 +1,7 @@
1#define NEST_UNDERSCORE_PROXY ${NEST${UNDERSCORE}PROXY}
2#define UNDERSCORE @NEST@UNDERSCORE@PROXY@
3
4#define NEST_UNDERSCORE_PROXY ${NEST${${NEST_UNDERSCORE${UNDERSCORE}PROXY}}PROXY}
5#define UNDERSCORE @NEST@@NEST_UNDERSCORE@UNDERSCORE@PROXY@@PROXY@
6
7#define (empty) ${NEST${${AT}UNDERSCORE${AT}}PROXY}
test/standalone/cmakedefine/wrapper.h.in created+35
......@@ -0,0 +1,35 @@
1// becomes TEXT
2#define @STRING@
3#define ${STRING}
4
5// becomes `at`TEXT`at`
6#define @${STRING}@
7#define @@STRING@@
8
9// becomes TRAP
10#define ${@STRING@}
11
12// becomes `dollar sign`{STRING}
13#define $@STRING_CURLY@
14#define $${STRING_CURLY}
15
16// becomes `dollar sign`{STRING}
17#define @STRING_VAR@
18#define ${STRING_VAR}
19
20// becomes `dollar sign`{TEXT}
21#define ${DOLLAR}{${STRING}}
22#define @DOLLAR@{${STRING}}
23
24// becomes `at`STRING`at`
25#define ${STRING_AT}
26#define @STRING_AT@
27
28// becomes `empty`
29#define ${${STRING_VAR}}
30#define ${@STRING_VAR@}
31
32#define \@STRING_VAR\@
33#define \${STRING_VAR}
34#define $\{STRING_VAR}
35#define ${STRING_VAR\}