aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-12-17 17:00:41 -0800
committerAndrew Kelley <andrew@ziglang.org>2025-12-23 22:15:10 -0800
commit608145c2f07d90c46cdaa8bc2013f31b965a5b8b (patch)
treea8704744b3808887c25ecf7b674eed030b2f6c7d /lib
parentaa57793b680b3da05f1d888b4df15807905e57c8 (diff)
downloadzig-608145c2f07d90c46cdaa8bc2013f31b965a5b8b.tar.gz
zig-608145c2f07d90c46cdaa8bc2013f31b965a5b8b.zip
fix more fallout from locking stderr
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/aro/aro/Diagnostics.zig28
-rw-r--r--lib/compiler/build_runner.zig338
-rw-r--r--lib/compiler/resinator/cli.zig10
-rw-r--r--lib/compiler/resinator/errors.zig6
-rw-r--r--lib/compiler/resinator/main.zig31
-rw-r--r--lib/compiler/test_runner.zig8
-rw-r--r--lib/std/Build.zig73
-rw-r--r--lib/std/Build/Fuzz.zig18
-rw-r--r--lib/std/Build/Step.zig9
-rw-r--r--lib/std/Build/Step/Compile.zig17
-rw-r--r--lib/std/Build/Step/Run.zig22
-rw-r--r--lib/std/Io.zig2
-rw-r--r--lib/std/Io/File/Writer.zig2
-rw-r--r--lib/std/Io/Terminal.zig22
-rw-r--r--lib/std/Io/Threaded.zig6
-rw-r--r--lib/std/debug.zig24
-rw-r--r--lib/std/debug/simple_panic.zig6
-rw-r--r--lib/std/json/dynamic.zig6
-rw-r--r--lib/std/log.zig2
-rw-r--r--lib/std/process.zig2
-rw-r--r--lib/std/testing.zig21
-rw-r--r--lib/std/zig.zig21
-rw-r--r--lib/std/zig/ErrorBundle.zig72
-rw-r--r--lib/std/zig/parser_test.zig16
24 files changed, 368 insertions, 394 deletions
diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig
index bebcf4e3d2..b33efa3f85 100644
--- a/lib/compiler/aro/aro/Diagnostics.zig
+++ b/lib/compiler/aro/aro/Diagnostics.zig
@@ -24,20 +24,21 @@ pub const Message = struct {
@"fatal error",
};
- pub fn write(msg: Message, w: *std.Io.Writer, config: std.Io.File.Writer.Mode, details: bool) std.Io.tty.Config.SetColorError!void {
- try config.setColor(w, .bold);
+ pub fn write(msg: Message, t: std.Io.Terminal, details: bool) std.Io.Terminal.SetColorError!void {
+ const w = t.writer;
+ try t.setColor(.bold);
if (msg.location) |loc| {
try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col });
}
switch (msg.effective_kind) {
- .@"fatal error", .@"error" => try config.setColor(w, .bright_red),
- .note => try config.setColor(w, .bright_cyan),
- .warning => try config.setColor(w, .bright_magenta),
+ .@"fatal error", .@"error" => try t.setColor(.bright_red),
+ .note => try t.setColor(.bright_cyan),
+ .warning => try t.setColor(.bright_magenta),
.off => unreachable,
}
try w.print("{s}: ", .{@tagName(msg.effective_kind)});
- try config.setColor(w, .white);
+ try t.setColor(.white);
try w.writeAll(msg.text);
if (msg.opt) |some| {
if (msg.effective_kind == .@"error" and msg.kind != .@"error") {
@@ -55,17 +56,17 @@ pub const Message = struct {
if (!details or msg.location == null) {
try w.writeAll("\n");
- try config.setColor(w, .reset);
+ try t.setColor(.reset);
} else {
const loc = msg.location.?;
const trailer = if (loc.end_with_splice) "\\ " else "";
- try config.setColor(w, .reset);
+ try t.setColor(.reset);
try w.print("\n{s}{s}\n", .{ loc.line, trailer });
try w.splatByteAll(' ', loc.width);
- try config.setColor(w, .bold);
- try config.setColor(w, .bright_green);
+ try t.setColor(.bold);
+ try t.setColor(.bright_green);
try w.writeAll("^\n");
- try config.setColor(w, .reset);
+ try t.setColor(.reset);
}
try w.flush();
}
@@ -290,10 +291,7 @@ pub const State = struct {
const Diagnostics = @This();
output: union(enum) {
- to_writer: struct {
- writer: *std.Io.Writer,
- color: std.Io.File.Writer.Mode,
- },
+ to_writer: std.Io.Terminal,
to_list: struct {
messages: std.ArrayList(Message) = .empty,
arena: std.heap.ArenaAllocator,
diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig
index d284d85747..1c30ecaadc 100644
--- a/lib/compiler/build_runner.zig
+++ b/lib/compiler/build_runner.zig
@@ -286,8 +286,8 @@ pub fn main() !void {
const next_arg = nextArg(args, &arg_idx) orelse
fatalWithHint("expected u16 after '{s}'", .{arg});
debounce_interval_ms = std.fmt.parseUnsigned(u16, next_arg, 0) catch |err| {
- fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {s}\n", .{
- next_arg, @errorName(err),
+ fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {t}\n", .{
+ next_arg, err,
});
};
} else if (mem.eql(u8, arg, "--webui")) {
@@ -429,6 +429,12 @@ pub fn main() !void {
}
}
+ graph.stderr_mode = switch (color) {
+ .auto => try .detect(io, .stderr()),
+ .on => .escape_codes,
+ .off => .no_color,
+ };
+
if (webui_listen != null) {
if (watch) fatal("using '--webui' and '--watch' together is not yet supported; consider omitting '--watch' in favour of the web UI \"Rebuild\" button", .{});
if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});
@@ -522,7 +528,7 @@ pub fn main() !void {
// Perhaps in the future there could be an Advanced Options flag
// such as --debug-build-runner-leaks which would make this code
// return instead of calling exit.
- _ = io.lockStderrWriter(&.{}) catch {};
+ _ = io.lockStderr(&.{}, graph.stderr_mode) catch {};
process.exit(1);
},
else => |e| return e,
@@ -554,9 +560,9 @@ pub fn main() !void {
}
rebuild: while (true) : (if (run.error_style.clearOnUpdate()) {
- const stderr = try io.lockStderrWriter(&stdio_buffer_allocation);
- defer io.unlockStderrWriter();
- try stderr.writeAllUnescaped("\x1B[2J\x1B[3J\x1B[H");
+ const stderr = try io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode);
+ defer io.unlockStderr();
+ try stderr.file_writer.interface.writeAll("\x1B[2J\x1B[3J\x1B[H");
}) {
if (run.web_server) |*ws| ws.startBuild();
@@ -730,7 +736,8 @@ fn runStepNames(
fuzz: ?std.Build.Fuzz.Mode,
) !void {
const gpa = run.gpa;
- const io = b.graph.io;
+ const graph = b.graph;
+ const io = graph.io;
const step_stack = &run.step_stack;
{
@@ -856,20 +863,19 @@ fn runStepNames(
.none => break :summary,
}
- const stderr = try io.lockStderrWriter(&stdio_buffer_allocation);
- defer io.unlockStderrWriter();
-
- const w = &stderr.interface;
- const fwm = stderr.mode;
+ const stderr = try io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode);
+ defer io.unlockStderr();
+ const t = stderr.terminal();
+ const w = &stderr.file_writer.interface;
const total_count = success_count + failure_count + pending_count + skipped_count;
- fwm.setColor(w, .cyan) catch {};
- fwm.setColor(w, .bold) catch {};
+ t.setColor(.cyan) catch {};
+ t.setColor(.bold) catch {};
w.writeAll("Build Summary: ") catch {};
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.reset) catch {};
w.print("{d}/{d} steps succeeded", .{ success_count, total_count }) catch {};
{
- fwm.setColor(w, .dim) catch {};
+ t.setColor(.dim) catch {};
var first = true;
if (skipped_count > 0) {
w.print("{s}{d} skipped", .{ if (first) " (" else ", ", skipped_count }) catch {};
@@ -880,12 +886,12 @@ fn runStepNames(
first = false;
}
if (!first) w.writeByte(')') catch {};
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.reset) catch {};
}
if (test_count > 0) {
w.print("; {d}/{d} tests passed", .{ test_pass_count, test_count }) catch {};
- fwm.setColor(w, .dim) catch {};
+ t.setColor(.dim) catch {};
var first = true;
if (test_skip_count > 0) {
w.print("{s}{d} skipped", .{ if (first) " (" else ", ", test_skip_count }) catch {};
@@ -904,7 +910,7 @@ fn runStepNames(
first = false;
}
if (!first) w.writeByte(')') catch {};
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.reset) catch {};
}
w.writeAll("\n") catch {};
@@ -918,7 +924,7 @@ fn runStepNames(
var print_node: PrintNode = .{ .parent = null };
if (step_names.len == 0) {
print_node.last = true;
- printTreeStep(b, b.default_step, run, w, fwm, &print_node, &step_stack_copy) catch {};
+ printTreeStep(b, b.default_step, run, t, &print_node, &step_stack_copy) catch {};
} else {
const last_index = if (run.summary == .all) b.top_level_steps.count() else blk: {
var i: usize = step_names.len;
@@ -937,7 +943,7 @@ fn runStepNames(
for (step_names, 0..) |step_name, i| {
const tls = b.top_level_steps.get(step_name).?;
print_node.last = i + 1 == last_index;
- printTreeStep(b, &tls.step, run, w, fwm, &print_node, &step_stack_copy) catch {};
+ printTreeStep(b, &tls.step, run, t, &print_node, &step_stack_copy) catch {};
}
}
w.writeByte('\n') catch {};
@@ -954,7 +960,7 @@ fn runStepNames(
if (run.error_style.verboseContext()) break :code 1; // failure; print build command
break :code 2; // failure; do not print build command
};
- _ = io.lockStderrWriter(&.{}) catch {};
+ _ = io.lockStderr(&.{}, graph.stderr_mode) catch {};
process.exit(code);
}
@@ -963,33 +969,30 @@ const PrintNode = struct {
last: bool = false,
};
-fn printPrefix(node: *PrintNode, w: *Writer, fwm: File.Writer.Mode) !void {
+fn printPrefix(node: *PrintNode, stderr: Io.Terminal) !void {
const parent = node.parent orelse return;
+ const writer = stderr.writer;
if (parent.parent == null) return;
- try printPrefix(parent, w, fwm);
+ try printPrefix(parent, stderr);
if (parent.last) {
- try w.writeAll(" ");
+ try writer.writeAll(" ");
} else {
- try w.writeAll(switch (fwm) {
- .terminal_escaped => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │
+ try writer.writeAll(switch (stderr.mode) {
+ .escape_codes => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │
else => "| ",
});
}
}
-fn printChildNodePrefix(w: *Writer, fwm: File.Writer.Mode) !void {
- try w.writeAll(switch (fwm) {
- .terminal_escaped => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─
+fn printChildNodePrefix(stderr: Io.Terminal) !void {
+ try stderr.writer.writeAll(switch (stderr.mode) {
+ .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─
else => "+- ",
});
}
-fn printStepStatus(
- s: *Step,
- stderr: *Writer,
- fwm: File.Writer.Mode,
- run: *const Run,
-) !void {
+fn printStepStatus(s: *Step, stderr: Io.Terminal, run: *const Run) !void {
+ const writer = stderr.writer;
switch (s.state) {
.precheck_unstarted => unreachable,
.precheck_started => unreachable,
@@ -997,139 +1000,135 @@ fn printStepStatus(
.running => unreachable,
.dependency_failure => {
- try fwm.setColor(stderr, .dim);
- try stderr.writeAll(" transitive failure\n");
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.dim);
+ try writer.writeAll(" transitive failure\n");
+ try stderr.setColor(.reset);
},
.success => {
- try fwm.setColor(stderr, .green);
+ try stderr.setColor(.green);
if (s.result_cached) {
- try stderr.writeAll(" cached");
+ try writer.writeAll(" cached");
} else if (s.test_results.test_count > 0) {
const pass_count = s.test_results.passCount();
assert(s.test_results.test_count == pass_count + s.test_results.skip_count);
- try stderr.print(" {d} pass", .{pass_count});
+ try writer.print(" {d} pass", .{pass_count});
if (s.test_results.skip_count > 0) {
- try fwm.setColor(stderr, .reset);
- try stderr.writeAll(", ");
- try fwm.setColor(stderr, .yellow);
- try stderr.print("{d} skip", .{s.test_results.skip_count});
+ try stderr.setColor(.reset);
+ try writer.writeAll(", ");
+ try stderr.setColor(.yellow);
+ try writer.print("{d} skip", .{s.test_results.skip_count});
}
- try fwm.setColor(stderr, .reset);
- try stderr.print(" ({d} total)", .{s.test_results.test_count});
+ try stderr.setColor(.reset);
+ try writer.print(" ({d} total)", .{s.test_results.test_count});
} else {
- try stderr.writeAll(" success");
+ try writer.writeAll(" success");
}
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.reset);
if (s.result_duration_ns) |ns| {
- try fwm.setColor(stderr, .dim);
+ try stderr.setColor(.dim);
if (ns >= std.time.ns_per_min) {
- try stderr.print(" {d}m", .{ns / std.time.ns_per_min});
+ try writer.print(" {d}m", .{ns / std.time.ns_per_min});
} else if (ns >= std.time.ns_per_s) {
- try stderr.print(" {d}s", .{ns / std.time.ns_per_s});
+ try writer.print(" {d}s", .{ns / std.time.ns_per_s});
} else if (ns >= std.time.ns_per_ms) {
- try stderr.print(" {d}ms", .{ns / std.time.ns_per_ms});
+ try writer.print(" {d}ms", .{ns / std.time.ns_per_ms});
} else if (ns >= std.time.ns_per_us) {
- try stderr.print(" {d}us", .{ns / std.time.ns_per_us});
+ try writer.print(" {d}us", .{ns / std.time.ns_per_us});
} else {
- try stderr.print(" {d}ns", .{ns});
+ try writer.print(" {d}ns", .{ns});
}
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.reset);
}
if (s.result_peak_rss != 0) {
const rss = s.result_peak_rss;
- try fwm.setColor(stderr, .dim);
+ try stderr.setColor(.dim);
if (rss >= 1000_000_000) {
- try stderr.print(" MaxRSS:{d}G", .{rss / 1000_000_000});
+ try writer.print(" MaxRSS:{d}G", .{rss / 1000_000_000});
} else if (rss >= 1000_000) {
- try stderr.print(" MaxRSS:{d}M", .{rss / 1000_000});
+ try writer.print(" MaxRSS:{d}M", .{rss / 1000_000});
} else if (rss >= 1000) {
- try stderr.print(" MaxRSS:{d}K", .{rss / 1000});
+ try writer.print(" MaxRSS:{d}K", .{rss / 1000});
} else {
- try stderr.print(" MaxRSS:{d}B", .{rss});
+ try writer.print(" MaxRSS:{d}B", .{rss});
}
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.reset);
}
- try stderr.writeAll("\n");
+ try writer.writeAll("\n");
},
.skipped, .skipped_oom => |skip| {
- try fwm.setColor(stderr, .yellow);
- try stderr.writeAll(" skipped");
+ try stderr.setColor(.yellow);
+ try writer.writeAll(" skipped");
if (skip == .skipped_oom) {
- try stderr.writeAll(" (not enough memory)");
- try fwm.setColor(stderr, .dim);
- try stderr.print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss });
- try fwm.setColor(stderr, .yellow);
+ try writer.writeAll(" (not enough memory)");
+ try stderr.setColor(.dim);
+ try writer.print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss });
+ try stderr.setColor(.yellow);
}
- try stderr.writeAll("\n");
- try fwm.setColor(stderr, .reset);
+ try writer.writeAll("\n");
+ try stderr.setColor(.reset);
},
.failure => {
- try printStepFailure(s, stderr, fwm, false);
- try fwm.setColor(stderr, .reset);
+ try printStepFailure(s, stderr, false);
+ try stderr.setColor(.reset);
},
}
}
-fn printStepFailure(
- s: *Step,
- stderr: *Writer,
- fwm: File.Writer.Mode,
- dim: bool,
-) !void {
+fn printStepFailure(s: *Step, stderr: Io.Terminal, dim: bool) !void {
+ const w = stderr.writer;
if (s.result_error_bundle.errorMessageCount() > 0) {
- try fwm.setColor(stderr, .red);
- try stderr.print(" {d} errors\n", .{
+ try stderr.setColor(.red);
+ try w.print(" {d} errors\n", .{
s.result_error_bundle.errorMessageCount(),
});
} else if (!s.test_results.isSuccess()) {
// These first values include all of the test "statuses". Every test is either passsed,
// skipped, failed, crashed, or timed out.
- try fwm.setColor(stderr, .green);
- try stderr.print(" {d} pass", .{s.test_results.passCount()});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try stderr.setColor(.green);
+ try w.print(" {d} pass", .{s.test_results.passCount()});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
if (s.test_results.skip_count > 0) {
- try stderr.writeAll(", ");
- try fwm.setColor(stderr, .yellow);
- try stderr.print("{d} skip", .{s.test_results.skip_count});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try w.writeAll(", ");
+ try stderr.setColor(.yellow);
+ try w.print("{d} skip", .{s.test_results.skip_count});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
}
if (s.test_results.fail_count > 0) {
- try stderr.writeAll(", ");
- try fwm.setColor(stderr, .red);
- try stderr.print("{d} fail", .{s.test_results.fail_count});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try w.writeAll(", ");
+ try stderr.setColor(.red);
+ try w.print("{d} fail", .{s.test_results.fail_count});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
}
if (s.test_results.crash_count > 0) {
- try stderr.writeAll(", ");
- try fwm.setColor(stderr, .red);
- try stderr.print("{d} crash", .{s.test_results.crash_count});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try w.writeAll(", ");
+ try stderr.setColor(.red);
+ try w.print("{d} crash", .{s.test_results.crash_count});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
}
if (s.test_results.timeout_count > 0) {
- try stderr.writeAll(", ");
- try fwm.setColor(stderr, .red);
- try stderr.print("{d} timeout", .{s.test_results.timeout_count});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try w.writeAll(", ");
+ try stderr.setColor(.red);
+ try w.print("{d} timeout", .{s.test_results.timeout_count});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
}
- try stderr.print(" ({d} total)", .{s.test_results.test_count});
+ try w.print(" ({d} total)", .{s.test_results.test_count});
// Memory leaks are intentionally written after the total, because is isn't a test *status*,
// but just a flag that any tests -- even passed ones -- can have. We also use a different
// separator, so it looks like:
// 2 pass, 1 skip, 2 fail (5 total); 2 leaks
if (s.test_results.leak_count > 0) {
- try stderr.writeAll("; ");
- try fwm.setColor(stderr, .red);
- try stderr.print("{d} leaks", .{s.test_results.leak_count});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try w.writeAll("; ");
+ try stderr.setColor(.red);
+ try w.print("{d} leaks", .{s.test_results.leak_count});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
}
// It's usually not helpful to know how many error logs there were because they tend to
@@ -1142,21 +1141,21 @@ fn printStepFailure(
break :show alt_results.isSuccess();
};
if (show_err_logs) {
- try stderr.writeAll("; ");
- try fwm.setColor(stderr, .red);
- try stderr.print("{d} error logs", .{s.test_results.log_err_count});
- try fwm.setColor(stderr, .reset);
- if (dim) try fwm.setColor(stderr, .dim);
+ try w.writeAll("; ");
+ try stderr.setColor(.red);
+ try w.print("{d} error logs", .{s.test_results.log_err_count});
+ try stderr.setColor(.reset);
+ if (dim) try stderr.setColor(.dim);
}
- try stderr.writeAll("\n");
+ try w.writeAll("\n");
} else if (s.result_error_msgs.items.len > 0) {
- try fwm.setColor(stderr, .red);
- try stderr.writeAll(" failure\n");
+ try stderr.setColor(.red);
+ try w.writeAll(" failure\n");
} else {
assert(s.result_stderr.len > 0);
- try fwm.setColor(stderr, .red);
- try stderr.writeAll(" stderr\n");
+ try stderr.setColor(.red);
+ try w.writeAll(" w\n");
}
}
@@ -1164,11 +1163,11 @@ fn printTreeStep(
b: *std.Build,
s: *Step,
run: *const Run,
- stderr: *Writer,
- fwm: File.Writer.Mode,
+ stderr: Io.Terminal,
parent_node: *PrintNode,
step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void),
) !void {
+ const writer = stderr.writer;
const first = step_stack.swapRemove(s);
const summary = run.summary;
const skip = switch (summary) {
@@ -1178,26 +1177,26 @@ fn printTreeStep(
.failures => s.state == .success,
};
if (skip) return;
- try printPrefix(parent_node, stderr, fwm);
+ try printPrefix(parent_node, stderr);
if (parent_node.parent != null) {
if (parent_node.last) {
- try printChildNodePrefix(stderr, fwm);
+ try printChildNodePrefix(stderr);
} else {
- try stderr.writeAll(switch (fwm) {
- .terminal_escaped => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─
+ try writer.writeAll(switch (stderr.mode) {
+ .escape_codes => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─
else => "+- ",
});
}
}
- if (!first) try fwm.setColor(stderr, .dim);
+ if (!first) try stderr.setColor(.dim);
// dep_prefix omitted here because it is redundant with the tree.
- try stderr.writeAll(s.name);
+ try writer.writeAll(s.name);
if (first) {
- try printStepStatus(s, stderr, fwm, run);
+ try printStepStatus(s, stderr, run);
const last_index = if (summary == .all) s.dependencies.items.len -| 1 else blk: {
var i: usize = s.dependencies.items.len;
@@ -1219,17 +1218,17 @@ fn printTreeStep(
.parent = parent_node,
.last = i == last_index,
};
- try printTreeStep(b, dep, run, stderr, fwm, &print_node, step_stack);
+ try printTreeStep(b, dep, run, stderr, &print_node, step_stack);
}
} else {
if (s.dependencies.items.len == 0) {
- try stderr.writeAll(" (reused)\n");
+ try writer.writeAll(" (reused)\n");
} else {
- try stderr.print(" (+{d} more reused dependencies)\n", .{
+ try writer.print(" (+{d} more reused dependencies)\n", .{
s.dependencies.items.len,
});
}
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.reset);
}
}
@@ -1300,7 +1299,8 @@ fn workerMakeOneStep(
prog_node: std.Progress.Node,
run: *Run,
) void {
- const io = b.graph.io;
+ const graph = b.graph;
+ const io = graph.io;
const gpa = run.gpa;
// First, check the conditions for running this step. If they are not met,
@@ -1369,11 +1369,11 @@ fn workerMakeOneStep(
const show_error_msgs = s.result_error_msgs.items.len > 0;
const show_stderr = s.result_stderr.len > 0;
if (show_error_msgs or show_compile_errors or show_stderr) {
- const stderr = io.lockStderrWriter(&stdio_buffer_allocation) catch |err| switch (err) {
+ const stderr = io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode) catch |err| switch (err) {
error.Canceled => return,
};
- defer io.unlockStderrWriter();
- printErrorMessages(gpa, s, .{}, &stderr.interface, stderr.mode, run.error_style, run.multiline_errors) catch {};
+ defer io.unlockStderr();
+ printErrorMessages(gpa, s, .{}, stderr.terminal(), run.error_style, run.multiline_errors) catch {};
}
handle_result: {
@@ -1440,11 +1440,11 @@ pub fn printErrorMessages(
gpa: Allocator,
failing_step: *Step,
options: std.zig.ErrorBundle.RenderOptions,
- stderr: *Writer,
- fwm: File.Writer.Mode,
+ stderr: Io.Terminal,
error_style: ErrorStyle,
multiline_errors: MultilineErrors,
) !void {
+ const writer = stderr.writer;
if (error_style.verboseContext()) {
// Provide context for where these error messages are coming from by
// printing the corresponding Step subtree.
@@ -1456,70 +1456,70 @@ pub fn printErrorMessages(
}
// Now, `step_stack` has the subtree that we want to print, in reverse order.
- try fwm.setColor(stderr, .dim);
+ try stderr.setColor(.dim);
var indent: usize = 0;
while (step_stack.pop()) |s| : (indent += 1) {
if (indent > 0) {
- try stderr.splatByteAll(' ', (indent - 1) * 3);
- try printChildNodePrefix(stderr, fwm);
+ try writer.splatByteAll(' ', (indent - 1) * 3);
+ try printChildNodePrefix(stderr);
}
- try stderr.writeAll(s.name);
+ try writer.writeAll(s.name);
if (s == failing_step) {
- try printStepFailure(s, stderr, fwm, true);
+ try printStepFailure(s, stderr, true);
} else {
- try stderr.writeAll("\n");
+ try writer.writeAll("\n");
}
}
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.reset);
} else {
// Just print the failing step itself.
- try fwm.setColor(stderr, .dim);
- try stderr.writeAll(failing_step.name);
- try printStepFailure(failing_step, stderr, fwm, true);
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.dim);
+ try writer.writeAll(failing_step.name);
+ try printStepFailure(failing_step, stderr, true);
+ try stderr.setColor(.reset);
}
if (failing_step.result_stderr.len > 0) {
- try stderr.writeAll(failing_step.result_stderr);
+ try writer.writeAll(failing_step.result_stderr);
if (!mem.endsWith(u8, failing_step.result_stderr, "\n")) {
- try stderr.writeAll("\n");
+ try writer.writeAll("\n");
}
}
- try failing_step.result_error_bundle.renderToWriter(options, stderr, fwm);
+ try failing_step.result_error_bundle.renderToTerminal(options, stderr);
for (failing_step.result_error_msgs.items) |msg| {
- try fwm.setColor(stderr, .red);
- try stderr.writeAll("error:");
- try fwm.setColor(stderr, .reset);
+ try stderr.setColor(.red);
+ try writer.writeAll("error:");
+ try stderr.setColor(.reset);
if (std.mem.indexOfScalar(u8, msg, '\n') == null) {
- try stderr.print(" {s}\n", .{msg});
+ try writer.print(" {s}\n", .{msg});
} else switch (multiline_errors) {
.indent => {
var it = std.mem.splitScalar(u8, msg, '\n');
- try stderr.print(" {s}\n", .{it.first()});
+ try writer.print(" {s}\n", .{it.first()});
while (it.next()) |line| {
- try stderr.print(" {s}\n", .{line});
+ try writer.print(" {s}\n", .{line});
}
},
- .newline => try stderr.print("\n{s}\n", .{msg}),
- .none => try stderr.print(" {s}\n", .{msg}),
+ .newline => try writer.print("\n{s}\n", .{msg}),
+ .none => try writer.print(" {s}\n", .{msg}),
}
}
if (error_style.verboseContext()) {
if (failing_step.result_failed_command) |cmd_str| {
- try fwm.setColor(stderr, .red);
- try stderr.writeAll("failed command: ");
- try fwm.setColor(stderr, .reset);
- try stderr.writeAll(cmd_str);
- try stderr.writeByte('\n');
+ try stderr.setColor(.red);
+ try writer.writeAll("failed command: ");
+ try stderr.setColor(.reset);
+ try writer.writeAll(cmd_str);
+ try writer.writeByte('\n');
}
}
- try stderr.writeByte('\n');
+ try writer.writeByte('\n');
}
fn printSteps(builder: *std.Build, w: *Writer) !void {
diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig
index 08befbe1fa..ddf3ca18b7 100644
--- a/lib/compiler/resinator/cli.zig
+++ b/lib/compiler/resinator/cli.zig
@@ -126,14 +126,14 @@ pub const Diagnostics = struct {
}
pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) void {
- const stderr = io.lockStderrWriter(&.{});
- defer io.unlockStderrWriter();
- self.renderToWriter(args, &stderr.interface, stderr.mode) catch return;
+ const stderr = io.lockStderr(&.{}, null);
+ defer io.unlockStderr();
+ self.renderToWriter(args, stderr.terminal()) catch return;
}
- pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void {
+ pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, t: Io.Terminal) !void {
for (self.errors.items) |err_details| {
- try renderErrorMessage(writer, config, err_details, args);
+ try renderErrorMessage(t, err_details, args);
}
}
diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig
index 031b5d3574..6146f777cd 100644
--- a/lib/compiler/resinator/errors.zig
+++ b/lib/compiler/resinator/errors.zig
@@ -69,10 +69,10 @@ pub const Diagnostics = struct {
pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
const io = self.io;
- const stderr = io.lockStderrWriter(&.{});
- defer io.unlockStderrWriter();
+ const stderr = io.lockStderr(&.{}, null);
+ defer io.unlockStderr();
for (self.errors.items) |err_details| {
- renderErrorMessage(io, &stderr.interface, stderr.mode, cwd, err_details, source, self.strings.items, source_mappings) catch return;
+ renderErrorMessage(io, stderr.terminal(), cwd, err_details, source, self.strings.items, source_mappings) catch return;
}
}
diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig
index bd2fcc912e..81a3a8689a 100644
--- a/lib/compiler/resinator/main.zig
+++ b/lib/compiler/resinator/main.zig
@@ -35,8 +35,8 @@ pub fn main() !void {
const args = try std.process.argsAlloc(arena);
if (args.len < 2) {
- const stderr = io.lockStderrWriter(&.{});
- try renderErrorMessage(&stderr.interface, stderr.mode, .err, "expected zig lib dir as first argument", .{});
+ const stderr = try io.lockStderr(&.{}, null);
+ try renderErrorMessage(stderr.terminal(), .err, "expected zig lib dir as first argument", .{});
std.process.exit(1);
}
const zig_lib_dir = args[1];
@@ -80,9 +80,9 @@ pub fn main() !void {
// so that there is a clear separation between the cli diagnostics and whatever
// gets printed after
if (cli_diagnostics.errors.items.len > 0) {
- const stderr = io.lockStderrWriter(&.{});
- defer io.unlockStderrWriter();
- try stderr.interface.writeByte('\n');
+ const stderr = try io.lockStderr(&.{}, null);
+ defer io.unlockStderr();
+ try stderr.file_writer.interface.writeByte('\n');
}
}
break :options options;
@@ -130,15 +130,12 @@ pub fn main() !void {
var stderr_buf: [512]u8 = undefined;
var diagnostics: aro.Diagnostics = .{ .output = output: {
if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } };
- const stderr = io.lockStderrWriter(&stderr_buf);
- break :output .{ .to_writer = .{
- .writer = &stderr.interface,
- .color = stderr.mode,
- } };
+ const stderr = try io.lockStderr(&stderr_buf, null);
+ break :output .{ .to_writer = stderr.terminal() };
} };
defer {
diagnostics.deinit();
- if (!zig_integration) std.debug.unlockStderrWriter();
+ if (!zig_integration) std.debug.unlockStderr();
}
var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd());
@@ -699,9 +696,9 @@ const ErrorHandler = union(enum) {
},
.stderr => {
// aro errors have already been emitted
- const stderr = io.lockStderrWriter(&.{});
- defer io.unlockStderrWriter();
- try renderErrorMessage(&stderr.interface, stderr.mode, .err, "{s}", .{fail_msg});
+ const stderr = io.lockStderr(&.{}, null);
+ defer io.unlockStderr();
+ try renderErrorMessage(stderr.terminal(), .err, "{s}", .{fail_msg});
},
}
}
@@ -745,9 +742,9 @@ const ErrorHandler = union(enum) {
try server.serveErrorBundle(error_bundle);
},
.stderr => {
- const stderr = io.lockStderrWriter(&.{});
- defer io.unlockStderrWriter();
- try renderErrorMessage(&stderr.interface, stderr.mode, msg_type, format, args);
+ const stderr = try io.lockStderr(&.{}, null);
+ defer io.unlockStderr();
+ try renderErrorMessage(stderr.terminal(), msg_type, format, args);
},
}
}
diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig
index 3a135ab8fd..3d97944a7f 100644
--- a/lib/compiler/test_runner.zig
+++ b/lib/compiler/test_runner.zig
@@ -405,18 +405,18 @@ pub fn fuzz(
testOne(ctx, input.toSlice()) catch |err| switch (err) {
error.SkipZigTest => return,
else => {
- const stderr = std.debug.lockStderrWriter(&.{});
+ const stderr = std.debug.lockStderr(&.{}, null).terminal();
p: {
if (@errorReturnTrace()) |trace| {
- std.debug.writeStackTrace(trace, &stderr.interface, stderr.mode) catch break :p;
+ std.debug.writeStackTrace(trace, stderr) catch break :p;
}
- stderr.interface.print("failed with error.{t}\n", .{err}) catch break :p;
+ stderr.writer.print("failed with error.{t}\n", .{err}) catch break :p;
}
std.process.exit(1);
},
};
if (log_err_count != 0) {
- const stderr = std.debug.lockStderrWriter(&.{});
+ const stderr = std.debug.lockStderr(&.{}, .no_color);
stderr.interface.print("error logs detected\n", .{}) catch {};
std.process.exit(1);
}
diff --git a/lib/std/Build.zig b/lib/std/Build.zig
index de2985d2b5..cf0b9e5b0d 100644
--- a/lib/std/Build.zig
+++ b/lib/std/Build.zig
@@ -129,6 +129,9 @@ pub const Graph = struct {
dependency_cache: InitializedDepMap = .empty,
allow_so_scripts: ?bool = null,
time_report: bool,
+ /// Similar to the `Io.Terminal.Mode` returned by `Io.lockStderr`, but also
+ /// respects the '--color' flag.
+ stderr_mode: ?Io.Terminal.Mode = null,
};
const AvailableDeps = []const struct { []const u8, []const u8 };
@@ -2255,9 +2258,10 @@ pub const GeneratedFile = struct {
pub fn getPath3(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) Io.Cancelable![]const u8 {
return gen.path orelse {
- const io = gen.step.owner.graph.io;
- const stderr = try io.lockStderrWriter(&.{});
- dumpBadGetPathHelp(gen.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {};
+ const graph = gen.step.owner.graph;
+ const io = graph.io;
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ dumpBadGetPathHelp(gen.step, stderr.terminal(), src_builder, asking_step) catch {};
@panic("misconfigured build script");
};
}
@@ -2468,13 +2472,15 @@ pub const LazyPath = union(enum) {
// TODO make gen.file.path not be absolute and use that as the
// basis for not traversing up too many directories.
+ const graph = src_builder.graph;
+
var file_path: Cache.Path = .{
.root_dir = Cache.Directory.cwd(),
.sub_path = gen.file.path orelse {
- const io = src_builder.graph.io;
- const stderr = try io.lockStderrWriter(&.{});
- dumpBadGetPathHelp(gen.file.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {};
- io.unlockStderrWriter();
+ const io = graph.io;
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ dumpBadGetPathHelp(gen.file.step, stderr.terminal(), src_builder, asking_step) catch {};
+ io.unlockStderr();
@panic("misconfigured build script");
},
};
@@ -2564,43 +2570,36 @@ fn dumpBadDirnameHelp(
comptime msg: []const u8,
args: anytype,
) anyerror!void {
- const stderr = std.debug.lockStderrWriter(&.{});
- defer std.debug.unlockStderrWriter();
-
- const w = &stderr.interface;
- const fwm = stderr.mode;
+ const stderr = std.debug.lockStderr(&.{}).terminal();
+ defer std.debug.unlockStderr();
+ const w = stderr.writer;
try w.print(msg, args);
if (fail_step) |s| {
- fwm.setColor(w, .red) catch {};
+ stderr.setColor(.red) catch {};
try w.writeAll(" The step was created by this stack trace:\n");
- fwm.setColor(w, .reset) catch {};
+ stderr.setColor(.reset) catch {};
- s.dump(w, fwm);
+ s.dump(stderr);
}
if (asking_step) |as| {
- fwm.setColor(w, .red) catch {};
+ stderr.setColor(.red) catch {};
try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name});
- fwm.setColor(w, .reset) catch {};
+ stderr.setColor(.reset) catch {};
- as.dump(w, fwm);
+ as.dump(stderr);
}
- fwm.setColor(w, .red) catch {};
- try w.writeAll(" Hope that helps. Proceeding to panic.\n");
- fwm.setColor(w, .reset) catch {};
+ stderr.setColor(.red) catch {};
+ try w.writeAll(" Proceeding to panic.\n");
+ stderr.setColor(.reset) catch {};
}
/// In this function the stderr mutex has already been locked.
-pub fn dumpBadGetPathHelp(
- s: *Step,
- w: *Io.Writer,
- fwm: File.Writer.Mode,
- src_builder: *Build,
- asking_step: ?*Step,
-) anyerror!void {
+pub fn dumpBadGetPathHelp(s: *Step, t: Io.Terminal, src_builder: *Build, asking_step: ?*Step) anyerror!void {
+ const w = t.writer;
try w.print(
\\getPath() was called on a GeneratedFile that wasn't built yet.
\\ source package path: {s}
@@ -2611,21 +2610,21 @@ pub fn dumpBadGetPathHelp(
s.name,
});
- fwm.setColor(w, .red) catch {};
+ t.setColor(.red) catch {};
try w.writeAll(" The step was created by this stack trace:\n");
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.reset) catch {};
- s.dump(w, fwm);
+ s.dump(t);
if (asking_step) |as| {
- fwm.setColor(w, .red) catch {};
+ t.setColor(.red) catch {};
try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name});
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.reset) catch {};
- as.dump(w, fwm);
+ as.dump(t);
}
- fwm.setColor(w, .red) catch {};
- try w.writeAll(" Hope that helps. Proceeding to panic.\n");
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.red) catch {};
+ try w.writeAll(" Proceeding to panic.\n");
+ t.setColor(.reset) catch {};
}
pub const InstallDir = union(enum) {
diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig
index 4770e03a0c..d308efdf70 100644
--- a/lib/std/Build/Fuzz.zig
+++ b/lib/std/Build/Fuzz.zig
@@ -158,7 +158,8 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, parent_prog_node: std.P
}
fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_node: std.Progress.Node) !void {
- const io = run.step.owner.graph.io;
+ const graph = run.step.owner.graph;
+ const io = graph.io;
const compile = run.producer.?;
const prog_node = parent_prog_node.start(compile.step.name, 0);
defer prog_node.end();
@@ -171,9 +172,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod
if (show_error_msgs or show_compile_errors or show_stderr) {
var buf: [256]u8 = undefined;
- const stderr = try io.lockStderrWriter(&buf);
- defer io.unlockStderrWriter();
- build_runner.printErrorMessages(gpa, &compile.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {};
+ const stderr = try io.lockStderr(&buf, graph.stderr_mode);
+ defer io.unlockStderr();
+ build_runner.printErrorMessages(gpa, &compile.step, .{}, stderr.terminal(), .verbose, .indent) catch {};
}
const rebuilt_bin_path = result catch |err| switch (err) {
@@ -186,7 +187,8 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod
fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void {
const owner = run.step.owner;
const gpa = owner.allocator;
- const io = owner.graph.io;
+ const graph = owner.graph;
+ const io = graph.io;
const test_name = run.cached_test_metadata.?.testName(unit_test_index);
const prog_node = fuzz.prog_node.start(test_name, 0);
@@ -195,11 +197,11 @@ fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void {
run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
error.MakeFailed => {
var buf: [256]u8 = undefined;
- const stderr = io.lockStderrWriter(&buf) catch |e| switch (e) {
+ const stderr = io.lockStderr(&buf, graph.stderr_mode) catch |e| switch (e) {
error.Canceled => return,
};
- defer io.unlockStderrWriter();
- build_runner.printErrorMessages(gpa, &run.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {};
+ defer io.unlockStderr();
+ build_runner.printErrorMessages(gpa, &run.step, .{}, stderr.terminal(), .verbose, .indent) catch {};
return;
},
else => {
diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig
index 0df58b24b7..74b41634a7 100644
--- a/lib/std/Build/Step.zig
+++ b/lib/std/Build/Step.zig
@@ -328,16 +328,17 @@ pub fn cast(step: *Step, comptime T: type) ?*T {
}
/// For debugging purposes, prints identifying information about this Step.
-pub fn dump(step: *Step, w: *Io.Writer, fwm: Io.File.Writer.Mode) void {
+pub fn dump(step: *Step, t: Io.Terminal) void {
+ const w = t.writer;
if (step.debug_stack_trace.instruction_addresses.len > 0) {
w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {};
- std.debug.writeStackTrace(&step.debug_stack_trace, w, fwm) catch {};
+ std.debug.writeStackTrace(&step.debug_stack_trace, t) catch {};
} else {
const field = "debug_stack_frames_count";
comptime assert(@hasField(Build, field));
- fwm.setColor(w, .yellow) catch {};
+ t.setColor(.yellow) catch {};
w.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {};
- fwm.setColor(w, .reset) catch {};
+ t.setColor(.reset) catch {};
}
}
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
index 888775884d..4752046089 100644
--- a/lib/std/Build/Step/Compile.zig
+++ b/lib/std/Build/Step/Compile.zig
@@ -925,20 +925,21 @@ const CliNamedModules = struct {
fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 {
const step = &compile.step;
const b = step.owner;
- const io = b.graph.io;
+ const graph = b.graph;
+ const io = graph.io;
const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
const generated_file = maybe_path orelse {
- const stderr = try io.lockStderrWriter(&.{});
- std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {};
- io.unlockStderrWriter();
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {};
+ io.unlockStderr();
@panic("missing emit option for " ++ tag_name);
};
const path = generated_file.path orelse {
- const stderr = try io.lockStderrWriter(&.{});
- std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {};
- io.unlockStderrWriter();
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {};
+ io.unlockStderr();
@panic(tag_name ++ " is null. Is there a missing step dependency?");
};
@@ -1907,7 +1908,7 @@ fn checkCompileErrors(compile: *Compile) !void {
try actual_eb.renderToWriter(.{
.include_reference_trace = false,
.include_source_line = false,
- }, &aw.writer, .streaming);
+ }, &aw.writer);
break :ae try aw.toOwnedSlice();
};
diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig
index 67cf201374..157a0292e7 100644
--- a/lib/std/Build/Step/Run.zig
+++ b/lib/std/Build/Step/Run.zig
@@ -1559,7 +1559,8 @@ fn spawnChildAndCollect(
) !?EvalGenericResult {
const b = run.step.owner;
const arena = b.allocator;
- const io = b.graph.io;
+ const graph = b.graph;
+ const io = graph.io;
if (fuzz_context != null) {
assert(!has_side_effects);
@@ -1625,11 +1626,12 @@ fn spawnChildAndCollect(
if (!run.disable_zig_progress and !inherit) {
child.progress_node = options.progress_node;
}
- if (inherit) {
- const stderr = try io.lockStderrWriter(&.{});
- try setColorEnvironmentVariables(run, env_map, stderr.mode);
- }
- defer if (inherit) io.unlockStderrWriter();
+ const terminal_mode: Io.Terminal.Mode = if (inherit) m: {
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ break :m stderr.terminal_mode;
+ } else .no_color;
+ defer if (inherit) io.unlockStderr();
+ try setColorEnvironmentVariables(run, env_map, terminal_mode);
var timer = try std.time.Timer.start();
const res = try evalGeneric(run, &child);
run.step.result_duration_ns = timer.read();
@@ -1637,7 +1639,7 @@ fn spawnChildAndCollect(
}
}
-fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, fwm: Io.File.Writer.Mode) !void {
+fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, terminal_mode: Io.Terminal.Mode) !void {
color: switch (run.color) {
.manual => {},
.enable => {
@@ -1648,9 +1650,9 @@ fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, fwm: Io.File.Writer
try env_map.put("NO_COLOR", "1");
env_map.remove("CLICOLOR_FORCE");
},
- .inherit => switch (fwm) {
- .terminal_escaped => continue :color .enable,
- else => continue :color .disable,
+ .inherit => switch (terminal_mode) {
+ .no_color, .windows_api => continue :color .disable,
+ .escape_codes => continue :color .enable,
},
.auto => {
const capture_stderr = run.captured_stderr != null or switch (run.stdio) {
diff --git a/lib/std/Io.zig b/lib/std/Io.zig
index 6fa05b16d2..78049633a0 100644
--- a/lib/std/Io.zig
+++ b/lib/std/Io.zig
@@ -713,7 +713,7 @@ pub const VTable = struct {
processExecutableOpen: *const fn (?*anyopaque, File.OpenFlags) std.process.OpenExecutableError!File,
processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize,
lockStderr: *const fn (?*anyopaque, buffer: []u8, ?Terminal.Mode) Cancelable!LockedStderr,
- tryLockStderr: *const fn (?*anyopaque, buffer: []u8) Cancelable!?LockedStderr,
+ tryLockStderr: *const fn (?*anyopaque, buffer: []u8, ?Terminal.Mode) Cancelable!?LockedStderr,
unlockStderr: *const fn (?*anyopaque) void,
now: *const fn (?*anyopaque, Clock) Clock.Error!Timestamp,
diff --git a/lib/std/Io/File/Writer.zig b/lib/std/Io/File/Writer.zig
index 1d0494c674..56a1c09340 100644
--- a/lib/std/Io/File/Writer.zig
+++ b/lib/std/Io/File/Writer.zig
@@ -229,7 +229,7 @@ pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void {
.positional, .positional_simple => {
w.pos = offset;
},
- .streaming, .streaming_simple, .terminal_escaped, .terminal_winapi => {
+ .streaming, .streaming_simple => {
if (w.seek_err) |err| return err;
io.vtable.fileSeekTo(io.userdata, w.file, offset) catch |err| {
w.seek_err = err;
diff --git a/lib/std/Io/Terminal.zig b/lib/std/Io/Terminal.zig
index cd0ec56caa..a39f2175d2 100644
--- a/lib/std/Io/Terminal.zig
+++ b/lib/std/Io/Terminal.zig
@@ -130,25 +130,3 @@ pub fn setColor(t: Terminal, color: Color) Io.Writer.Error!void {
},
}
}
-
-pub fn disableEscape(t: *Terminal) Mode {
- const prev = t.mode;
- t.mode = t.mode.toUnescaped();
- return prev;
-}
-
-pub fn restoreEscape(t: *Terminal, mode: Mode) void {
- t.mode = mode;
-}
-
-pub fn writeAllUnescaped(t: *Terminal, bytes: []const u8) Io.Writer.Error!void {
- const prev_mode = t.disableEscape();
- defer t.restoreEscape(prev_mode);
- return t.interface.writeAll(bytes);
-}
-
-pub fn printUnescaped(t: *Terminal, comptime fmt: []const u8, args: anytype) Io.Writer.Error!void {
- const prev_mode = t.disableEscape();
- defer t.restoreEscape(prev_mode);
- return t.interface.print(fmt, args);
-}
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
index 3e7b6950d4..b07a9bb9a8 100644
--- a/lib/std/Io/Threaded.zig
+++ b/lib/std/Io/Threaded.zig
@@ -7178,7 +7178,7 @@ fn fileWriteFileStreaming(
break :o .{ &off, @min(@intFromEnum(limit), size - file_reader.pos, max_count) };
},
.streaming => .{ null, limit.minInt(max_count) },
- .streaming_reading, .positional_reading => break :sf,
+ .streaming_simple, .positional_simple => break :sf,
.failure => return error.ReadFailed,
};
const current_thread = Thread.getCurrent(t);
@@ -7251,7 +7251,7 @@ fn fileWriteFileStreaming(
}
var off_in: i64 = undefined;
const off_in_ptr: ?*i64 = switch (file_reader.mode) {
- .positional_reading, .streaming_reading => return error.Unimplemented,
+ .positional_simple, .streaming_simple => return error.Unimplemented,
.positional => p: {
off_in = @intCast(file_reader.pos);
break :p &off_in;
@@ -7427,7 +7427,7 @@ fn fileWriteFilePositional(
}
var off_in: i64 = undefined;
const off_in_ptr: ?*i64 = switch (file_reader.mode) {
- .positional_reading, .streaming_reading => return error.Unimplemented,
+ .positional_simple, .streaming_simple => return error.Unimplemented,
.positional => p: {
off_in = @intCast(file_reader.pos);
break :p &off_in;
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index fd3a456ff7..e33a2bd575 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -283,12 +283,12 @@ var static_single_threaded_io: Io.Threaded = .init_single_threaded;
///
/// Alternatively, use the higher-level `Io.lockStderr` to integrate with the
/// application's chosen `Io` implementation.
-pub fn lockStderr(buffer: []u8) Io.Terminal {
- return (static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) {
+pub fn lockStderr(buffer: []u8) Io.LockedStderr {
+ return static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) {
// Impossible to cancel because no calls to cancel using
// `static_single_threaded_io` exist.
error.Canceled => unreachable,
- }).terminal();
+ };
}
pub fn unlockStderr() void {
@@ -311,7 +311,7 @@ pub fn print(comptime fmt: []const u8, args: anytype) void {
var buffer: [64]u8 = undefined;
const stderr = lockStderr(&buffer);
defer unlockStderr();
- stderr.writer.print(fmt, args) catch return;
+ stderr.file_writer.interface.print(fmt, args) catch return;
}
}
@@ -327,7 +327,7 @@ pub inline fn getSelfDebugInfo() !*SelfInfo {
/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
/// Obtains the stderr mutex while dumping.
pub fn dumpHex(bytes: []const u8) void {
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
dumpHexFallible(stderr, bytes) catch {};
}
@@ -551,7 +551,7 @@ pub fn defaultPanic(
_ = panicking.fetchAdd(1, .seq_cst);
trace: {
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
const writer = stderr.writer;
@@ -581,7 +581,7 @@ pub fn defaultPanic(
// A panic happened while trying to print a previous panic message.
// We're still holding the mutex but that's fine as we're going to
// call abort().
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
stderr.writer.writeAll("aborting due to recursive panic\n") catch {};
},
else => {}, // Panicked while printing the recursive panic message.
@@ -751,7 +751,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, t: Io.Termin
}
/// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors.
pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
writeCurrentStackTrace(.{
.first_address = a: {
@@ -814,7 +814,7 @@ pub fn writeStackTrace(st: *const StackTrace, t: Io.Terminal) Writer.Error!void
}
/// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors.
pub fn dumpStackTrace(st: *const StackTrace) void {
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
writeStackTrace(st, stderr) catch |err| switch (err) {
error.WriteFailed => {},
@@ -1550,7 +1550,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex
_ = panicking.fetchAdd(1, .seq_cst);
trace: {
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
if (addr) |a| {
@@ -1571,7 +1571,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex
// A segfault happened while trying to print a previous panic message.
// We're still holding the mutex but that's fine as we're going to
// call abort().
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
stderr.writer.writeAll("aborting due to recursive panic\n") catch {};
},
else => {}, // Panicked while printing the recursive panic message.
@@ -1678,7 +1678,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
pub fn dump(t: @This()) void {
if (!enabled) return;
- const stderr = lockStderr(&.{});
+ const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
const end = @min(t.index, size);
for (t.addrs[0..end], 0..) |frames_array, i| {
diff --git a/lib/std/debug/simple_panic.zig b/lib/std/debug/simple_panic.zig
index 2d0e5abf4e..34e8f7b43c 100644
--- a/lib/std/debug/simple_panic.zig
+++ b/lib/std/debug/simple_panic.zig
@@ -14,9 +14,9 @@ const std = @import("../std.zig");
pub fn call(msg: []const u8, ra: ?usize) noreturn {
@branchHint(.cold);
_ = ra;
- const stderr = std.debug.lockStderrWriter(&.{});
- stderr.interface.writeAll(msg) catch {};
- stderr.interface.flush(msg) catch {};
+ const stderr_writer = std.debug.lockStderr(&.{}, null).terminal().writer;
+ stderr_writer.writeAll(msg) catch {};
+ stderr_writer.flush(msg) catch {};
@trap();
}
diff --git a/lib/std/json/dynamic.zig b/lib/std/json/dynamic.zig
index f85916670b..e38ea9cb17 100644
--- a/lib/std/json/dynamic.zig
+++ b/lib/std/json/dynamic.zig
@@ -47,9 +47,9 @@ pub const Value = union(enum) {
}
pub fn dump(v: Value) void {
- const stderr = std.debug.lockStderrWriter(&.{});
- defer std.debug.unlockStderrWriter();
- json.Stringify.value(v, .{}, &stderr.interface) catch return;
+ const stderr = std.debug.lockStderr(&.{}, null);
+ defer std.debug.unlockStderr();
+ json.Stringify.value(v, .{}, &stderr.file_writer.interface) catch return;
}
pub fn jsonStringify(value: @This(), jws: anytype) !void {
diff --git a/lib/std/log.zig b/lib/std/log.zig
index 8579bb04e0..81bfc4ebb6 100644
--- a/lib/std/log.zig
+++ b/lib/std/log.zig
@@ -92,7 +92,7 @@ pub fn defaultLog(
args: anytype,
) void {
var buffer: [64]u8 = undefined;
- const stderr = std.debug.lockStderr(&buffer);
+ const stderr = std.debug.lockStderr(&buffer).terminal();
defer std.debug.unlockStderr();
return defaultLogFileTerminal(level, scope, format, args, stderr) catch {};
}
diff --git a/lib/std/process.zig b/lib/std/process.zig
index 45cd575133..23a3d92e9b 100644
--- a/lib/std/process.zig
+++ b/lib/std/process.zig
@@ -1856,7 +1856,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
/// and does not return.
pub fn cleanExit(io: Io) void {
if (builtin.mode == .Debug) return;
- _ = io.lockStderrWriter(&.{}) catch {};
+ _ = io.lockStderr(&.{}, .no_color) catch {};
exit(0);
}
diff --git a/lib/std/testing.zig b/lib/std/testing.zig
index be6f316804..98fca2f2d5 100644
--- a/lib/std/testing.zig
+++ b/lib/std/testing.zig
@@ -368,8 +368,8 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
break :diff_index if (expected.len == actual.len) return else shortest;
};
if (!backend_can_print) return error.TestExpectedEqual;
- if (io.lockStderrWriter(&.{})) |stderr| {
- defer io.unlockStderrWriter();
+ if (io.lockStderr(&.{}, null)) |stderr| {
+ defer io.unlockStderr();
failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {};
} else |_| {}
return error.TestExpectedEqual;
@@ -381,7 +381,7 @@ fn failEqualSlices(
actual: []const T,
diff_index: usize,
w: *Io.Writer,
- fwm: Io.File.Writer.Mode,
+ terminal_mode: Io.Terminal.Mode,
) !void {
try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });
@@ -404,12 +404,12 @@ fn failEqualSlices(
var differ = if (T == u8) BytesDiffer{
.expected = expected_window,
.actual = actual_window,
- .file_writer_mode = fwm,
+ .terminal_mode = terminal_mode,
} else SliceDiffer(T){
.start_index = window_start,
.expected = expected_window,
.actual = actual_window,
- .file_writer_mode = fwm,
+ .terminal_mode = terminal_mode,
};
// Print indexes as hex for slices of u8 since it's more likely to be binary data where
@@ -466,21 +466,22 @@ fn SliceDiffer(comptime T: type) type {
start_index: usize,
expected: []const T,
actual: []const T,
- file_writer_mode: Io.File.Writer.Mode,
+ terminal_mode: Io.Terminal.Mode,
const Self = @This();
pub fn write(self: Self, writer: *Io.Writer) !void {
+ const t: Io.Terminal = .{ .writer = writer, .mode = self.terminal_mode };
for (self.expected, 0..) |value, i| {
const full_index = self.start_index + i;
const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true;
- if (diff) try self.file_writer_mode.setColor(writer, .red);
+ if (diff) try t.setColor(writer, .red);
if (@typeInfo(T) == .pointer) {
try writer.print("[{}]{*}: {any}\n", .{ full_index, value, value });
} else {
try writer.print("[{}]: {any}\n", .{ full_index, value });
}
- if (diff) try self.file_writer_mode.setColor(writer, .reset);
+ if (diff) try t.setColor(writer, .reset);
}
}
};
@@ -489,7 +490,7 @@ fn SliceDiffer(comptime T: type) type {
const BytesDiffer = struct {
expected: []const u8,
actual: []const u8,
- file_writer_mode: Io.File.Writer.Mode,
+ terminal_mode: Io.Terminal.Mode,
pub fn write(self: BytesDiffer, writer: *Io.Writer) !void {
var expected_iterator = std.mem.window(u8, self.expected, 16, 16);
@@ -516,7 +517,7 @@ const BytesDiffer = struct {
try self.writeDiff(writer, "{c}", .{byte}, diff);
} else {
// TODO: remove this `if` when https://github.com/ziglang/zig/issues/7600 is fixed
- if (self.file_writer_mode == .terminal_winapi) {
+ if (self.terminal_mode == .windows_api) {
try self.writeDiff(writer, ".", .{}, diff);
continue;
}
diff --git a/lib/std/zig.zig b/lib/std/zig.zig
index 6e89c75d91..6212264005 100644
--- a/lib/std/zig.zig
+++ b/lib/std/zig.zig
@@ -46,25 +46,18 @@ pub const SrcHasher = std.crypto.hash.Blake3;
pub const SrcHash = [16]u8;
pub const Color = enum {
- /// Determine whether stderr is a terminal or not automatically.
+ /// Auto-detect whether stream supports terminal colors.
auto,
- /// Assume stderr is not a terminal.
+ /// Force-enable colors.
off,
- /// Assume stderr is a terminal.
+ /// Suppress colors.
on,
- pub fn getTtyConf(color: Color, detected: Io.File.Writer.Mode) Io.File.Writer.Mode {
+ pub fn terminalMode(color: Color) ?Io.Terminal.Mode {
return switch (color) {
- .auto => detected,
- .on => .terminal_escaped,
- .off => .streaming,
- };
- }
- pub fn detectTtyConf(color: Color, io: Io) Io.File.Writer.Mode {
- return switch (color) {
- .auto => .detect(io, .stderr()),
- .on => .terminal_escaped,
- .off => .streaming,
+ .auto => null,
+ .on => .escape_codes,
+ .off => .no_color,
};
}
};
diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig
index 556b1167a3..c5275729ae 100644
--- a/lib/std/zig/ErrorBundle.zig
+++ b/lib/std/zig/ErrorBundle.zig
@@ -166,51 +166,53 @@ pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Error;
pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: std.zig.Color) RenderToStderrError!void {
var buffer: [256]u8 = undefined;
- const stderr = try io.lockStderrWriter(&buffer);
- defer io.unlockStderrWriter();
- renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch |err| switch (err) {
- error.WriteFailed => return stderr.err.?,
+ const stderr = try io.lockStderr(&buffer, color.terminalMode());
+ defer io.unlockStderr();
+ renderToTerminal(eb, options, stderr.terminal()) catch |err| switch (err) {
+ error.WriteFailed => return stderr.file_writer.err.?,
else => |e| return e,
};
}
-pub fn renderToWriter(
- eb: ErrorBundle,
- options: RenderOptions,
- w: *Writer,
- fwm: Io.File.Writer.Mode,
-) Io.File.Writer.Mode.SetColorError!void {
+pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer) Writer.Error!void {
+ return renderToTerminal(eb, options, .{ .writer = w, .mode = .no_color }) catch |err| switch (err) {
+ error.WriteFailed => |e| return e,
+ else => unreachable,
+ };
+}
+
+pub fn renderToTerminal(eb: ErrorBundle, options: RenderOptions, t: Io.Terminal) Io.Terminal.SetColorError!void {
if (eb.extra.len == 0) return;
for (eb.getMessages()) |err_msg| {
- try renderErrorMessageToWriter(eb, options, err_msg, w, fwm, "error", .red, 0);
+ try renderErrorMessage(eb, options, err_msg, t, "error", .red, 0);
}
if (options.include_log_text) {
const log_text = eb.getCompileLogOutput();
if (log_text.len != 0) {
- try w.writeAll("\nCompile Log Output:\n");
- try w.writeAll(log_text);
+ try t.writer.writeAll("\nCompile Log Output:\n");
+ try t.writer.writeAll(log_text);
}
}
}
-fn renderErrorMessageToWriter(
+fn renderErrorMessage(
eb: ErrorBundle,
options: RenderOptions,
err_msg_index: MessageIndex,
- w: *Writer,
- fwm: Io.File.Writer.Mode,
+ t: Io.Terminal,
kind: []const u8,
- color: Io.File.Writer.Color,
+ color: Io.Terminal.Color,
indent: usize,
-) Io.File.Writer.Mode.SetColorError!void {
+) Io.Terminal.SetColorError!void {
+ const w = t.writer;
const err_msg = eb.getErrorMessage(err_msg_index);
if (err_msg.src_loc != .none) {
const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
var prefix: Writer.Discarding = .init(&.{});
try w.splatByteAll(' ', indent);
prefix.count += indent;
- try fwm.setColor(w, .bold);
+ try t.setColor(.bold);
try w.print("{s}:{d}:{d}: ", .{
eb.nullTerminatedString(src.data.src_path),
src.data.line + 1,
@@ -221,7 +223,7 @@ fn renderErrorMessageToWriter(
src.data.line + 1,
src.data.column + 1,
});
- try fwm.setColor(w, color);
+ try t.setColor(color);
try w.writeAll(kind);
prefix.count += kind.len;
try w.writeAll(": ");
@@ -229,17 +231,17 @@ fn renderErrorMessageToWriter(
// This is the length of the part before the error message:
// e.g. "file.zig:4:5: error: "
const prefix_len: usize = @intCast(prefix.count);
- try fwm.setColor(w, .reset);
- try fwm.setColor(w, .bold);
+ try t.setColor(.reset);
+ try t.setColor(.bold);
if (err_msg.count == 1) {
try writeMsg(eb, err_msg, w, prefix_len);
try w.writeByte('\n');
} else {
try writeMsg(eb, err_msg, w, prefix_len);
- try fwm.setColor(w, .dim);
+ try t.setColor(.dim);
try w.print(" ({d} times)\n", .{err_msg.count});
}
- try fwm.setColor(w, .reset);
+ try t.setColor(.reset);
if (src.data.source_line != 0 and options.include_source_line) {
const line = eb.nullTerminatedString(src.data.source_line);
for (line) |b| switch (b) {
@@ -252,19 +254,19 @@ fn renderErrorMessageToWriter(
// -1 since span.main includes the caret
const after_caret = src.data.span_end -| src.data.span_main -| 1;
try w.splatByteAll(' ', src.data.column - before_caret);
- try fwm.setColor(w, .green);
+ try t.setColor(.green);
try w.splatByteAll('~', before_caret);
try w.writeByte('^');
try w.splatByteAll('~', after_caret);
try w.writeByte('\n');
- try fwm.setColor(w, .reset);
+ try t.setColor(.reset);
}
for (eb.getNotes(err_msg_index)) |note| {
- try renderErrorMessageToWriter(eb, options, note, w, fwm, "note", .cyan, indent);
+ try renderErrorMessage(eb, options, note, t, "note", .cyan, indent);
}
if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
- try fwm.setColor(w, .reset);
- try fwm.setColor(w, .dim);
+ try t.setColor(.reset);
+ try t.setColor(.dim);
try w.print("referenced by:\n", .{});
var ref_index = src.end;
for (0..src.data.reference_trace_len) |_| {
@@ -291,25 +293,25 @@ fn renderErrorMessageToWriter(
);
}
}
- try fwm.setColor(w, .reset);
+ try t.setColor(.reset);
}
} else {
- try fwm.setColor(w, color);
+ try t.setColor(color);
try w.splatByteAll(' ', indent);
try w.writeAll(kind);
try w.writeAll(": ");
- try fwm.setColor(w, .reset);
+ try t.setColor(.reset);
const msg = eb.nullTerminatedString(err_msg.msg);
if (err_msg.count == 1) {
try w.print("{s}\n", .{msg});
} else {
try w.print("{s}", .{msg});
- try fwm.setColor(w, .dim);
+ try t.setColor(.dim);
try w.print(" ({d} times)\n", .{err_msg.count});
}
- try fwm.setColor(w, .reset);
+ try t.setColor(.reset);
for (eb.getNotes(err_msg_index)) |note| {
- try renderErrorMessageToWriter(eb, options, note, w, fwm, "note", .cyan, indent + 4);
+ try renderErrorMessage(eb, options, note, t, "note", .cyan, indent + 4);
}
}
}
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 6c11c3021b..94d877b406 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -6333,25 +6333,25 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;
fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 {
var buffer: [64]u8 = undefined;
- const stderr = try io.lockStderrWriter(&buffer);
- defer io.unlockStderrWriter();
+ const stderr = try io.lockStderr(&buffer, null);
+ defer io.unlockStderr();
var tree = try std.zig.Ast.parse(allocator, source, .zig);
defer tree.deinit(allocator);
for (tree.errors) |parse_error| {
const loc = tree.tokenLocation(0, parse_error.token);
- try stderr.printUnescaped("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 });
- try tree.renderError(parse_error, &stderr.interface);
- try stderr.interface.print("\n{s}\n", .{source[loc.line_start..loc.line_end]});
+ try stderr.writer.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 });
+ try tree.renderError(parse_error, stderr.writer);
+ try stderr.writer.print("\n{s}\n", .{source[loc.line_start..loc.line_end]});
{
var i: usize = 0;
while (i < loc.column) : (i += 1) {
- try stderr.writeAllUnescaped(" ");
+ try stderr.writer.writeAll(" ");
}
- try stderr.writeAllUnescaped("^");
+ try stderr.writer.writeAll("^");
}
- try stderr.writeAllUnescaped("\n");
+ try stderr.writer.writeAll("\n");
}
if (tree.errors.len != 0) {
return error.ParseError;