authorgravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2020-03-06 12:03:15-06:00
committergravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2020-03-12 10:41:09-05:00
log6a53fe7c93ddc6216e7cd41514bebe701531c9c3
tree3822ff2abcb8638f8b67d96fa5fd34eb39b972ae
parent0059d9ee3e7298df03723d97adbea72ff142cacd

Handle potential downcast when translating stream size


2 files changed, 10 insertions(+), 4 deletions(-)

lib/std/buffer.zig+3-1
...@@ -65,7 +65,9 @@ pub const Buffer = struct {...@@ -65,7 +65,9 @@ pub const Buffer = struct {
65 }65 }
6666
67 pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer {67 pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer {
68 const size = std.fmtstream.count(format, args);68 const size = std.fmtstream.count(format, args) catch |err| switch (err) {
69 error.Overflow => return error.OutOfMemory,
70 };
69 var self = try Buffer.initSize(allocator, size);71 var self = try Buffer.initSize(allocator, size);
70 assert((std.fmtstream.bufPrint(self.list.items, format, args) catch unreachable).len == size);72 assert((std.fmtstream.bufPrint(self.list.items, format, args) catch unreachable).len == size);
71 return self;73 return self;
lib/std/fmtstream.zig+7-3
...@@ -1081,16 +1081,20 @@ pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![]...@@ -1081,16 +1081,20 @@ pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![]
1081}1081}
10821082
1083// Count the characters needed for format. Useful for preallocating memory1083// Count the characters needed for format. Useful for preallocating memory
1084pub fn count(comptime fmt: []const u8, args: var) usize {1084pub fn count(comptime fmt: []const u8, args: var) !usize {
1085 var counting_stream = std.io.countingOutStream(std.io.null_out_stream);1085 var counting_stream = std.io.countingOutStream(std.io.null_out_stream);
1086 format(counting_stream.outStream(), fmt, args) catch |err| switch (err) {};1086 format(counting_stream.outStream(), fmt, args) catch |err| switch (err) {};
1087 return counting_stream.bytes_written;1087 return std.math.cast(usize, counting_stream.bytes_written);
1088}1088}
10891089
1090pub const AllocPrintError = error{OutOfMemory};1090pub const AllocPrintError = error{OutOfMemory};
10911091
1092pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![]u8 {1092pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![]u8 {
1093 const buf = try allocator.alloc(u8, count(fmt, args));1093 const size = count(fmt, args) catch |err| switch (err) {
1094 // Output too long. Can't possibly allocate enough memory to display it.
1095 error.Overflow => return error.OutOfMemory,
1096 };
1097 const buf = try allocator.alloc(u8, size);
1094 return bufPrint(buf, fmt, args) catch |err| switch (err) {1098 return bufPrint(buf, fmt, args) catch |err| switch (err) {
1095 error.BufferTooSmall => unreachable, // we just counted the size above1099 error.BufferTooSmall => unreachable, // we just counted the size above
1096 };1100 };