From b6fbd524f122449e6e2bb4d73ce3f59b01286f50 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 10 Mar 2020 16:31:04 -0400 Subject: (breaking) improve and simplify fixed buffer streams API --- lib/std/progress.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/std/progress.zig') diff --git a/lib/std/progress.zig b/lib/std/progress.zig index 1c5ecd261a..0264d99c91 100644 --- a/lib/std/progress.zig +++ b/lib/std/progress.zig @@ -177,7 +177,7 @@ pub const Progress = struct { pub fn log(self: *Progress, comptime format: []const u8, args: var) void { const file = self.terminal orelse return; self.refresh(); - file.outStream().stream.print(format, args) catch { + file.outStream().print(format, args) catch { self.terminal = null; return; }; -- cgit v1.2.3 From 4905102901e7d798860f8346faeae505a7268968 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 13 Mar 2020 11:55:50 -0400 Subject: fix all the TODOs from the pull request * `std.Buffer.print` is removed; use `buffer.outStream().print` * `std.fmt.count` returns a `u64` * `std.Fifo.print` is removed; use `fifo.outStream().print` * `std.fmt.bufPrint` error is renamed from `BufferTooSmall` to `NoSpaceLeft` to match `std.os.write`. * `std.io.FixedBufferStream.getWritten` returns mutable buffer if the buffer is mutable. --- lib/std/buffer.zig | 8 ++------ lib/std/fifo.zig | 26 ++++++++++++-------------- lib/std/fmt.zig | 24 ++++++++++-------------- lib/std/io/fixed_buffer_stream.zig | 2 +- lib/std/progress.zig | 2 +- lib/std/zig/cross_target.zig | 12 ++++++------ src-self-hosted/dep_tokenizer.zig | 10 +++++----- src-self-hosted/stage2.zig | 6 +++--- src-self-hosted/translate_c.zig | 2 +- 9 files changed, 41 insertions(+), 51 deletions(-) (limited to 'lib/std/progress.zig') diff --git a/lib/std/buffer.zig b/lib/std/buffer.zig index cf028f104e..a1e29ef51a 100644 --- a/lib/std/buffer.zig +++ b/lib/std/buffer.zig @@ -65,7 +65,7 @@ pub const Buffer = struct { } pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer { - const size = std.fmt.count(format, args) catch |err| switch (err) { + const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) { error.Overflow => return error.OutOfMemory, }; var self = try Buffer.initSize(allocator, size); @@ -150,10 +150,6 @@ pub const Buffer = struct { mem.copy(u8, self.list.toSlice(), m); } - pub fn print(self: *Buffer, comptime fmt: []const u8, args: var) !void { - return self.outStream().print(fmt, args); - } - pub fn outStream(self: *Buffer) std.io.OutStream(*Buffer, error{OutOfMemory}, appendWrite) { return .{ .context = self }; } @@ -212,7 +208,7 @@ test "Buffer.print" { var buf = try Buffer.init(testing.allocator, ""); defer buf.deinit(); - try buf.print("Hello {} the {}", .{ 2, "world" }); + try buf.outStream().print("Hello {} the {}", .{ 2, "world" }); testing.expect(buf.eql("Hello 2 the world")); } diff --git a/lib/std/fifo.zig b/lib/std/fifo.zig index 65ddc65d3c..94570e93ef 100644 --- a/lib/std/fifo.zig +++ b/lib/std/fifo.zig @@ -293,20 +293,18 @@ pub fn LinearFifo( pub usingnamespace if (T == u8) struct { - pub fn print(self: *Self, comptime format: []const u8, args: var) !void { - // TODO: maybe expose this stream as a method? - const FifoStream = struct { - const OutStream = std.io.OutStream(*Self, Error, write); - const Error = error{OutOfMemory}; - - fn write(fifo: *Self, bytes: []const u8) Error!usize { - try fifo.write(bytes); - return bytes.len; - } - }; + const OutStream = std.io.OutStream(*Self, Error, appendWrite); + const Error = error{OutOfMemory}; + + /// Same as `write` except it returns the number of bytes written, which is always the same + /// as `bytes.len`. The purpose of this function existing is to match `std.io.OutStream` API. + pub fn appendWrite(fifo: *Self, bytes: []const u8) Error!usize { + try fifo.write(bytes); + return bytes.len; + } - var out_stream = FifoStream.OutStream{ .context = self }; - try out_stream.print(format, args); + pub fn outStream(self: *Self) OutStream { + return .{ .context = self }; } } else @@ -419,7 +417,7 @@ test "LinearFifo(u8, .Dynamic)" { fifo.shrink(0); { - try fifo.print("{}, {}!", .{ "Hello", "World" }); + try fifo.outStream().print("{}, {}!", .{ "Hello", "World" }); var result: [30]u8 = undefined; testing.expectEqualSlices(u8, "Hello, World!", result[0..fifo.read(&result)]); testing.expectEqual(@as(usize, 0), fifo.readableLength()); diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 5173015b38..592fe9bb4e 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -580,7 +580,7 @@ pub fn formatAsciiChar( options: FormatOptions, out_stream: var, ) !void { - return out_stream.writeAll(@as(*const [1]u8, &c)[0..]); + return out_stream.writeAll(@as(*const [1]u8, &c)); } pub fn formatBuf( @@ -592,9 +592,9 @@ pub fn formatBuf( const width = options.width orelse 0; var leftover_padding = if (width > buf.len) (width - buf.len) else return; - const pad_byte: u8 = options.fill; + const pad_byte = [1]u8{options.fill}; while (leftover_padding > 0) : (leftover_padding -= 1) { - try out_stream.writeAll(@as(*const [1]u8, &pad_byte)[0..1]); + try out_stream.writeAll(&pad_byte); } } @@ -1068,35 +1068,31 @@ fn digitToChar(digit: u8, uppercase: bool) u8 { pub const BufPrintError = error{ /// As much as possible was written to the buffer, but it was too small to fit all the printed bytes. - BufferTooSmall, + NoSpaceLeft, }; pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![]u8 { var fbs = std.io.fixedBufferStream(buf); - format(fbs.outStream(), fmt, args) catch |err| switch (err) { - error.NoSpaceLeft => return error.BufferTooSmall, - }; - //TODO: should we change one of these return signatures? - //return fbs.getWritten(); - return buf[0..fbs.pos]; + try format(fbs.outStream(), fmt, args); + return fbs.getWritten(); } // Count the characters needed for format. Useful for preallocating memory -pub fn count(comptime fmt: []const u8, args: var) !usize { +pub fn count(comptime fmt: []const u8, args: var) u64 { var counting_stream = std.io.countingOutStream(std.io.null_out_stream); format(counting_stream.outStream(), fmt, args) catch |err| switch (err) {}; - return std.math.cast(usize, counting_stream.bytes_written); + return counting_stream.bytes_written; } pub const AllocPrintError = error{OutOfMemory}; pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![]u8 { - const size = count(fmt, args) catch |err| switch (err) { + const size = math.cast(usize, count(fmt, args)) catch |err| switch (err) { // Output too long. Can't possibly allocate enough memory to display it. error.Overflow => return error.OutOfMemory, }; const buf = try allocator.alloc(u8, size); return bufPrint(buf, fmt, args) catch |err| switch (err) { - error.BufferTooSmall => unreachable, // we just counted the size above + error.NoSpaceLeft => unreachable, // we just counted the size above }; } diff --git a/lib/std/io/fixed_buffer_stream.zig b/lib/std/io/fixed_buffer_stream.zig index 0d091eea72..2f7d613aa6 100644 --- a/lib/std/io/fixed_buffer_stream.zig +++ b/lib/std/io/fixed_buffer_stream.zig @@ -103,7 +103,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type { return self.pos; } - pub fn getWritten(self: Self) []const u8 { + pub fn getWritten(self: Self) Buffer { return self.buffer[0..self.pos]; } diff --git a/lib/std/progress.zig b/lib/std/progress.zig index 0264d99c91..a693ec8619 100644 --- a/lib/std/progress.zig +++ b/lib/std/progress.zig @@ -190,7 +190,7 @@ pub const Progress = struct { end.* += amt; self.columns_written += amt; } else |err| switch (err) { - error.BufferTooSmall => { + error.NoSpaceLeft => { self.columns_written += self.output_buffer.len - end.*; end.* = self.output_buffer.len; }, diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index cec3ea05e5..130e8cdbc1 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -504,22 +504,22 @@ pub const CrossTarget = struct { if (self.os_version_min != null or self.os_version_max != null) { switch (self.getOsVersionMin()) { .none => {}, - .semver => |v| try result.print(".{}", .{v}), - .windows => |v| try result.print(".{}", .{@tagName(v)}), + .semver => |v| try result.outStream().print(".{}", .{v}), + .windows => |v| try result.outStream().print(".{}", .{@tagName(v)}), } } if (self.os_version_max) |max| { switch (max) { .none => {}, - .semver => |v| try result.print("...{}", .{v}), - .windows => |v| try result.print("...{}", .{@tagName(v)}), + .semver => |v| try result.outStream().print("...{}", .{v}), + .windows => |v| try result.outStream().print("...{}", .{@tagName(v)}), } } if (self.glibc_version) |v| { - try result.print("-{}.{}", .{ @tagName(self.getAbi()), v }); + try result.outStream().print("-{}.{}", .{ @tagName(self.getAbi()), v }); } else if (self.abi) |abi| { - try result.print("-{}", .{@tagName(abi)}); + try result.outStream().print("-{}", .{@tagName(abi)}); } return result.toOwnedSlice(); diff --git a/src-self-hosted/dep_tokenizer.zig b/src-self-hosted/dep_tokenizer.zig index c73719ebea..e0c67694e1 100644 --- a/src-self-hosted/dep_tokenizer.zig +++ b/src-self-hosted/dep_tokenizer.zig @@ -306,12 +306,12 @@ pub const Tokenizer = struct { fn errorPosition(self: *Tokenizer, position: usize, bytes: []const u8, comptime fmt: []const u8, args: var) Error { var buffer = try std.Buffer.initSize(&self.arena.allocator, 0); - try buffer.print(fmt, args); + try buffer.outStream().print(fmt, args); try buffer.append(" '"); var out = makeOutput(std.Buffer.append, &buffer); try printCharValues(&out, bytes); try buffer.append("'"); - try buffer.print(" at position {}", .{position - (bytes.len - 1)}); + try buffer.outStream().print(" at position {}", .{position - (bytes.len - 1)}); self.error_text = buffer.toSlice(); return Error.InvalidInput; } @@ -320,8 +320,8 @@ pub const Tokenizer = struct { var buffer = try std.Buffer.initSize(&self.arena.allocator, 0); try buffer.append("illegal char "); try printUnderstandableChar(&buffer, char); - try buffer.print(" at position {}", .{position}); - if (fmt.len != 0) try buffer.print(": " ++ fmt, args); + try buffer.outStream().print(" at position {}", .{position}); + if (fmt.len != 0) try buffer.outStream().print(": " ++ fmt, args); self.error_text = buffer.toSlice(); return Error.InvalidInput; } @@ -997,7 +997,7 @@ fn printCharValues(out: var, bytes: []const u8) !void { fn printUnderstandableChar(buffer: *std.Buffer, char: u8) !void { if (!std.ascii.isPrint(char) or char == ' ') { - try buffer.print("\\x{X:2}", .{char}); + try buffer.outStream().print("\\x{X:2}", .{char}); } else { try buffer.append("'"); try buffer.appendByte(printable_char_tab[char]); diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index b355f8f02a..38dfbaf072 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -1019,7 +1019,7 @@ const Stage2Target = extern struct { .macosx, .netbsd, .openbsd, - => try os_builtin_str_buffer.print( + => try os_builtin_str_buffer.outStream().print( \\ .semver = .{{ \\ .min = .{{ \\ .major = {}, @@ -1043,7 +1043,7 @@ const Stage2Target = extern struct { target.os.version_range.semver.max.patch, }), - .linux => try os_builtin_str_buffer.print( + .linux => try os_builtin_str_buffer.outStream().print( \\ .linux = .{{ \\ .range = .{{ \\ .min = .{{ @@ -1078,7 +1078,7 @@ const Stage2Target = extern struct { target.os.version_range.linux.glibc.patch, }), - .windows => try os_builtin_str_buffer.print( + .windows => try os_builtin_str_buffer.outStream().print( \\ .windows = .{{ \\ .min = .{}, \\ .max = .{}, diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index d7dd2cea48..84416ac980 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -4755,7 +4755,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, const start_index = c.source_buffer.len(); errdefer c.source_buffer.shrink(start_index); - try c.source_buffer.print(format, args); + try c.source_buffer.outStream().print(format, args); const end_index = c.source_buffer.len(); const token_index = c.tree.tokens.len; const new_token = try c.tree.tokens.addOne(); -- cgit v1.2.3