| ... | ... | @@ -94,12 +94,8 @@ pub const Error = struct { |
| 94 | 94 | /// Errors encountered while parsing ZON. See `log` and `fatal` for reporting errors to the user. |
| 95 | 95 | pub const Errors = struct { |
| 96 | 96 | items: []const Error, |
| 97 | | oom: bool, |
| 98 | 97 | |
| 99 | | pub const empty: Errors = .{ |
| 100 | | .items = &.{}, |
| 101 | | .oom = false, |
| 102 | | }; |
| 98 | pub const empty: Errors = .{ .items = &.{} }; |
| 103 | 99 | |
| 104 | 100 | /// Log the failure with `std.log.err`. |
| 105 | 101 | pub fn log(self: *const Errors, path: []const u8) void { |
| ... | ... | @@ -123,9 +119,12 @@ pub const Errors = struct { |
| 123 | 119 | .arena = arena, |
| 124 | 120 | .source = ".{ .foo = 1, .bar = 2 }", |
| 125 | 121 | .errors = &errors, |
| 126 | | }) catch b: { |
| 127 | | errors.log("input.zon"); |
| 128 | | break :b .{ .foo = 0, .bar = 0 }; |
| 122 | }) catch |err| switch (err) { |
| 123 | error.OutOfMemory => return error.OutOfMemory, |
| 124 | error.ParseZon => b: { |
| 125 | errors.log("input.zon"); |
| 126 | break :b .{ .foo = 0, .bar = 0 }; |
| 127 | }, |
| 129 | 128 | }; |
| 130 | 129 | _ = parsed; |
| 131 | 130 | } |
| ... | ... | @@ -152,14 +151,16 @@ pub const Errors = struct { |
| 152 | 151 | .arena = arena, |
| 153 | 152 | .source = ".{ .foo = 1, .bar = 2 }", |
| 154 | 153 | .errors = &errors, |
| 155 | | }) catch errors.fatal("input.zon"); |
| 154 | }) catch |err| switch (err) { |
| 155 | error.OutOfMemory => return error.OutOfMemory, |
| 156 | error.ParseZon => errors.fatal("input.zon"), |
| 157 | }; |
| 156 | 158 | _ = parsed; |
| 157 | 159 | } |
| 158 | 160 | |
| 159 | 161 | pub fn fmt(self: *const Errors, path: []const u8) Formatter { |
| 160 | 162 | return .{ |
| 161 | 163 | .items = self.items, |
| 162 | | .oom = self.oom, |
| 163 | 164 | .path = path, |
| 164 | 165 | }; |
| 165 | 166 | } |
| ... | ... | @@ -167,12 +168,8 @@ pub const Errors = struct { |
| 167 | 168 | pub const Formatter = struct { |
| 168 | 169 | path: []const u8, |
| 169 | 170 | items: []const Error, |
| 170 | | oom: bool, |
| 171 | 171 | |
| 172 | 172 | pub fn format(self: *const @This(), w: *std.Io.Writer) std.Io.Writer.Error!void { |
| 173 | | if (self.oom) { |
| 174 | | try w.print("{s}: out of memory", .{self.path}); |
| 175 | | } |
| 176 | 173 | for (self.items) |e| { |
| 177 | 174 | try w.print("{s}:", .{self.path}); |
| 178 | 175 | try w.print("{d}:{d}: error: {s}\n", .{ |
| ... | ... | @@ -192,11 +189,6 @@ pub const Errors = struct { |
| 192 | 189 | } |
| 193 | 190 | } |
| 194 | 191 | }; |
| 195 | | |
| 196 | | fn checkOom(self: *Errors, result: anytype) @TypeOf(result) { |
| 197 | | self.oom |= result == error.OutOfMemory; |
| 198 | | return result; |
| 199 | | } |
| 200 | 192 | }; |
| 201 | 193 | |
| 202 | 194 | pub const Options = struct { |
| ... | ... | @@ -246,9 +238,12 @@ test fromSlice { |
| 246 | 238 | .arena = arena, |
| 247 | 239 | .source = source, |
| 248 | 240 | .errors = &errors, |
| 249 | | }) catch |err| { |
| 250 | | errors.log("texture_options.zon"); |
| 251 | | return err; |
| 241 | }) catch |err| switch (err) { |
| 242 | error.OutOfMemory => return err, |
| 243 | error.ParseZon => { |
| 244 | errors.log("texture_options.zon"); |
| 245 | return err; |
| 246 | }, |
| 252 | 247 | }; |
| 253 | 248 | |
| 254 | 249 | try std.testing.expectEqualDeep(TextureOptions{ |
| ... | ... | @@ -318,18 +313,24 @@ test updateFromSlice { |
| 318 | 313 | .arena = arena, |
| 319 | 314 | .source = global_config, |
| 320 | 315 | .errors = &errors, |
| 321 | | }) catch |err| { |
| 322 | | errors.log("global_config.zon"); |
| 323 | | return err; |
| 316 | }) catch |err| switch (err) { |
| 317 | error.OutOfMemory => return err, |
| 318 | error.ParseZon => { |
| 319 | errors.log("global_config.zon"); |
| 320 | return err; |
| 321 | }, |
| 324 | 322 | }; |
| 325 | 323 | updateFromSlice(MyTextEditorConfig, &config, .{ |
| 326 | 324 | .gpa = gpa, |
| 327 | 325 | .arena = arena, |
| 328 | 326 | .source = project_config, |
| 329 | 327 | .errors = &errors, |
| 330 | | }) catch |err| { |
| 331 | | errors.log("project_config.zon"); |
| 332 | | return err; |
| 328 | }) catch |err| switch (err) { |
| 329 | error.OutOfMemory => return err, |
| 330 | error.ParseZon => { |
| 331 | errors.log("project_config.zon"); |
| 332 | return err; |
| 333 | }, |
| 333 | 334 | }; |
| 334 | 335 | |
| 335 | 336 | try std.testing.expectEqualDeep(MyTextEditorConfig{ |
| ... | ... | @@ -357,32 +358,23 @@ fn fromSliceInner( |
| 357 | 358 | initialized: bool, |
| 358 | 359 | options: Options, |
| 359 | 360 | ) error{ OutOfMemory, ParseZon }!void { |
| 360 | | options.errors.oom = false; |
| 361 | 361 | var errors: std.ArrayList(Error) = .empty; |
| 362 | 362 | defer options.errors.items = errors.items; |
| 363 | 363 | |
| 364 | | var ast = try options.errors.checkOom(std.zig.Ast.parse( |
| 365 | | options.gpa, |
| 366 | | options.source, |
| 367 | | .{ .mode = .zon }, |
| 368 | | )); |
| 364 | var ast = try std.zig.Ast.parse(options.gpa, options.source, .{ .mode = .zon }); |
| 369 | 365 | defer ast.deinit(options.gpa); |
| 370 | 366 | |
| 371 | | var zoir = try options.errors.checkOom(ZonGen.generate( |
| 372 | | options.gpa, |
| 373 | | ast, |
| 374 | | .{ .parse_str_lits = false }, |
| 375 | | )); |
| 367 | var zoir = try ZonGen.generate(options.gpa, ast, .{ .parse_str_lits = false }); |
| 376 | 368 | defer zoir.deinit(options.gpa); |
| 377 | 369 | |
| 378 | | try options.errors.checkOom(inner(T, value, initialized, .{ |
| 370 | try inner(T, value, initialized, .{ |
| 379 | 371 | .arena = options.arena, |
| 380 | 372 | .ast = &ast, |
| 381 | 373 | .zoir = &zoir, |
| 382 | 374 | .node = .root, |
| 383 | 375 | .errors = &errors, |
| 384 | 376 | .ignore_unknown_fields = options.ignore_unknown_fields, |
| 385 | | })); |
| 377 | }); |
| 386 | 378 | } |
| 387 | 379 | |
| 388 | 380 | pub const FromZoirOptions = struct { |
| ... | ... | @@ -439,16 +431,15 @@ fn fromZoirInner( |
| 439 | 431 | initialized: bool, |
| 440 | 432 | options: FromZoirOptions, |
| 441 | 433 | ) error{ OutOfMemory, ParseZon }!void { |
| 442 | | options.errors.oom = false; |
| 443 | 434 | var errors: std.ArrayList(Error) = .empty; |
| 444 | 435 | defer options.errors.items = errors.items; |
| 445 | | return options.errors.checkOom(inner(T, value, initialized, .{ |
| 436 | return inner(T, value, initialized, .{ |
| 446 | 437 | .arena = options.arena, |
| 447 | 438 | .ast = options.ast, |
| 448 | 439 | .zoir = options.zoir, |
| 449 | 440 | .errors = &errors, |
| 450 | 441 | .ignore_unknown_fields = options.ignore_unknown_fields, |
| 451 | | })); |
| 442 | }); |
| 452 | 443 | } |
| 453 | 444 | |
| 454 | 445 | const InnerOptions = struct { |
| ... | ... | @@ -1450,38 +1441,17 @@ test "std.zon failure/oom formatting" { |
| 1450 | 1441 | var arena_allocator: ArenaAllocator = .init(gpa); |
| 1451 | 1442 | defer arena_allocator.deinit(); |
| 1452 | 1443 | const arena = arena_allocator.allocator(); |
| 1444 | var errors: Errors = .empty; |
| 1453 | 1445 | |
| 1454 | | { |
| 1455 | | var errors: Errors = .empty; |
| 1456 | | try std.testing.expectError(error.OutOfMemory, fromSlice([]const u8, .{ |
| 1457 | | .gpa = .failing, |
| 1458 | | .arena = arena, |
| 1459 | | .source = "\"foo\"", |
| 1460 | | .errors = &errors, |
| 1461 | | })); |
| 1462 | | try std.testing.expectFmt( |
| 1463 | | \\input.zon: out of memory |
| 1464 | | , "{f}", .{errors.fmt("input.zon")}); |
| 1465 | | } |
| 1466 | | |
| 1467 | | { |
| 1468 | | var ast = try std.zig.Ast.parse(gpa, "\"foo\"", .{ .mode = .zon }); |
| 1469 | | defer ast.deinit(gpa); |
| 1470 | | |
| 1471 | | var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false }); |
| 1472 | | defer zoir.deinit(gpa); |
| 1473 | | |
| 1474 | | var errors: Errors = .empty; |
| 1475 | | try std.testing.expectError(error.OutOfMemory, fromZoir([]const u8, .{ |
| 1476 | | .arena = .failing, |
| 1477 | | .ast = &ast, |
| 1478 | | .zoir = &zoir, |
| 1479 | | .errors = &errors, |
| 1480 | | })); |
| 1481 | | try std.testing.expectFmt( |
| 1482 | | \\input.zon: out of memory |
| 1483 | | , "{f}", .{errors.fmt("input.zon")}); |
| 1484 | | } |
| 1446 | try std.testing.expectError(error.OutOfMemory, fromSlice([]const u8, .{ |
| 1447 | .gpa = .failing, |
| 1448 | .arena = arena, |
| 1449 | .source = "\"foo\"", |
| 1450 | .errors = &errors, |
| 1451 | })); |
| 1452 | try std.testing.expectFmt( |
| 1453 | \\ |
| 1454 | , "{f}", .{errors.fmt("input.zon")}); |
| 1485 | 1455 | } |
| 1486 | 1456 | |
| 1487 | 1457 | test "std.zon fromSlice syntax error" { |