@@ -5,7 +5,6 @@ const mem = std.mem;
55const io = std .io ;
66const os = std .os ;
77const fs = std .fs ;
8- const process = std .process ;
98const testing = std .testing ;
109const elf = std .elf ;
1110const DW = std .dwarf ;
@@ -109,31 +108,6 @@ pub fn getSelfDebugInfo() !*DebugInfo {
109108 }
110109}
111110
112- pub fn detectTTYConfig (file : std.fs.File ) TTY.Config {
113- if (builtin .os .tag == .wasi ) {
114- // Per https://github.com/WebAssembly/WASI/issues/162 ANSI codes
115- // aren't currently supported.
116- return .no_color ;
117- } else if (process .hasEnvVarConstant ("ZIG_DEBUG_COLOR" )) {
118- return .escape_codes ;
119- } else if (process .hasEnvVarConstant ("NO_COLOR" )) {
120- return .no_color ;
121- } else if (file .supportsAnsiEscapeCodes ()) {
122- return .escape_codes ;
123- } else if (native_os == .windows and file .isTty ()) {
124- var info : windows.CONSOLE_SCREEN_BUFFER_INFO = undefined ;
125- if (windows .kernel32 .GetConsoleScreenBufferInfo (file .handle , & info ) != windows .TRUE ) {
126- // TODO: Should this return an error instead?
127- return .no_color ;
128- }
129- return .{ .windows_api = .{
130- .handle = file .handle ,
131- .reset_attributes = info .wAttributes ,
132- } };
133- }
134- return .no_color ;
135- }
136-
137111/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
138112/// TODO multithreaded awareness
139113pub fn dumpCurrentStackTrace (start_addr : ? usize ) void {
@@ -154,7 +128,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
154128 stderr .print ("Unable to dump stack trace: Unable to open debug info: {s}\n " , .{@errorName (err )}) catch return ;
155129 return ;
156130 };
157- writeCurrentStackTrace (stderr , debug_info , detectTTYConfig (io .getStdErr ()), start_addr ) catch | err | {
131+ writeCurrentStackTrace (stderr , debug_info , io . tty . detectConfig (io .getStdErr ()), start_addr ) catch | err | {
158132 stderr .print ("Unable to dump stack trace: {s}\n " , .{@errorName (err )}) catch return ;
159133 return ;
160134 };
@@ -182,7 +156,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
182156 stderr .print ("Unable to dump stack trace: Unable to open debug info: {s}\n " , .{@errorName (err )}) catch return ;
183157 return ;
184158 };
185- const tty_config = detectTTYConfig (io .getStdErr ());
159+ const tty_config = io . tty . detectConfig (io .getStdErr ());
186160 if (native_os == .windows ) {
187161 writeCurrentStackTraceWindows (stderr , debug_info , tty_config , ip ) catch return ;
188162 return ;
@@ -265,7 +239,7 @@ pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void {
265239 stderr .print ("Unable to dump stack trace: Unable to open debug info: {s}\n " , .{@errorName (err )}) catch return ;
266240 return ;
267241 };
268- writeStackTrace (stack_trace , stderr , getDebugInfoAllocator (), debug_info , detectTTYConfig (io .getStdErr ())) catch | err | {
242+ writeStackTrace (stack_trace , stderr , getDebugInfoAllocator (), debug_info , io . tty . detectConfig (io .getStdErr ())) catch | err | {
269243 stderr .print ("Unable to dump stack trace: {s}\n " , .{@errorName (err )}) catch return ;
270244 return ;
271245 };
@@ -403,7 +377,7 @@ pub fn writeStackTrace(
403377 out_stream : anytype ,
404378 allocator : mem.Allocator ,
405379 debug_info : * DebugInfo ,
406- tty_config : TTY .Config ,
380+ tty_config : io.tty .Config ,
407381) ! void {
408382 _ = allocator ;
409383 if (builtin .strip_debug_info ) return error .MissingDebugInfo ;
@@ -562,7 +536,7 @@ pub const StackIterator = struct {
562536pub fn writeCurrentStackTrace (
563537 out_stream : anytype ,
564538 debug_info : * DebugInfo ,
565- tty_config : TTY .Config ,
539+ tty_config : io.tty .Config ,
566540 start_addr : ? usize ,
567541) ! void {
568542 if (native_os == .windows ) {
@@ -634,7 +608,7 @@ pub noinline fn walkStackWindows(addresses: []usize) usize {
634608pub fn writeCurrentStackTraceWindows (
635609 out_stream : anytype ,
636610 debug_info : * DebugInfo ,
637- tty_config : TTY .Config ,
611+ tty_config : io.tty .Config ,
638612 start_addr : ? usize ,
639613) ! void {
640614 var addr_buf : [1024 ]usize = undefined ;
@@ -651,95 +625,6 @@ pub fn writeCurrentStackTraceWindows(
651625 }
652626}
653627
654- /// Provides simple functionality for manipulating the terminal in some way,
655- /// for debugging purposes, such as coloring text, etc.
656- pub const TTY = struct {
657- pub const Color = enum {
658- red ,
659- green ,
660- yellow ,
661- cyan ,
662- white ,
663- dim ,
664- bold ,
665- reset ,
666- };
667-
668- pub const Config = union (enum ) {
669- no_color ,
670- escape_codes ,
671- windows_api : if (native_os == .windows ) WindowsContext else void ,
672-
673- pub const WindowsContext = struct {
674- handle : File.Handle ,
675- reset_attributes : u16 ,
676- };
677-
678- pub fn setColor (conf : Config , out_stream : anytype , color : Color ) ! void {
679- nosuspend switch (conf ) {
680- .no_color = > return ,
681- .escape_codes = > {
682- const color_string = switch (color ) {
683- .red = > "\x1b [31;1m" ,
684- .green = > "\x1b [32;1m" ,
685- .yellow = > "\x1b [33;1m" ,
686- .cyan = > "\x1b [36;1m" ,
687- .white = > "\x1b [37;1m" ,
688- .bold = > "\x1b [1m" ,
689- .dim = > "\x1b [2m" ,
690- .reset = > "\x1b [0m" ,
691- };
692- try out_stream .writeAll (color_string );
693- },
694- .windows_api = > | ctx | if (native_os == .windows ) {
695- const attributes = switch (color ) {
696- .red = > windows .FOREGROUND_RED | windows .FOREGROUND_INTENSITY ,
697- .green = > windows .FOREGROUND_GREEN | windows .FOREGROUND_INTENSITY ,
698- .yellow = > windows .FOREGROUND_RED | windows .FOREGROUND_GREEN | windows .FOREGROUND_INTENSITY ,
699- .cyan = > windows .FOREGROUND_GREEN | windows .FOREGROUND_BLUE | windows .FOREGROUND_INTENSITY ,
700- .white , .bold = > windows .FOREGROUND_RED | windows .FOREGROUND_GREEN | windows .FOREGROUND_BLUE | windows .FOREGROUND_INTENSITY ,
701- .dim = > windows .FOREGROUND_INTENSITY ,
702- .reset = > ctx .reset_attributes ,
703- };
704- try windows .SetConsoleTextAttribute (ctx .handle , attributes );
705- } else {
706- unreachable ;
707- },
708- };
709- }
710-
711- pub fn writeDEC (conf : Config , writer : anytype , codepoint : u8 ) ! void {
712- const bytes = switch (conf ) {
713- .no_color , .windows_api = > switch (codepoint ) {
714- 0x50... 0x5e = > @as (* const [1 ]u8 , & codepoint ),
715- 0x6a = > "+" , // ┘
716- 0x6b = > "+" , // ┐
717- 0x6c = > "+" , // ┌
718- 0x6d = > "+" , // └
719- 0x6e = > "+" , // ┼
720- 0x71 = > "-" , // ─
721- 0x74 = > "+" , // ├
722- 0x75 = > "+" , // ┤
723- 0x76 = > "+" , // ┴
724- 0x77 = > "+" , // ┬
725- 0x78 = > "|" , // │
726- else = > " " , // TODO
727- },
728- .escape_codes = > switch (codepoint ) {
729- // Here we avoid writing the DEC beginning sequence and
730- // ending sequence in separate syscalls by putting the
731- // beginning and ending sequence into the same string
732- // literals, to prevent terminals ending up in bad states
733- // in case a crash happens between syscalls.
734- inline 0x50... 0x7f = > | x | "\x1B\x28\x30 " ++ [1 ]u8 {x } ++ "\x1B\x28\x42 " ,
735- else = > unreachable ,
736- },
737- };
738- return writer .writeAll (bytes );
739- }
740- };
741- };
742-
743628fn machoSearchSymbols (symbols : []const MachoSymbol , address : usize ) ? * const MachoSymbol {
744629 var min : usize = 0 ;
745630 var max : usize = symbols .len - 1 ;
@@ -785,7 +670,7 @@ test "machoSearchSymbols" {
785670 try testing .expectEqual (& symbols [2 ], machoSearchSymbols (& symbols , 5000 ).? );
786671}
787672
788- fn printUnknownSource (debug_info : * DebugInfo , out_stream : anytype , address : usize , tty_config : TTY .Config ) ! void {
673+ fn printUnknownSource (debug_info : * DebugInfo , out_stream : anytype , address : usize , tty_config : io.tty .Config ) ! void {
789674 const module_name = debug_info .getModuleNameForAddress (address );
790675 return printLineInfo (
791676 out_stream ,
@@ -798,7 +683,7 @@ fn printUnknownSource(debug_info: *DebugInfo, out_stream: anytype, address: usiz
798683 );
799684}
800685
801- pub fn printSourceAtAddress (debug_info : * DebugInfo , out_stream : anytype , address : usize , tty_config : TTY .Config ) ! void {
686+ pub fn printSourceAtAddress (debug_info : * DebugInfo , out_stream : anytype , address : usize , tty_config : io.tty .Config ) ! void {
802687 const module = debug_info .getModuleForAddress (address ) catch | err | switch (err ) {
803688 error .MissingDebugInfo , error .InvalidDebugInfo = > return printUnknownSource (debug_info , out_stream , address , tty_config ),
804689 else = > return err ,
@@ -827,7 +712,7 @@ fn printLineInfo(
827712 address : usize ,
828713 symbol_name : []const u8 ,
829714 compile_unit_name : []const u8 ,
830- tty_config : TTY .Config ,
715+ tty_config : io.tty .Config ,
831716 comptime printLineFromFile : anytype ,
832717) ! void {
833718 nosuspend {
@@ -2193,7 +2078,7 @@ test "manage resources correctly" {
21932078 const writer = std .io .null_writer ;
21942079 var di = try openSelfDebugInfo (testing .allocator );
21952080 defer di .deinit ();
2196- try printSourceAtAddress (& di , writer , showMyTrace (), detectTTYConfig (std .io .getStdErr ()));
2081+ try printSourceAtAddress (& di , writer , showMyTrace (), io . tty . detectConfig (std .io .getStdErr ()));
21972082}
21982083
21992084noinline fn showMyTrace () usize {
@@ -2253,7 +2138,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
22532138 pub fn dump (t : @This ()) void {
22542139 if (! enabled ) return ;
22552140
2256- const tty_config = detectTTYConfig (std .io .getStdErr ());
2141+ const tty_config = io . tty . detectConfig (std .io .getStdErr ());
22572142 const stderr = io .getStdErr ().writer ();
22582143 const end = @min (t .index , size );
22592144 const debug_info = getSelfDebugInfo () catch | err | {
0 commit comments