| ... | ... | @@ -235,9 +235,9 @@ const TestManifest = struct { |
| 235 | 235 | inner: std.mem.SplitIterator(u8), |
| 236 | 236 | parse_fn: ParseFn(T), |
| 237 | 237 | |
| 238 | | fn next(self: *@This()) ?T { |
| 238 | fn next(self: *@This()) !?T { |
| 239 | 239 | const next_raw = self.inner.next() orelse return null; |
| 240 | | return self.parse_fn(next_raw); |
| 240 | return try self.parse_fn(next_raw); |
| 241 | 241 | } |
| 242 | 242 | }; |
| 243 | 243 | } |
| ... | ... | @@ -339,20 +339,20 @@ const TestManifest = struct { |
| 339 | 339 | allocator: Allocator, |
| 340 | 340 | key: []const u8, |
| 341 | 341 | comptime T: type, |
| 342 | | ) error{OutOfMemory}![]const T { |
| 342 | ) ![]const T { |
| 343 | 343 | var out = std.ArrayList(T).init(allocator); |
| 344 | 344 | defer out.deinit(); |
| 345 | 345 | var it = self.getConfigForKey(key, T); |
| 346 | | while (it.next()) |item| { |
| 346 | while (try it.next()) |item| { |
| 347 | 347 | try out.append(item); |
| 348 | 348 | } |
| 349 | 349 | return out.toOwnedSlice(); |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | | fn getConfigForKeyAssertSingle(self: TestManifest, key: []const u8, comptime T: type) T { |
| 352 | fn getConfigForKeyAssertSingle(self: TestManifest, key: []const u8, comptime T: type) !T { |
| 353 | 353 | var it = self.getConfigForKey(key, T); |
| 354 | | const res = it.next().?; |
| 355 | | assert(it.next() == null); |
| 354 | const res = (try it.next()) orelse unreachable; |
| 355 | assert((try it.next()) == null); |
| 356 | 356 | return res; |
| 357 | 357 | } |
| 358 | 358 | |
| ... | ... | @@ -373,33 +373,36 @@ const TestManifest = struct { |
| 373 | 373 | } |
| 374 | 374 | |
| 375 | 375 | fn ParseFn(comptime T: type) type { |
| 376 | | return fn ([]const u8) ?T; |
| 376 | return fn ([]const u8) anyerror!T; |
| 377 | 377 | } |
| 378 | 378 | |
| 379 | 379 | fn getDefaultParser(comptime T: type) ParseFn(T) { |
| 380 | 380 | switch (@typeInfo(T)) { |
| 381 | 381 | .Int => return struct { |
| 382 | | fn parse(str: []const u8) ?T { |
| 383 | | return std.fmt.parseInt(T, str, 0) catch null; |
| 382 | fn parse(str: []const u8) anyerror!T { |
| 383 | return try std.fmt.parseInt(T, str, 0); |
| 384 | 384 | } |
| 385 | 385 | }.parse, |
| 386 | 386 | .Bool => return struct { |
| 387 | | fn parse(str: []const u8) ?T { |
| 388 | | const as_int = std.fmt.parseInt(u1, str, 0) catch return null; |
| 387 | fn parse(str: []const u8) anyerror!T { |
| 388 | const as_int = try std.fmt.parseInt(u1, str, 0); |
| 389 | 389 | return as_int > 0; |
| 390 | 390 | } |
| 391 | 391 | }.parse, |
| 392 | 392 | .Enum => return struct { |
| 393 | | fn parse(str: []const u8) ?T { |
| 394 | | return std.meta.stringToEnum(T, str); |
| 393 | fn parse(str: []const u8) anyerror!T { |
| 394 | return std.meta.stringToEnum(T, str) orelse { |
| 395 | std.log.err("unknown enum variant for {s}: {s}", .{ @typeName(T), str }); |
| 396 | return error.UnknownEnumVariant; |
| 397 | }; |
| 395 | 398 | } |
| 396 | 399 | }.parse, |
| 397 | 400 | .Struct => if (comptime std.mem.eql(u8, @typeName(T), "CrossTarget")) return struct { |
| 398 | | fn parse(str: []const u8) ?T { |
| 401 | fn parse(str: []const u8) anyerror!T { |
| 399 | 402 | var opts = CrossTarget.ParseOptions{ |
| 400 | 403 | .arch_os_abi = str, |
| 401 | 404 | }; |
| 402 | | return CrossTarget.parse(opts) catch null; |
| 405 | return try CrossTarget.parse(opts); |
| 403 | 406 | } |
| 404 | 407 | }.parse else @compileError("no default parser for " ++ @typeName(T)), |
| 405 | 408 | else => @compileError("no default parser for " ++ @typeName(T)), |
| ... | ... | @@ -1128,8 +1131,8 @@ pub const TestContext = struct { |
| 1128 | 1131 | if (cases.items.len == 0) { |
| 1129 | 1132 | const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend); |
| 1130 | 1133 | const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", CrossTarget); |
| 1131 | | const is_test = manifest.getConfigForKeyAssertSingle("is_test", bool); |
| 1132 | | const output_mode = manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode); |
| 1134 | const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); |
| 1135 | const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode); |
| 1133 | 1136 | |
| 1134 | 1137 | const name_prefix = blk: { |
| 1135 | 1138 | const ext_index = std.mem.lastIndexOfScalar(u8, current_file.*, '.') orelse |