authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-08 00:16:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:48:14-07:00
log030742f1f73d0c9a237d7512d894e88b05ad53af
treeb05b85401ffb09d9d7d5b6a86608394b67c0fbd1
parent15c4fae1c93d970d02a9eede96371fb7c053837f

re-enable standalone tests based on build.zig


44 files changed, 767 insertions(+), 648 deletions(-)

build.zig+1-3
......@@ -445,9 +445,7 @@ pub fn build(b: *std.Build) !void {
445445 test_step.dependOn(tests.addCompareOutputTests(b, test_filter, optimization_modes));
446446 test_step.dependOn(tests.addStandaloneTests(
447447 b,
448 test_filter,
449448 optimization_modes,
450 skip_non_native,
451449 enable_macos_sdk,
452450 skip_stage2_tests,
453451 enable_symlinks_windows,
......@@ -455,7 +453,7 @@ pub fn build(b: *std.Build) !void {
455453 test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
456454 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, skip_stage2_tests, enable_symlinks_windows));
457455 test_step.dependOn(tests.addStackTraceTests(b, test_filter, optimization_modes));
458 test_step.dependOn(tests.addCliTests(b, test_filter, optimization_modes));
456 test_step.dependOn(tests.addCliTests(b));
459457 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, optimization_modes));
460458 test_step.dependOn(tests.addTranslateCTests(b, test_filter));
461459 if (!skip_run_translated_c) {
test/standalone.zig+151-83
......@@ -3,6 +3,8 @@ pub const SimpleCase = struct {
33 link_libc: bool = false,
44 all_modes: bool = false,
55 target: std.zig.CrossTarget = .{},
6 is_test: bool = false,
7 is_exe: bool = true,
68};
79
810pub const BuildCase = struct {
......@@ -27,6 +29,17 @@ pub const simple_cases = [_]SimpleCase{
2729 //.{
2830 // .src_path = "test/standalone/issue_9693/main.zig",
2931 //},
32 .{
33 .src_path = "test/standalone/brace_expansion.zig",
34 .is_test = true,
35 },
36 .{
37 .src_path = "test/standalone/issue_7030.zig",
38 .target = .{
39 .cpu_arch = .wasm32,
40 .os_tag = .freestanding,
41 },
42 },
3043
3144 .{ .src_path = "test/standalone/issue_12471/main.zig" },
3245 .{ .src_path = "test/standalone/guess_number/main.zig" },
......@@ -57,88 +70,143 @@ pub const simple_cases = [_]SimpleCase{
5770 .{ .src_path = "tools/update_spirv_features.zig" },
5871};
5972
60pub const build_cases = [_]BuildCase{};
61
62//pub fn addCases(cases: *tests.StandaloneContext) void {
63// cases.addBuildFile("test/standalone/options/build.zig", .{
64// .extra_argv = &.{
65// "-Dbool_true",
66// "-Dbool_false=false",
67// "-Dint=1234",
68// "-De=two",
69// "-Dstring=hello",
70// },
71// });
72//
73// cases.addBuildFile("test/standalone/test_runner_path/build.zig", .{ .requires_stage2 = true });
74// cases.addBuildFile("test/standalone/issue_13970/build.zig", .{});
75// cases.addBuildFile("test/standalone/main_pkg_path/build.zig", .{});
76// cases.addBuildFile("test/standalone/shared_library/build.zig", .{});
77// cases.addBuildFile("test/standalone/mix_o_files/build.zig", .{});
78// cases.addBuildFile("test/standalone/mix_c_files/build.zig", .{
79// .build_modes = true,
80// .cross_targets = true,
81// });
82// cases.addBuildFile("test/standalone/global_linkage/build.zig", .{});
83// cases.addBuildFile("test/standalone/static_c_lib/build.zig", .{});
84// cases.addBuildFile("test/standalone/issue_339/build.zig", .{});
85// cases.addBuildFile("test/standalone/issue_8550/build.zig", .{});
86// cases.addBuildFile("test/standalone/issue_794/build.zig", .{});
87// cases.addBuildFile("test/standalone/issue_5825/build.zig", .{});
88// cases.addBuildFile("test/standalone/pkg_import/build.zig", .{});
89// cases.addBuildFile("test/standalone/use_alias/build.zig", .{});
90// cases.addBuildFile("test/standalone/brace_expansion/build.zig", .{});
91// if (builtin.os.tag != .windows or builtin.cpu.arch != .aarch64) {
92// // https://github.com/ziglang/zig/issues/13685
93// cases.addBuildFile("test/standalone/empty_env/build.zig", .{});
94// }
95// cases.addBuildFile("test/standalone/issue_7030/build.zig", .{});
96// cases.addBuildFile("test/standalone/install_raw_hex/build.zig", .{});
97// if (builtin.zig_backend == .stage1) { // https://github.com/ziglang/zig/issues/12194
98// cases.addBuildFile("test/standalone/issue_9812/build.zig", .{});
99// }
100// if (builtin.os.tag != .windows) {
101// // https://github.com/ziglang/zig/issues/12419
102// cases.addBuildFile("test/standalone/issue_11595/build.zig", .{});
103// }
104//
105// if (builtin.os.tag != .wasi and
106// // https://github.com/ziglang/zig/issues/13550
107// (builtin.os.tag != .macos or builtin.cpu.arch != .aarch64) and
108// // https://github.com/ziglang/zig/issues/13686
109// (builtin.os.tag != .windows or builtin.cpu.arch != .aarch64))
110// {
111// cases.addBuildFile("test/standalone/load_dynamic_library/build.zig", .{});
112// }
113//
114// if (builtin.os.tag == .windows) {
115// cases.addBuildFile("test/standalone/windows_spawn/build.zig", .{});
116// }
117//
118// cases.addBuildFile("test/standalone/c_compiler/build.zig", .{
119// .build_modes = true,
120// .cross_targets = true,
121// });
122//
123// // Try to build and run a PIE executable.
124// if (builtin.os.tag == .linux) {
125// cases.addBuildFile("test/standalone/pie/build.zig", .{});
126// }
127// cases.addBuildFile("test/standalone/issue_12706/build.zig", .{});
128// if (std.os.have_sigpipe_support) {
129// cases.addBuildFile("test/standalone/sigpipe/build.zig", .{});
130// }
131//
132// cases.addBuildFile("test/standalone/issue_13030/build.zig", .{ .build_modes = true });
133// cases.addBuildFile("test/standalone/emit_asm_and_bin/build.zig", .{});
134// cases.addBuildFile("test/standalone/issue_12588/build.zig", .{});
135// cases.addBuildFile("test/standalone/embed_generated_file/build.zig", .{});
136//
137// cases.addBuildFile("test/standalone/dep_diamond/build.zig", .{});
138// cases.addBuildFile("test/standalone/dep_triangle/build.zig", .{});
139// cases.addBuildFile("test/standalone/dep_recursive/build.zig", .{});
140// cases.addBuildFile("test/standalone/dep_mutually_recursive/build.zig", .{});
141// cases.addBuildFile("test/standalone/dep_shared_builtin/build.zig", .{});
142//}
73pub const build_cases = [_]BuildCase{
74 .{
75 .build_root = "test/standalone/test_runner_path",
76 .import = @import("standalone/test_runner_path/build.zig"),
77 },
78 .{
79 .build_root = "test/standalone/issue_13970",
80 .import = @import("standalone/issue_13970/build.zig"),
81 },
82 .{
83 .build_root = "test/standalone/main_pkg_path",
84 .import = @import("standalone/main_pkg_path/build.zig"),
85 },
86 .{
87 .build_root = "test/standalone/shared_library",
88 .import = @import("standalone/shared_library/build.zig"),
89 },
90 .{
91 .build_root = "test/standalone/mix_o_files",
92 .import = @import("standalone/mix_o_files/build.zig"),
93 },
94 .{
95 .build_root = "test/standalone/mix_c_files",
96 .import = @import("standalone/mix_c_files/build.zig"),
97 },
98 .{
99 .build_root = "test/standalone/global_linkage",
100 .import = @import("standalone/global_linkage/build.zig"),
101 },
102 .{
103 .build_root = "test/standalone/static_c_lib",
104 .import = @import("standalone/static_c_lib/build.zig"),
105 },
106 .{
107 .build_root = "test/standalone/issue_339",
108 .import = @import("standalone/issue_339/build.zig"),
109 },
110 .{
111 .build_root = "test/standalone/issue_8550",
112 .import = @import("standalone/issue_8550/build.zig"),
113 },
114 .{
115 .build_root = "test/standalone/issue_794",
116 .import = @import("standalone/issue_794/build.zig"),
117 },
118 .{
119 .build_root = "test/standalone/issue_5825",
120 .import = @import("standalone/issue_5825/build.zig"),
121 },
122 .{
123 .build_root = "test/standalone/pkg_import",
124 .import = @import("standalone/pkg_import/build.zig"),
125 },
126 .{
127 .build_root = "test/standalone/use_alias",
128 .import = @import("standalone/use_alias/build.zig"),
129 },
130 .{
131 .build_root = "test/standalone/install_raw_hex",
132 .import = @import("standalone/install_raw_hex/build.zig"),
133 },
134 // TODO take away EmitOption.emit_to option and make it give a FileSource
135 //.{
136 // .build_root = "test/standalone/emit_asm_and_bin",
137 // .import = @import("standalone/emit_asm_and_bin/build.zig"),
138 //},
139 // TODO take away EmitOption.emit_to option and make it give a FileSource
140 //.{
141 // .build_root = "test/standalone/issue_12588",
142 // .import = @import("standalone/issue_12588/build.zig"),
143 //},
144 .{
145 .build_root = "test/standalone/embed_generated_file",
146 .import = @import("standalone/embed_generated_file/build.zig"),
147 },
148 .{
149 .build_root = "test/standalone/dep_diamond",
150 .import = @import("standalone/dep_diamond/build.zig"),
151 },
152 .{
153 .build_root = "test/standalone/dep_triangle",
154 .import = @import("standalone/dep_triangle/build.zig"),
155 },
156 .{
157 .build_root = "test/standalone/dep_recursive",
158 .import = @import("standalone/dep_recursive/build.zig"),
159 },
160 .{
161 .build_root = "test/standalone/dep_mutually_recursive",
162 .import = @import("standalone/dep_mutually_recursive/build.zig"),
163 },
164 .{
165 .build_root = "test/standalone/dep_shared_builtin",
166 .import = @import("standalone/dep_shared_builtin/build.zig"),
167 },
168 .{
169 .build_root = "test/standalone/empty_env",
170 .import = @import("standalone/empty_env/build.zig"),
171 },
172 .{
173 .build_root = "test/standalone/issue_9812",
174 .import = @import("standalone/issue_9812/build.zig"),
175 },
176 .{
177 .build_root = "test/standalone/issue_11595",
178 .import = @import("standalone/issue_11595/build.zig"),
179 },
180 .{
181 .build_root = "test/standalone/load_dynamic_library",
182 .import = @import("standalone/load_dynamic_library/build.zig"),
183 },
184 .{
185 .build_root = "test/standalone/windows_spawn",
186 .import = @import("standalone/windows_spawn/build.zig"),
187 },
188 .{
189 .build_root = "test/standalone/c_compiler",
190 .import = @import("standalone/c_compiler/build.zig"),
191 },
192 .{
193 .build_root = "test/standalone/pie",
194 .import = @import("standalone/pie/build.zig"),
195 },
196 .{
197 .build_root = "test/standalone/issue_12706",
198 .import = @import("standalone/issue_12706/build.zig"),
199 },
200 // TODO This test is disabled for doing naughty things in the build script.
201 // The logic needs to get moved to a child process instead of build.zig.
202 //.{
203 // .build_root = "test/standalone/sigpipe",
204 // .import = @import("standalone/sigpipe/build.zig"),
205 //},
206 .{
207 .build_root = "test/standalone/issue_13030",
208 .import = @import("standalone/issue_13030/build.zig"),
209 },
210};
143211
144212const std = @import("std");
test/standalone/brace_expansion.zig created+292
......@@ -0,0 +1,292 @@
1const std = @import("std");
2const io = std.io;
3const mem = std.mem;
4const debug = std.debug;
5const assert = debug.assert;
6const testing = std.testing;
7const ArrayList = std.ArrayList;
8const maxInt = std.math.maxInt;
9
10const Token = union(enum) {
11 Word: []const u8,
12 OpenBrace,
13 CloseBrace,
14 Comma,
15 Eof,
16};
17
18var gpa = std.heap.GeneralPurposeAllocator(.{}){};
19var global_allocator = gpa.allocator();
20
21fn tokenize(input: []const u8) !ArrayList(Token) {
22 const State = enum {
23 Start,
24 Word,
25 };
26
27 var token_list = ArrayList(Token).init(global_allocator);
28 errdefer token_list.deinit();
29 var tok_begin: usize = undefined;
30 var state = State.Start;
31
32 for (input, 0..) |b, i| {
33 switch (state) {
34 .Start => switch (b) {
35 'a'...'z', 'A'...'Z' => {
36 state = State.Word;
37 tok_begin = i;
38 },
39 '{' => try token_list.append(Token.OpenBrace),
40 '}' => try token_list.append(Token.CloseBrace),
41 ',' => try token_list.append(Token.Comma),
42 else => return error.InvalidInput,
43 },
44 .Word => switch (b) {
45 'a'...'z', 'A'...'Z' => {},
46 '{', '}', ',' => {
47 try token_list.append(Token{ .Word = input[tok_begin..i] });
48 switch (b) {
49 '{' => try token_list.append(Token.OpenBrace),
50 '}' => try token_list.append(Token.CloseBrace),
51 ',' => try token_list.append(Token.Comma),
52 else => unreachable,
53 }
54 state = State.Start;
55 },
56 else => return error.InvalidInput,
57 },
58 }
59 }
60 switch (state) {
61 State.Start => {},
62 State.Word => try token_list.append(Token{ .Word = input[tok_begin..] }),
63 }
64 try token_list.append(Token.Eof);
65 return token_list;
66}
67
68const Node = union(enum) {
69 Scalar: []const u8,
70 List: ArrayList(Node),
71 Combine: []Node,
72
73 fn deinit(self: Node) void {
74 switch (self) {
75 .Scalar => {},
76 .Combine => |pair| {
77 pair[0].deinit();
78 pair[1].deinit();
79 global_allocator.free(pair);
80 },
81 .List => |list| {
82 for (list.items) |item| {
83 item.deinit();
84 }
85 list.deinit();
86 },
87 }
88 }
89};
90
91const ParseError = error{
92 InvalidInput,
93 OutOfMemory,
94};
95
96fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
97 const first_token = tokens.items[token_index.*];
98 token_index.* += 1;
99
100 const result_node = switch (first_token) {
101 .Word => |word| Node{ .Scalar = word },
102 .OpenBrace => blk: {
103 var list = ArrayList(Node).init(global_allocator);
104 errdefer {
105 for (list.items) |node| node.deinit();
106 list.deinit();
107 }
108 while (true) {
109 try list.append(try parse(tokens, token_index));
110
111 const token = tokens.items[token_index.*];
112 token_index.* += 1;
113
114 switch (token) {
115 .CloseBrace => break,
116 .Comma => continue,
117 else => return error.InvalidInput,
118 }
119 }
120 break :blk Node{ .List = list };
121 },
122 else => return error.InvalidInput,
123 };
124
125 switch (tokens.items[token_index.*]) {
126 .Word, .OpenBrace => {
127 const pair = try global_allocator.alloc(Node, 2);
128 errdefer global_allocator.free(pair);
129 pair[0] = result_node;
130 pair[1] = try parse(tokens, token_index);
131 return Node{ .Combine = pair };
132 },
133 else => return result_node,
134 }
135}
136
137fn expandString(input: []const u8, output: *ArrayList(u8)) !void {
138 const tokens = try tokenize(input);
139 defer tokens.deinit();
140 if (tokens.items.len == 1) {
141 return output.resize(0);
142 }
143
144 var token_index: usize = 0;
145 const root = try parse(&tokens, &token_index);
146 defer root.deinit();
147 const last_token = tokens.items[token_index];
148 switch (last_token) {
149 Token.Eof => {},
150 else => return error.InvalidInput,
151 }
152
153 var result_list = ArrayList(ArrayList(u8)).init(global_allocator);
154 defer {
155 for (result_list.items) |*buf| buf.deinit();
156 result_list.deinit();
157 }
158
159 try expandNode(root, &result_list);
160
161 try output.resize(0);
162 for (result_list.items, 0..) |buf, i| {
163 if (i != 0) {
164 try output.append(' ');
165 }
166 try output.appendSlice(buf.items);
167 }
168}
169
170const ExpandNodeError = error{OutOfMemory};
171
172fn expandNode(node: Node, output: *ArrayList(ArrayList(u8))) ExpandNodeError!void {
173 assert(output.items.len == 0);
174 switch (node) {
175 .Scalar => |scalar| {
176 var list = ArrayList(u8).init(global_allocator);
177 errdefer list.deinit();
178 try list.appendSlice(scalar);
179 try output.append(list);
180 },
181 .Combine => |pair| {
182 const a_node = pair[0];
183 const b_node = pair[1];
184
185 var child_list_a = ArrayList(ArrayList(u8)).init(global_allocator);
186 defer {
187 for (child_list_a.items) |*buf| buf.deinit();
188 child_list_a.deinit();
189 }
190 try expandNode(a_node, &child_list_a);
191
192 var child_list_b = ArrayList(ArrayList(u8)).init(global_allocator);
193 defer {
194 for (child_list_b.items) |*buf| buf.deinit();
195 child_list_b.deinit();
196 }
197 try expandNode(b_node, &child_list_b);
198
199 for (child_list_a.items) |buf_a| {
200 for (child_list_b.items) |buf_b| {
201 var combined_buf = ArrayList(u8).init(global_allocator);
202 errdefer combined_buf.deinit();
203
204 try combined_buf.appendSlice(buf_a.items);
205 try combined_buf.appendSlice(buf_b.items);
206 try output.append(combined_buf);
207 }
208 }
209 },
210 .List => |list| {
211 for (list.items) |child_node| {
212 var child_list = ArrayList(ArrayList(u8)).init(global_allocator);
213 errdefer for (child_list.items) |*buf| buf.deinit();
214 defer child_list.deinit();
215
216 try expandNode(child_node, &child_list);
217
218 for (child_list.items) |buf| {
219 try output.append(buf);
220 }
221 }
222 },
223 }
224}
225
226pub fn main() !void {
227 defer _ = gpa.deinit();
228 const stdin_file = io.getStdIn();
229 const stdout_file = io.getStdOut();
230
231 const stdin = try stdin_file.reader().readAllAlloc(global_allocator, std.math.maxInt(usize));
232 defer global_allocator.free(stdin);
233
234 var result_buf = ArrayList(u8).init(global_allocator);
235 defer result_buf.deinit();
236
237 try expandString(stdin, &result_buf);
238 try stdout_file.writeAll(result_buf.items);
239}
240
241test "invalid inputs" {
242 global_allocator = std.testing.allocator;
243
244 try expectError("}ABC", error.InvalidInput);
245 try expectError("{ABC", error.InvalidInput);
246 try expectError("}{", error.InvalidInput);
247 try expectError("{}", error.InvalidInput);
248 try expectError("A,B,C", error.InvalidInput);
249 try expectError("{A{B,C}", error.InvalidInput);
250 try expectError("{A,}", error.InvalidInput);
251
252 try expectError("\n", error.InvalidInput);
253}
254
255fn expectError(test_input: []const u8, expected_err: anyerror) !void {
256 var output_buf = ArrayList(u8).init(global_allocator);
257 defer output_buf.deinit();
258
259 try testing.expectError(expected_err, expandString(test_input, &output_buf));
260}
261
262test "valid inputs" {
263 global_allocator = std.testing.allocator;
264
265 try expectExpansion("{x,y,z}", "x y z");
266 try expectExpansion("{A,B}{x,y}", "Ax Ay Bx By");
267 try expectExpansion("{A,B{x,y}}", "A Bx By");
268
269 try expectExpansion("{ABC}", "ABC");
270 try expectExpansion("{A,B,C}", "A B C");
271 try expectExpansion("ABC", "ABC");
272
273 try expectExpansion("", "");
274 try expectExpansion("{A,B}{C,{x,y}}{g,h}", "ACg ACh Axg Axh Ayg Ayh BCg BCh Bxg Bxh Byg Byh");
275 try expectExpansion("{A,B}{C,C{x,y}}{g,h}", "ACg ACh ACxg ACxh ACyg ACyh BCg BCh BCxg BCxh BCyg BCyh");
276 try expectExpansion("{A,B}a", "Aa Ba");
277 try expectExpansion("{C,{x,y}}", "C x y");
278 try expectExpansion("z{C,{x,y}}", "zC zx zy");
279 try expectExpansion("a{b,c{d,e{f,g}}}", "ab acd acef aceg");
280 try expectExpansion("a{x,y}b", "axb ayb");
281 try expectExpansion("z{{a,b}}", "za zb");
282 try expectExpansion("a{b}", "ab");
283}
284
285fn expectExpansion(test_input: []const u8, expected_result: []const u8) !void {
286 var result = ArrayList(u8).init(global_allocator);
287 defer result.deinit();
288
289 expandString(test_input, &result) catch unreachable;
290
291 try testing.expectEqualSlices(u8, expected_result, result.items);
292}
test/standalone/brace_expansion/build.zig deleted-11
......@@ -1,11 +0,0 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const main = b.addTest(.{
5 .root_source_file = .{ .path = "main.zig" },
6 .optimize = b.standardOptimizeOption(.{}),
7 });
8
9 const test_step = b.step("test", "Test it");
10 test_step.dependOn(&main.step);
11}
test/standalone/brace_expansion/main.zig deleted-292
......@@ -1,292 +0,0 @@
1const std = @import("std");
2const io = std.io;
3const mem = std.mem;
4const debug = std.debug;
5const assert = debug.assert;
6const testing = std.testing;
7const ArrayList = std.ArrayList;
8const maxInt = std.math.maxInt;
9
10const Token = union(enum) {
11 Word: []const u8,
12 OpenBrace,
13 CloseBrace,
14 Comma,
15 Eof,
16};
17
18var gpa = std.heap.GeneralPurposeAllocator(.{}){};
19var global_allocator = gpa.allocator();
20
21fn tokenize(input: []const u8) !ArrayList(Token) {
22 const State = enum {
23 Start,
24 Word,
25 };
26
27 var token_list = ArrayList(Token).init(global_allocator);
28 errdefer token_list.deinit();
29 var tok_begin: usize = undefined;
30 var state = State.Start;
31
32 for (input, 0..) |b, i| {
33 switch (state) {
34 .Start => switch (b) {
35 'a'...'z', 'A'...'Z' => {
36 state = State.Word;
37 tok_begin = i;
38 },
39 '{' => try token_list.append(Token.OpenBrace),
40 '}' => try token_list.append(Token.CloseBrace),
41 ',' => try token_list.append(Token.Comma),
42 else => return error.InvalidInput,
43 },
44 .Word => switch (b) {
45 'a'...'z', 'A'...'Z' => {},
46 '{', '}', ',' => {
47 try token_list.append(Token{ .Word = input[tok_begin..i] });
48 switch (b) {
49 '{' => try token_list.append(Token.OpenBrace),
50 '}' => try token_list.append(Token.CloseBrace),
51 ',' => try token_list.append(Token.Comma),
52 else => unreachable,
53 }
54 state = State.Start;
55 },
56 else => return error.InvalidInput,
57 },
58 }
59 }
60 switch (state) {
61 State.Start => {},
62 State.Word => try token_list.append(Token{ .Word = input[tok_begin..] }),
63 }
64 try token_list.append(Token.Eof);
65 return token_list;
66}
67
68const Node = union(enum) {
69 Scalar: []const u8,
70 List: ArrayList(Node),
71 Combine: []Node,
72
73 fn deinit(self: Node) void {
74 switch (self) {
75 .Scalar => {},
76 .Combine => |pair| {
77 pair[0].deinit();
78 pair[1].deinit();
79 global_allocator.free(pair);
80 },
81 .List => |list| {
82 for (list.items) |item| {
83 item.deinit();
84 }
85 list.deinit();
86 },
87 }
88 }
89};
90
91const ParseError = error{
92 InvalidInput,
93 OutOfMemory,
94};
95
96fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
97 const first_token = tokens.items[token_index.*];
98 token_index.* += 1;
99
100 const result_node = switch (first_token) {
101 .Word => |word| Node{ .Scalar = word },
102 .OpenBrace => blk: {
103 var list = ArrayList(Node).init(global_allocator);
104 errdefer {
105 for (list.items) |node| node.deinit();
106 list.deinit();
107 }
108 while (true) {
109 try list.append(try parse(tokens, token_index));
110
111 const token = tokens.items[token_index.*];
112 token_index.* += 1;
113
114 switch (token) {
115 .CloseBrace => break,
116 .Comma => continue,
117 else => return error.InvalidInput,
118 }
119 }
120 break :blk Node{ .List = list };
121 },
122 else => return error.InvalidInput,
123 };
124
125 switch (tokens.items[token_index.*]) {
126 .Word, .OpenBrace => {
127 const pair = try global_allocator.alloc(Node, 2);
128 errdefer global_allocator.free(pair);
129 pair[0] = result_node;
130 pair[1] = try parse(tokens, token_index);
131 return Node{ .Combine = pair };
132 },
133 else => return result_node,
134 }
135}
136
137fn expandString(input: []const u8, output: *ArrayList(u8)) !void {
138 const tokens = try tokenize(input);
139 defer tokens.deinit();
140 if (tokens.items.len == 1) {
141 return output.resize(0);
142 }
143
144 var token_index: usize = 0;
145 const root = try parse(&tokens, &token_index);
146 defer root.deinit();
147 const last_token = tokens.items[token_index];
148 switch (last_token) {
149 Token.Eof => {},
150 else => return error.InvalidInput,
151 }
152
153 var result_list = ArrayList(ArrayList(u8)).init(global_allocator);
154 defer {
155 for (result_list.items) |*buf| buf.deinit();
156 result_list.deinit();
157 }
158
159 try expandNode(root, &result_list);
160
161 try output.resize(0);
162 for (result_list.items, 0..) |buf, i| {
163 if (i != 0) {
164 try output.append(' ');
165 }
166 try output.appendSlice(buf.items);
167 }
168}
169
170const ExpandNodeError = error{OutOfMemory};
171
172fn expandNode(node: Node, output: *ArrayList(ArrayList(u8))) ExpandNodeError!void {
173 assert(output.items.len == 0);
174 switch (node) {
175 .Scalar => |scalar| {
176 var list = ArrayList(u8).init(global_allocator);
177 errdefer list.deinit();
178 try list.appendSlice(scalar);
179 try output.append(list);
180 },
181 .Combine => |pair| {
182 const a_node = pair[0];
183 const b_node = pair[1];
184
185 var child_list_a = ArrayList(ArrayList(u8)).init(global_allocator);
186 defer {
187 for (child_list_a.items) |*buf| buf.deinit();
188 child_list_a.deinit();
189 }
190 try expandNode(a_node, &child_list_a);
191
192 var child_list_b = ArrayList(ArrayList(u8)).init(global_allocator);
193 defer {
194 for (child_list_b.items) |*buf| buf.deinit();
195 child_list_b.deinit();
196 }
197 try expandNode(b_node, &child_list_b);
198
199 for (child_list_a.items) |buf_a| {
200 for (child_list_b.items) |buf_b| {
201 var combined_buf = ArrayList(u8).init(global_allocator);
202 errdefer combined_buf.deinit();
203
204 try combined_buf.appendSlice(buf_a.items);
205 try combined_buf.appendSlice(buf_b.items);
206 try output.append(combined_buf);
207 }
208 }
209 },
210 .List => |list| {
211 for (list.items) |child_node| {
212 var child_list = ArrayList(ArrayList(u8)).init(global_allocator);
213 errdefer for (child_list.items) |*buf| buf.deinit();
214 defer child_list.deinit();
215
216 try expandNode(child_node, &child_list);
217
218 for (child_list.items) |buf| {
219 try output.append(buf);
220 }
221 }
222 },
223 }
224}
225
226pub fn main() !void {
227 defer _ = gpa.deinit();
228 const stdin_file = io.getStdIn();
229 const stdout_file = io.getStdOut();
230
231 const stdin = try stdin_file.reader().readAllAlloc(global_allocator, std.math.maxInt(usize));
232 defer global_allocator.free(stdin);
233
234 var result_buf = ArrayList(u8).init(global_allocator);
235 defer result_buf.deinit();
236
237 try expandString(stdin.items, &result_buf);
238 try stdout_file.write(result_buf.items);
239}
240
241test "invalid inputs" {
242 global_allocator = std.testing.allocator;
243
244 try expectError("}ABC", error.InvalidInput);
245 try expectError("{ABC", error.InvalidInput);
246 try expectError("}{", error.InvalidInput);
247 try expectError("{}", error.InvalidInput);
248 try expectError("A,B,C", error.InvalidInput);
249 try expectError("{A{B,C}", error.InvalidInput);
250 try expectError("{A,}", error.InvalidInput);
251
252 try expectError("\n", error.InvalidInput);
253}
254
255fn expectError(test_input: []const u8, expected_err: anyerror) !void {
256 var output_buf = ArrayList(u8).init(global_allocator);
257 defer output_buf.deinit();
258
259 try testing.expectError(expected_err, expandString(test_input, &output_buf));
260}
261
262test "valid inputs" {
263 global_allocator = std.testing.allocator;
264
265 try expectExpansion("{x,y,z}", "x y z");
266 try expectExpansion("{A,B}{x,y}", "Ax Ay Bx By");
267 try expectExpansion("{A,B{x,y}}", "A Bx By");
268
269 try expectExpansion("{ABC}", "ABC");
270 try expectExpansion("{A,B,C}", "A B C");
271 try expectExpansion("ABC", "ABC");
272
273 try expectExpansion("", "");
274 try expectExpansion("{A,B}{C,{x,y}}{g,h}", "ACg ACh Axg Axh Ayg Ayh BCg BCh Bxg Bxh Byg Byh");
275 try expectExpansion("{A,B}{C,C{x,y}}{g,h}", "ACg ACh ACxg ACxh ACyg ACyh BCg BCh BCxg BCxh BCyg BCyh");
276 try expectExpansion("{A,B}a", "Aa Ba");
277 try expectExpansion("{C,{x,y}}", "C x y");
278 try expectExpansion("z{C,{x,y}}", "zC zx zy");
279 try expectExpansion("a{b,c{d,e{f,g}}}", "ab acd acef aceg");
280 try expectExpansion("a{x,y}b", "axb ayb");
281 try expectExpansion("z{{a,b}}", "za zb");
282 try expectExpansion("a{b}", "ab");
283}
284
285fn expectExpansion(test_input: []const u8, expected_result: []const u8) !void {
286 var result = ArrayList(u8).init(global_allocator);
287 defer result.deinit();
288
289 expandString(test_input, &result) catch unreachable;
290
291 try testing.expectEqualSlices(u8, expected_result, result.items);
292}
test/standalone/c_compiler/build.zig+18-21
......@@ -1,27 +1,24 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const CrossTarget = std.zig.CrossTarget;
43
5// TODO integrate this with the std.Build executor API
6fn isRunnableTarget(t: CrossTarget) bool {
7 if (t.isNative()) return true;
4pub fn build(b: *std.Build) void {
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
87
9 return (t.getOsTag() == builtin.os.tag and
10 t.getCpuArch() == builtin.cpu.arch);
8 add(b, test_step, .Debug);
9 add(b, test_step, .ReleaseFast);
10 add(b, test_step, .ReleaseSmall);
11 add(b, test_step, .ReleaseSafe);
1112}
1213
13pub fn build(b: *std.Build) void {
14 const optimize = b.standardOptimizeOption(.{});
15 const target = b.standardTargetOptions(.{});
16
17 const test_step = b.step("test", "Test the program");
14fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
15 const target: std.zig.CrossTarget = .{};
1816
1917 const exe_c = b.addExecutable(.{
2018 .name = "test_c",
2119 .optimize = optimize,
2220 .target = target,
2321 });
24 b.default_step.dependOn(&exe_c.step);
2522 exe_c.addCSourceFile("test.c", &[0][]const u8{});
2623 exe_c.linkLibC();
2724
......@@ -47,13 +44,13 @@ pub fn build(b: *std.Build) void {
4744 else => {},
4845 }
4946
50 if (isRunnableTarget(target)) {
51 const run_c_cmd = exe_c.run();
52 test_step.dependOn(&run_c_cmd.step);
53 const run_cpp_cmd = exe_cpp.run();
54 test_step.dependOn(&run_cpp_cmd.step);
55 } else {
56 test_step.dependOn(&exe_c.step);
57 test_step.dependOn(&exe_cpp.step);
58 }
47 const run_c_cmd = b.addRunArtifact(exe_c);
48 run_c_cmd.expectExitCode(0);
49 run_c_cmd.skip_foreign_checks = true;
50 test_step.dependOn(&run_c_cmd.step);
51
52 const run_cpp_cmd = b.addRunArtifact(exe_cpp);
53 run_cpp_cmd.expectExitCode(0);
54 run_cpp_cmd.skip_foreign_checks = true;
55 test_step.dependOn(&run_cpp_cmd.step);
5956}
test/standalone/dep_diamond/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const shared = b.createModule(.{
710 .source_file = .{ .path = "shared.zig" },
......@@ -23,6 +26,5 @@ pub fn build(b: *std.Build) void {
2326
2427 const run = exe.run();
2528
26 const test_step = b.step("test", "Test it");
2729 test_step.dependOn(&run.step);
2830}
test/standalone/dep_mutually_recursive/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const foo = b.createModule(.{
710 .source_file = .{ .path = "foo.zig" },
......@@ -21,6 +24,5 @@ pub fn build(b: *std.Build) void {
2124
2225 const run = exe.run();
2326
24 const test_step = b.step("test", "Test it");
2527 test_step.dependOn(&run.step);
2628}
test/standalone/dep_recursive/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const foo = b.createModule(.{
710 .source_file = .{ .path = "foo.zig" },
......@@ -17,6 +20,5 @@ pub fn build(b: *std.Build) void {
1720
1821 const run = exe.run();
1922
20 const test_step = b.step("test", "Test it");
2123 test_step.dependOn(&run.step);
2224}
test/standalone/dep_shared_builtin/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const exe = b.addExecutable(.{
710 .name = "test",
......@@ -14,6 +17,5 @@ pub fn build(b: *std.Build) void {
1417
1518 const run = exe.run();
1619
17 const test_step = b.step("test", "Test it");
1820 test_step.dependOn(&run.step);
1921}
test/standalone/dep_triangle/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const shared = b.createModule(.{
710 .source_file = .{ .path = "shared.zig" },
......@@ -20,6 +23,5 @@ pub fn build(b: *std.Build) void {
2023
2124 const run = exe.run();
2225
23 const test_step = b.step("test", "Test it");
2426 test_step.dependOn(&run.step);
2527}
test/standalone/embed_generated_file/build.zig+3-5
......@@ -1,8 +1,8 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const target = b.standardTargetOptions(.{});
5 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
66
77 const bootloader = b.addExecutable(.{
88 .name = "bootloader",
......@@ -16,13 +16,11 @@ pub fn build(b: *std.Build) void {
1616
1717 const exe = b.addTest(.{
1818 .root_source_file = .{ .path = "main.zig" },
19 .target = target,
20 .optimize = optimize,
19 .optimize = .Debug,
2120 });
2221 exe.addAnonymousModule("bootloader.elf", .{
2322 .source_file = bootloader.getOutputSource(),
2423 });
2524
26 const test_step = b.step("test", "Test the program");
2725 test_step.dependOn(&exe.step);
2826}
test/standalone/emit_asm_and_bin/build.zig+3-1
......@@ -1,6 +1,9 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
47 const main = b.addTest(.{
58 .root_source_file = .{ .path = "main.zig" },
69 .optimize = b.standardOptimizeOption(.{}),
......@@ -8,6 +11,5 @@ pub fn build(b: *std.Build) void {
811 main.emit_asm = .{ .emit_to = b.pathFromRoot("main.s") };
912 main.emit_bin = .{ .emit_to = b.pathFromRoot("main") };
1013
11 const test_step = b.step("test", "Run test");
1214 test_step.dependOn(&main.step);
1315}
test/standalone/empty_env/build.zig+13-3
......@@ -1,15 +1,25 @@
11const std = @import("std");
2const builtin = @import("builtin");
23
34pub fn build(b: *std.Build) void {
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
7
8 const optimize: std.builtin.OptimizeMode = .Debug;
9
10 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) {
11 // https://github.com/ziglang/zig/issues/13685
12 return;
13 }
14
415 const main = b.addExecutable(.{
516 .name = "main",
617 .root_source_file = .{ .path = "main.zig" },
7 .optimize = b.standardOptimizeOption(.{}),
18 .optimize = optimize,
819 });
920
10 const run = main.run();
21 const run = b.addRunArtifact(main);
1122 run.clearEnvironment();
1223
13 const test_step = b.step("test", "Test it");
1424 test_step.dependOn(&run.step);
1525}
test/standalone/global_linkage/build.zig+7-4
......@@ -1,20 +1,24 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test the program");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
59
610 const obj1 = b.addStaticLibrary(.{
711 .name = "obj1",
812 .root_source_file = .{ .path = "obj1.zig" },
913 .optimize = optimize,
10 .target = .{},
14 .target = target,
1115 });
1216
1317 const obj2 = b.addStaticLibrary(.{
1418 .name = "obj2",
1519 .root_source_file = .{ .path = "obj2.zig" },
1620 .optimize = optimize,
17 .target = .{},
21 .target = target,
1822 });
1923
2024 const main = b.addTest(.{
......@@ -24,6 +28,5 @@ pub fn build(b: *std.Build) void {
2428 main.linkLibrary(obj1);
2529 main.linkLibrary(obj2);
2630
27 const test_step = b.step("test", "Test it");
2831 test_step.dependOn(&main.step);
2932}
test/standalone/install_raw_hex/build.zig+3-3
......@@ -3,8 +3,8 @@ const std = @import("std");
33const CheckFileStep = std.Build.CheckFileStep;
44
55pub fn build(b: *std.Build) void {
6 const test_step = b.step("test", "Test the program");
7 b.default_step.dependOn(test_step);
6 const test_step = b.step("test", "Test it");
7 b.default_step = test_step;
88
99 const target = .{
1010 .cpu_arch = .thumb,
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313 .abi = .gnueabihf,
1414 };
1515
16 const optimize = b.standardOptimizeOption(.{});
16 const optimize: std.builtin.OptimizeMode = .Debug;
1717
1818 const elf = b.addExecutable(.{
1919 .name = "zig-nrf52-blink.elf",
test/standalone/issue_11595/build.zig+14-17
......@@ -1,18 +1,17 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const CrossTarget = std.zig.CrossTarget;
43
5// TODO integrate this with the std.Build executor API
6fn isRunnableTarget(t: CrossTarget) bool {
7 if (t.isNative()) return true;
4pub fn build(b: *std.Build) void {
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
87
9 return (t.getOsTag() == builtin.os.tag and
10 t.getCpuArch() == builtin.cpu.arch);
11}
8 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{};
1210
13pub fn build(b: *std.Build) void {
14 const optimize = b.standardOptimizeOption(.{});
15 const target = b.standardTargetOptions(.{});
11 if (builtin.os.tag == .windows) {
12 // https://github.com/ziglang/zig/issues/12419
13 return;
14 }
1615
1716 const exe = b.addExecutable(.{
1817 .name = "zigtest",
......@@ -44,11 +43,9 @@ pub fn build(b: *std.Build) void {
4443
4544 b.default_step.dependOn(&exe.step);
4645
47 const test_step = b.step("test", "Test the program");
48 if (isRunnableTarget(target)) {
49 const run_cmd = exe.run();
50 test_step.dependOn(&run_cmd.step);
51 } else {
52 test_step.dependOn(&exe.step);
53 }
46 const run_cmd = b.addRunArtifact(exe);
47 run_cmd.skip_foreign_checks = true;
48 run_cmd.expectExitCode(0);
49
50 test_step.dependOn(&run_cmd.step);
5451}
test/standalone/issue_12588/build.zig+5-3
......@@ -1,8 +1,11 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5 const target = b.standardTargetOptions(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
69
710 const obj = b.addObject(.{
811 .name = "main",
......@@ -15,6 +18,5 @@ pub fn build(b: *std.Build) void {
1518 obj.emit_bin = .no_emit;
1619 b.default_step.dependOn(&obj.step);
1720
18 const test_step = b.step("test", "Test the program");
1921 test_step.dependOn(&obj.step);
2022}
test/standalone/issue_12706/build.zig+9-21
......@@ -2,17 +2,12 @@ const std = @import("std");
22const builtin = @import("builtin");
33const CrossTarget = std.zig.CrossTarget;
44
5// TODO integrate this with the std.Build executor API
6fn isRunnableTarget(t: CrossTarget) bool {
7 if (t.isNative()) return true;
8
9 return (t.getOsTag() == builtin.os.tag and
10 t.getCpuArch() == builtin.cpu.arch);
11}
12
135pub fn build(b: *std.Build) void {
14 const optimize = b.standardOptimizeOption(.{});
15 const target = b.standardTargetOptions(.{});
6 const test_step = b.step("test", "Test it");
7 b.default_step = test_step;
8
9 const optimize: std.builtin.OptimizeMode = .Debug;
10 const target: std.zig.CrossTarget = .{};
1611
1712 const exe = b.addExecutable(.{
1813 .name = "main",
......@@ -20,22 +15,15 @@ pub fn build(b: *std.Build) void {
2015 .optimize = optimize,
2116 .target = target,
2217 });
23 exe.install();
2418
2519 const c_sources = [_][]const u8{
2620 "test.c",
2721 };
28
2922 exe.addCSourceFiles(&c_sources, &.{});
3023 exe.linkLibC();
3124
32 b.default_step.dependOn(&exe.step);
33
34 const test_step = b.step("test", "Test the program");
35 if (isRunnableTarget(target)) {
36 const run_cmd = exe.run();
37 test_step.dependOn(&run_cmd.step);
38 } else {
39 test_step.dependOn(&exe.step);
40 }
25 const run_cmd = b.addRunArtifact(exe);
26 run_cmd.expectExitCode(0);
27 run_cmd.skip_foreign_checks = true;
28 test_step.dependOn(&run_cmd.step);
4129}
test/standalone/issue_13030/build.zig+10-5
......@@ -3,17 +3,22 @@ const builtin = @import("builtin");
33const CrossTarget = std.zig.CrossTarget;
44
55pub fn build(b: *std.Build) void {
6 const optimize = b.standardOptimizeOption(.{});
7 const target = b.standardTargetOptions(.{});
6 const test_step = b.step("test", "Test it");
7 b.default_step = test_step;
88
9 add(b, test_step, .Debug);
10 add(b, test_step, .ReleaseFast);
11 add(b, test_step, .ReleaseSmall);
12 add(b, test_step, .ReleaseSafe);
13}
14
15fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
916 const obj = b.addObject(.{
1017 .name = "main",
1118 .root_source_file = .{ .path = "main.zig" },
1219 .optimize = optimize,
13 .target = target,
20 .target = .{},
1421 });
15 b.default_step.dependOn(&obj.step);
1622
17 const test_step = b.step("test", "Test the program");
1823 test_step.dependOn(&obj.step);
1924}
test/standalone/issue_13970/build.zig+3-1
......@@ -1,6 +1,9 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
47 const test1 = b.addTest(.{
58 .root_source_file = .{ .path = "test_root/empty.zig" },
69 });
......@@ -14,7 +17,6 @@ pub fn build(b: *std.Build) void {
1417 test2.setTestRunner("src/main.zig");
1518 test3.setTestRunner("src/main.zig");
1619
17 const test_step = b.step("test", "Test package path resolution of custom test runner");
1820 test_step.dependOn(&test1.step);
1921 test_step.dependOn(&test2.step);
2022 test_step.dependOn(&test3.step);
test/standalone/issue_339/build.zig+8-3
......@@ -1,13 +1,18 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
9
410 const obj = b.addObject(.{
511 .name = "test",
612 .root_source_file = .{ .path = "test.zig" },
7 .target = b.standardTargetOptions(.{}),
8 .optimize = b.standardOptimizeOption(.{}),
13 .target = target,
14 .optimize = optimize,
915 });
1016
11 const test_step = b.step("test", "Test the program");
1217 test_step.dependOn(&obj.step);
1318}
test/standalone/issue_5825/build.zig+4-2
......@@ -1,12 +1,15 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
47 const target = .{
58 .cpu_arch = .x86_64,
69 .os_tag = .windows,
710 .abi = .msvc,
811 };
9 const optimize = b.standardOptimizeOption(.{});
12 const optimize: std.builtin.OptimizeMode = .Debug;
1013 const obj = b.addObject(.{
1114 .name = "issue_5825",
1215 .root_source_file = .{ .path = "main.zig" },
......@@ -24,6 +27,5 @@ pub fn build(b: *std.Build) void {
2427 exe.linkSystemLibrary("ntdll");
2528 exe.addObject(obj);
2629
27 const test_step = b.step("test", "Test the program");
2830 test_step.dependOn(&exe.step);
2931}
test/standalone/issue_7030.zig created+21
......@@ -0,0 +1,21 @@
1const std = @import("std");
2
3pub const std_options = struct {
4 pub const logFn = log;
5};
6
7pub fn log(
8 comptime message_level: std.log.Level,
9 comptime scope: @Type(.EnumLiteral),
10 comptime format: []const u8,
11 args: anytype,
12) void {
13 _ = message_level;
14 _ = scope;
15 _ = format;
16 _ = args;
17}
18
19pub fn main() anyerror!void {
20 std.log.info("All your codebase are belong to us.", .{});
21}
test/standalone/issue_7030/build.zig deleted-17
......@@ -1,17 +0,0 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const exe = b.addExecutable(.{
5 .name = "issue_7030",
6 .root_source_file = .{ .path = "main.zig" },
7 .target = .{
8 .cpu_arch = .wasm32,
9 .os_tag = .freestanding,
10 },
11 });
12 exe.install();
13 b.default_step.dependOn(&exe.step);
14
15 const test_step = b.step("test", "Test the program");
16 test_step.dependOn(&exe.step);
17}
test/standalone/issue_7030/main.zig deleted-21
......@@ -1,21 +0,0 @@
1const std = @import("std");
2
3pub const std_options = struct {
4 pub const logFn = log;
5};
6
7pub fn log(
8 comptime message_level: std.log.Level,
9 comptime scope: @Type(.EnumLiteral),
10 comptime format: []const u8,
11 args: anytype,
12) void {
13 _ = message_level;
14 _ = scope;
15 _ = format;
16 _ = args;
17}
18
19pub fn main() anyerror!void {
20 std.log.info("All your codebase are belong to us.", .{});
21}
test/standalone/issue_794/build.zig+3-3
......@@ -1,13 +1,13 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
47 const test_artifact = b.addTest(.{
58 .root_source_file = .{ .path = "main.zig" },
69 });
710 test_artifact.addIncludePath("a_directory");
811
9 b.default_step.dependOn(&test_artifact.step);
10
11 const test_step = b.step("test", "Test the program");
1212 test_step.dependOn(&test_artifact.step);
1313}
test/standalone/issue_8550/build.zig+5-2
......@@ -1,6 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) !void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
48 const target = std.zig.CrossTarget{
59 .os_tag = .freestanding,
610 .cpu_arch = .arm,
......@@ -8,7 +12,7 @@ pub fn build(b: *std.Build) !void {
812 .explicit = &std.Target.arm.cpu.arm1176jz_s,
913 },
1014 };
11 const optimize = b.standardOptimizeOption(.{});
15
1216 const kernel = b.addExecutable(.{
1317 .name = "kernel",
1418 .root_source_file = .{ .path = "./main.zig" },
......@@ -19,6 +23,5 @@ pub fn build(b: *std.Build) !void {
1923 kernel.setLinkerScriptPath(.{ .path = "./linker.ld" });
2024 kernel.install();
2125
22 const test_step = b.step("test", "Test it");
2326 test_step.dependOn(&kernel.step);
2427}
test/standalone/issue_9812/build.zig+5-2
......@@ -1,7 +1,11 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) !void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8
59 const zip_add = b.addTest(.{
610 .root_source_file = .{ .path = "main.zig" },
711 .optimize = optimize,
......@@ -13,6 +17,5 @@ pub fn build(b: *std.Build) !void {
1317 zip_add.addIncludePath("vendor/kuba-zip");
1418 zip_add.linkLibC();
1519
16 const test_step = b.step("test", "Test it");
1720 test_step.dependOn(&zip_add.step);
1821}
test/standalone/load_dynamic_library/build.zig+16-4
......@@ -1,8 +1,19 @@
11const std = @import("std");
2const builtin = @import("builtin");
23
34pub fn build(b: *std.Build) void {
4 const target = b.standardTargetOptions(.{});
5 const optimize = b.standardOptimizeOption(.{});
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
7
8 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{};
10
11 const ok = (builtin.os.tag != .wasi and
12 // https://github.com/ziglang/zig/issues/13550
13 (builtin.os.tag != .macos or builtin.cpu.arch != .aarch64) and
14 // https://github.com/ziglang/zig/issues/13686
15 (builtin.os.tag != .windows or builtin.cpu.arch != .aarch64));
16 if (!ok) return;
617
718 const lib = b.addSharedLibrary(.{
819 .name = "add",
......@@ -19,9 +30,10 @@ pub fn build(b: *std.Build) void {
1930 .target = target,
2031 });
2132
22 const run = main.run();
33 const run = b.addRunArtifact(main);
2334 run.addArtifactArg(lib);
35 run.skip_foreign_checks = true;
36 run.expectExitCode(0);
2437
25 const test_step = b.step("test", "Test the program");
2638 test_step.dependOn(&run.step);
2739}
test/standalone/load_dynamic_library/main.zig+1-5
......@@ -11,11 +11,7 @@ pub fn main() !void {
1111 var lib = try std.DynLib.open(dynlib_name);
1212 defer lib.close();
1313
14 const Add = switch (@import("builtin").zig_backend) {
15 .stage1 => fn (i32, i32) callconv(.C) i32,
16 else => *const fn (i32, i32) callconv(.C) i32,
17 };
18
14 const Add = *const fn (i32, i32) callconv(.C) i32;
1915 const addFn = lib.lookup(Add, "add") orelse return error.SymbolNotFound;
2016
2117 const result = addFn(12, 34);
test/standalone/main_pkg_path/build.zig+3-1
......@@ -1,11 +1,13 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
47 const test_exe = b.addTest(.{
58 .root_source_file = .{ .path = "a/test.zig" },
69 });
710 test_exe.setMainPkgPath(".");
811
9 const test_step = b.step("test", "Test the program");
1012 test_step.dependOn(&test_exe.step);
1113}
test/standalone/mix_c_files/build.zig+13-19
......@@ -1,34 +1,28 @@
11const std = @import("std");
2const builtin = @import("builtin");
3const CrossTarget = std.zig.CrossTarget;
42
5// TODO integrate this with the std.Build executor API
6fn isRunnableTarget(t: CrossTarget) bool {
7 if (t.isNative()) return true;
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
86
9 return (t.getOsTag() == builtin.os.tag and
10 t.getCpuArch() == builtin.cpu.arch);
7 add(b, test_step, .Debug);
8 add(b, test_step, .ReleaseFast);
9 add(b, test_step, .ReleaseSmall);
10 add(b, test_step, .ReleaseSafe);
1111}
1212
13pub fn build(b: *std.Build) void {
14 const optimize = b.standardOptimizeOption(.{});
15 const target = b.standardTargetOptions(.{});
16
13fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
1714 const exe = b.addExecutable(.{
1815 .name = "test",
1916 .root_source_file = .{ .path = "main.zig" },
2017 .optimize = optimize,
21 .target = target,
2218 });
2319 exe.addCSourceFile("test.c", &[_][]const u8{"-std=c11"});
2420 exe.linkLibC();
2521 b.default_step.dependOn(&exe.step);
2622
27 const test_step = b.step("test", "Test the program");
28 if (isRunnableTarget(target)) {
29 const run_cmd = exe.run();
30 test_step.dependOn(&run_cmd.step);
31 } else {
32 test_step.dependOn(&exe.step);
33 }
23 const run_cmd = b.addRunArtifact(exe);
24 run_cmd.skip_foreign_checks = true;
25 run_cmd.expectExitCode(0);
26
27 test_step.dependOn(&run_cmd.step);
3428}
test/standalone/mix_o_files/build.zig+7-3
......@@ -1,18 +1,23 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
59
610 const obj = b.addObject(.{
711 .name = "base64",
812 .root_source_file = .{ .path = "base64.zig" },
913 .optimize = optimize,
10 .target = .{},
14 .target = target,
1115 });
1216
1317 const exe = b.addExecutable(.{
1418 .name = "test",
1519 .optimize = optimize,
20 .target = target,
1621 });
1722 exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"});
1823 exe.addObject(obj);
......@@ -22,6 +27,5 @@ pub fn build(b: *std.Build) void {
2227
2328 const run_cmd = exe.run();
2429
25 const test_step = b.step("test", "Test the program");
2630 test_step.dependOn(&run_cmd.step);
2731}
test/standalone/pie/build.zig+11-4
......@@ -1,14 +1,21 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{
9 .os_tag = .linux,
10 .cpu_arch = .x86_64,
11 };
12
413 const main = b.addTest(.{
514 .root_source_file = .{ .path = "main.zig" },
6 .optimize = b.standardOptimizeOption(.{}),
15 .optimize = optimize,
16 .target = target,
717 });
818 main.pie = true;
919
10 const test_step = b.step("test", "Test the program");
1120 test_step.dependOn(&main.step);
12
13 b.default_step.dependOn(test_step);
1421}
test/standalone/pkg_import/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const exe = b.addExecutable(.{
710 .name = "test",
......@@ -12,6 +15,5 @@ pub fn build(b: *std.Build) void {
1215
1316 const run = exe.run();
1417
15 const test_step = b.step("test", "Test it");
1618 test_step.dependOn(&run.step);
1719}
test/standalone/shared_library/build.zig+5-5
......@@ -1,8 +1,11 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5 const target = b.standardTargetOptions(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
69 const lib = b.addSharedLibrary(.{
710 .name = "mathtest",
811 .root_source_file = .{ .path = "mathtest.zig" },
......@@ -20,10 +23,7 @@ pub fn build(b: *std.Build) void {
2023 exe.linkLibrary(lib);
2124 exe.linkSystemLibrary("c");
2225
23 b.default_step.dependOn(&exe.step);
24
2526 const run_cmd = exe.run();
2627
27 const test_step = b.step("test", "Test the program");
2828 test_step.dependOn(&run_cmd.step);
2929}
test/standalone/sigpipe/build.zig+10-1
......@@ -2,7 +2,16 @@ const std = @import("std");
22const os = std.os;
33
44pub fn build(b: *std.build.Builder) !void {
5 const test_step = b.step("test", "Run the tests");
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
7
8 // TODO signal handling code has no business being in a build script.
9 // this logic needs to move to a file called parent.zig which is
10 // added as an executable.
11
12 //if (!std.os.have_sigpipe_support) {
13 // return;
14 //}
615
716 // This test runs "breakpipe" as a child process and that process
817 // depends on inheriting a SIGPIPE disposition of "default".
test/standalone/static_c_lib/build.zig+4-2
......@@ -1,7 +1,10 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
58
69 const foo = b.addStaticLibrary(.{
710 .name = "foo",
......@@ -18,6 +21,5 @@ pub fn build(b: *std.Build) void {
1821 test_exe.linkLibrary(foo);
1922 test_exe.addIncludePath(".");
2023
21 const test_step = b.step("test", "Test it");
2224 test_step.dependOn(&test_exe.step);
2325}
test/standalone/test_runner_path/build.zig+5-1
......@@ -1,6 +1,11 @@
11const std = @import("std");
22
3pub const requires_stage2 = true;
4
35pub fn build(b: *std.Build) void {
6 const test_step = b.step("test", "Test the program");
7 b.default_step = test_step;
8
49 const test_exe = b.addTest(.{
510 .root_source_file = .{ .path = "test.zig" },
611 .kind = .test_exe,
......@@ -9,6 +14,5 @@ pub fn build(b: *std.Build) void {
914
1015 const test_run = test_exe.run();
1116
12 const test_step = b.step("test", "Test the program");
1317 test_step.dependOn(&test_run.step);
1418}
test/standalone/test_runner_path/test_runner.zig+4-36
......@@ -1,51 +1,19 @@
11const std = @import("std");
2const io = std.io;
32const builtin = @import("builtin");
43
5pub const io_mode: io.Mode = builtin.test_io_mode;
6
74pub fn main() void {
8 const test_fn_list = builtin.test_functions;
95 var ok_count: usize = 0;
106 var skip_count: usize = 0;
117 var fail_count: usize = 0;
128
13 var async_frame_buffer: []align(std.Target.stack_align) u8 = undefined;
14 // TODO this is on the next line (using `undefined` above) because otherwise zig incorrectly
15 // ignores the alignment of the slice.
16 async_frame_buffer = &[_]u8{};
17
18 for (test_fn_list) |test_fn| {
19 const result = if (test_fn.async_frame_size) |size| switch (io_mode) {
20 .evented => blk: {
21 if (async_frame_buffer.len < size) {
22 std.heap.page_allocator.free(async_frame_buffer);
23 async_frame_buffer = std.heap.page_allocator.alignedAlloc(u8, std.Target.stack_align, size) catch @panic("out of memory");
24 }
25 const casted_fn = @ptrCast(fn () callconv(.Async) anyerror!void, test_fn.func);
26 break :blk await @asyncCall(async_frame_buffer, {}, casted_fn, .{});
27 },
28 .blocking => {
29 skip_count += 1;
30 continue;
31 },
32 } else test_fn.func();
33 if (result) |_| {
9 for (builtin.test_functions) |test_fn| {
10 if (test_fn.func()) |_| {
3411 ok_count += 1;
3512 } else |err| switch (err) {
36 error.SkipZigTest => {
37 skip_count += 1;
38 },
39 else => {
40 fail_count += 1;
41 },
13 error.SkipZigTest => skip_count += 1,
14 else => fail_count += 1,
4215 }
4316 }
44 if (ok_count == test_fn_list.len) {
45 std.debug.print("All {d} tests passed.\n", .{ok_count});
46 } else {
47 std.debug.print("{d} passed; {d} skipped; {d} failed.\n", .{ ok_count, skip_count, fail_count });
48 }
4917 if (ok_count != 1 or skip_count != 1 or fail_count != 1) {
5018 std.process.exit(1);
5119 }
test/standalone/use_alias/build.zig+6-2
......@@ -1,12 +1,16 @@
11const std = @import("std");
22
33pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8
49 const main = b.addTest(.{
510 .root_source_file = .{ .path = "main.zig" },
6 .optimize = b.standardOptimizeOption(.{}),
11 .optimize = optimize,
712 });
813 main.addIncludePath(".");
914
10 const test_step = b.step("test", "Test it");
1115 test_step.dependOn(&main.step);
1216}
test/standalone/windows_spawn/build.zig+14-3
......@@ -1,23 +1,34 @@
11const std = @import("std");
2const builtin = @import("builtin");
23
34pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
7
8 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{
10 .os_tag = .windows,
11 .cpu_arch = .x86_64,
12 };
513
614 const hello = b.addExecutable(.{
715 .name = "hello",
816 .root_source_file = .{ .path = "hello.zig" },
917 .optimize = optimize,
18 .target = target,
1019 });
1120
1221 const main = b.addExecutable(.{
1322 .name = "main",
1423 .root_source_file = .{ .path = "main.zig" },
1524 .optimize = optimize,
25 .target = target,
1626 });
1727
18 const run = main.run();
28 const run = b.addRunArtifact(main);
1929 run.addArtifactArg(hello);
30 run.expectExitCode(0);
31 run.skip_foreign_checks = true;
2032
21 const test_step = b.step("test", "Test it");
2233 test_step.dependOn(&run.step);
2334}
test/tests.zig+66-27
......@@ -560,34 +560,62 @@ pub fn addStackTraceTests(
560560
561561pub fn addStandaloneTests(
562562 b: *std.Build,
563 test_filter: ?[]const u8,
564563 optimize_modes: []const OptimizeMode,
565 skip_non_native: bool,
566564 enable_macos_sdk: bool,
567565 omit_stage2: bool,
568566 enable_symlinks_windows: bool,
569567) *Step {
570568 const step = b.step("test-standalone", "Run the standalone tests");
571
572 _ = test_filter;
573 _ = skip_non_native;
574 _ = enable_macos_sdk;
575 _ = omit_stage2;
576 _ = enable_symlinks_windows;
569 const omit_symlinks = builtin.os.tag == .windows and !enable_symlinks_windows;
577570
578571 for (standalone.simple_cases) |case| {
579572 for (optimize_modes) |optimize| {
580573 if (!case.all_modes and optimize != .Debug) continue;
581574
582 const exe = b.addExecutable(.{
583 .name = std.fs.path.stem(case.src_path),
584 .root_source_file = .{ .path = case.src_path },
585 .optimize = optimize,
586 .target = case.target,
587 });
588 if (case.link_libc) exe.linkLibC();
575 if (case.is_exe) {
576 const exe = b.addExecutable(.{
577 .name = std.fs.path.stem(case.src_path),
578 .root_source_file = .{ .path = case.src_path },
579 .optimize = optimize,
580 .target = case.target,
581 });
582 if (case.link_libc) exe.linkLibC();
583
584 step.dependOn(&exe.step);
585 }
589586
590 step.dependOn(&exe.step);
587 if (case.is_test) {
588 const exe = b.addTest(.{
589 .name = std.fs.path.stem(case.src_path),
590 .root_source_file = .{ .path = case.src_path },
591 .optimize = optimize,
592 .target = case.target,
593 });
594 if (case.link_libc) exe.linkLibC();
595
596 step.dependOn(&exe.step);
597 }
598 }
599 }
600
601 inline for (standalone.build_cases) |case| {
602 const requires_stage2 = @hasDecl(case.import, "requires_stage2") and
603 case.import.requires_stage2;
604 const requires_symlinks = @hasDecl(case.import, "requires_symlinks") and
605 case.import.requires_symlinks;
606 const requires_macos_sdk = @hasDecl(case.import, "requires_macos_sdk") and
607 case.import.requires_macos_sdk;
608 const bad =
609 (requires_stage2 and omit_stage2) or
610 (requires_symlinks and omit_symlinks) or
611 (requires_macos_sdk and !enable_macos_sdk);
612 if (!bad) {
613 const dep = b.anonymousDependency(case.build_root, case.import, .{});
614 const dep_step = dep.builder.default_step;
615 assert(mem.startsWith(u8, dep.builder.dep_prefix, "test."));
616 const dep_prefix_adjusted = dep.builder.dep_prefix["test.".len..];
617 dep_step.name = b.fmt("{s}{s}", .{ dep_prefix_adjusted, dep_step.name });
618 step.dependOn(dep_step);
591619 }
592620 }
593621
......@@ -603,19 +631,19 @@ pub fn addLinkTests(
603631 const step = b.step("test-link", "Run the linker tests");
604632 const omit_symlinks = builtin.os.tag == .windows and !enable_symlinks_windows;
605633
606 inline for (link.cases) |link_test| {
607 const requires_stage2 = @hasDecl(link_test.import, "requires_stage2") and
608 link_test.import.requires_stage2;
609 const requires_symlinks = @hasDecl(link_test.import, "requires_symlinks") and
610 link_test.import.requires_symlinks;
611 const requires_macos_sdk = @hasDecl(link_test.import, "requires_macos_sdk") and
612 link_test.import.requires_macos_sdk;
634 inline for (link.cases) |case| {
635 const requires_stage2 = @hasDecl(case.import, "requires_stage2") and
636 case.import.requires_stage2;
637 const requires_symlinks = @hasDecl(case.import, "requires_symlinks") and
638 case.import.requires_symlinks;
639 const requires_macos_sdk = @hasDecl(case.import, "requires_macos_sdk") and
640 case.import.requires_macos_sdk;
613641 const bad =
614642 (requires_stage2 and omit_stage2) or
615643 (requires_symlinks and omit_symlinks) or
616644 (requires_macos_sdk and !enable_macos_sdk);
617645 if (!bad) {
618 const dep = b.anonymousDependency(link_test.build_root, link_test.import, .{});
646 const dep = b.anonymousDependency(case.build_root, case.import, .{});
619647 const dep_step = dep.builder.default_step;
620648 assert(mem.startsWith(u8, dep.builder.dep_prefix, "test."));
621649 const dep_prefix_adjusted = dep.builder.dep_prefix["test.".len..];
......@@ -627,9 +655,7 @@ pub fn addLinkTests(
627655 return step;
628656}
629657
630pub fn addCliTests(b: *std.Build, test_filter: ?[]const u8, optimize_modes: []const OptimizeMode) *Step {
631 _ = test_filter;
632 _ = optimize_modes;
658pub fn addCliTests(b: *std.Build) *Step {
633659 const step = b.step("test-cli", "Test the command line interface");
634660
635661 {
......@@ -815,6 +841,19 @@ pub fn addCliTests(b: *std.Build, test_filter: ?[]const u8, optimize_modes: []co
815841 step.dependOn(&cleanup.step);
816842 }
817843
844 {
845 // TODO this should move to become a CLI test rather than standalone
846 // cases.addBuildFile("test/standalone/options/build.zig", .{
847 // .extra_argv = &.{
848 // "-Dbool_true",
849 // "-Dbool_false=false",
850 // "-Dint=1234",
851 // "-De=two",
852 // "-Dstring=hello",
853 // },
854 // });
855 }
856
818857 return step;
819858}
820859