-
-
Notifications
You must be signed in to change notification settings - Fork 97
/
Copy pathStackTrace.zig
108 lines (93 loc) · 3.2 KB
/
StackTrace.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
b: *std.Build,
step: *Step,
test_index: usize,
test_filters: []const []const u8,
optimize_modes: []const OptimizeMode,
check_exe: *std.Build.Step.Compile,
const Config = struct {
name: []const u8,
source: []const u8,
Debug: ?PerMode = null,
ReleaseSmall: ?PerMode = null,
ReleaseSafe: ?PerMode = null,
ReleaseFast: ?PerMode = null,
const PerMode = struct {
expect: []const u8,
exclude_os: []const std.Target.Os.Tag = &.{},
error_tracing: ?bool = null,
};
};
pub fn addCase(self: *StackTrace, config: Config) void {
self.addCaseInner(config, true);
if (shouldTestNonLlvm(self.b.graph.host.result)) {
self.addCaseInner(config, false);
}
}
fn addCaseInner(self: *StackTrace, config: Config, use_llvm: bool) void {
if (config.Debug) |per_mode|
self.addExpect(config.name, config.source, .Debug, use_llvm, per_mode);
if (config.ReleaseSmall) |per_mode|
self.addExpect(config.name, config.source, .ReleaseSmall, use_llvm, per_mode);
if (config.ReleaseFast) |per_mode|
self.addExpect(config.name, config.source, .ReleaseFast, use_llvm, per_mode);
if (config.ReleaseSafe) |per_mode|
self.addExpect(config.name, config.source, .ReleaseSafe, use_llvm, per_mode);
}
fn shouldTestNonLlvm(target: std.Target) bool {
return switch (target.cpu.arch) {
.x86_64 => switch (target.ofmt) {
.elf => true,
else => false,
},
else => false,
};
}
fn addExpect(
self: *StackTrace,
name: []const u8,
source: []const u8,
optimize_mode: OptimizeMode,
use_llvm: bool,
mode_config: Config.PerMode,
) void {
for (mode_config.exclude_os) |tag| if (tag == builtin.os.tag) return;
const b = self.b;
const annotated_case_name = b.fmt("check {s} ({s} {s})", .{
name, @tagName(optimize_mode), if (use_llvm) "llvm" else "selfhosted",
});
for (self.test_filters) |test_filter| {
if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
} else if (self.test_filters.len > 0) return;
const write_files = b.addWriteFiles();
const source_zig = write_files.add("source.zig", source);
const exe = b.addExecutable(.{
.name = "test",
.root_module = b.createModule(.{
.root_source_file = source_zig,
.optimize = optimize_mode,
.target = b.graph.host,
.error_tracing = mode_config.error_tracing,
}),
.use_llvm = use_llvm,
});
exe.bundle_ubsan_rt = false;
const run = b.addRunArtifact(exe);
run.removeEnvironmentVariable("CLICOLOR_FORCE");
run.setEnvironmentVariable("NO_COLOR", "1");
run.expectExitCode(1);
run.expectStdOutEqual("");
const check_run = b.addRunArtifact(self.check_exe);
check_run.setName(annotated_case_name);
check_run.addFileArg(run.captureStdErr());
check_run.addArgs(&.{
@tagName(optimize_mode),
});
check_run.expectStdOutEqual(mode_config.expect);
self.step.dependOn(&check_run.step);
}
const StackTrace = @This();
const std = @import("std");
const builtin = @import("builtin");
const Step = std.Build.Step;
const OptimizeMode = std.builtin.OptimizeMode;
const mem = std.mem;