Skip to content

Commit 14cb53d

Browse files
committed
std: Move std.debug.{TTY.Config,detectTTYConfig} to std.io.tty
Also get rid of the TTY wrapper struct, which was exlusively used as a namespace - this is done by the tty.zig root struct now. detectTTYConfig has been renamed to just detectConfig, which is enough given the new namespace. Additionally, a doc comment had been added.
1 parent 9029af6 commit 14cb53d

File tree

11 files changed

+152
-144
lines changed

11 files changed

+152
-144
lines changed

lib/build_runner.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ const Run = struct {
333333

334334
claimed_rss: usize,
335335
enable_summary: ?bool,
336-
ttyconf: std.debug.TTY.Config,
336+
ttyconf: std.io.tty.Config,
337337
stderr: std.fs.File,
338338
};
339339

@@ -535,7 +535,7 @@ const PrintNode = struct {
535535
last: bool = false,
536536
};
537537

538-
fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.debug.TTY.Config) !void {
538+
fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.io.tty.Config) !void {
539539
const parent = node.parent orelse return;
540540
if (parent.parent == null) return;
541541
try printPrefix(parent, stderr, ttyconf);
@@ -553,7 +553,7 @@ fn printTreeStep(
553553
b: *std.Build,
554554
s: *Step,
555555
stderr: std.fs.File,
556-
ttyconf: std.debug.TTY.Config,
556+
ttyconf: std.io.tty.Config,
557557
parent_node: *PrintNode,
558558
step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void),
559559
) !void {
@@ -1026,15 +1026,15 @@ fn cleanExit() void {
10261026

10271027
const Color = enum { auto, off, on };
10281028

1029-
fn get_tty_conf(color: Color, stderr: std.fs.File) std.debug.TTY.Config {
1029+
fn get_tty_conf(color: Color, stderr: std.fs.File) std.io.tty.Config {
10301030
return switch (color) {
1031-
.auto => std.debug.detectTTYConfig(stderr),
1031+
.auto => std.io.tty.detectConfig(stderr),
10321032
.on => .escape_codes,
10331033
.off => .no_color,
10341034
};
10351035
}
10361036

1037-
fn renderOptions(ttyconf: std.debug.TTY.Config) std.zig.ErrorBundle.RenderOptions {
1037+
fn renderOptions(ttyconf: std.io.tty.Config) std.zig.ErrorBundle.RenderOptions {
10381038
return .{
10391039
.ttyconf = ttyconf,
10401040
.include_source_line = ttyconf != .no_color,

lib/std/Build.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ fn dumpBadGetPathHelp(
17121712
s.name,
17131713
});
17141714

1715-
const tty_config = std.debug.detectTTYConfig(stderr);
1715+
const tty_config = std.io.tty.detectConfig(stderr);
17161716
tty_config.setColor(w, .red) catch {};
17171717
try stderr.writeAll(" The step was created by this stack trace:\n");
17181718
tty_config.setColor(w, .reset) catch {};

lib/std/Build/Step.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub fn dump(step: *Step) void {
237237

238238
const stderr = std.io.getStdErr();
239239
const w = stderr.writer();
240-
const tty_config = std.debug.detectTTYConfig(stderr);
240+
const tty_config = std.io.tty.detectConfig(stderr);
241241
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
242242
w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{
243243
@errorName(err),

lib/std/builtin.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub const StackTrace = struct {
5151
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
5252
return writer.print("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
5353
};
54-
const tty_config = std.debug.detectTTYConfig(std.io.getStdErr());
54+
const tty_config = std.io.tty.detectConfig(std.io.getStdErr());
5555
try writer.writeAll("\n");
5656
std.debug.writeStackTrace(self, writer, arena.allocator(), debug_info, tty_config) catch |err| {
5757
try writer.print("Unable to print stack trace: {s}\n", .{@errorName(err)});

lib/std/debug.zig

Lines changed: 11 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const mem = std.mem;
55
const io = std.io;
66
const os = std.os;
77
const fs = std.fs;
8-
const process = std.process;
98
const testing = std.testing;
109
const elf = std.elf;
1110
const 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
139113
pub 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 {
562536
pub 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 {
634608
pub 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-
743628
fn 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

21992084
noinline 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| {

lib/std/io.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ pub const BufferedAtomicFile = @import("io/buffered_atomic_file.zig").BufferedAt
155155

156156
pub const StreamSource = @import("io/stream_source.zig").StreamSource;
157157

158+
pub const tty = @import("io/tty.zig");
159+
158160
/// A Writer that doesn't write to anything.
159161
pub const null_writer = @as(NullWriter, .{ .context = {} });
160162

0 commit comments

Comments
 (0)