| ... | ... | @@ -6,6 +6,27 @@ const Cache = std.Build.Cache; |
| 6 | 6 | |
| 7 | 7 | const usage = "usage: incr-check <zig binary path> <input file> [--zig-lib-dir lib] [--debug-log foo] [--preserve-tmp] [--zig-cc-binary /path/to/zig]"; |
| 8 | 8 | |
| 9 | pub const std_options: std.Options = .{ |
| 10 | .logFn = logImpl, |
| 11 | }; |
| 12 | var log_cur_update: ?struct { *const Case.Target, *const Case.Update } = null; |
| 13 | fn logImpl( |
| 14 | comptime level: std.log.Level, |
| 15 | comptime scope: @EnumLiteral(), |
| 16 | comptime format: []const u8, |
| 17 | args: anytype, |
| 18 | ) void { |
| 19 | const target, const update = log_cur_update orelse { |
| 20 | return std.log.defaultLog(level, scope, format, args); |
| 21 | }; |
| 22 | std.log.defaultLog( |
| 23 | level, |
| 24 | scope, |
| 25 | "[{s}-{t} '{s}'] " ++ format, |
| 26 | .{ target.query, target.backend, update.name } ++ args, |
| 27 | ); |
| 28 | } |
| 29 | |
| 9 | 30 | pub fn main() !void { |
| 10 | 31 | const fatal = std.process.fatal; |
| 11 | 32 | |
| ... | ... | @@ -225,6 +246,9 @@ pub fn main() !void { |
| 225 | 246 | std.log.scoped(.status).info("update: '{s}'", .{update.name}); |
| 226 | 247 | } |
| 227 | 248 | |
| 249 | log_cur_update = .{ &target, &update }; |
| 250 | defer log_cur_update = null; |
| 251 | |
| 228 | 252 | eval.write(update); |
| 229 | 253 | try eval.requestUpdate(); |
| 230 | 254 | try eval.check(&poller, update, update_node); |
| ... | ... | @@ -295,9 +319,9 @@ const Eval = struct { |
| 295 | 319 | if (stderr.bufferedLen() > 0) { |
| 296 | 320 | const stderr_data = try poller.toOwnedSlice(.stderr); |
| 297 | 321 | if (eval.allow_stderr) { |
| 298 | | std.log.info("error_bundle included stderr:\n{s}", .{stderr_data}); |
| 322 | std.log.info("error_bundle stderr:\n{s}", .{stderr_data}); |
| 299 | 323 | } else { |
| 300 | | eval.fatal("error_bundle included unexpected stderr:\n{s}", .{stderr_data}); |
| 324 | eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr_data}); |
| 301 | 325 | } |
| 302 | 326 | } |
| 303 | 327 | if (result_error_bundle.errorMessageCount() != 0) { |
| ... | ... | @@ -312,9 +336,9 @@ const Eval = struct { |
| 312 | 336 | if (stderr.bufferedLen() > 0) { |
| 313 | 337 | const stderr_data = try poller.toOwnedSlice(.stderr); |
| 314 | 338 | if (eval.allow_stderr) { |
| 315 | | std.log.info("emit_digest included stderr:\n{s}", .{stderr_data}); |
| 339 | std.log.info("emit_digest stderr:\n{s}", .{stderr_data}); |
| 316 | 340 | } else { |
| 317 | | eval.fatal("emit_digest included unexpected stderr:\n{s}", .{stderr_data}); |
| 341 | eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr_data}); |
| 318 | 342 | } |
| 319 | 343 | } |
| 320 | 344 | |
| ... | ... | @@ -344,14 +368,14 @@ const Eval = struct { |
| 344 | 368 | |
| 345 | 369 | if (stderr.bufferedLen() > 0) { |
| 346 | 370 | if (eval.allow_stderr) { |
| 347 | | std.log.info("update '{s}' included stderr:\n{s}", .{ update.name, stderr.buffered() }); |
| 371 | std.log.info("stderr:\n{s}", .{stderr.buffered()}); |
| 348 | 372 | } else { |
| 349 | | eval.fatal("update '{s}' failed:\n{s}", .{ update.name, stderr.buffered() }); |
| 373 | eval.fatal("unexpected stderr:\n{s}", .{stderr.buffered()}); |
| 350 | 374 | } |
| 351 | 375 | } |
| 352 | 376 | |
| 353 | 377 | waitChild(eval.child, eval); |
| 354 | | eval.fatal("update '{s}': compiler failed to send error_bundle or emit_bin_path", .{update.name}); |
| 378 | eval.fatal("compiler failed to send error_bundle or emit_bin_path", .{}); |
| 355 | 379 | } |
| 356 | 380 | |
| 357 | 381 | fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void { |
| ... | ... | @@ -361,7 +385,7 @@ const Eval = struct { |
| 361 | 385 | .compile_errors => |ce| ce, |
| 362 | 386 | .stdout, .exit_code => { |
| 363 | 387 | try error_bundle.renderToStderr(io, .{}, .auto); |
| 364 | | eval.fatal("update '{s}': unexpected compile errors", .{update.name}); |
| 388 | eval.fatal("unexpected compile errors", .{}); |
| 365 | 389 | }, |
| 366 | 390 | }; |
| 367 | 391 | |
| ... | ... | @@ -370,30 +394,29 @@ const Eval = struct { |
| 370 | 394 | for (error_bundle.getMessages()) |err_idx| { |
| 371 | 395 | if (expected_idx == expected.errors.len) { |
| 372 | 396 | try error_bundle.renderToStderr(io, .{}, .auto); |
| 373 | | eval.fatal("update '{s}': more errors than expected", .{update.name}); |
| 397 | eval.fatal("more errors than expected", .{}); |
| 374 | 398 | } |
| 375 | | try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx); |
| 399 | try eval.checkOneError(error_bundle, expected.errors[expected_idx], false, err_idx); |
| 376 | 400 | expected_idx += 1; |
| 377 | 401 | |
| 378 | 402 | for (error_bundle.getNotes(err_idx)) |note_idx| { |
| 379 | 403 | if (expected_idx == expected.errors.len) { |
| 380 | 404 | try error_bundle.renderToStderr(io, .{}, .auto); |
| 381 | | eval.fatal("update '{s}': more error notes than expected", .{update.name}); |
| 405 | eval.fatal("more error notes than expected", .{}); |
| 382 | 406 | } |
| 383 | | try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx); |
| 407 | try eval.checkOneError(error_bundle, expected.errors[expected_idx], true, note_idx); |
| 384 | 408 | expected_idx += 1; |
| 385 | 409 | } |
| 386 | 410 | } |
| 387 | 411 | |
| 388 | 412 | if (!std.mem.eql(u8, error_bundle.getCompileLogOutput(), expected.compile_log_output)) { |
| 389 | 413 | try error_bundle.renderToStderr(io, .{}, .auto); |
| 390 | | eval.fatal("update '{s}': unexpected compile log output", .{update.name}); |
| 414 | eval.fatal("unexpected compile log output", .{}); |
| 391 | 415 | } |
| 392 | 416 | } |
| 393 | 417 | |
| 394 | 418 | fn checkOneError( |
| 395 | 419 | eval: *Eval, |
| 396 | | update: Case.Update, |
| 397 | 420 | eb: std.zig.ErrorBundle, |
| 398 | 421 | expected: Case.ExpectedError, |
| 399 | 422 | is_note: bool, |
| ... | ... | @@ -423,7 +446,7 @@ const Eval = struct { |
| 423 | 446 | !std.mem.eql(u8, expected.msg, msg)) |
| 424 | 447 | { |
| 425 | 448 | eb.renderToStderr(io, .{}, .auto) catch {}; |
| 426 | | eval.fatal("update '{s}': compile error did not match expected error", .{update.name}); |
| 449 | eval.fatal("compile error did not match expected error", .{}); |
| 427 | 450 | } |
| 428 | 451 | } |
| 429 | 452 | |
| ... | ... | @@ -444,7 +467,7 @@ const Eval = struct { |
| 444 | 467 | .cbe => bin: { |
| 445 | 468 | const rand_int = std.crypto.random.int(u64); |
| 446 | 469 | const out_bin_name = "./out_" ++ std.fmt.hex(rand_int); |
| 447 | | try eval.buildCOutput(update, emitted_path, out_bin_name, prog_node); |
| 470 | try eval.buildCOutput(emitted_path, out_bin_name, prog_node); |
| 448 | 471 | break :bin out_bin_name; |
| 449 | 472 | }, |
| 450 | 473 | }; |
| ... | ... | @@ -521,8 +544,7 @@ const Eval = struct { |
| 521 | 544 | if (is_foreign) { |
| 522 | 545 | // Chances are the foreign executor isn't available. Skip this evaluation. |
| 523 | 546 | if (eval.allow_stderr) { |
| 524 | | std.log.warn("update '{s}': skipping execution of '{s}' via executor for foreign target '{s}': {t}", .{ |
| 525 | | update.name, |
| 547 | std.log.warn("skipping execution of '{s}' via executor for foreign target '{s}': {t}", .{ |
| 526 | 548 | binary_path, |
| 527 | 549 | try eval.target.resolved.zigTriple(eval.arena), |
| 528 | 550 | err, |
| ... | ... | @@ -530,16 +552,14 @@ const Eval = struct { |
| 530 | 552 | } |
| 531 | 553 | return; |
| 532 | 554 | } |
| 533 | | eval.fatal("update '{s}': failed to run the generated executable '{s}': {t}", .{ |
| 534 | | update.name, binary_path, err, |
| 535 | | }); |
| 555 | eval.fatal("failed to run the generated executable '{s}': {t}", .{ binary_path, err }); |
| 536 | 556 | }; |
| 537 | 557 | |
| 538 | 558 | // Some executors (looking at you, Wine) like throwing some stderr in, just for fun. |
| 539 | 559 | // Therefore, we'll ignore stderr when using a foreign executor. |
| 540 | 560 | if (!is_foreign and result.stderr.len != 0) { |
| 541 | | std.log.err("update '{s}': generated executable '{s}' had unexpected stderr:\n{s}", .{ |
| 542 | | update.name, binary_path, result.stderr, |
| 561 | std.log.err("generated executable '{s}' had unexpected stderr:\n{s}", .{ |
| 562 | binary_path, result.stderr, |
| 543 | 563 | }); |
| 544 | 564 | } |
| 545 | 565 | |
| ... | ... | @@ -548,18 +568,14 @@ const Eval = struct { |
| 548 | 568 | .unknown, .compile_errors => unreachable, |
| 549 | 569 | .stdout => |expected_stdout| { |
| 550 | 570 | if (code != 0) { |
| 551 | | eval.fatal("update '{s}': generated executable '{s}' failed with code {d}", .{ |
| 552 | | update.name, binary_path, code, |
| 553 | | }); |
| 571 | eval.fatal("generated executable '{s}' failed with code {d}", .{ binary_path, code }); |
| 554 | 572 | } |
| 555 | 573 | try std.testing.expectEqualStrings(expected_stdout, result.stdout); |
| 556 | 574 | }, |
| 557 | 575 | .exit_code => |expected_code| try std.testing.expectEqual(expected_code, result.term.Exited), |
| 558 | 576 | }, |
| 559 | 577 | .Signal, .Stopped, .Unknown => { |
| 560 | | eval.fatal("update '{s}': generated executable '{s}' terminated unexpectedly", .{ |
| 561 | | update.name, binary_path, |
| 562 | | }); |
| 578 | eval.fatal("generated executable '{s}' terminated unexpectedly", .{binary_path}); |
| 563 | 579 | }, |
| 564 | 580 | } |
| 565 | 581 | |
| ... | ... | @@ -597,7 +613,7 @@ const Eval = struct { |
| 597 | 613 | } |
| 598 | 614 | } |
| 599 | 615 | |
| 600 | | fn buildCOutput(eval: *Eval, update: Case.Update, c_path: []const u8, out_path: []const u8, prog_node: std.Progress.Node) !void { |
| 616 | fn buildCOutput(eval: *Eval, c_path: []const u8, out_path: []const u8, prog_node: std.Progress.Node) !void { |
| 601 | 617 | std.debug.assert(eval.cc_child_args.items.len > 0); |
| 602 | 618 | |
| 603 | 619 | const child_prog_node = prog_node.start("build cbe output", 0); |
| ... | ... | @@ -612,28 +628,20 @@ const Eval = struct { |
| 612 | 628 | .cwd = eval.tmp_dir_path, |
| 613 | 629 | .progress_node = child_prog_node, |
| 614 | 630 | }) catch |err| { |
| 615 | | eval.fatal("update '{s}': failed to spawn zig cc for '{s}': {t}", .{ update.name, c_path, err }); |
| 631 | eval.fatal("failed to spawn zig cc for '{s}': {t}", .{ c_path, err }); |
| 616 | 632 | }; |
| 617 | 633 | switch (result.term) { |
| 618 | 634 | .Exited => |code| if (code != 0) { |
| 619 | 635 | if (result.stderr.len != 0) { |
| 620 | | std.log.err("update '{s}': zig cc stderr:\n{s}", .{ |
| 621 | | update.name, result.stderr, |
| 622 | | }); |
| 636 | std.log.err("zig cc stderr:\n{s}", .{result.stderr}); |
| 623 | 637 | } |
| 624 | | eval.fatal("update '{s}': zig cc for '{s}' failed with code {d}", .{ |
| 625 | | update.name, c_path, code, |
| 626 | | }); |
| 638 | eval.fatal("zig cc for '{s}' failed with code {d}", .{ c_path, code }); |
| 627 | 639 | }, |
| 628 | 640 | .Signal, .Stopped, .Unknown => { |
| 629 | 641 | if (result.stderr.len != 0) { |
| 630 | | std.log.err("update '{s}': zig cc stderr:\n{s}", .{ |
| 631 | | update.name, result.stderr, |
| 632 | | }); |
| 642 | std.log.err("zig cc stderr:\n{s}", .{result.stderr}); |
| 633 | 643 | } |
| 634 | | eval.fatal("update '{s}': zig cc for '{s}' terminated unexpectedly", .{ |
| 635 | | update.name, c_path, |
| 636 | | }); |
| 644 | eval.fatal("zig cc for '{s}' terminated unexpectedly", .{c_path}); |
| 637 | 645 | }, |
| 638 | 646 | } |
| 639 | 647 | } |