authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-11 10:56:24+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-07-11 10:56:24+02:00
logb60e9f2e85e1ca42d80d8822783dbbaed55e0526
tree32f17f4e8f8b940c0b0ab75e9d915d304dc4b69d
parenteb375525366ba51c3f626cf9b27d97fc81e2c938
parente25541549852c8dcf4acbcc1a3f3d7ef4bcef9d7
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24394 from ziglang/fixes

buffering fixes

4 files changed, 29 insertions(+), 14 deletions(-)

lib/std/Io/Reader.zig+9
......@@ -840,6 +840,9 @@ pub fn peekDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
840840/// Returns number of bytes streamed, which may be zero, or error.EndOfStream
841841/// if the delimiter was not found.
842842///
843/// Asserts buffer capacity of at least one. This function performs better with
844/// larger buffers.
845///
843846/// See also:
844847/// * `streamDelimiterEnding`
845848/// * `streamDelimiterLimit`
......@@ -858,6 +861,9 @@ pub fn streamDelimiter(r: *Reader, w: *Writer, delimiter: u8) StreamError!usize
858861/// Returns number of bytes streamed, which may be zero. End of stream can be
859862/// detected by checking if the next byte in the stream is the delimiter.
860863///
864/// Asserts buffer capacity of at least one. This function performs better with
865/// larger buffers.
866///
861867/// See also:
862868/// * `streamDelimiter`
863869/// * `streamDelimiterLimit`
......@@ -884,6 +890,9 @@ pub const StreamDelimiterLimitError = error{
884890///
885891/// Returns number of bytes streamed, which may be zero. End of stream can be
886892/// detected by checking if the next byte in the stream is the delimiter.
893///
894/// Asserts buffer capacity of at least one. This function performs better with
895/// larger buffers.
887896pub fn streamDelimiterLimit(
888897 r: *Reader,
889898 w: *Writer,
lib/std/Io/Writer.zig+5
......@@ -572,6 +572,10 @@ pub fn writeAllPreserve(w: *Writer, preserve_length: usize, bytes: []const u8) E
572572/// A user type may be a `struct`, `vector`, `union` or `enum` type.
573573///
574574/// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`.
575///
576/// Asserts `buffer` capacity of at least 2 if a union is printed. This
577/// requirement could be lifted by adjusting the code, but if you trigger that
578/// assertion it is a clue that you should probably be using a buffer.
575579pub fn print(w: *Writer, comptime fmt: []const u8, args: anytype) Error!void {
576580 const ArgsType = @TypeOf(args);
577581 const args_type_info = @typeInfo(ArgsType);
......@@ -942,6 +946,7 @@ pub fn printAddress(w: *Writer, value: anytype) Error!void {
942946 @compileError("cannot format non-pointer type " ++ @typeName(T) ++ " with * specifier");
943947}
944948
949/// Asserts `buffer` capacity of at least 2 if `value` is a union.
945950pub fn printValue(
946951 w: *Writer,
947952 comptime fmt: []const u8,
lib/std/debug.zig+7-3
......@@ -219,10 +219,14 @@ pub fn unlockStderrWriter() void {
219219 std.Progress.unlockStderrWriter();
220220}
221221
222/// Print to stderr, unbuffered, and silently returning on failure. Intended
223/// for use in "printf debugging". Use `std.log` functions for proper logging.
222/// Print to stderr, silently returning on failure. Intended for use in "printf
223/// debugging". Use `std.log` functions for proper logging.
224///
225/// Uses a 64-byte buffer for formatted printing which is flushed before this
226/// function returns.
224227pub fn print(comptime fmt: []const u8, args: anytype) void {
225 const bw = lockStderrWriter(&.{});
228 var buffer: [64]u8 = undefined;
229 const bw = lockStderrWriter(&buffer);
226230 defer unlockStderrWriter();
227231 nosuspend bw.print(fmt, args) catch return;
228232}
lib/std/log.zig+8-11
......@@ -137,8 +137,11 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {
137137 return comptime logEnabled(message_level, default_log_scope);
138138}
139139
140/// The default implementation for the log function, custom log functions may
140/// The default implementation for the log function. Custom log functions may
141141/// forward log messages to this function.
142///
143/// Uses a 64-byte buffer for formatted printing which is flushed before this
144/// function returns.
142145pub fn defaultLog(
143146 comptime message_level: Level,
144147 comptime scope: @Type(.enum_literal),
......@@ -147,16 +150,10 @@ pub fn defaultLog(
147150) void {
148151 const level_txt = comptime message_level.asText();
149152 const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
150 const stderr = std.fs.File.stderr().deprecatedWriter();
151 var bw = std.io.bufferedWriter(stderr);
152 const writer = bw.writer();
153
154 std.debug.lockStdErr();
155 defer std.debug.unlockStdErr();
156 nosuspend {
157 writer.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
158 bw.flush() catch return;
159 }
153 var buffer: [64]u8 = undefined;
154 const stderr = std.debug.lockStderrWriter(&buffer);
155 defer std.debug.unlockStderrWriter();
156 nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
160157}
161158
162159/// Returns a scoped logging namespace that logs all messages using the scope