std.io: move getStdIn, getStdOut, getStdErr functions to fs.File

preparing to rearrange std.io namespace into an interface
This commit is contained in:
Andrew Kelley 2025-04-04 19:26:50 -07:00
parent 6c48aad991
commit 890a02c345
36 changed files with 183 additions and 203 deletions

View File

@ -69,8 +69,8 @@ fn mainServer() !void {
@disableInstrumentation();
var server = try std.zig.Server.init(.{
.gpa = fba.allocator(),
.in = std.io.getStdIn(),
.out = std.io.getStdOut(),
.in = .stdin(),
.out = .stdout(),
.zig_version = builtin.zig_version_string,
});
defer server.deinit();
@ -191,7 +191,7 @@ fn mainTerminal() void {
.root_name = "Test",
.estimated_total_items = test_fn_list.len,
});
const have_tty = std.io.getStdErr().isTty();
const have_tty = std.fs.File.stderr().isTty();
var async_frame_buffer: []align(builtin.target.stackAlignment()) u8 = undefined;
// TODO this is on the next line (using `undefined` above) because otherwise zig incorrectly

View File

@ -2677,7 +2677,7 @@ pub const LazyPath = union(enum) {
.root_dir = Cache.Directory.cwd(),
.sub_path = gen.file.path orelse {
std.debug.lockStdErr();
const stderr = std.io.getStdErr();
const stderr: fs.File = .stderr();
dumpBadGetPathHelp(gen.file.step, stderr, src_builder, asking_step) catch {};
std.debug.unlockStdErr();
@panic("misconfigured build script");
@ -2766,11 +2766,11 @@ fn dumpBadDirnameHelp(
comptime msg: []const u8,
args: anytype,
) anyerror!void {
var buffered_writer = debug.lockStdErr2();
var buffered_writer = debug.lockStdErr2(&.{});
defer debug.unlockStdErr();
const w = &buffered_writer;
const stderr = io.getStdErr();
const stderr: fs.File = .stderr();
try w.print(msg, args);
const tty_config = std.io.tty.detectConfig(stderr);

View File

@ -124,7 +124,7 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, ttyconf: std.io.tty.Config, par
const show_stderr = compile.step.result_stderr.len > 0;
if (show_error_msgs or show_compile_errors or show_stderr) {
var bw = std.debug.lockStdErr2();
var bw = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
build_runner.printErrorMessages(gpa, &compile.step, .{ .ttyconf = ttyconf }, &bw, false) catch {};
}
@ -151,7 +151,7 @@ fn fuzzWorkerRun(
run.rerunInFuzzMode(web_server, unit_test_index, prog_node) catch |err| switch (err) {
error.MakeFailed => {
var bw = std.debug.lockStdErr2();
var bw = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
build_runner.printErrorMessages(gpa, &run.step, .{ .ttyconf = ttyconf }, &bw, false) catch {};
return;

View File

@ -1018,7 +1018,7 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking
const generated_file = maybe_path orelse {
std.debug.lockStdErr();
const stderr = std.io.getStdErr();
const stderr: fs.File = .stderr();
std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {};
@ -1027,7 +1027,7 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking
const path = generated_file.path orelse {
std.debug.lockStdErr();
const stderr = std.io.getStdErr();
const stderr: fs.File = .stderr();
std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {};

View File

@ -451,7 +451,7 @@ pub fn start(options: Options) Node {
if (options.disable_printing) {
return Node.none;
}
const stderr = std.io.getStdErr();
const stderr: std.fs.File = .stderr();
global_progress.terminal = stderr;
if (stderr.getOrEnableAnsiEscapeSupport()) {
global_progress.terminal_mode = .ansi_escape_codes;

View File

@ -122,7 +122,7 @@ fn mode(comptime x: comptime_int) comptime_int {
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const stdout = std.fs.File.stdout().writer();
var buffer: [1024]u8 = undefined;
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);

View File

@ -51,7 +51,7 @@ pub const StackTrace = struct {
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
return writer.print("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
};
const tty_config = std.io.tty.detectConfig(std.io.getStdErr());
const tty_config = std.io.tty.detectConfig(.stderr());
try writer.writeAll("\n");
std.debug.writeStackTrace(self, writer, debug_info, tty_config) catch |err| {
try writer.print("Unable to print stack trace: {s}\n", .{@errorName(err)});

View File

@ -458,7 +458,7 @@ fn mode(comptime x: comptime_int) comptime_int {
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const stdout = std.fs.File.stdout().writer();
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();

View File

@ -210,15 +210,15 @@ pub fn unlockStdErr() void {
///
/// Returns a `std.io.BufferedWriter` with empty buffer, meaning that it is
/// in fact unbuffered and does not need to be flushed.
pub fn lockStdErr2() std.io.BufferedWriter {
pub fn lockStdErr2(buffer: []u8) std.io.BufferedWriter {
std.Progress.lockStdErr();
return io.getStdErr().writer().unbuffered();
return std.fs.File.stderr().writer().buffered(buffer);
}
/// Print to stderr, unbuffered, and silently returning on failure. Intended
/// for use in "printf debugging." Use `std.log` functions for proper logging.
pub fn print(comptime fmt: []const u8, args: anytype) void {
var bw = lockStdErr2();
var bw = lockStdErr2(&.{});
defer unlockStdErr();
nosuspend bw.print(fmt, args) catch return;
}
@ -242,9 +242,9 @@ pub 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 {
var bw = lockStdErr2();
var bw = lockStdErr2(&.{});
defer unlockStdErr();
const ttyconf = std.io.tty.detectConfig(std.io.getStdErr());
const ttyconf = std.io.tty.detectConfig(.stderr());
dumpHexFallible(&bw, ttyconf, bytes) catch {};
}
@ -320,7 +320,7 @@ test dumpHexFallible {
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
var stderr = lockStdErr2();
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
nosuspend dumpCurrentStackTraceToWriter(start_addr, &stderr) catch return;
}
@ -341,7 +341,7 @@ pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *std.io.Buffere
try writer.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
return;
};
writeCurrentStackTrace(writer, debug_info, io.tty.detectConfig(io.getStdErr()), start_addr) catch |err| {
writeCurrentStackTrace(writer, debug_info, io.tty.detectConfig(.stderr()), start_addr) catch |err| {
try writer.print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
return;
};
@ -426,7 +426,7 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *std.io.BufferedW
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
return;
};
const tty_config = io.tty.detectConfig(io.getStdErr());
const tty_config = io.tty.detectConfig(.stderr());
if (native_os == .windows) {
// On x86_64 and aarch64, the stack will be unwound using RtlVirtualUnwind using the context
// provided by the exception handler. On x86, RtlVirtualUnwind doesn't exist. Instead, a new backtrace
@ -516,13 +516,13 @@ pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void {
nosuspend {
if (builtin.target.cpu.arch.isWasm()) {
if (native_os == .wasi) {
var stderr = lockStdErr2();
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
stderr.writeAll("Unable to dump stack trace: not implemented for Wasm\n") catch return;
}
return;
}
var stderr = lockStdErr2();
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
if (builtin.strip_debug_info) {
stderr.writeAll("Unable to dump stack trace: debug info stripped\n") catch return;
@ -532,7 +532,7 @@ pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void {
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
return;
};
writeStackTrace(stack_trace, &stderr, debug_info, io.tty.detectConfig(io.getStdErr())) catch |err| {
writeStackTrace(stack_trace, &stderr, debug_info, io.tty.detectConfig(.stderr())) catch |err| {
stderr.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch return;
return;
};
@ -683,7 +683,7 @@ pub fn defaultPanic(
_ = panicking.fetchAdd(1, .seq_cst);
{
var stderr = lockStdErr2();
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
if (builtin.single_threaded) {
@ -706,7 +706,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().
io.getStdErr().writeAll("aborting due to recursive panic\n") catch {};
fs.File.stderr().writeAll("aborting due to recursive panic\n") catch {};
},
else => {}, // Panicked while printing the recursive panic message.
};
@ -1468,7 +1468,8 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
}
fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void {
var stderr = io.getStdErr().writer().unbuffered();
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
_ = switch (sig) {
posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
// x86_64 doesn't have a full 64-bit virtual address space.
@ -1546,25 +1547,24 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, msg: u8, label:
_ = panicking.fetchAdd(1, .seq_cst);
{
lockStdErr();
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
dumpSegfaultInfoWindows(info, msg, label);
dumpSegfaultInfoWindows(info, msg, label, &stderr);
}
waitForOtherThreadToFinishPanicking();
},
1 => {
panic_stage = 2;
io.getStdErr().writeAll("aborting due to recursive panic\n") catch {};
fs.File.stderr().writeAll("aborting due to recursive panic\n") catch {};
},
else => {},
};
posix.abort();
}
fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8) void {
var stderr = io.getStdErr().writer().unbuffered();
fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *std.io.BufferedWriter) void {
_ = switch (msg) {
0 => stderr.print("{s}\n", .{label.?}),
1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
@ -1572,7 +1572,7 @@ fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[
else => unreachable,
} catch posix.abort();
dumpStackTraceFromBase(info.ContextRecord, &stderr);
dumpStackTraceFromBase(info.ContextRecord, stderr);
}
pub fn dumpStackPointerAddr(prefix: []const u8) void {
@ -1598,7 +1598,7 @@ test "manage resources correctly" {
const writer = std.io.null_writer;
var di = try SelfInfo.open(testing.allocator);
defer di.deinit();
try printSourceAtAddress(&di, writer, showMyTrace(), io.tty.detectConfig(std.io.getStdErr()));
try printSourceAtAddress(&di, writer, showMyTrace(), io.tty.detectConfig(.stderr()));
}
noinline fn showMyTrace() usize {
@ -1664,8 +1664,8 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
pub fn dump(t: @This()) void {
if (!enabled) return;
const tty_config = io.tty.detectConfig(std.io.getStdErr());
var stderr = lockStdErr2();
const tty_config = io.tty.detectConfig(.stderr());
var stderr = lockStdErr2(&.{});
defer unlockStdErr();
const end = @min(t.index, size);
const debug_info = getSelfDebugInfo() catch |err| {

View File

@ -15,7 +15,7 @@ pub fn call(msg: []const u8, ra: ?usize) noreturn {
@branchHint(.cold);
_ = ra;
std.debug.lockStdErr();
const stderr = std.io.getStdErr();
const stderr: std.fs.File = .stderr();
stderr.writeAll(msg) catch {};
@trap();
}

View File

@ -168,6 +168,18 @@ pub const CreateFlags = struct {
mode: Mode = default_mode,
};
pub fn stdout() File {
return .{ .handle = if (is_windows) windows.peb().ProcessParameters.hStdOutput else posix.STDOUT_FILENO };
}
pub fn stderr() File {
return .{ .handle = if (is_windows) windows.peb().ProcessParameters.hStdError else posix.STDERR_FILENO };
}
pub fn stdin() File {
return .{ .handle = if (is_windows) windows.peb().ProcessParameters.hStdInput else posix.STDIN_FILENO };
}
/// Upon success, the stream is in an uninitialized state. To continue using it,
/// you must use the open() function.
pub fn close(self: File) void {

View File

@ -346,7 +346,7 @@ fn mode(comptime x: comptime_int) comptime_int {
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const stdout = std.fs.File.stdout().writer().unbuffered();
var buffer: [1024]u8 = undefined;
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);

View File

@ -14,54 +14,6 @@ const File = std.fs.File;
const Allocator = std.mem.Allocator;
const Alignment = std.mem.Alignment;
fn getStdOutHandle() posix.fd_t {
if (is_windows) {
return windows.peb().ProcessParameters.hStdOutput;
}
if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdOutHandle")) {
return root.os.io.getStdOutHandle();
}
return posix.STDOUT_FILENO;
}
pub fn getStdOut() File {
return .{ .handle = getStdOutHandle() };
}
fn getStdErrHandle() posix.fd_t {
if (is_windows) {
return windows.peb().ProcessParameters.hStdError;
}
if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdErrHandle")) {
return root.os.io.getStdErrHandle();
}
return posix.STDERR_FILENO;
}
pub fn getStdErr() File {
return .{ .handle = getStdErrHandle() };
}
fn getStdInHandle() posix.fd_t {
if (is_windows) {
return windows.peb().ProcessParameters.hStdInput;
}
if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdInHandle")) {
return root.os.io.getStdInHandle();
}
return posix.STDIN_FILENO;
}
pub fn getStdIn() File {
return .{ .handle = getStdInHandle() };
}
pub const Reader = @import("io/Reader.zig");
pub const Writer = @import("io/Writer.zig");

View File

@ -421,9 +421,9 @@ pub fn takeByte(br: *BufferedReader) anyerror!u8 {
return buffer[seek];
}
/// Same as `readByte` except the returned byte is signed.
/// Same as `takeByte` except the returned byte is signed.
pub fn takeByteSigned(br: *BufferedReader) anyerror!i8 {
return @bitCast(try br.readByte());
return @bitCast(try br.takeByte());
}
/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.

View File

@ -2,7 +2,7 @@ const std = @import("../std.zig");
const Reader = @This();
const assert = std.debug.assert;
context: *anyopaque,
context: ?*anyopaque,
vtable: *const VTable,
pub const VTable = struct {
@ -19,8 +19,8 @@ pub const VTable = struct {
///
/// If this is `null` it is equivalent to always returning
/// `error.Unseekable`.
posRead: ?*const fn (ctx: *anyopaque, bw: *std.io.BufferedWriter, limit: Limit, offset: u64) anyerror!Status,
posReadVec: ?*const fn (ctx: *anyopaque, data: []const []u8, offset: u64) anyerror!Status,
posRead: ?*const fn (ctx: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Limit, offset: u64) Result,
posReadVec: ?*const fn (ctx: ?*anyopaque, data: []const []u8, offset: u64) VecResult,
/// Writes bytes from the internally tracked stream position to `bw`, or
/// returns `error.Unstreamable`, indicating `posRead` should be used
@ -37,14 +37,30 @@ pub const VTable = struct {
///
/// If this is `null` it is equivalent to always returning
/// `error.Unstreamable`.
streamRead: ?*const fn (ctx: *anyopaque, bw: *std.io.BufferedWriter, limit: Limit) anyerror!Status,
streamReadVec: ?*const fn (ctx: *anyopaque, data: []const []u8) anyerror!Status,
streamRead: ?*const fn (ctx: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Limit) Result,
streamReadVec: ?*const fn (ctx: ?*anyopaque, data: []const []u8) VecResult,
};
pub const Len = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(usize) - 1 } });
pub const Status = packed struct(usize) {
/// Number of bytes that were written to `writer`.
pub const VecResult = struct {
/// Even when a failure occurs, `Effect.written` may be nonzero, and
/// `Effect.end` may be true.
failure: anyerror!void,
effect: VecEffect,
};
pub const Result = struct {
/// Even when a failure occurs, `Effect.written` may be nonzero, and
/// `Effect.end` may be true.
failure: anyerror!void,
write_effect: Effect,
read_effect: Effect,
};
pub const Effect = packed struct(usize) {
/// Number of bytes that were read from the reader or written to the
/// writer.
len: Len,
/// Indicates end of stream.
end: bool,

View File

@ -17,7 +17,7 @@ pub const VTable = struct {
/// Number of bytes returned may be zero, which does not mean
/// end-of-stream. A subsequent call may return nonzero, or may signal end
/// of stream via an error.
writeSplat: *const fn (ctx: *anyopaque, data: []const []const u8, splat: usize) anyerror!usize,
writeSplat: *const fn (ctx: *anyopaque, data: []const []const u8, splat: usize) Result,
/// Writes contents from an open file. `headers` are written first, then `len`
/// bytes of `file` starting from `offset`, then `trailers`.
@ -38,7 +38,23 @@ pub const VTable = struct {
/// zero, they can be forwarded directly to `VTable.writev`.
headers_and_trailers: []const []const u8,
headers_len: usize,
) anyerror!usize,
) Result,
};
pub const Len = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(usize) - 1 } });
pub const Result = struct {
/// Even when a failure occurs, `Effect.written` may be nonzero, and
/// `Effect.end` may be true.
failure: anyerror!void,
effect: Effect,
};
pub const Effect = packed struct(usize) {
/// Number of bytes that were written to `writer`.
len: Len,
/// Indicates end of stream.
end: bool,
};
pub const Offset = enum(u64) {

View File

@ -51,7 +51,7 @@ pub const Value = union(enum) {
}
pub fn dump(v: Value) void {
var bw = std.debug.lockStdErr2();
var bw = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
json.Stringify.value(v, .{}, &bw) catch return;

View File

@ -47,7 +47,7 @@
//! // Print the message to stderr, silently ignoring any errors
//! std.debug.lockStdErr();
//! defer std.debug.unlockStdErr();
//! const stderr = std.io.getStdErr().writer();
//! const stderr = std.fs.File.stderr().writer();
//! nosuspend stderr.print(prefix ++ format ++ "\n", args) catch return;
//! }
//!
@ -149,11 +149,7 @@ pub fn defaultLog(
const level_txt = comptime message_level.asText();
const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
var buffer: [1024]u8 = undefined;
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = std.io.getStdErr().writer(),
.buffer = &buffer,
};
std.debug.lockStdErr();
var bw: std.io.BufferedWriter = std.debug.lockStdErr2(&buffer);
defer std.debug.unlockStdErr();
nosuspend {
bw.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;

View File

@ -390,9 +390,9 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
const actual_truncated = window_start + actual_window.len < actual.len;
var bw = std.debug.lockStdErr2();
var bw = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
const ttyconf = std.io.tty.detectConfig(std.io.getStdErr());
const ttyconf = std.io.tty.detectConfig(.stderr());
var differ = if (T == u8) BytesDiffer{
.expected = expected_window,
.actual = actual_window,

View File

@ -39,7 +39,7 @@ fn benchmarkCodepointCount(buf: []const u8) !ResultCount {
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const stdout = std.fs.File.stdout().writer();
try stdout.print("short ASCII strings\n", .{});
{

View File

@ -48,7 +48,7 @@ pub const Color = enum {
pub fn get_tty_conf(color: Color) std.io.tty.Config {
return switch (color) {
.auto => std.io.tty.detectConfig(std.io.getStdErr()),
.auto => std.io.tty.detectConfig(.stderr()),
.on => .escape_codes,
.off => .no_color,
};

View File

@ -157,13 +157,9 @@ pub const RenderOptions = struct {
};
pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {
std.debug.lockStdErr();
defer std.debug.unlockStdErr();
var buffer: [256]u8 = undefined;
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = std.io.getStdErr().writer(),
.buffer = &buffer,
};
var bw = std.debug.lockStdErr2(&buffer);
defer std.debug.unlockStdErr();
renderToWriter(eb, options, &bw) catch return;
bw.flush() catch return;
}

View File

@ -9493,7 +9493,8 @@ pub fn asmValue(
}
pub fn dump(self: *Builder) void {
self.print(std.io.getStdErr().writer()) catch {};
const stderr: std.fs.File = .stderr();
self.print(stderr.writer().unbuffered()) catch {};
}
pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
@ -9509,7 +9510,7 @@ pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
return true;
}
pub fn print(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator.Error)!void {
pub fn print(self: *Builder, writer: *std.io.BufferedWriter) (@TypeOf(writer).Error || Allocator.Error)!void {
var bw = std.io.bufferedWriter(writer);
try self.printUnbuffered(bw.writer());
try bw.flush();

View File

@ -6463,24 +6463,25 @@ const maxInt = std.math.maxInt;
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {
const stderr = io.getStdErr().writer();
const stderr: std.fs.File = .stderr();
const stderr_writer = stderr.writer().unbuffered();
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.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 });
try tree.renderError(parse_error, stderr);
try stderr.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.writeAll(" ");
try stderr_writer.writeAll(" ");
}
try stderr.writeAll("^");
try stderr_writer.writeAll("^");
}
try stderr.writeAll("\n");
try stderr_writer.writeAll("\n");
}
if (tree.errors.len != 0) {
return error.ParseError;

View File

@ -22,7 +22,7 @@ pub fn main() !void {
const bytes_per_sec_float = @as(f64, @floatFromInt(source.len * iterations)) / elapsed_s;
const bytes_per_sec = @as(u64, @intFromFloat(@floor(bytes_per_sec_float)));
var stdout_file = std.io.getStdOut();
var stdout_file: std.fs.File = .stdout();
const stdout = stdout_file.writer();
try stdout.print("parsing speed: {:.2}/s, {:.2} used \n", .{
fmtIntSizeBin(bytes_per_sec),

View File

@ -72,13 +72,13 @@ pub fn writeInst(
}
pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
var bw = std.debug.lockStdErr2();
var bw = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
air.write(&bw, pt, liveness);
}
pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
var bw = std.debug.lockStdErr2();
var bw = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
air.writeInst(&bw, inst, pt, liveness);
}

View File

@ -1880,7 +1880,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
if (options.verbose_llvm_cpu_features) {
if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {
var stderr = std.debug.lockStdErr2();
var stderr = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
nosuspend {
stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print;
@ -3942,7 +3942,8 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
// This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error.
// However, we haven't reported any such error.
// This is a compiler bug.
const stderr = std.io.getStdErr().writer();
var stderr = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
try stderr.writeAll("referenced transitive analysis errors, but none actually emitted\n");
try stderr.print("{} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)});
while (ref) |r| {
@ -7222,13 +7223,14 @@ pub fn lockAndSetMiscFailure(
}
pub fn dump_argv(argv: []const []const u8) void {
std.debug.lockStdErr();
var stderr = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
const stderr = std.io.getStdErr().writer();
for (argv[0 .. argv.len - 1]) |arg| {
nosuspend stderr.print("{s} ", .{arg}) catch return;
nosuspend {
for (argv[0 .. argv.len - 1]) |arg| {
stderr.print("{s} ", .{arg}) catch return;
}
stderr.print("{s}\n", .{argv[argv.len - 1]}) catch {};
}
nosuspend stderr.print("{s}\n", .{argv[argv.len - 1]}) catch {};
}
pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {

View File

@ -11267,8 +11267,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
}
fn dumpAllFallible(ip: *const InternPool) anyerror!void {
var bw = std.io.bufferedWriter(std.io.getStdErr().writer());
const w = bw.writer();
var buffer: [4096]u8 = undefined;
var bw = std.debug.lockStdErr2(&buffer);
defer std.debug.unlockStdErr();
for (ip.locals, 0..) |*local, tid| {
const items = local.shared.items.view();
for (
@ -11277,12 +11278,12 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
0..,
) |tag, data, index| {
const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip);
try w.print("${d} = {s}(", .{ i, @tagName(tag) });
try bw.print("${d} = {s}(", .{ i, @tagName(tag) });
switch (tag) {
.removed => {},
.simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}),
.simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}),
.simple_type => try bw.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}),
.simple_value => try bw.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}),
.type_int_signed,
.type_int_unsigned,
@ -11355,14 +11356,14 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
.func_coerced,
.union_value,
.memoized_call,
=> try w.print("{d}", .{data}),
=> try bw.print("{d}", .{data}),
.opt_null,
.type_slice,
.only_possible_value,
=> try w.print("${d}", .{data}),
=> try bw.print("${d}", .{data}),
}
try w.writeAll(")\n");
try bw.writeAll(")\n");
}
}
try bw.flush();
@ -11377,9 +11378,6 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
var bw = std.io.bufferedWriter(std.io.getStdErr().writer());
const w = bw.writer();
var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .empty;
for (ip.locals, 0..) |*local, tid| {
const items = local.shared.items.view().slice();
@ -11402,6 +11400,10 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
}
}
var buffer: [4096]u8 = undefined;
var bw = std.debug.lockStdErr2(&buffer);
defer std.debug.unlockStdErr();
const SortContext = struct {
values: []std.ArrayListUnmanaged(Index),
pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool {
@ -11413,19 +11415,19 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
var it = instances.iterator();
while (it.next()) |entry| {
const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);
try w.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
try bw.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
for (entry.value_ptr.items) |index| {
const unwrapped_index = index.unwrap(ip);
const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
const owner_nav = ip.getNav(func.owner_nav);
try w.print(" {}: (", .{owner_nav.name.fmt(ip)});
try bw.print(" {}: (", .{owner_nav.name.fmt(ip)});
for (func.comptime_args.get(ip)) |arg| {
if (arg != .none) {
const key = ip.indexToKey(arg);
try w.print(" {} ", .{key});
try bw.print(" {} ", .{key});
}
}
try w.writeAll(")\n");
try bw.writeAll(")\n");
}
}

View File

@ -1643,10 +1643,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute
fn dumpHashInfo(all_files: []const *const HashedFile) !void {
var buffer: [4096]u8 = undefined;
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = std.io.getStdOut().writer(),
.buffer = &buffer,
};
var bw: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&buffer);
for (all_files) |hashed_file| {
try bw.print("{s}: {x}: {s}\n", .{
@tagName(hashed_file.kind), &hashed_file.hash, hashed_file.normalized_path,

View File

@ -80,7 +80,7 @@ fn dumpStatusReport() !void {
var fba = std.heap.FixedBufferAllocator.init(&crash_heap);
const allocator = fba.allocator();
const stderr = io.getStdErr().writer();
const stderr = std.fs.File.stderr.writer().unbuffered();
const block: *Sema.Block = anal.block;
const zcu = anal.sema.pt.zcu;
@ -271,8 +271,7 @@ const StackContext = union(enum) {
debug.dumpStackTraceFromBase(context);
},
.not_supported => {
const stderr = io.getStdErr().writer();
stderr.writeAll("Stack trace not supported on this platform.\n") catch {};
std.fs.File.stderr().writeAll("Stack trace not supported on this platform.\n") catch {};
},
}
}
@ -379,7 +378,7 @@ const PanicSwitch = struct {
state.recover_stage = .release_mutex;
const stderr = io.getStdErr().writer();
const stderr = std.fs.File.stderr().writer().unbuffered();
if (builtin.single_threaded) {
stderr.print("panic: ", .{}) catch goTo(releaseMutex, .{state});
} else {
@ -406,7 +405,7 @@ const PanicSwitch = struct {
recover(state, trace, stack, msg);
state.recover_stage = .release_mutex;
const stderr = io.getStdErr().writer();
const stderr = std.fs.File.stderr().writer().unbuffered();
stderr.writeAll("\nOriginal Error:\n") catch {};
goTo(reportStack, .{state});
}
@ -477,7 +476,7 @@ const PanicSwitch = struct {
recover(state, trace, stack, msg);
state.recover_stage = .silent_abort;
const stderr = io.getStdErr().writer();
var stderr = std.fs.File.stderr().writer().unbuffered();
stderr.writeAll("Aborting...\n") catch {};
goTo(abort, .{});
}
@ -505,7 +504,7 @@ const PanicSwitch = struct {
// lower the verbosity, and restore it at the end if we don't panic.
state.recover_verbosity = .message_only;
const stderr = io.getStdErr().writer();
var stderr = std.fs.File.stderr().writer().unbuffered();
stderr.writeAll("\nPanicked during a panic: ") catch {};
stderr.writeAll(msg) catch {};
stderr.writeAll("\nInner panic stack:\n") catch {};
@ -519,7 +518,7 @@ const PanicSwitch = struct {
.message_only => {
state.recover_verbosity = .silent;
const stderr = io.getStdErr().writer();
var stderr = std.fs.File.stderr().writer().unbuffered();
stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {};
stderr.writeAll(msg) catch {};
stderr.writeAll("\n") catch {};

View File

@ -49,7 +49,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
try std.io.getStdOut().writeAll(usage_fmt);
try std.fs.File.stdout().writeAll(usage_fmt);
return process.cleanExit();
} else if (mem.eql(u8, arg, "--color")) {
if (i + 1 >= args.len) {
@ -89,8 +89,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
fatal("cannot use --stdin with positional arguments", .{});
}
const stdin = std.io.getStdIn();
const source_code = std.zig.readSourceFileToEndAlloc(gpa, stdin, null) catch |err| {
const source_code = std.zig.readSourceFileToEndAlloc(gpa, .stdin(), null) catch |err| {
fatal("unable to read stdin: {}", .{err});
};
defer gpa.free(source_code);
@ -145,7 +144,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
process.exit(code);
}
return std.io.getStdOut().writeAll(formatted);
return std.fs.File.stdout().writeAll(formatted);
}
if (input_files.items.len == 0) {
@ -153,10 +152,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
}
var stdout_buffer: [4096]u8 = undefined;
var stdout: std.io.BufferedWriter = .{
.buffer = &stdout_buffer,
.unbuffered_writer = std.io.getStdOut().writer(),
};
var stdout: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&stdout_buffer);
var fmt: Fmt = .{
.gpa = gpa,

View File

@ -304,7 +304,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });
if (comp.verbose_cc) print: {
var stderr = std.debug.lockStdErr2();
var stderr = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;
@ -325,7 +325,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
for (aro_comp.diagnostics.list.items) |diagnostic| {
if (diagnostic.kind == .@"fatal error" or diagnostic.kind == .@"error") {
aro.Diagnostics.render(&aro_comp, std.io.tty.detectConfig(std.io.getStdErr()));
aro.Diagnostics.render(&aro_comp, std.io.tty.detectConfig(.stderr()));
return error.AroPreprocessorFailed;
}
}

View File

@ -163,13 +163,13 @@ fn prune(elf_file: *Elf) void {
}
pub fn dumpPrunedAtoms(elf_file: *Elf) !void {
const stderr = std.io.getStdErr().writer();
var stderr = std.debug.lockStdErr2(&.{});
defer std.debug.unlockStdErr();
for (elf_file.objects.items) |index| {
const file = elf_file.file(index).?;
for (file.atoms()) |atom_index| {
const atom = file.atom(atom_index) orelse continue;
if (!atom.alive)
// TODO should we simply print to stderr?
try stderr.print("link: removing unused section '{s}' in file '{}'\n", .{
atom.name(elf_file),
atom.file(elf_file).?.fmtPath(),

View File

@ -344,7 +344,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
return @import("print_targets.zig").cmdTargets(arena, cmd_args);
} else if (mem.eql(u8, cmd, "version")) {
dev.check(.version_command);
try std.io.getStdOut().writeAll(build_options.version ++ "\n");
try fs.File.stdout().writeAll(build_options.version ++ "\n");
// Check libc++ linkage to make sure Zig was built correctly, but only
// for "env" and "version" to avoid affecting the startup time for
// build-critical commands (check takes about ~10 μs)
@ -360,10 +360,10 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
});
} else if (mem.eql(u8, cmd, "zen")) {
dev.check(.zen_command);
return io.getStdOut().writeAll(info_zen);
return fs.File.stdout().writeAll(info_zen);
} else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) {
dev.check(.help_command);
return io.getStdOut().writeAll(usage);
return fs.File.stdout().writeAll(usage);
} else if (mem.eql(u8, cmd, "ast-check")) {
return cmdAstCheck(arena, cmd_args);
} else if (mem.eql(u8, cmd, "detect-cpu")) {
@ -1040,7 +1040,7 @@ fn buildOutputType(
};
} else if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
try io.getStdOut().writeAll(usage_build_generic);
try fs.File.stdout().writeAll(usage_build_generic);
return cleanExit();
} else if (mem.eql(u8, arg, "--")) {
if (arg_mode == .run) {
@ -2768,9 +2768,9 @@ fn buildOutputType(
} else if (mem.eql(u8, arg, "-V")) {
warn("ignoring request for supported emulations: unimplemented", .{});
} else if (mem.eql(u8, arg, "-v")) {
try std.io.getStdOut().writeAll("zig ld " ++ build_options.version ++ "\n");
try fs.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n");
} else if (mem.eql(u8, arg, "--version")) {
try std.io.getStdOut().writeAll("zig ld " ++ build_options.version ++ "\n");
try fs.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n");
process.exit(0);
} else {
fatal("unsupported linker arg: {s}", .{arg});
@ -3330,7 +3330,7 @@ fn buildOutputType(
var hasher = Cache.Hasher.init("0123456789abcdef");
var w = io.multiWriter(.{ f.writer(), hasher.writer() });
var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init();
try fifo.pump(io.getStdIn().reader(), w.writer());
try fifo.pump(fs.File.stdin().reader().unbuffered(), w.writer().unbuffered());
var bin_digest: Cache.BinDigest = undefined;
hasher.final(&bin_digest);
@ -3548,15 +3548,15 @@ fn buildOutputType(
if (show_builtin) {
const builtin_opts = comp.root_mod.getBuiltinOptions(comp.config);
const source = try builtin_opts.generate(arena);
return std.io.getStdOut().writeAll(source);
return fs.File.stdout().writeAll(source);
}
switch (listen) {
.none => {},
.stdio => {
try serve(
comp,
std.io.getStdIn(),
std.io.getStdOut(),
fs.File.stdin(),
fs.File.stdout(),
test_exec_args.items,
self_exe_path,
arg_mode,
@ -4618,7 +4618,7 @@ fn cmdTranslateC(
fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{ path, fs.path.sep_str, out_zig_path, @errorName(err) });
};
defer zig_file.close();
try io.getStdOut().writeFileAll(zig_file, .{});
try fs.File.stdout().writeFileAll(zig_file, .{});
return cleanExit();
}
}
@ -4648,7 +4648,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
if (mem.eql(u8, arg, "-s") or mem.eql(u8, arg, "--strip")) {
strip = true;
} else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
try io.getStdOut().writeAll(usage_init);
try fs.File.stdout().writeAll(usage_init);
return cleanExit();
} else {
fatal("unrecognized parameter: '{s}'", .{arg});
@ -5478,7 +5478,7 @@ fn jitCmd(
if (options.server) {
var server = std.zig.Server{
.out = std.io.getStdOut(),
.out = fs.File.stdout(),
.in = undefined, // won't be receiving messages
.receive_fifo = undefined, // won't be receiving messages
};
@ -6011,7 +6011,7 @@ fn cmdAstCheck(
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
try io.getStdOut().writeAll(usage_ast_check);
try fs.File.stdout().writeAll(usage_ast_check);
return cleanExit();
} else if (mem.eql(u8, arg, "-t")) {
want_output_text = true;
@ -6062,7 +6062,7 @@ fn cmdAstCheck(
const tree = try Ast.parse(arena, source, mode);
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = io.getStdOut().writer(),
.unbuffered_writer = fs.File.stdout().writer(),
.buffer = &stdout_buffer,
};
@ -6187,7 +6187,7 @@ fn cmdDetectCpu(args: []const []const u8) !void {
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
const stdout = io.getStdOut().writer();
const stdout = fs.File.stdout().writer();
try stdout.writeAll(detect_cpu_usage);
return cleanExit();
} else if (mem.eql(u8, arg, "--llvm")) {
@ -6281,7 +6281,7 @@ fn detectNativeCpuWithLLVM(
fn printCpu(cpu: std.Target.Cpu) !void {
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = io.getStdOut().writer(),
.unbuffered_writer = fs.File.stdout().writer(),
.buffer = &stdout_buffer,
};
@ -6331,7 +6331,7 @@ fn cmdDumpLlvmInts(
const dl = tm.createTargetDataLayout();
const context = llvm.Context.create();
var bw = io.bufferedWriter(io.getStdOut().writer());
var bw = io.bufferedWriter(fs.File.stdout().writer());
const stdout = bw.writer();
for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| {
@ -6364,7 +6364,7 @@ fn cmdDumpZir(
const zir = try Zcu.loadZirCache(arena, f);
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = io.getStdOut().writer(),
.unbuffered_writer = fs.File.stdout().writer(),
.buffer = &stdout_buffer,
};
@ -6452,7 +6452,7 @@ fn cmdChangelist(
try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map);
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = io.getStdOut().writer(),
.unbuffered_writer = fs.File.stdout().writer(),
.buffer = &stdout_buffer,
};
{
@ -6800,7 +6800,7 @@ fn cmdFetch(
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
const stdout = io.getStdOut().writer();
const stdout = fs.File.stdout().writer();
try stdout.writeAll(usage_fetch);
return cleanExit();
} else if (mem.eql(u8, arg, "--global-cache-dir")) {
@ -6914,7 +6914,7 @@ fn cmdFetch(
const name = switch (save) {
.no => {
try io.getStdOut().writer().print("{s}\n", .{package_hash_slice});
try fs.File.stdout().writer().print("{s}\n", .{package_hash_slice});
return cleanExit();
},
.yes, .exact => |name| name: {

View File

@ -22,10 +22,7 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8) !void {
const triple = try host.zigTriple(arena);
var buffer: [1024]u8 = undefined;
var bw: std.io.BufferedWriter = .{
.buffer = &buffer,
.unbuffered_writer = std.io.getStdOut().writer(),
};
var bw: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&buffer);
var jws: std.json.Stringify = .{ .writer = &bw, .options = .{ .whitespace = .indent_1 } };
try jws.beginObject();

View File

@ -15,10 +15,7 @@ pub fn cmdTargets(arena: Allocator, args: []const []const u8) anyerror!void {
_ = args;
const host = std.zig.resolveTargetQueryOrFatal(.{});
var buffer: [1024]u8 = undefined;
var bw: std.io.BufferedWriter = .{
.unbuffered_writer = io.getStdOut().writer(),
.buffer = &buffer,
};
var bw = fs.File.stdout().writer().buffered(&buffer);
try print(arena, &bw, host);
try bw.flush();
}