| author | |
| committer | |
| log | 65270cdc3345e9840427179168a09ef6e4dd34b9 |
| tree | 3d4cd45795caaae02817d6642b1a373b07150b55 |
| parent | 9be5323e93123a3979037997fa40a95b4c985b85 |
| parent | 7561f63b5d93fb32b39410590625bb16bf2ac0dd |
| signature |
std.debug: handle some possible errors and resolve low-hanging TODOs4 files changed, 73 insertions(+), 94 deletions(-)
lib/std/Progress.zig+17-8| ... | ... | @@ -210,8 +210,11 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 210 | 210 | std.debug.assert(self.is_windows_terminal); |
| 211 | 211 | |
| 212 | 212 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 213 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) | |
| 214 | unreachable; | |
| 213 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) { | |
| 214 | // stop trying to write to this file | |
| 215 | self.terminal = null; | |
| 216 | break :winapi; | |
| 217 | } | |
| 215 | 218 | |
| 216 | 219 | var cursor_pos = windows.COORD{ |
| 217 | 220 | .X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written), |
| ... | ... | @@ -231,7 +234,7 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 231 | 234 | cursor_pos, |
| 232 | 235 | &written, |
| 233 | 236 | ) != windows.TRUE) { |
| 234 | // Stop trying to write to this file. | |
| 237 | // stop trying to write to this file | |
| 235 | 238 | self.terminal = null; |
| 236 | 239 | break :winapi; |
| 237 | 240 | } |
| ... | ... | @@ -241,10 +244,16 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 241 | 244 | fill_chars, |
| 242 | 245 | cursor_pos, |
| 243 | 246 | &written, |
| 244 | ) != windows.TRUE) unreachable; | |
| 245 | ||
| 246 | if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) | |
| 247 | unreachable; | |
| 247 | ) != windows.TRUE) { | |
| 248 | // stop trying to write to this file | |
| 249 | self.terminal = null; | |
| 250 | break :winapi; | |
| 251 | } | |
| 252 | if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) { | |
| 253 | // stop trying to write to this file | |
| 254 | self.terminal = null; | |
| 255 | break :winapi; | |
| 256 | } | |
| 248 | 257 | } else { |
| 249 | 258 | // we are in a "dumb" terminal like in acme or writing to a file |
| 250 | 259 | self.output_buffer[end] = '\n'; |
| ... | ... | @@ -288,7 +297,7 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 288 | 297 | } |
| 289 | 298 | |
| 290 | 299 | _ = file.write(self.output_buffer[0..end]) catch { |
| 291 | // Stop trying to write to this file once it errors. | |
| 300 | // stop trying to write to this file | |
| 292 | 301 | self.terminal = null; |
| 293 | 302 | }; |
| 294 | 303 | if (self.timer) |*timer| { |
lib/std/debug.zig+37-67| ... | ... | @@ -119,7 +119,7 @@ pub fn detectTTYConfig() TTY.Config { |
| 119 | 119 | if (stderr_file.supportsAnsiEscapeCodes()) { |
| 120 | 120 | return .escape_codes; |
| 121 | 121 | } else if (native_os == .windows and stderr_file.isTty()) { |
| 122 | return .windows_api; | |
| 122 | return .{ .windows_api = stderr_file }; | |
| 123 | 123 | } else { |
| 124 | 124 | return .no_color; |
| 125 | 125 | } |
| ... | ... | @@ -384,14 +384,6 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize |
| 384 | 384 | os.abort(); |
| 385 | 385 | } |
| 386 | 386 | |
| 387 | const RED = "\x1b[31;1m"; | |
| 388 | const GREEN = "\x1b[32;1m"; | |
| 389 | const CYAN = "\x1b[36;1m"; | |
| 390 | const WHITE = "\x1b[37;1m"; | |
| 391 | const BOLD = "\x1b[1m"; | |
| 392 | const DIM = "\x1b[2m"; | |
| 393 | const RESET = "\x1b[0m"; | |
| 394 | ||
| 395 | 387 | pub fn writeStackTrace( |
| 396 | 388 | stack_trace: std.builtin.StackTrace, |
| 397 | 389 | out_stream: anytype, |
| ... | ... | @@ -415,9 +407,9 @@ pub fn writeStackTrace( |
| 415 | 407 | if (stack_trace.index > stack_trace.instruction_addresses.len) { |
| 416 | 408 | const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len; |
| 417 | 409 | |
| 418 | tty_config.setColor(out_stream, .Bold); | |
| 410 | tty_config.setColor(out_stream, .Bold) catch {}; | |
| 419 | 411 | try out_stream.print("({d} additional stack frames skipped...)\n", .{dropped_frames}); |
| 420 | tty_config.setColor(out_stream, .Reset); | |
| 412 | tty_config.setColor(out_stream, .Reset) catch {}; | |
| 421 | 413 | } |
| 422 | 414 | } |
| 423 | 415 | |
| ... | ... | @@ -605,59 +597,39 @@ pub const TTY = struct { |
| 605 | 597 | Reset, |
| 606 | 598 | }; |
| 607 | 599 | |
| 608 | pub const Config = enum { | |
| 600 | pub const Config = union(enum) { | |
| 609 | 601 | no_color, |
| 610 | 602 | escape_codes, |
| 611 | // TODO give this a payload of file handle | |
| 612 | windows_api, | |
| 603 | windows_api: File, | |
| 613 | 604 | |
| 614 | pub fn setColor(conf: Config, out_stream: anytype, color: Color) void { | |
| 605 | pub fn setColor(conf: Config, out_stream: anytype, color: Color) !void { | |
| 615 | 606 | nosuspend switch (conf) { |
| 616 | 607 | .no_color => return, |
| 617 | .escape_codes => switch (color) { | |
| 618 | .Red => out_stream.writeAll(RED) catch return, | |
| 619 | .Green => out_stream.writeAll(GREEN) catch return, | |
| 620 | .Cyan => out_stream.writeAll(CYAN) catch return, | |
| 621 | .White => out_stream.writeAll(WHITE) catch return, | |
| 622 | .Dim => out_stream.writeAll(DIM) catch return, | |
| 623 | .Bold => out_stream.writeAll(BOLD) catch return, | |
| 624 | .Reset => out_stream.writeAll(RESET) catch return, | |
| 608 | .escape_codes => { | |
| 609 | const color_string = switch (color) { | |
| 610 | .Red => "\x1b[31;1m", | |
| 611 | .Green => "\x1b[32;1m", | |
| 612 | .Cyan => "\x1b[36;1m", | |
| 613 | .White => "\x1b[37;1m", | |
| 614 | .Bold => "\x1b[1m", | |
| 615 | .Dim => "\x1b[2m", | |
| 616 | .Reset => "\x1b[0m", | |
| 617 | }; | |
| 618 | try out_stream.writeAll(color_string); | |
| 625 | 619 | }, |
| 626 | .windows_api => if (native_os == .windows) { | |
| 627 | const stderr_file = io.getStdErr(); | |
| 628 | const S = struct { | |
| 629 | var attrs: windows.WORD = undefined; | |
| 630 | var init_attrs = false; | |
| 620 | .windows_api => |file| if (native_os == .windows) { | |
| 621 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | |
| 622 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) | |
| 623 | return error.FailedRetrievingTerminalInfo; | |
| 624 | const attributes = switch (color) { | |
| 625 | .Red => windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY, | |
| 626 | .Green => windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY, | |
| 627 | .Cyan => windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY, | |
| 628 | .White, .Bold => windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY, | |
| 629 | .Dim => windows.FOREGROUND_INTENSITY, | |
| 630 | .Reset => info.wAttributes, | |
| 631 | 631 | }; |
| 632 | if (!S.init_attrs) { | |
| 633 | S.init_attrs = true; | |
| 634 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | |
| 635 | // TODO handle error | |
| 636 | _ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info); | |
| 637 | S.attrs = info.wAttributes; | |
| 638 | } | |
| 639 | ||
| 640 | // TODO handle errors | |
| 641 | switch (color) { | |
| 642 | .Red => { | |
| 643 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {}; | |
| 644 | }, | |
| 645 | .Green => { | |
| 646 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {}; | |
| 647 | }, | |
| 648 | .Cyan => { | |
| 649 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; | |
| 650 | }, | |
| 651 | .White, .Bold => { | |
| 652 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; | |
| 653 | }, | |
| 654 | .Dim => { | |
| 655 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {}; | |
| 656 | }, | |
| 657 | .Reset => { | |
| 658 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {}; | |
| 659 | }, | |
| 660 | } | |
| 632 | try windows.SetConsoleTextAttribute(file.handle, attributes); | |
| 661 | 633 | } else { |
| 662 | 634 | unreachable; |
| 663 | 635 | }, |
| ... | ... | @@ -751,7 +723,7 @@ fn printLineInfo( |
| 751 | 723 | comptime printLineFromFile: anytype, |
| 752 | 724 | ) !void { |
| 753 | 725 | nosuspend { |
| 754 | tty_config.setColor(out_stream, .Bold); | |
| 726 | try tty_config.setColor(out_stream, .Bold); | |
| 755 | 727 | |
| 756 | 728 | if (line_info) |*li| { |
| 757 | 729 | try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column }); |
| ... | ... | @@ -759,11 +731,11 @@ fn printLineInfo( |
| 759 | 731 | try out_stream.writeAll("???:?:?"); |
| 760 | 732 | } |
| 761 | 733 | |
| 762 | tty_config.setColor(out_stream, .Reset); | |
| 734 | try tty_config.setColor(out_stream, .Reset); | |
| 763 | 735 | try out_stream.writeAll(": "); |
| 764 | tty_config.setColor(out_stream, .Dim); | |
| 736 | try tty_config.setColor(out_stream, .Dim); | |
| 765 | 737 | try out_stream.print("0x{x} in {s} ({s})", .{ address, symbol_name, compile_unit_name }); |
| 766 | tty_config.setColor(out_stream, .Reset); | |
| 738 | try tty_config.setColor(out_stream, .Reset); | |
| 767 | 739 | try out_stream.writeAll("\n"); |
| 768 | 740 | |
| 769 | 741 | // Show the matching source code line if possible |
| ... | ... | @@ -774,9 +746,9 @@ fn printLineInfo( |
| 774 | 746 | const space_needed = @intCast(usize, li.column - 1); |
| 775 | 747 | |
| 776 | 748 | try out_stream.writeByteNTimes(' ', space_needed); |
| 777 | tty_config.setColor(out_stream, .Green); | |
| 749 | try tty_config.setColor(out_stream, .Green); | |
| 778 | 750 | try out_stream.writeAll("^"); |
| 779 | tty_config.setColor(out_stream, .Reset); | |
| 751 | try tty_config.setColor(out_stream, .Reset); | |
| 780 | 752 | } |
| 781 | 753 | try out_stream.writeAll("\n"); |
| 782 | 754 | } else |err| switch (err) { |
| ... | ... | @@ -789,14 +761,12 @@ fn printLineInfo( |
| 789 | 761 | } |
| 790 | 762 | } |
| 791 | 763 | |
| 792 | // TODO use this | |
| 793 | 764 | pub const OpenSelfDebugInfoError = error{ |
| 794 | 765 | MissingDebugInfo, |
| 795 | OutOfMemory, | |
| 796 | 766 | UnsupportedOperatingSystem, |
| 797 | 767 | }; |
| 798 | 768 | |
| 799 | pub fn openSelfDebugInfo(allocator: mem.Allocator) anyerror!DebugInfo { | |
| 769 | pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!DebugInfo { | |
| 800 | 770 | nosuspend { |
| 801 | 771 | if (builtin.strip_debug_info) |
| 802 | 772 | return error.MissingDebugInfo; |
| ... | ... | @@ -813,7 +783,7 @@ pub fn openSelfDebugInfo(allocator: mem.Allocator) anyerror!DebugInfo { |
| 813 | 783 | .windows, |
| 814 | 784 | .solaris, |
| 815 | 785 | => return DebugInfo.init(allocator), |
| 816 | else => return error.UnsupportedDebugInfo, | |
| 786 | else => return error.UnsupportedOperatingSystem, | |
| 817 | 787 | } |
| 818 | 788 | } |
| 819 | 789 | } |
lib/std/testing.zig+4-4| ... | ... | @@ -387,9 +387,9 @@ fn SliceDiffer(comptime T: type) type { |
| 387 | 387 | for (self.expected) |value, i| { |
| 388 | 388 | var full_index = self.start_index + i; |
| 389 | 389 | const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; |
| 390 | if (diff) self.ttyconf.setColor(writer, .Red); | |
| 390 | if (diff) try self.ttyconf.setColor(writer, .Red); | |
| 391 | 391 | try writer.print("[{}]: {any}\n", .{ full_index, value }); |
| 392 | if (diff) self.ttyconf.setColor(writer, .Reset); | |
| 392 | if (diff) try self.ttyconf.setColor(writer, .Reset); | |
| 393 | 393 | } |
| 394 | 394 | } |
| 395 | 395 | }; |
| ... | ... | @@ -427,9 +427,9 @@ const BytesDiffer = struct { |
| 427 | 427 | } |
| 428 | 428 | |
| 429 | 429 | fn writeByteDiff(self: BytesDiffer, writer: anytype, comptime fmt: []const u8, byte: u8, diff: bool) !void { |
| 430 | if (diff) self.ttyconf.setColor(writer, .Red); | |
| 430 | if (diff) try self.ttyconf.setColor(writer, .Red); | |
| 431 | 431 | try writer.print(fmt, .{byte}); |
| 432 | if (diff) self.ttyconf.setColor(writer, .Reset); | |
| 432 | if (diff) try self.ttyconf.setColor(writer, .Reset); | |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | const ChunkIterator = struct { |
src/Compilation.zig+15-15| ... | ... | @@ -428,29 +428,29 @@ pub const AllErrors = struct { |
| 428 | 428 | switch (msg) { |
| 429 | 429 | .src => |src| { |
| 430 | 430 | try counting_stderr.writeByteNTimes(' ', indent); |
| 431 | ttyconf.setColor(stderr, .Bold); | |
| 431 | try ttyconf.setColor(stderr, .Bold); | |
| 432 | 432 | try counting_stderr.print("{s}:{d}:{d}: ", .{ |
| 433 | 433 | src.src_path, |
| 434 | 434 | src.line + 1, |
| 435 | 435 | src.column + 1, |
| 436 | 436 | }); |
| 437 | ttyconf.setColor(stderr, color); | |
| 437 | try ttyconf.setColor(stderr, color); | |
| 438 | 438 | try counting_stderr.writeAll(kind); |
| 439 | 439 | try counting_stderr.writeAll(": "); |
| 440 | 440 | // This is the length of the part before the error message: |
| 441 | 441 | // e.g. "file.zig:4:5: error: " |
| 442 | 442 | const prefix_len = @intCast(usize, counting_stderr.context.bytes_written); |
| 443 | ttyconf.setColor(stderr, .Reset); | |
| 444 | ttyconf.setColor(stderr, .Bold); | |
| 443 | try ttyconf.setColor(stderr, .Reset); | |
| 444 | try ttyconf.setColor(stderr, .Bold); | |
| 445 | 445 | if (src.count == 1) { |
| 446 | 446 | try src.writeMsg(stderr, prefix_len); |
| 447 | 447 | try stderr.writeByte('\n'); |
| 448 | 448 | } else { |
| 449 | 449 | try src.writeMsg(stderr, prefix_len); |
| 450 | ttyconf.setColor(stderr, .Dim); | |
| 450 | try ttyconf.setColor(stderr, .Dim); | |
| 451 | 451 | try stderr.print(" ({d} times)\n", .{src.count}); |
| 452 | 452 | } |
| 453 | ttyconf.setColor(stderr, .Reset); | |
| 453 | try ttyconf.setColor(stderr, .Reset); | |
| 454 | 454 | if (src.source_line) |line| { |
| 455 | 455 | for (line) |b| switch (b) { |
| 456 | 456 | '\t' => try stderr.writeByte(' '), |
| ... | ... | @@ -462,19 +462,19 @@ pub const AllErrors = struct { |
| 462 | 462 | // -1 since span.main includes the caret |
| 463 | 463 | const after_caret = src.span.end - src.span.main -| 1; |
| 464 | 464 | try stderr.writeByteNTimes(' ', src.column - before_caret); |
| 465 | ttyconf.setColor(stderr, .Green); | |
| 465 | try ttyconf.setColor(stderr, .Green); | |
| 466 | 466 | try stderr.writeByteNTimes('~', before_caret); |
| 467 | 467 | try stderr.writeByte('^'); |
| 468 | 468 | try stderr.writeByteNTimes('~', after_caret); |
| 469 | 469 | try stderr.writeByte('\n'); |
| 470 | ttyconf.setColor(stderr, .Reset); | |
| 470 | try ttyconf.setColor(stderr, .Reset); | |
| 471 | 471 | } |
| 472 | 472 | for (src.notes) |note| { |
| 473 | 473 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent); |
| 474 | 474 | } |
| 475 | 475 | if (src.reference_trace.len != 0) { |
| 476 | ttyconf.setColor(stderr, .Reset); | |
| 477 | ttyconf.setColor(stderr, .Dim); | |
| 476 | try ttyconf.setColor(stderr, .Reset); | |
| 477 | try ttyconf.setColor(stderr, .Dim); | |
| 478 | 478 | try stderr.print("referenced by:\n", .{}); |
| 479 | 479 | for (src.reference_trace) |reference| { |
| 480 | 480 | switch (reference) { |
| ... | ... | @@ -498,23 +498,23 @@ pub const AllErrors = struct { |
| 498 | 498 | } |
| 499 | 499 | } |
| 500 | 500 | try stderr.writeByte('\n'); |
| 501 | ttyconf.setColor(stderr, .Reset); | |
| 501 | try ttyconf.setColor(stderr, .Reset); | |
| 502 | 502 | } |
| 503 | 503 | }, |
| 504 | 504 | .plain => |plain| { |
| 505 | ttyconf.setColor(stderr, color); | |
| 505 | try ttyconf.setColor(stderr, color); | |
| 506 | 506 | try stderr.writeByteNTimes(' ', indent); |
| 507 | 507 | try stderr.writeAll(kind); |
| 508 | 508 | try stderr.writeAll(": "); |
| 509 | ttyconf.setColor(stderr, .Reset); | |
| 509 | try ttyconf.setColor(stderr, .Reset); | |
| 510 | 510 | if (plain.count == 1) { |
| 511 | 511 | try stderr.print("{s}\n", .{plain.msg}); |
| 512 | 512 | } else { |
| 513 | 513 | try stderr.print("{s}", .{plain.msg}); |
| 514 | ttyconf.setColor(stderr, .Dim); | |
| 514 | try ttyconf.setColor(stderr, .Dim); | |
| 515 | 515 | try stderr.print(" ({d} times)\n", .{plain.count}); |
| 516 | 516 | } |
| 517 | ttyconf.setColor(stderr, .Reset); | |
| 517 | try ttyconf.setColor(stderr, .Reset); | |
| 518 | 518 | for (plain.notes) |note| { |
| 519 | 519 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent + 4); |
| 520 | 520 | } |