authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-10 22:22:56-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:26-07:00
log60854795b85d075ffc5418f9009c832f6a06a84c
tree02f69ffcb3b1a81ef81312f007916d84923056cc
parent646454beb5026ba50ae6bf4d75d018d1c67fe77a

array list tests passing again


7 files changed, 187 insertions(+), 234 deletions(-)

lib/std/Uri.zig+22-27
...@@ -40,17 +40,16 @@ pub const Component = union(enum) {...@@ -40,17 +40,16 @@ pub const Component = union(enum) {
40 };40 };
41 }41 }
4242
43 pub fn format(component: Component, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!usize {43 pub fn format(component: Component, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
44 var n: usize = 0;
45 if (fmt.len == 0) {44 if (fmt.len == 0) {
46 n += try bw.printCount("std.Uri.Component{{ .{s} = \"{}\" }}", .{45 try bw.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{
47 @tagName(component),46 @tagName(component),
48 std.zig.fmtEscapes(switch (component) {47 std.zig.fmtEscapes(switch (component) {
49 .raw, .percent_encoded => |string| string,48 .raw, .percent_encoded => |string| string,
50 }),49 }),
51 });50 });
52 } else if (comptime std.mem.eql(u8, fmt, "raw")) switch (component) {51 } else if (comptime std.mem.eql(u8, fmt, "raw")) switch (component) {
53 .raw => |raw| n += try bw.writeAllCount(raw),52 .raw => |raw| try bw.writeAll(raw),
54 .percent_encoded => |percent_encoded| {53 .percent_encoded => |percent_encoded| {
55 var start: usize = 0;54 var start: usize = 0;
56 var index: usize = 0;55 var index: usize = 0;
...@@ -59,55 +58,51 @@ pub const Component = union(enum) {...@@ -59,55 +58,51 @@ pub const Component = union(enum) {
59 if (percent_encoded.len - index < 2) continue;58 if (percent_encoded.len - index < 2) continue;
60 const percent_encoded_char =59 const percent_encoded_char =
61 std.fmt.parseInt(u8, percent_encoded[index..][0..2], 16) catch continue;60 std.fmt.parseInt(u8, percent_encoded[index..][0..2], 16) catch continue;
62 n += try bw.printCount("{s}{c}", .{61 try bw.print("{s}{c}", .{
63 percent_encoded[start..percent],62 percent_encoded[start..percent],
64 percent_encoded_char,63 percent_encoded_char,
65 });64 });
66 start = percent + 3;65 start = percent + 3;
67 index = percent + 3;66 index = percent + 3;
68 }67 }
69 n += try bw.writeAllCount(percent_encoded[start..]);68 try bw.writeAll(percent_encoded[start..]);
70 },69 },
71 } else if (comptime std.mem.eql(u8, fmt, "%")) switch (component) {70 } else if (comptime std.mem.eql(u8, fmt, "%")) switch (component) {
72 .raw => |raw| n += try percentEncode(bw, raw, isUnreserved),71 .raw => |raw| try percentEncode(bw, raw, isUnreserved),
73 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),72 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
74 } else if (comptime std.mem.eql(u8, fmt, "user")) switch (component) {73 } else if (comptime std.mem.eql(u8, fmt, "user")) switch (component) {
75 .raw => |raw| n += try percentEncode(bw, raw, isUserChar),74 .raw => |raw| try percentEncode(bw, raw, isUserChar),
76 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),75 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
77 } else if (comptime std.mem.eql(u8, fmt, "password")) switch (component) {76 } else if (comptime std.mem.eql(u8, fmt, "password")) switch (component) {
78 .raw => |raw| n += try percentEncode(bw, raw, isPasswordChar),77 .raw => |raw| try percentEncode(bw, raw, isPasswordChar),
79 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),78 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
80 } else if (comptime std.mem.eql(u8, fmt, "host")) switch (component) {79 } else if (comptime std.mem.eql(u8, fmt, "host")) switch (component) {
81 .raw => |raw| n += try percentEncode(bw, raw, isHostChar),80 .raw => |raw| try percentEncode(bw, raw, isHostChar),
82 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),81 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
83 } else if (comptime std.mem.eql(u8, fmt, "path")) switch (component) {82 } else if (comptime std.mem.eql(u8, fmt, "path")) switch (component) {
84 .raw => |raw| n += try percentEncode(bw, raw, isPathChar),83 .raw => |raw| try percentEncode(bw, raw, isPathChar),
85 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),84 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
86 } else if (comptime std.mem.eql(u8, fmt, "query")) switch (component) {85 } else if (comptime std.mem.eql(u8, fmt, "query")) switch (component) {
87 .raw => |raw| n += try percentEncode(bw, raw, isQueryChar),86 .raw => |raw| try percentEncode(bw, raw, isQueryChar),
88 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),87 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
89 } else if (comptime std.mem.eql(u8, fmt, "fragment")) switch (component) {88 } else if (comptime std.mem.eql(u8, fmt, "fragment")) switch (component) {
90 .raw => |raw| n += try percentEncode(bw, raw, isFragmentChar),89 .raw => |raw| try percentEncode(bw, raw, isFragmentChar),
91 .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded),90 .percent_encoded => |percent_encoded| try bw.writeAll(percent_encoded),
92 } else @compileError("invalid format string '" ++ fmt ++ "'");91 } else @compileError("invalid format string '" ++ fmt ++ "'");
93
94 return n;
95 }92 }
9693
97 pub fn percentEncode(94 pub fn percentEncode(
98 bw: *std.io.BufferedWriter,95 bw: *std.io.BufferedWriter,
99 raw: []const u8,96 raw: []const u8,
100 comptime isValidChar: fn (u8) bool,97 comptime isValidChar: fn (u8) bool,
101 ) anyerror!usize {98 ) anyerror!void {
102 var n: usize = 0;
103 var start: usize = 0;99 var start: usize = 0;
104 for (raw, 0..) |char, index| {100 for (raw, 0..) |char, index| {
105 if (isValidChar(char)) continue;101 if (isValidChar(char)) continue;
106 n += try bw.printCount("{s}%{X:0>2}", .{ raw[start..index], char });102 try bw.print("{s}%{X:0>2}", .{ raw[start..index], char });
107 start = index + 1;103 start = index + 1;
108 }104 }
109 n += try bw.writeAllCount(raw[start..]);105 try bw.writeAll(raw[start..]);
110 return n;
111 }106 }
112};107};
113108
lib/std/builtin.zig+5-7
...@@ -34,8 +34,8 @@ pub const StackTrace = struct {...@@ -34,8 +34,8 @@ pub const StackTrace = struct {
34 index: usize,34 index: usize,
35 instruction_addresses: []usize,35 instruction_addresses: []usize,
3636
37 pub fn format(st: StackTrace, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!usize {37 pub fn format(st: StackTrace, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
38 comptime std.debug.assert(fmt.len == 0);38 comptime if (fmt.len != 0) unreachable;
3939
40 // TODO: re-evaluate whether to use format() methods at all.40 // TODO: re-evaluate whether to use format() methods at all.
41 // Until then, avoid an error when using DebugAllocator with WebAssembly41 // Until then, avoid an error when using DebugAllocator with WebAssembly
...@@ -43,17 +43,15 @@ pub const StackTrace = struct {...@@ -43,17 +43,15 @@ pub const StackTrace = struct {
43 if (builtin.os.tag == .freestanding) return 0;43 if (builtin.os.tag == .freestanding) return 0;
4444
45 const debug_info = std.debug.getSelfDebugInfo() catch |err| {45 const debug_info = std.debug.getSelfDebugInfo() catch |err| {
46 return bw.printCount("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{46 return bw.print("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{
47 @errorName(err),47 @errorName(err),
48 });48 });
49 };49 };
50 const tty_config = std.io.tty.detectConfig(.stderr());50 const tty_config = std.io.tty.detectConfig(.stderr());
51 var n: usize = 0;51 try bw.writeAll("\n");
52 n += try bw.writeAllCount("\n");52 std.debug.writeStackTrace(st, bw, debug_info, tty_config) catch |err| {
53 n += std.debug.writeStackTrace(st, bw, debug_info, tty_config) catch |err| {
54 try bw.print("Unable to print stack trace: {s}\n", .{@errorName(err)});53 try bw.print("Unable to print stack trace: {s}\n", .{@errorName(err)});
55 };54 };
56 return n;
57 }55 }
58};56};
5957
lib/std/debug.zig+6-13
...@@ -733,28 +733,26 @@ pub fn writeStackTrace(...@@ -733,28 +733,26 @@ pub fn writeStackTrace(
733 writer: *std.io.BufferedWriter,733 writer: *std.io.BufferedWriter,
734 debug_info: *SelfInfo,734 debug_info: *SelfInfo,
735 tty_config: io.tty.Config,735 tty_config: io.tty.Config,
736) !usize {736) !void {
737 if (builtin.strip_debug_info) return error.MissingDebugInfo;737 if (builtin.strip_debug_info) return error.MissingDebugInfo;
738 var frame_index: usize = 0;738 var frame_index: usize = 0;
739 var frames_left: usize = @min(stack_trace.index, stack_trace.instruction_addresses.len);739 var frames_left: usize = @min(stack_trace.index, stack_trace.instruction_addresses.len);
740 var n: usize = 0;
741740
742 while (frames_left != 0) : ({741 while (frames_left != 0) : ({
743 frames_left -= 1;742 frames_left -= 1;
744 frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;743 frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;
745 }) {744 }) {
746 const return_address = stack_trace.instruction_addresses[frame_index];745 const return_address = stack_trace.instruction_addresses[frame_index];
747 n += try printSourceAtAddress(debug_info, writer, return_address - 1, tty_config);746 try printSourceAtAddress(debug_info, writer, return_address - 1, tty_config);
748 }747 }
749748
750 if (stack_trace.index > stack_trace.instruction_addresses.len) {749 if (stack_trace.index > stack_trace.instruction_addresses.len) {
751 const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len;750 const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len;
752751
753 n += tty_config.setColor(writer, .bold) catch {};752 tty_config.setColor(writer, .bold) catch {};
754 n += try writer.printCount("({d} additional stack frames skipped...)\n", .{dropped_frames});753 try writer.print("({d} additional stack frames skipped...)\n", .{dropped_frames});
755 n += tty_config.setColor(writer, .reset) catch {};754 tty_config.setColor(writer, .reset) catch {};
756 }755 }
757 return n;
758}756}
759757
760pub const UnwindError = if (have_ucontext)758pub const UnwindError = if (have_ucontext)
...@@ -1102,12 +1100,7 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre...@@ -1102,12 +1100,7 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre
1102 try tty_config.setColor(writer, .reset);1100 try tty_config.setColor(writer, .reset);
1103}1101}
11041102
1105pub fn printSourceAtAddress(1103pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void {
1106 debug_info: *SelfInfo,
1107 writer: *std.io.BufferedWriter,
1108 address: usize,
1109 tty_config: io.tty.Config,
1110) !void {
1111 const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {1104 const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {
1112 error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config),1105 error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config),
1113 else => return err,1106 else => return err,
lib/std/fmt.zig+5-7
...@@ -91,7 +91,7 @@ pub const Options = struct {...@@ -91,7 +91,7 @@ pub const Options = struct {
91/// A user type may be a `struct`, `vector`, `union` or `enum` type.91/// A user type may be a `struct`, `vector`, `union` or `enum` type.
92///92///
93/// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`.93/// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`.
94pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype) anyerror!usize {94pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype) anyerror!void {
95 const ArgsType = @TypeOf(args);95 const ArgsType = @TypeOf(args);
96 const args_type_info = @typeInfo(ArgsType);96 const args_type_info = @typeInfo(ArgsType);
97 if (args_type_info != .@"struct") {97 if (args_type_info != .@"struct") {
...@@ -107,7 +107,6 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp...@@ -107,7 +107,6 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp
107 comptime var arg_state: ArgState = .{ .args_len = fields_info.len };107 comptime var arg_state: ArgState = .{ .args_len = fields_info.len };
108 comptime var i = 0;108 comptime var i = 0;
109 comptime var literal: []const u8 = "";109 comptime var literal: []const u8 = "";
110 var bytes_written: usize = 0;
111 inline while (true) {110 inline while (true) {
112 const start_index = i;111 const start_index = i;
113112
...@@ -137,7 +136,7 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp...@@ -137,7 +136,7 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp
137136
138 // Write out the literal137 // Write out the literal
139 if (literal.len != 0) {138 if (literal.len != 0) {
140 bytes_written += try bw.writeAllCount(literal);139 try bw.writeAll(literal);
141 literal = "";140 literal = "";
142 }141 }
143142
...@@ -197,7 +196,7 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp...@@ -197,7 +196,7 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp
197 const arg_to_print = comptime arg_state.nextArg(arg_pos) orelse196 const arg_to_print = comptime arg_state.nextArg(arg_pos) orelse
198 @compileError("too few arguments");197 @compileError("too few arguments");
199198
200 bytes_written += try bw.printValue(199 try bw.printValue(
201 placeholder.specifier_arg,200 placeholder.specifier_arg,
202 .{201 .{
203 .fill = placeholder.fill,202 .fill = placeholder.fill,
...@@ -218,8 +217,6 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp...@@ -218,8 +217,6 @@ pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytyp
218 else => @compileError(comptimePrint("{d}", .{missing_count}) ++ " unused arguments in '" ++ fmt ++ "'"),217 else => @compileError(comptimePrint("{d}", .{missing_count}) ++ " unused arguments in '" ++ fmt ++ "'"),
219 }218 }
220 }219 }
221
222 return bytes_written;
223}220}
224221
225fn cacheString(str: anytype) []const u8 {222fn cacheString(str: anytype) []const u8 {
...@@ -858,7 +855,8 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr...@@ -858,7 +855,8 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr
858pub fn count(comptime fmt: []const u8, args: anytype) usize {855pub fn count(comptime fmt: []const u8, args: anytype) usize {
859 var buffer: [std.atomic.cache_line]u8 = undefined;856 var buffer: [std.atomic.cache_line]u8 = undefined;
860 var bw = std.io.Writer.null.buffered(&buffer);857 var bw = std.io.Writer.null.buffered(&buffer);
861 return bw.printCount(fmt, args) catch unreachable;858 bw.print(fmt, args) catch unreachable;
859 return bw.bytes_written;
862}860}
863861
864pub const AllocPrintError = error{OutOfMemory};862pub const AllocPrintError = error{OutOfMemory};
lib/std/io/BufferedWriter.zig+135-163
...@@ -19,6 +19,10 @@ buffer: std.ArrayListUnmanaged(u8),...@@ -19,6 +19,10 @@ buffer: std.ArrayListUnmanaged(u8),
19/// equals number of bytes provided. This property is exploited by19/// equals number of bytes provided. This property is exploited by
20/// `std.io.AllocatingWriter` for example.20/// `std.io.AllocatingWriter` for example.
21unbuffered_writer: Writer,21unbuffered_writer: Writer,
22/// Tracks total number of bytes written to this `BufferedWriter`. This value
23/// only increases. In the case of fixed mode, this value always equals
24/// `buffer.items.len`.
25bytes_written: usize = 0,
2226
23/// Number of slices to store on the stack, when trying to send as many byte27/// Number of slices to store on the stack, when trying to send as many byte
24/// vectors through the underlying write calls as possible.28/// vectors through the underlying write calls as possible.
...@@ -106,6 +110,7 @@ pub fn advance(bw: *BufferedWriter, n: usize) void {...@@ -106,6 +110,7 @@ pub fn advance(bw: *BufferedWriter, n: usize) void {
106 const list = &bw.buffer;110 const list = &bw.buffer;
107 list.items.len += n;111 list.items.len += n;
108 assert(list.items.len <= list.capacity);112 assert(list.items.len <= list.capacity);
113 bw.bytes_written += n;
109}114}
110115
111/// The `data` parameter is mutable because this function needs to mutate the116/// The `data` parameter is mutable because this function needs to mutate the
...@@ -114,8 +119,9 @@ pub fn writevAll(bw: *BufferedWriter, data: [][]const u8) anyerror!void {...@@ -114,8 +119,9 @@ pub fn writevAll(bw: *BufferedWriter, data: [][]const u8) anyerror!void {
114 var i: usize = 0;119 var i: usize = 0;
115 while (true) {120 while (true) {
116 var n = try passthru_writeSplat(bw, data[i..], 1);121 var n = try passthru_writeSplat(bw, data[i..], 1);
117 while (n >= data[i].len) {122 const len = data[i].len;
118 n -= data[i].len;123 while (n >= len) {
124 n -= len;
119 i += 1;125 i += 1;
120 if (i >= data.len) return;126 if (i >= data.len) return;
121 }127 }
...@@ -147,7 +153,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -147,7 +153,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
147 end = new_end;153 end = new_end;
148 continue;154 continue;
149 }155 }
150 if (end == 0) return bw.unbuffered_writer.writeSplat(data, splat);156 if (end == 0) return track(&bw.bytes_written, try bw.unbuffered_writer.writeSplat(data, splat));
151 buffers[0] = buffer[0..end];157 buffers[0] = buffer[0..end];
152 const remaining_data = data[i..];158 const remaining_data = data[i..];
153 const remaining_buffers = buffers[1..];159 const remaining_buffers = buffers[1..];
...@@ -163,10 +169,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -163,10 +169,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
163 const remainder = buffer[n..end];169 const remainder = buffer[n..end];
164 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);170 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
165 list.items.len = remainder.len;171 list.items.len = remainder.len;
166 return end - start_end;172 return track(&bw.bytes_written, end - start_end);
167 }173 }
168 list.items.len = 0;174 list.items.len = 0;
169 return n - start_end;175 return track(&bw.bytes_written, n - start_end);
170 }176 }
171 const n = try bw.unbuffered_writer.writeSplat(send_buffers, 1);177 const n = try bw.unbuffered_writer.writeSplat(send_buffers, 1);
172 if (n < end) {178 if (n < end) {
...@@ -174,10 +180,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -174,10 +180,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
174 const remainder = buffer[n..end];180 const remainder = buffer[n..end];
175 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);181 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
176 list.items.len = remainder.len;182 list.items.len = remainder.len;
177 return end - start_end;183 return track(&bw.bytes_written, end - start_end);
178 }184 }
179 list.items.len = 0;185 list.items.len = 0;
180 return n - start_end;186 return track(&bw.bytes_written, n - start_end);
181 }187 }
182188
183 const pattern = data[data.len - 1];189 const pattern = data[data.len - 1];
...@@ -187,7 +193,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -187,7 +193,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
187 // It was added in the loop above; undo it here.193 // It was added in the loop above; undo it here.
188 end -= pattern.len;194 end -= pattern.len;
189 list.items.len = end;195 list.items.len = end;
190 return end - start_end;196 return track(&bw.bytes_written, end - start_end);
191 }197 }
192198
193 const remaining_splat = splat - 1;199 const remaining_splat = splat - 1;
...@@ -195,7 +201,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -195,7 +201,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
195 switch (pattern.len) {201 switch (pattern.len) {
196 0 => {202 0 => {
197 list.items.len = end;203 list.items.len = end;
198 return end - start_end;204 return track(&bw.bytes_written, end - start_end);
199 },205 },
200 1 => {206 1 => {
201 const new_end = end + remaining_splat;207 const new_end = end + remaining_splat;
...@@ -203,7 +209,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -203,7 +209,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
203 @branchHint(.likely);209 @branchHint(.likely);
204 @memset(buffer[end..new_end], pattern[0]);210 @memset(buffer[end..new_end], pattern[0]);
205 list.items.len = new_end;211 list.items.len = new_end;
206 return new_end - start_end;212 return track(&bw.bytes_written, new_end - start_end);
207 }213 }
208 buffers[0] = buffer[0..end];214 buffers[0] = buffer[0..end];
209 buffers[1] = pattern;215 buffers[1] = pattern;
...@@ -213,10 +219,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -213,10 +219,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
213 const remainder = buffer[n..end];219 const remainder = buffer[n..end];
214 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);220 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
215 list.items.len = remainder.len;221 list.items.len = remainder.len;
216 return end - start_end;222 return track(&bw.bytes_written, end - start_end);
217 }223 }
218 list.items.len = 0;224 list.items.len = 0;
219 return n - start_end;225 return track(&bw.bytes_written, n - start_end);
220 },226 },
221 else => {227 else => {
222 const new_end = end + pattern.len * remaining_splat;228 const new_end = end + pattern.len * remaining_splat;
...@@ -226,7 +232,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -226,7 +232,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
226 @memcpy(buffer[end..][0..pattern.len], pattern);232 @memcpy(buffer[end..][0..pattern.len], pattern);
227 }233 }
228 list.items.len = new_end;234 list.items.len = new_end;
229 return new_end - start_end;235 return track(&bw.bytes_written, new_end - start_end);
230 }236 }
231 buffers[0] = buffer[0..end];237 buffers[0] = buffer[0..end];
232 buffers[1] = pattern;238 buffers[1] = pattern;
...@@ -236,14 +242,19 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us...@@ -236,14 +242,19 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us
236 const remainder = buffer[n..end];242 const remainder = buffer[n..end];
237 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);243 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
238 list.items.len = remainder.len;244 list.items.len = remainder.len;
239 return end - start_end;245 return track(&bw.bytes_written, end - start_end);
240 }246 }
241 list.items.len = 0;247 list.items.len = 0;
242 return n - start_end;248 return track(&bw.bytes_written, n - start_end);
243 },249 },
244 }250 }
245}251}
246252
253fn track(bytes_written: *usize, n: usize) usize {
254 bytes_written.* += n;
255 return n;
256}
257
247/// When this function is called it means the buffer got full, so it's time258/// When this function is called it means the buffer got full, so it's time
248/// to return an error. However, we still need to make sure all of the259/// to return an error. However, we still need to make sure all of the
249/// available buffer has been filled.260/// available buffer has been filled.
...@@ -256,6 +267,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize...@@ -256,6 +267,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize
256 const len = @min(bytes.len, dest.len);267 const len = @min(bytes.len, dest.len);
257 @memcpy(dest[0..len], bytes[0..len]);268 @memcpy(dest[0..len], bytes[0..len]);
258 list.items.len += len;269 list.items.len += len;
270 bw.bytes_written = list.items.len;
259 }271 }
260 const pattern = data[data.len - 1];272 const pattern = data[data.len - 1];
261 const dest = list.unusedCapacitySlice();273 const dest = list.unusedCapacitySlice();
...@@ -265,6 +277,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize...@@ -265,6 +277,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize
265 else => for (0..splat - 1) |i| @memcpy(dest[i * pattern.len ..][0..pattern.len], pattern),277 else => for (0..splat - 1) |i| @memcpy(dest[i * pattern.len ..][0..pattern.len], pattern),
266 }278 }
267 list.items.len = list.capacity;279 list.items.len = list.capacity;
280 bw.bytes_written = list.items.len;
268 return error.NoSpaceLeft;281 return error.NoSpaceLeft;
269}282}
270283
...@@ -284,17 +297,11 @@ pub fn write(bw: *BufferedWriter, bytes: []const u8) anyerror!usize {...@@ -284,17 +297,11 @@ pub fn write(bw: *BufferedWriter, bytes: []const u8) anyerror!usize {
284 return 0;297 return 0;
285 }298 }
286 list.items.len = 0;299 list.items.len = 0;
287 return n - end;300 return track(&bw.bytes_written, n - end);
288 }301 }
289 @memcpy(buffer[end..new_end], bytes);302 @memcpy(buffer[end..new_end], bytes);
290 list.items.len = new_end;303 list.items.len = new_end;
291 return bytes.len;304 return track(&bw.bytes_written, bytes.len);
292}
293
294/// Convenience function that calls `writeAll` and then returns `bytes.len`.
295pub fn writeAllCount(bw: *BufferedWriter, bytes: []const u8) anyerror!usize {
296 try writeAll(bw, bytes);
297 return bytes.len;
298}305}
299306
300/// Calls `write` as many times as necessary such that all of `bytes` are307/// Calls `write` as many times as necessary such that all of `bytes` are
...@@ -305,17 +312,7 @@ pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) anyerror!void {...@@ -305,17 +312,7 @@ pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) anyerror!void {
305}312}
306313
307pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!void {314pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!void {
308 _ = try std.fmt.format(bw, format, args);315 try std.fmt.format(bw, format, args);
309}
310
311pub fn printCount(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!usize {
312 return std.fmt.format(bw, format, args);
313}
314
315/// Returns 0 or 1 indicating how many bytes were written.
316pub fn writeByteCount(bw: *BufferedWriter, byte: u8) anyerror!usize {
317 try writeByte(bw, byte);
318 return 1;
319}316}
320317
321pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {318pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {
...@@ -325,6 +322,7 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {...@@ -325,6 +322,7 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {
325 @branchHint(.likely);322 @branchHint(.likely);
326 buffer.ptr[buffer.len] = byte;323 buffer.ptr[buffer.len] = byte;
327 list.items.len = buffer.len + 1;324 list.items.len = buffer.len + 1;
325 bw.bytes_written += 1;
328 return;326 return;
329 }327 }
330 var buffers: [2][]const u8 = .{ buffer, &.{byte} };328 var buffers: [2][]const u8 = .{ buffer, &.{byte} };
...@@ -333,7 +331,9 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {...@@ -333,7 +331,9 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {
333 if (n == 0) {331 if (n == 0) {
334 @branchHint(.unlikely);332 @branchHint(.unlikely);
335 continue;333 continue;
336 } else if (n >= buffer.len) {334 }
335 bw.bytes_written += 1;
336 if (n >= buffer.len) {
337 @branchHint(.likely);337 @branchHint(.likely);
338 if (n > buffer.len) {338 if (n > buffer.len) {
339 @branchHint(.likely);339 @branchHint(.likely);
...@@ -353,12 +353,6 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {...@@ -353,12 +353,6 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {
353 }353 }
354}354}
355355
356/// Convenience function that calls `splatByteAll` and then returns `n`.
357pub fn splatByteAllCount(bw: *BufferedWriter, byte: u8, n: usize) anyerror!usize {
358 try splatByteAll(bw, byte, n);
359 return n;
360}
361
362/// Writes the same byte many times, performing the underlying write call as356/// Writes the same byte many times, performing the underlying write call as
363/// many times as necessary.357/// many times as necessary.
364pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) anyerror!void {358pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) anyerror!void {
...@@ -438,7 +432,10 @@ fn passthru_writeFile(...@@ -438,7 +432,10 @@ fn passthru_writeFile(
438 const bw: *BufferedWriter = @alignCast(@ptrCast(context));432 const bw: *BufferedWriter = @alignCast(@ptrCast(context));
439 const list = &bw.buffer;433 const list = &bw.buffer;
440 const buffer = list.allocatedSlice();434 const buffer = list.allocatedSlice();
441 if (buffer.len == 0) return bw.unbuffered_writer.writeFile(file, offset, len, headers_and_trailers, headers_len);435 if (buffer.len == 0) return track(
436 &bw.bytes_written,
437 try bw.unbuffered_writer.writeFile(file, offset, len, headers_and_trailers, headers_len),
438 );
442 const start_end = list.items.len;439 const start_end = list.items.len;
443 const headers = headers_and_trailers[0..headers_len];440 const headers = headers_and_trailers[0..headers_len];
444 const trailers = headers_and_trailers[headers_len..];441 const trailers = headers_and_trailers[headers_len..];
...@@ -470,10 +467,10 @@ fn passthru_writeFile(...@@ -470,10 +467,10 @@ fn passthru_writeFile(
470 const remainder = buffer[n..end];467 const remainder = buffer[n..end];
471 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);468 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
472 list.items.len = remainder.len;469 list.items.len = remainder.len;
473 return end - start_end;470 return track(&bw.bytes_written, end - start_end);
474 }471 }
475 list.items.len = 0;472 list.items.len = 0;
476 return n - start_end;473 return track(&bw.bytes_written, n - start_end);
477 }474 }
478 // Have not made it past the headers yet; must call `writev`.475 // Have not made it past the headers yet; must call `writev`.
479 const n = try bw.unbuffered_writer.writev(buffers[0 .. buffers_len + 1]);476 const n = try bw.unbuffered_writer.writev(buffers[0 .. buffers_len + 1]);
...@@ -482,10 +479,10 @@ fn passthru_writeFile(...@@ -482,10 +479,10 @@ fn passthru_writeFile(
482 const remainder = buffer[n..end];479 const remainder = buffer[n..end];
483 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);480 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
484 list.items.len = remainder.len;481 list.items.len = remainder.len;
485 return end - start_end;482 return track(&bw.bytes_written, end - start_end);
486 }483 }
487 list.items.len = 0;484 list.items.len = 0;
488 return n - start_end;485 return track(&bw.bytes_written, n - start_end);
489 }486 }
490 // All headers written to buffer.487 // All headers written to buffer.
491 buffers[0] = buffer[0..end];488 buffers[0] = buffer[0..end];
...@@ -500,10 +497,10 @@ fn passthru_writeFile(...@@ -500,10 +497,10 @@ fn passthru_writeFile(
500 const remainder = buffer[n..end];497 const remainder = buffer[n..end];
501 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);498 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
502 list.items.len = remainder.len;499 list.items.len = remainder.len;
503 return end - start_end;500 return track(&bw.bytes_written, end - start_end);
504 }501 }
505 list.items.len = 0;502 list.items.len = 0;
506 return n - start_end;503 return track(&bw.bytes_written, n - start_end);
507}504}
508505
509pub const WriteFileOptions = struct {506pub const WriteFileOptions = struct {
...@@ -583,54 +580,51 @@ pub fn alignBuffer(...@@ -583,54 +580,51 @@ pub fn alignBuffer(
583 width: usize,580 width: usize,
584 alignment: std.fmt.Alignment,581 alignment: std.fmt.Alignment,
585 fill: u8,582 fill: u8,
586) anyerror!usize {583) anyerror!void {
587 const padding = if (buffer.len < width) width - buffer.len else 0;584 const padding = if (buffer.len < width) width - buffer.len else 0;
588 if (padding == 0) {585 if (padding == 0) {
589 @branchHint(.likely);586 @branchHint(.likely);
590 return bw.writeAllCount(buffer);587 return bw.writeAll(buffer);
591 }588 }
592 var n: usize = 0;
593 switch (alignment) {589 switch (alignment) {
594 .left => {590 .left => {
595 n += try bw.writeAllCount(buffer);591 try bw.writeAll(buffer);
596 n += try bw.splatByteAllCount(fill, padding);592 try bw.splatByteAll(fill, padding);
597 },593 },
598 .center => {594 .center => {
599 const left_padding = padding / 2;595 const left_padding = padding / 2;
600 const right_padding = (padding + 1) / 2;596 const right_padding = (padding + 1) / 2;
601 n += try bw.splatByteAllCount(fill, left_padding);597 try bw.splatByteAll(fill, left_padding);
602 n += try bw.writeAllCount(buffer);598 try bw.writeAll(buffer);
603 n += try bw.splatByteAllCount(fill, right_padding);599 try bw.splatByteAll(fill, right_padding);
604 },600 },
605 .right => {601 .right => {
606 n += try bw.splatByteAllCount(fill, padding);602 try bw.splatByteAll(fill, padding);
607 n += try bw.writeAllCount(buffer);603 try bw.writeAll(buffer);
608 },604 },
609 }605 }
610 return n;
611}606}
612607
613pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std.fmt.Options) anyerror!usize {608pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std.fmt.Options) anyerror!void {
614 return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill);609 return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill);
615}610}
616611
617pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!usize {612pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void {
618 const T = @TypeOf(value);613 const T = @TypeOf(value);
619 var n: usize = 0;
620 switch (@typeInfo(T)) {614 switch (@typeInfo(T)) {
621 .pointer => |info| {615 .pointer => |info| {
622 n += try bw.writeAllCount(@typeName(info.child) ++ "@");616 try bw.writeAll(@typeName(info.child) ++ "@");
623 if (info.size == .slice)617 if (info.size == .slice)
624 n += try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{})618 try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{})
625 else619 else
626 n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{});620 try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{});
627 return n;621 return;
628 },622 },
629 .optional => |info| {623 .optional => |info| {
630 if (@typeInfo(info.child) == .pointer) {624 if (@typeInfo(info.child) == .pointer) {
631 n += try bw.writeAll(@typeName(info.child) ++ "@");625 try bw.writeAll(@typeName(info.child) ++ "@");
632 n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{});626 try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{});
633 return n;627 return;
634 }628 }
635 },629 },
636 else => {},630 else => {},
...@@ -645,7 +639,7 @@ pub fn printValue(...@@ -645,7 +639,7 @@ pub fn printValue(
645 options: std.fmt.Options,639 options: std.fmt.Options,
646 value: anytype,640 value: anytype,
647 max_depth: usize,641 max_depth: usize,
648) anyerror!usize {642) anyerror!void {
649 const T = @TypeOf(value);643 const T = @TypeOf(value);
650 const actual_fmt = comptime if (std.mem.eql(u8, fmt, ANY))644 const actual_fmt = comptime if (std.mem.eql(u8, fmt, ANY))
651 defaultFormatString(T)645 defaultFormatString(T)
...@@ -700,104 +694,96 @@ pub fn printValue(...@@ -700,104 +694,96 @@ pub fn printValue(
700 },694 },
701 .error_set => {695 .error_set => {
702 if (actual_fmt.len > 0 and actual_fmt[0] == 's') {696 if (actual_fmt.len > 0 and actual_fmt[0] == 's') {
703 return bw.writeAllCount(@errorName(value));697 return bw.writeAll(@errorName(value));
704 } else if (actual_fmt.len != 0) {698 } else if (actual_fmt.len != 0) {
705 invalidFmtError(fmt, value);699 invalidFmtError(fmt, value);
706 } else {700 } else {
707 var n: usize = 0;701 try bw.writeAll("error.");
708 n += try bw.writeAllCount("error.");702 try bw.writeAll(@errorName(value));
709 n += try bw.writeAllCount(@errorName(value));
710 return n;
711 }703 }
712 },704 },
713 .@"enum" => |enum_info| {705 .@"enum" => |enum_info| {
714 var n: usize = 0;706 try bw.writeAll(@typeName(T));
715 n += try bw.writeAllCount(@typeName(T));
716 if (enum_info.is_exhaustive) {707 if (enum_info.is_exhaustive) {
717 if (actual_fmt.len != 0) invalidFmtError(fmt, value);708 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
718 n += try bw.writeAllCount(".");709 try bw.writeAll(".");
719 n += try bw.writeAllCount(@tagName(value));710 try bw.writeAll(@tagName(value));
720 return n;711 return;
721 }712 }
722713
723 // Use @tagName only if value is one of known fields714 // Use @tagName only if value is one of known fields
724 @setEvalBranchQuota(3 * enum_info.fields.len);715 @setEvalBranchQuota(3 * enum_info.fields.len);
725 inline for (enum_info.fields) |enumField| {716 inline for (enum_info.fields) |enumField| {
726 if (@intFromEnum(value) == enumField.value) {717 if (@intFromEnum(value) == enumField.value) {
727 n += try bw.writeAllCount(".");718 try bw.writeAll(".");
728 n += try bw.writeAllCount(@tagName(value));719 try bw.writeAll(@tagName(value));
729 return;720 return;
730 }721 }
731 }722 }
732723
733 n += try bw.writeByteCount('(');724 try bw.writeByteCount('(');
734 n += try printValue(bw, actual_fmt, options, @intFromEnum(value), max_depth);725 try printValue(bw, actual_fmt, options, @intFromEnum(value), max_depth);
735 n += try bw.writeByteCount(')');726 try bw.writeByteCount(')');
736 return n;
737 },727 },
738 .@"union" => |info| {728 .@"union" => |info| {
739 if (actual_fmt.len != 0) invalidFmtError(fmt, value);729 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
740 var n: usize = 0;730 try bw.writeAll(@typeName(T));
741 n += try bw.writeAllCount(@typeName(T));
742 if (max_depth == 0) {731 if (max_depth == 0) {
743 n += bw.writeAllCount("{ ... }");732 bw.writeAll("{ ... }");
744 return n;733 return;
745 }734 }
746 if (info.tag_type) |UnionTagType| {735 if (info.tag_type) |UnionTagType| {
747 n += try bw.writeAllCount("{ .");736 try bw.writeAll("{ .");
748 n += try bw.writeAllCount(@tagName(@as(UnionTagType, value)));737 try bw.writeAll(@tagName(@as(UnionTagType, value)));
749 n += try bw.writeAllCount(" = ");738 try bw.writeAll(" = ");
750 inline for (info.fields) |u_field| {739 inline for (info.fields) |u_field| {
751 if (value == @field(UnionTagType, u_field.name)) {740 if (value == @field(UnionTagType, u_field.name)) {
752 n += try printValue(bw, ANY, options, @field(value, u_field.name), max_depth - 1);741 try printValue(bw, ANY, options, @field(value, u_field.name), max_depth - 1);
753 }742 }
754 }743 }
755 n += try bw.writeAllCount(" }");744 try bw.writeAll(" }");
756 } else {745 } else {
757 n += try bw.writeByte('@');746 try bw.writeByte('@');
758 n += try bw.printIntOptions(@intFromPtr(&value), 16, .lower);747 try bw.printIntOptions(@intFromPtr(&value), 16, .lower);
759 }748 }
760 return n;
761 },749 },
762 .@"struct" => |info| {750 .@"struct" => |info| {
763 if (actual_fmt.len != 0) invalidFmtError(fmt, value);751 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
764 var n: usize = 0;
765 if (info.is_tuple) {752 if (info.is_tuple) {
766 // Skip the type and field names when formatting tuples.753 // Skip the type and field names when formatting tuples.
767 if (max_depth == 0) {754 if (max_depth == 0) {
768 n += try bw.writeAllCount("{ ... }");755 try bw.writeAll("{ ... }");
769 return n;756 return;
770 }757 }
771 n += try bw.writeAllCount("{");758 try bw.writeAll("{");
772 inline for (info.fields, 0..) |f, i| {759 inline for (info.fields, 0..) |f, i| {
773 if (i == 0) {760 if (i == 0) {
774 n += try bw.writeAllCount(" ");761 try bw.writeAll(" ");
775 } else {762 } else {
776 n += try bw.writeAllCount(", ");763 try bw.writeAll(", ");
777 }764 }
778 n += try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1);765 try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1);
779 }766 }
780 n += try bw.writeAllCount(" }");767 try bw.writeAll(" }");
781 return n;768 return;
782 }769 }
783 n += try bw.writeAllCount(@typeName(T));770 try bw.writeAll(@typeName(T));
784 if (max_depth == 0) {771 if (max_depth == 0) {
785 n += try bw.writeAllCount("{ ... }");772 try bw.writeAll("{ ... }");
786 return n;773 return;
787 }774 }
788 n += try bw.writeAllCount("{");775 try bw.writeAll("{");
789 inline for (info.fields, 0..) |f, i| {776 inline for (info.fields, 0..) |f, i| {
790 if (i == 0) {777 if (i == 0) {
791 n += try bw.writeAllCount(" .");778 try bw.writeAll(" .");
792 } else {779 } else {
793 n += try bw.writeAllCount(", .");780 try bw.writeAll(", .");
794 }781 }
795 n += try bw.writeAllCount(f.name);782 try bw.writeAll(f.name);
796 n += try bw.writeAllCount(" = ");783 try bw.writeAll(" = ");
797 n += try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1);784 try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1);
798 }785 }
799 n += try bw.writeAllCount(" }");786 try bw.writeAll(" }");
800 return n;
801 },787 },
802 .pointer => |ptr_info| switch (ptr_info.size) {788 .pointer => |ptr_info| switch (ptr_info.size) {
803 .one => switch (@typeInfo(ptr_info.child)) {789 .one => switch (@typeInfo(ptr_info.child)) {
...@@ -806,10 +792,9 @@ pub fn printValue(...@@ -806,10 +792,9 @@ pub fn printValue(
806 },792 },
807 else => {793 else => {
808 var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" };794 var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" };
809 var n: usize = 0;795 try writevAll(bw, &buffers);
810 n += try writevAll(bw, &buffers);796 try printIntOptions(bw, @intFromPtr(value), 16, .lower, options);
811 n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, options);797 return;
812 return n;
813 },798 },
814 },799 },
815 .many, .c => {800 .many, .c => {
...@@ -827,7 +812,7 @@ pub fn printValue(...@@ -827,7 +812,7 @@ pub fn printValue(
827 if (actual_fmt.len == 0)812 if (actual_fmt.len == 0)
828 @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})");813 @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})");
829 if (max_depth == 0) {814 if (max_depth == 0) {
830 return bw.writeAllCount("{ ... }");815 return bw.writeAll("{ ... }");
831 }816 }
832 if (ptr_info.child == u8) switch (actual_fmt.len) {817 if (ptr_info.child == u8) switch (actual_fmt.len) {
833 1 => switch (actual_fmt[0]) {818 1 => switch (actual_fmt[0]) {
...@@ -841,23 +826,21 @@ pub fn printValue(...@@ -841,23 +826,21 @@ pub fn printValue(
841 },826 },
842 else => {},827 else => {},
843 };828 };
844 var n: usize = 0;829 try bw.writeAll("{ ");
845 n += try bw.writeAllCount("{ ");
846 for (value, 0..) |elem, i| {830 for (value, 0..) |elem, i| {
847 n += try printValue(bw, actual_fmt, options, elem, max_depth - 1);831 try printValue(bw, actual_fmt, options, elem, max_depth - 1);
848 if (i != value.len - 1) {832 if (i != value.len - 1) {
849 n += try bw.writeAllCount(", ");833 try bw.writeAll(", ");
850 }834 }
851 }835 }
852 n += try bw.writeAllCount(" }");836 try bw.writeAll(" }");
853 return n;
854 },837 },
855 },838 },
856 .array => |info| {839 .array => |info| {
857 if (actual_fmt.len == 0)840 if (actual_fmt.len == 0)
858 @compileError("cannot format array without a specifier (i.e. {s} or {any})");841 @compileError("cannot format array without a specifier (i.e. {s} or {any})");
859 if (max_depth == 0) {842 if (max_depth == 0) {
860 return bw.writeAllCount("{ ... }");843 return bw.writeAll("{ ... }");
861 }844 }
862 if (info.child == u8) {845 if (info.child == u8) {
863 if (actual_fmt[0] == 's') {846 if (actual_fmt[0] == 's') {
...@@ -868,32 +851,28 @@ pub fn printValue(...@@ -868,32 +851,28 @@ pub fn printValue(
868 return printHex(bw, &value, .upper);851 return printHex(bw, &value, .upper);
869 }852 }
870 }853 }
871 var n: usize = 0;854 try bw.writeAll("{ ");
872 n += try bw.writeAllCount("{ ");
873 for (value, 0..) |elem, i| {855 for (value, 0..) |elem, i| {
874 n += try printValue(bw, actual_fmt, options, elem, max_depth - 1);856 try printValue(bw, actual_fmt, options, elem, max_depth - 1);
875 if (i < value.len - 1) {857 if (i < value.len - 1) {
876 n += try bw.writeAllCount(", ");858 try bw.writeAll(", ");
877 }859 }
878 }860 }
879 n += try bw.writeAllCount(" }");861 try bw.writeAll(" }");
880 return n;
881 },862 },
882 .vector => |info| {863 .vector => |info| {
883 if (max_depth == 0) {864 if (max_depth == 0) {
884 return bw.writeAllCount("{ ... }");865 return bw.writeAll("{ ... }");
885 }866 }
886 var n: usize = 0;867 try bw.writeAll("{ ");
887 n += try bw.writeAllCount("{ ");
888 var i: usize = 0;868 var i: usize = 0;
889 while (i < info.len) : (i += 1) {869 while (i < info.len) : (i += 1) {
890 n += try printValue(bw, actual_fmt, options, value[i], max_depth - 1);870 try printValue(bw, actual_fmt, options, value[i], max_depth - 1);
891 if (i < info.len - 1) {871 if (i < info.len - 1) {
892 n += try bw.writeAllCount(", ");872 try bw.writeAll(", ");
893 }873 }
894 }874 }
895 n += try bw.writeAllCount(" }");875 try bw.writeAll(" }");
896 return n;
897 },876 },
898 .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),877 .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),
899 .type => {878 .type => {
...@@ -918,7 +897,7 @@ pub fn printInt(...@@ -918,7 +897,7 @@ pub fn printInt(
918 comptime fmt: []const u8,897 comptime fmt: []const u8,
919 options: std.fmt.Options,898 options: std.fmt.Options,
920 value: anytype,899 value: anytype,
921) anyerror!usize {900) anyerror!void {
922 const int_value = if (@TypeOf(value) == comptime_int) blk: {901 const int_value = if (@TypeOf(value) == comptime_int) blk: {
923 const Int = std.math.IntFittingRange(value, value);902 const Int = std.math.IntFittingRange(value, value);
924 break :blk @as(Int, value);903 break :blk @as(Int, value);
...@@ -962,15 +941,15 @@ pub fn printInt(...@@ -962,15 +941,15 @@ pub fn printInt(
962 comptime unreachable;941 comptime unreachable;
963}942}
964943
965pub fn printAsciiChar(bw: *BufferedWriter, c: u8, options: std.fmt.Options) anyerror!usize {944pub fn printAsciiChar(bw: *BufferedWriter, c: u8, options: std.fmt.Options) anyerror!void {
966 return alignBufferOptions(bw, @as(*const [1]u8, &c), options);945 return alignBufferOptions(bw, @as(*const [1]u8, &c), options);
967}946}
968947
969pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) anyerror!usize {948pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) anyerror!void {
970 return alignBufferOptions(bw, bytes, options);949 return alignBufferOptions(bw, bytes, options);
971}950}
972951
973pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) anyerror!usize {952pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) anyerror!void {
974 var buf: [4]u8 = undefined;953 var buf: [4]u8 = undefined;
975 const len = try std.unicode.utf8Encode(c, &buf);954 const len = try std.unicode.utf8Encode(c, &buf);
976 return alignBufferOptions(bw, buf[0..len], options);955 return alignBufferOptions(bw, buf[0..len], options);
...@@ -982,7 +961,7 @@ pub fn printIntOptions(...@@ -982,7 +961,7 @@ pub fn printIntOptions(
982 base: u8,961 base: u8,
983 case: std.fmt.Case,962 case: std.fmt.Case,
984 options: std.fmt.Options,963 options: std.fmt.Options,
985) anyerror!usize {964) anyerror!void {
986 assert(base >= 2);965 assert(base >= 2);
987966
988 const int_value = if (@TypeOf(value) == comptime_int) blk: {967 const int_value = if (@TypeOf(value) == comptime_int) blk: {
...@@ -1049,7 +1028,7 @@ pub fn printFloat(...@@ -1049,7 +1028,7 @@ pub fn printFloat(
1049 comptime fmt: []const u8,1028 comptime fmt: []const u8,
1050 options: std.fmt.Options,1029 options: std.fmt.Options,
1051 value: anytype,1030 value: anytype,
1052) anyerror!usize {1031) anyerror!void {
1053 var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined;1032 var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined;
10541033
1055 if (fmt.len > 1) invalidFmtError(fmt, value);1034 if (fmt.len > 1) invalidFmtError(fmt, value);
...@@ -1337,7 +1316,7 @@ pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt...@@ -1337,7 +1316,7 @@ pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt
1337 return alignBufferOptions(bw, sub_bw.getWritten(), options);1316 return alignBufferOptions(bw, sub_bw.getWritten(), options);
1338}1317}
13391318
1340pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anyerror!usize {1319pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anyerror!void {
1341 const charset = switch (case) {1320 const charset = switch (case) {
1342 .upper => "0123456789ABCDEF",1321 .upper => "0123456789ABCDEF",
1343 .lower => "0123456789abcdef",1322 .lower => "0123456789abcdef",
...@@ -1346,21 +1325,18 @@ pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anye...@@ -1346,21 +1325,18 @@ pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anye
1346 try writeByte(bw, charset[c >> 4]);1325 try writeByte(bw, charset[c >> 4]);
1347 try writeByte(bw, charset[c & 15]);1326 try writeByte(bw, charset[c & 15]);
1348 }1327 }
1349 return bytes.len * 2;
1350}1328}
13511329
1352pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) anyerror!usize {1330pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) anyerror!void {
1353 var chunker = std.mem.window(u8, bytes, 3, 3);1331 var chunker = std.mem.window(u8, bytes, 3, 3);
1354 var temp: [5]u8 = undefined;1332 var temp: [5]u8 = undefined;
1355 var n: usize = 0;
1356 while (chunker.next()) |chunk| {1333 while (chunker.next()) |chunk| {
1357 n += try bw.writeAllCount(std.base64.standard.Encoder.encode(&temp, chunk));1334 try bw.writeAll(std.base64.standard.Encoder.encode(&temp, chunk));
1358 }1335 }
1359 return n;
1360}1336}
13611337
1362/// Write a single unsigned integer as unsigned LEB128 to the given writer.1338/// Write a single unsigned integer as unsigned LEB128 to the given writer.
1363pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {1339pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!void {
1364 const Arg = @TypeOf(arg);1340 const Arg = @TypeOf(arg);
1365 const Int = switch (Arg) {1341 const Int = switch (Arg) {
1366 comptime_int => std.math.IntFittingRange(arg, arg),1342 comptime_int => std.math.IntFittingRange(arg, arg),
...@@ -1368,23 +1344,21 @@ pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {...@@ -1368,23 +1344,21 @@ pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {
1368 };1344 };
1369 const Value = if (@typeInfo(Int).int.bits < 8) u8 else Int;1345 const Value = if (@typeInfo(Int).int.bits < 8) u8 else Int;
1370 var value: Value = arg;1346 var value: Value = arg;
1371 var n: usize = 0;
13721347
1373 while (true) {1348 while (true) {
1374 const byte: u8 = @truncate(value & 0x7f);1349 const byte: u8 = @truncate(value & 0x7f);
1375 value >>= 7;1350 value >>= 7;
1376 if (value == 0) {1351 if (value == 0) {
1377 try bw.writeByte(byte);1352 try bw.writeByte(byte);
1378 return n + 1;1353 return;
1379 } else {1354 } else {
1380 try bw.writeByte(byte | 0x80);1355 try bw.writeByte(byte | 0x80);
1381 n += 1;
1382 }1356 }
1383 }1357 }
1384}1358}
13851359
1386/// Write a single signed integer as signed LEB128 to the given writer.1360/// Write a single signed integer as signed LEB128 to the given writer.
1387pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {1361pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!void {
1388 const Arg = @TypeOf(arg);1362 const Arg = @TypeOf(arg);
1389 const Int = switch (Arg) {1363 const Int = switch (Arg) {
1390 comptime_int => std.math.IntFittingRange(-@abs(arg), @abs(arg)),1364 comptime_int => std.math.IntFittingRange(-@abs(arg), @abs(arg)),
...@@ -1393,7 +1367,6 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {...@@ -1393,7 +1367,6 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {
1393 const Signed = if (@typeInfo(Int).int.bits < 8) i8 else Int;1367 const Signed = if (@typeInfo(Int).int.bits < 8) i8 else Int;
1394 const Unsigned = std.meta.Int(.unsigned, @typeInfo(Signed).int.bits);1368 const Unsigned = std.meta.Int(.unsigned, @typeInfo(Signed).int.bits);
1395 var value: Signed = arg;1369 var value: Signed = arg;
1396 var n: usize = 0;
13971370
1398 while (true) {1371 while (true) {
1399 const unsigned: Unsigned = @bitCast(value);1372 const unsigned: Unsigned = @bitCast(value);
...@@ -1401,11 +1374,10 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {...@@ -1401,11 +1374,10 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize {
1401 value >>= 6;1374 value >>= 6;
1402 if (value == -1 or value == 0) {1375 if (value == -1 or value == 0) {
1403 try bw.writeByte(byte & 0x7F);1376 try bw.writeByte(byte & 0x7F);
1404 return n + 1;1377 return;
1405 } else {1378 } else {
1406 value >>= 1;1379 value >>= 1;
1407 try bw.writeByte(byte | 0x80);1380 try bw.writeByte(byte | 0x80);
1408 n += 1;
1409 }1381 }
1410 }1382 }
1411}1383}
lib/std/zig/ErrorBundle.zig+8-7
...@@ -190,21 +190,22 @@ fn renderErrorMessageToWriter(...@@ -190,21 +190,22 @@ fn renderErrorMessageToWriter(
190) anyerror!void {190) anyerror!void {
191 const ttyconf = options.ttyconf;191 const ttyconf = options.ttyconf;
192 const err_msg = eb.getErrorMessage(err_msg_index);192 const err_msg = eb.getErrorMessage(err_msg_index);
193 // This is the length of the part before the error message:193 const prefix_start = bw.bytes_written;
194 // e.g. "file.zig:4:5: error: "
195 var prefix_len: usize = 0;
196 if (err_msg.src_loc != .none) {194 if (err_msg.src_loc != .none) {
197 const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));195 const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
198 prefix_len += try bw.splatByteAllCount(' ', indent);196 try bw.splatByteAll(' ', indent);
199 try ttyconf.setColor(bw, .bold);197 try ttyconf.setColor(bw, .bold);
200 prefix_len += try bw.printCount("{s}:{d}:{d}: ", .{198 try bw.print("{s}:{d}:{d}: ", .{
201 eb.nullTerminatedString(src.data.src_path),199 eb.nullTerminatedString(src.data.src_path),
202 src.data.line + 1,200 src.data.line + 1,
203 src.data.column + 1,201 src.data.column + 1,
204 });202 });
205 try ttyconf.setColor(bw, color);203 try ttyconf.setColor(bw, color);
206 prefix_len += try bw.writeAllCount(kind);204 try bw.writeAll(kind);
207 prefix_len += try bw.writeAllCount(": ");205 try bw.writeAll(": ");
206 // This is the length of the part before the error message:
207 // e.g. "file.zig:4:5: error: "
208 const prefix_len = bw.bytes_written - prefix_start;
208 try ttyconf.setColor(bw, .reset);209 try ttyconf.setColor(bw, .reset);
209 try ttyconf.setColor(bw, .bold);210 try ttyconf.setColor(bw, .bold);
210 if (err_msg.count == 1) {211 if (err_msg.count == 1) {
lib/ubsan_rt.zig+6-10
...@@ -119,28 +119,24 @@ const Value = extern struct {...@@ -119,28 +119,24 @@ const Value = extern struct {
119 }119 }
120 }120 }
121121
122 pub fn format(122 pub fn format(value: Value, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
123 value: Value,
124 bw: *std.io.BufferedWriter,
125 comptime fmt: []const u8,
126 ) anyerror!usize {
127 comptime assert(fmt.len == 0);123 comptime assert(fmt.len == 0);
128124
129 // Work around x86_64 backend limitation.125 // Work around x86_64 backend limitation.
130 if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) {126 if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) {
131 return bw.writeAllCount("(unknown)");127 return bw.writeAll("(unknown)");
132 }128 }
133129
134 switch (value.td.kind) {130 switch (value.td.kind) {
135 .integer => {131 .integer => {
136 if (value.td.isSigned()) {132 if (value.td.isSigned()) {
137 return bw.printCount("{d}", .{value.getSignedInteger()});133 return bw.print("{d}", .{value.getSignedInteger()});
138 } else {134 } else {
139 return bw.printCount("{d}", .{value.getUnsignedInteger()});135 return bw.print("{d}", .{value.getUnsignedInteger()});
140 }136 }
141 },137 },
142 .float => return bw.printCount("{d}", .{value.getFloat()}),138 .float => return bw.print("{d}", .{value.getFloat()}),
143 .unknown => return bw.writeAllCount("(unknown)"),139 .unknown => return bw.writeAll("(unknown)"),
144 }140 }
145 }141 }
146};142};