| author | |
| committer | |
| log | 7f975bf09f4e6e81d68c9a573ac2e31b997b5816 |
| tree | 1fd5c25caa7321898f45c45e6a42f6623b94c760 |
| parent | fa46bcb36864e6616ce4449965063f3b8720f8e1 |
| parent | 231a4b8fde6ff061198c76d02990a471ec48c977 |
| signature |
Closes #4405
Closes #465611 files changed, 165 insertions(+), 131 deletions(-)
build.zig-1| ... | ... | @@ -6,7 +6,6 @@ const BufMap = std.BufMap; |
| 6 | 6 | const warn = std.debug.warn; |
| 7 | 7 | const mem = std.mem; |
| 8 | 8 | const ArrayList = std.ArrayList; |
| 9 | const Buffer = std.Buffer; | |
| 10 | 9 | const io = std.io; |
| 11 | 10 | const fs = std.fs; |
| 12 | 11 | const InstallDirectoryOptions = std.build.InstallDirectoryOptions; |
lib/std/array_list.zig+48-34| ... | ... | @@ -5,10 +5,8 @@ const testing = std.testing; |
| 5 | 5 | const mem = std.mem; |
| 6 | 6 | const Allocator = mem.Allocator; |
| 7 | 7 | |
| 8 | /// List of items. | |
| 9 | /// | |
| 10 | /// This is a wrapper around an array of T values. Initialize with | |
| 11 | /// `init`. | |
| 8 | /// A contiguous, growable list of items in memory. | |
| 9 | /// This is a wrapper around an array of T values. Initialize with `init`. | |
| 12 | 10 | pub fn ArrayList(comptime T: type) type { |
| 13 | 11 | return AlignedArrayList(T, null); |
| 14 | 12 | } |
| ... | ... | @@ -22,7 +20,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 22 | 20 | return struct { |
| 23 | 21 | const Self = @This(); |
| 24 | 22 | |
| 25 | /// Use toSlice instead of slicing this directly, because if you don't | |
| 23 | /// Use `span` instead of slicing this directly, because if you don't | |
| 26 | 24 | /// specify the end position of the slice, this will potentially give |
| 27 | 25 | /// you uninitialized memory. |
| 28 | 26 | items: Slice, |
| ... | ... | @@ -56,34 +54,37 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 56 | 54 | |
| 57 | 55 | /// Return contents as a slice. Only valid while the list |
| 58 | 56 | /// doesn't change size. |
| 59 | pub fn toSlice(self: Self) Slice { | |
| 57 | pub fn span(self: var) @TypeOf(self.items[0..self.len]) { | |
| 60 | 58 | return self.items[0..self.len]; |
| 61 | 59 | } |
| 62 | 60 | |
| 63 | /// Return list as const slice. Only valid while the list | |
| 64 | /// doesn't change size. | |
| 61 | /// Deprecated: use `span`. | |
| 62 | pub fn toSlice(self: Self) Slice { | |
| 63 | return self.span(); | |
| 64 | } | |
| 65 | ||
| 66 | /// Deprecated: use `span`. | |
| 65 | 67 | pub fn toSliceConst(self: Self) SliceConst { |
| 66 | return self.items[0..self.len]; | |
| 68 | return self.span(); | |
| 67 | 69 | } |
| 68 | 70 | |
| 69 | /// Safely access index i of the list. | |
| 71 | /// Deprecated: use `span()[i]`. | |
| 70 | 72 | pub fn at(self: Self, i: usize) T { |
| 71 | return self.toSliceConst()[i]; | |
| 73 | return self.span()[i]; | |
| 72 | 74 | } |
| 73 | 75 | |
| 74 | /// Safely access ptr to index i of the list. | |
| 76 | /// Deprecated: use `&span()[i]`. | |
| 75 | 77 | pub fn ptrAt(self: Self, i: usize) *T { |
| 76 | return &self.toSlice()[i]; | |
| 78 | return &self.span()[i]; | |
| 77 | 79 | } |
| 78 | 80 | |
| 79 | /// Sets the value at index `i`, or returns `error.OutOfBounds` if | |
| 80 | /// the index is not in range. | |
| 81 | /// Deprecated: use `if (i >= list.len) return error.OutOfBounds else span()[i] = item`. | |
| 81 | 82 | pub fn setOrError(self: Self, i: usize, item: T) !void { |
| 82 | 83 | if (i >= self.len) return error.OutOfBounds; |
| 83 | 84 | self.items[i] = item; |
| 84 | 85 | } |
| 85 | 86 | |
| 86 | /// Sets the value at index `i`, asserting that the value is in range. | |
| 87 | /// Deprecated: use `list.span()[i] = item`. | |
| 87 | 88 | pub fn set(self: *Self, i: usize, item: T) void { |
| 88 | 89 | assert(i < self.len); |
| 89 | 90 | self.items[i] = item; |
| ... | ... | @@ -124,18 +125,18 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 124 | 125 | self.items[n] = item; |
| 125 | 126 | } |
| 126 | 127 | |
| 127 | /// Insert slice `items` at index `n`. Moves | |
| 128 | /// `list[n .. list.len]` to make room. | |
| 129 | pub fn insertSlice(self: *Self, n: usize, items: SliceConst) !void { | |
| 128 | /// Insert slice `items` at index `i`. Moves | |
| 129 | /// `list[i .. list.len]` to make room. | |
| 130 | /// This operation is O(N). | |
| 131 | pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void { | |
| 130 | 132 | try self.ensureCapacity(self.len + items.len); |
| 131 | 133 | self.len += items.len; |
| 132 | 134 | |
| 133 | mem.copyBackwards(T, self.items[n + items.len .. self.len], self.items[n .. self.len - items.len]); | |
| 134 | mem.copy(T, self.items[n .. n + items.len], items); | |
| 135 | mem.copyBackwards(T, self.items[i + items.len .. self.len], self.items[i .. self.len - items.len]); | |
| 136 | mem.copy(T, self.items[i .. i + items.len], items); | |
| 135 | 137 | } |
| 136 | 138 | |
| 137 | /// Extend the list by 1 element. Allocates more memory as | |
| 138 | /// necessary. | |
| 139 | /// Extend the list by 1 element. Allocates more memory as necessary. | |
| 139 | 140 | pub fn append(self: *Self, item: T) !void { |
| 140 | 141 | const new_item_ptr = try self.addOne(); |
| 141 | 142 | new_item_ptr.* = item; |
| ... | ... | @@ -148,8 +149,9 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 148 | 149 | new_item_ptr.* = item; |
| 149 | 150 | } |
| 150 | 151 | |
| 151 | /// Remove the element at index `i` from the list and return | |
| 152 | /// its value. Asserts the array has at least one item. | |
| 152 | /// Remove the element at index `i` from the list and return its value. | |
| 153 | /// Asserts the array has at least one item. | |
| 154 | /// This operation is O(N). | |
| 153 | 155 | pub fn orderedRemove(self: *Self, i: usize) T { |
| 154 | 156 | const newlen = self.len - 1; |
| 155 | 157 | if (newlen == i) return self.pop(); |
| ... | ... | @@ -163,18 +165,17 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 163 | 165 | |
| 164 | 166 | /// Removes the element at the specified index and returns it. |
| 165 | 167 | /// The empty slot is filled from the end of the list. |
| 168 | /// This operation is O(1). | |
| 166 | 169 | pub fn swapRemove(self: *Self, i: usize) T { |
| 167 | 170 | if (self.len - 1 == i) return self.pop(); |
| 168 | 171 | |
| 169 | const slice = self.toSlice(); | |
| 172 | const slice = self.span(); | |
| 170 | 173 | const old_item = slice[i]; |
| 171 | 174 | slice[i] = self.pop(); |
| 172 | 175 | return old_item; |
| 173 | 176 | } |
| 174 | 177 | |
| 175 | /// Removes the element at the specified index and returns it | |
| 176 | /// or an error.OutOfBounds is returned. If no error then | |
| 177 | /// the empty slot is filled from the end of the list. | |
| 178 | /// Deprecated: use `if (i >= list.len) return error.OutOfBounds else list.swapRemove(i)`. | |
| 178 | 179 | pub fn swapRemoveOrError(self: *Self, i: usize) !T { |
| 179 | 180 | if (i >= self.len) return error.OutOfBounds; |
| 180 | 181 | return self.swapRemove(i); |
| ... | ... | @@ -204,6 +205,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 204 | 205 | } |
| 205 | 206 | |
| 206 | 207 | /// Reduce allocated capacity to `new_len`. |
| 208 | /// Invalidates element pointers. | |
| 207 | 209 | pub fn shrink(self: *Self, new_len: usize) void { |
| 208 | 210 | assert(new_len <= self.len); |
| 209 | 211 | self.len = new_len; |
| ... | ... | @@ -222,13 +224,24 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 222 | 224 | self.items = try self.allocator.realloc(self.items, better_capacity); |
| 223 | 225 | } |
| 224 | 226 | |
| 227 | /// Increases the array's length to match the full capacity that is already allocated. | |
| 228 | /// The new elements have `undefined` values. This operation does not invalidate any | |
| 229 | /// element pointers. | |
| 230 | pub fn expandToCapacity(self: *Self) void { | |
| 231 | self.len = self.items.len; | |
| 232 | } | |
| 233 | ||
| 225 | 234 | /// Increase length by 1, returning pointer to the new item. |
| 235 | /// The returned pointer becomes invalid when the list is resized. | |
| 226 | 236 | pub fn addOne(self: *Self) !*T { |
| 227 | 237 | const new_length = self.len + 1; |
| 228 | 238 | try self.ensureCapacity(new_length); |
| 229 | 239 | return self.addOneAssumeCapacity(); |
| 230 | 240 | } |
| 231 | 241 | |
| 242 | /// Increase length by 1, returning pointer to the new item. | |
| 243 | /// Asserts that there is already space for the new item without allocating more. | |
| 244 | /// The returned pointer becomes invalid when the list is resized. | |
| 232 | 245 | pub fn addOneAssumeCapacity(self: *Self) *T { |
| 233 | 246 | assert(self.len < self.capacity()); |
| 234 | 247 | const result = &self.items[self.len]; |
| ... | ... | @@ -236,14 +249,15 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 236 | 249 | return result; |
| 237 | 250 | } |
| 238 | 251 | |
| 239 | /// Remove and return the last element from the list. Asserts | |
| 240 | /// the list has at least one item. | |
| 252 | /// Remove and return the last element from the list. | |
| 253 | /// Asserts the list has at least one item. | |
| 241 | 254 | pub fn pop(self: *Self) T { |
| 242 | 255 | self.len -= 1; |
| 243 | 256 | return self.items[self.len]; |
| 244 | 257 | } |
| 245 | 258 | |
| 246 | /// Like `pop` but returns `null` if empty. | |
| 259 | /// Remove and return the last element from the list. | |
| 260 | /// If the list is empty, returns `null`. | |
| 247 | 261 | pub fn popOrNull(self: *Self) ?T { |
| 248 | 262 | if (self.len == 0) return null; |
| 249 | 263 | return self.pop(); |
| ... | ... | @@ -287,7 +301,7 @@ test "std.ArrayList.basic" { |
| 287 | 301 | } |
| 288 | 302 | } |
| 289 | 303 | |
| 290 | for (list.toSlice()) |v, i| { | |
| 304 | for (list.span()) |v, i| { | |
| 291 | 305 | testing.expect(v == @intCast(i32, i + 1)); |
| 292 | 306 | } |
| 293 | 307 | |
| ... | ... | @@ -325,7 +339,7 @@ test "std.ArrayList.appendNTimes" { |
| 325 | 339 | |
| 326 | 340 | try list.appendNTimes(2, 10); |
| 327 | 341 | testing.expectEqual(@as(usize, 10), list.len); |
| 328 | for (list.toSlice()) |element| { | |
| 342 | for (list.span()) |element| { | |
| 329 | 343 | testing.expectEqual(@as(i32, 2), element); |
| 330 | 344 | } |
| 331 | 345 | } |
lib/std/buffer.zig+8-2| ... | ... | @@ -81,12 +81,18 @@ pub const Buffer = struct { |
| 81 | 81 | self.list.deinit(); |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :0]) { | |
| 85 | return self.list.span()[0..self.len() :0]; | |
| 86 | } | |
| 87 | ||
| 88 | /// Deprecated: use `span` | |
| 84 | 89 | pub fn toSlice(self: Buffer) [:0]u8 { |
| 85 | return self.list.toSlice()[0..self.len() :0]; | |
| 90 | return self.span(); | |
| 86 | 91 | } |
| 87 | 92 | |
| 93 | /// Deprecated: use `span` | |
| 88 | 94 | pub fn toSliceConst(self: Buffer) [:0]const u8 { |
| 89 | return self.list.toSliceConst()[0..self.len() :0]; | |
| 95 | return self.span(); | |
| 90 | 96 | } |
| 91 | 97 | |
| 92 | 98 | pub fn shrink(self: *Buffer, new_len: usize) void { |
lib/std/build.zig+3-5| ... | ... | @@ -926,11 +926,9 @@ pub const Builder = struct { |
| 926 | 926 | |
| 927 | 927 | try child.spawn(); |
| 928 | 928 | |
| 929 | var stdout = std.Buffer.initNull(self.allocator); | |
| 930 | defer std.Buffer.deinit(&stdout); | |
| 931 | ||
| 932 | 929 | var stdout_file_in_stream = child.stdout.?.inStream(); |
| 933 | try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); | |
| 930 | const stdout = try stdout_file_in_stream.stream.readAllAlloc(self.allocator, max_output_size); | |
| 931 | errdefer self.allocator.free(stdout); | |
| 934 | 932 | |
| 935 | 933 | const term = try child.wait(); |
| 936 | 934 | switch (term) { |
| ... | ... | @@ -939,7 +937,7 @@ pub const Builder = struct { |
| 939 | 937 | out_code.* = @truncate(u8, code); |
| 940 | 938 | return error.ExitCodeFailure; |
| 941 | 939 | } |
| 942 | return stdout.toOwnedSlice(); | |
| 940 | return stdout; | |
| 943 | 941 | }, |
| 944 | 942 | .Signal, .Stopped, .Unknown => |code| { |
| 945 | 943 | out_code.* = @truncate(u8, code); |
lib/std/build/run.zig+17-15| ... | ... | @@ -9,7 +9,6 @@ const mem = std.mem; |
| 9 | 9 | const process = std.process; |
| 10 | 10 | const ArrayList = std.ArrayList; |
| 11 | 11 | const BufMap = std.BufMap; |
| 12 | const Buffer = std.Buffer; | |
| 13 | 12 | const warn = std.debug.warn; |
| 14 | 13 | |
| 15 | 14 | const max_stdout_size = 1 * 1024 * 1024; // 1 MiB |
| ... | ... | @@ -169,23 +168,26 @@ pub const RunStep = struct { |
| 169 | 168 | return err; |
| 170 | 169 | }; |
| 171 | 170 | |
| 172 | var stdout = Buffer.initNull(self.builder.allocator); | |
| 173 | var stderr = Buffer.initNull(self.builder.allocator); | |
| 174 | ||
| 175 | 171 | // TODO need to poll to read these streams to prevent a deadlock (or rely on evented I/O). |
| 176 | 172 | |
| 173 | var stdout: ?[]const u8 = null; | |
| 174 | defer if (stdout) |s| self.builder.allocator.free(s); | |
| 175 | ||
| 177 | 176 | switch (self.stdout_action) { |
| 178 | 177 | .expect_exact, .expect_matches => { |
| 179 | 178 | var stdout_file_in_stream = child.stdout.?.inStream(); |
| 180 | stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size) catch unreachable; | |
| 179 | stdout = stdout_file_in_stream.stream.readAllAlloc(self.builder.allocator, max_stdout_size) catch unreachable; | |
| 181 | 180 | }, |
| 182 | 181 | .inherit, .ignore => {}, |
| 183 | 182 | } |
| 184 | 183 | |
| 185 | switch (self.stdout_action) { | |
| 184 | var stderr: ?[]const u8 = null; | |
| 185 | defer if (stderr) |s| self.builder.allocator.free(s); | |
| 186 | ||
| 187 | switch (self.stderr_action) { | |
| 186 | 188 | .expect_exact, .expect_matches => { |
| 187 | 189 | var stderr_file_in_stream = child.stderr.?.inStream(); |
| 188 | stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size) catch unreachable; | |
| 190 | stderr = stderr_file_in_stream.stream.readAllAlloc(self.builder.allocator, max_stdout_size) catch unreachable; | |
| 189 | 191 | }, |
| 190 | 192 | .inherit, .ignore => {}, |
| 191 | 193 | } |
| ... | ... | @@ -216,7 +218,7 @@ pub const RunStep = struct { |
| 216 | 218 | switch (self.stderr_action) { |
| 217 | 219 | .inherit, .ignore => {}, |
| 218 | 220 | .expect_exact => |expected_bytes| { |
| 219 | if (!mem.eql(u8, expected_bytes, stderr.toSliceConst())) { | |
| 221 | if (!mem.eql(u8, expected_bytes, stderr.?)) { | |
| 220 | 222 | warn( |
| 221 | 223 | \\ |
| 222 | 224 | \\========= Expected this stderr: ========= |
| ... | ... | @@ -224,13 +226,13 @@ pub const RunStep = struct { |
| 224 | 226 | \\========= But found: ==================== |
| 225 | 227 | \\{} |
| 226 | 228 | \\ |
| 227 | , .{ expected_bytes, stderr.toSliceConst() }); | |
| 229 | , .{ expected_bytes, stderr.? }); | |
| 228 | 230 | printCmd(cwd, argv); |
| 229 | 231 | return error.TestFailed; |
| 230 | 232 | } |
| 231 | 233 | }, |
| 232 | 234 | .expect_matches => |matches| for (matches) |match| { |
| 233 | if (mem.indexOf(u8, stderr.toSliceConst(), match) == null) { | |
| 235 | if (mem.indexOf(u8, stderr.?, match) == null) { | |
| 234 | 236 | warn( |
| 235 | 237 | \\ |
| 236 | 238 | \\========= Expected to find in stderr: ========= |
| ... | ... | @@ -238,7 +240,7 @@ pub const RunStep = struct { |
| 238 | 240 | \\========= But stderr does not contain it: ===== |
| 239 | 241 | \\{} |
| 240 | 242 | \\ |
| 241 | , .{ match, stderr.toSliceConst() }); | |
| 243 | , .{ match, stderr.? }); | |
| 242 | 244 | printCmd(cwd, argv); |
| 243 | 245 | return error.TestFailed; |
| 244 | 246 | } |
| ... | ... | @@ -248,7 +250,7 @@ pub const RunStep = struct { |
| 248 | 250 | switch (self.stdout_action) { |
| 249 | 251 | .inherit, .ignore => {}, |
| 250 | 252 | .expect_exact => |expected_bytes| { |
| 251 | if (!mem.eql(u8, expected_bytes, stdout.toSliceConst())) { | |
| 253 | if (!mem.eql(u8, expected_bytes, stdout.?)) { | |
| 252 | 254 | warn( |
| 253 | 255 | \\ |
| 254 | 256 | \\========= Expected this stdout: ========= |
| ... | ... | @@ -256,13 +258,13 @@ pub const RunStep = struct { |
| 256 | 258 | \\========= But found: ==================== |
| 257 | 259 | \\{} |
| 258 | 260 | \\ |
| 259 | , .{ expected_bytes, stdout.toSliceConst() }); | |
| 261 | , .{ expected_bytes, stdout.? }); | |
| 260 | 262 | printCmd(cwd, argv); |
| 261 | 263 | return error.TestFailed; |
| 262 | 264 | } |
| 263 | 265 | }, |
| 264 | 266 | .expect_matches => |matches| for (matches) |match| { |
| 265 | if (mem.indexOf(u8, stdout.toSliceConst(), match) == null) { | |
| 267 | if (mem.indexOf(u8, stdout.?, match) == null) { | |
| 266 | 268 | warn( |
| 267 | 269 | \\ |
| 268 | 270 | \\========= Expected to find in stdout: ========= |
| ... | ... | @@ -270,7 +272,7 @@ pub const RunStep = struct { |
| 270 | 272 | \\========= But stdout does not contain it: ===== |
| 271 | 273 | \\{} |
| 272 | 274 | \\ |
| 273 | , .{ match, stdout.toSliceConst() }); | |
| 275 | , .{ match, stdout.? }); | |
| 274 | 276 | printCmd(cwd, argv); |
| 275 | 277 | return error.TestFailed; |
| 276 | 278 | } |
lib/std/child_process.zig+7-9| ... | ... | @@ -217,21 +217,19 @@ pub const ChildProcess = struct { |
| 217 | 217 | |
| 218 | 218 | try child.spawn(); |
| 219 | 219 | |
| 220 | var stdout = Buffer.initNull(args.allocator); | |
| 221 | var stderr = Buffer.initNull(args.allocator); | |
| 222 | defer Buffer.deinit(&stdout); | |
| 223 | defer Buffer.deinit(&stderr); | |
| 224 | ||
| 225 | 220 | var stdout_file_in_stream = child.stdout.?.inStream(); |
| 226 | 221 | var stderr_file_in_stream = child.stderr.?.inStream(); |
| 227 | 222 | |
| 228 | try stdout_file_in_stream.stream.readAllBuffer(&stdout, args.max_output_bytes); | |
| 229 | try stderr_file_in_stream.stream.readAllBuffer(&stderr, args.max_output_bytes); | |
| 223 | // TODO need to poll to read these streams to prevent a deadlock (or rely on evented I/O). | |
| 224 | const stdout = try stdout_file_in_stream.stream.readAllAlloc(args.allocator, args.max_output_bytes); | |
| 225 | errdefer args.allocator.free(stdout); | |
| 226 | const stderr = try stderr_file_in_stream.stream.readAllAlloc(args.allocator, args.max_output_bytes); | |
| 227 | errdefer args.allocator.free(stderr); | |
| 230 | 228 | |
| 231 | 229 | return ExecResult{ |
| 232 | 230 | .term = try child.wait(), |
| 233 | .stdout = stdout.toOwnedSlice(), | |
| 234 | .stderr = stderr.toOwnedSlice(), | |
| 231 | .stdout = stdout, | |
| 232 | .stderr = stderr, | |
| 235 | 233 | }; |
| 236 | 234 | } |
| 237 | 235 |
lib/std/fmt.zig+11-11| ... | ... | @@ -1643,10 +1643,10 @@ test "hexToBytes" { |
| 1643 | 1643 | test "formatIntValue with comptime_int" { |
| 1644 | 1644 | const value: comptime_int = 123456789123456789; |
| 1645 | 1645 | |
| 1646 | var buf = try std.Buffer.init(std.testing.allocator, ""); | |
| 1646 | var buf = std.ArrayList(u8).init(std.testing.allocator); | |
| 1647 | 1647 | defer buf.deinit(); |
| 1648 | try formatIntValue(value, "", FormatOptions{}, &buf, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append); | |
| 1649 | std.testing.expect(mem.eql(u8, buf.toSlice(), "123456789123456789")); | |
| 1648 | try formatIntValue(value, "", FormatOptions{}, &buf, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice); | |
| 1649 | std.testing.expect(mem.eql(u8, buf.toSliceConst(), "123456789123456789")); | |
| 1650 | 1650 | } |
| 1651 | 1651 | |
| 1652 | 1652 | test "formatType max_depth" { |
| ... | ... | @@ -1698,24 +1698,24 @@ test "formatType max_depth" { |
| 1698 | 1698 | inst.a = &inst; |
| 1699 | 1699 | inst.tu.ptr = &inst.tu; |
| 1700 | 1700 | |
| 1701 | var buf0 = try std.Buffer.init(std.testing.allocator, ""); | |
| 1701 | var buf0 = std.ArrayList(u8).init(std.testing.allocator); | |
| 1702 | 1702 | defer buf0.deinit(); |
| 1703 | try formatType(inst, "", FormatOptions{}, &buf0, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0); | |
| 1703 | try formatType(inst, "", FormatOptions{}, &buf0, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice, 0); | |
| 1704 | 1704 | std.testing.expect(mem.eql(u8, buf0.toSlice(), "S{ ... }")); |
| 1705 | 1705 | |
| 1706 | var buf1 = try std.Buffer.init(std.testing.allocator, ""); | |
| 1706 | var buf1 = std.ArrayList(u8).init(std.testing.allocator); | |
| 1707 | 1707 | defer buf1.deinit(); |
| 1708 | try formatType(inst, "", FormatOptions{}, &buf1, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1); | |
| 1708 | try formatType(inst, "", FormatOptions{}, &buf1, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice, 1); | |
| 1709 | 1709 | std.testing.expect(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }")); |
| 1710 | 1710 | |
| 1711 | var buf2 = try std.Buffer.init(std.testing.allocator, ""); | |
| 1711 | var buf2 = std.ArrayList(u8).init(std.testing.allocator); | |
| 1712 | 1712 | defer buf2.deinit(); |
| 1713 | try formatType(inst, "", FormatOptions{}, &buf2, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2); | |
| 1713 | try formatType(inst, "", FormatOptions{}, &buf2, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice, 2); | |
| 1714 | 1714 | std.testing.expect(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }")); |
| 1715 | 1715 | |
| 1716 | var buf3 = try std.Buffer.init(std.testing.allocator, ""); | |
| 1716 | var buf3 = std.ArrayList(u8).init(std.testing.allocator); | |
| 1717 | 1717 | defer buf3.deinit(); |
| 1718 | try formatType(inst, "", FormatOptions{}, &buf3, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3); | |
| 1718 | try formatType(inst, "", FormatOptions{}, &buf3, @TypeOf(std.ArrayList(u8).appendSlice).ReturnType.ErrorSet, std.ArrayList(u8).appendSlice, 3); | |
| 1719 | 1719 | std.testing.expect(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }")); |
| 1720 | 1720 | } |
| 1721 | 1721 |
lib/std/io/in_stream.zig+56-33| ... | ... | @@ -41,10 +41,13 @@ pub fn InStream(comptime ReadError: type) type { |
| 41 | 41 | } |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | /// Deprecated: use `readAll`. | |
| 45 | pub const readFull = readAll; | |
| 46 | ||
| 44 | 47 | /// Returns the number of bytes read. If the number read is smaller than buf.len, it |
| 45 | 48 | /// means the stream reached the end. Reaching the end of a stream is not an error |
| 46 | 49 | /// condition. |
| 47 | pub fn readFull(self: *Self, buffer: []u8) Error!usize { | |
| 50 | pub fn readAll(self: *Self, buffer: []u8) Error!usize { | |
| 48 | 51 | var index: usize = 0; |
| 49 | 52 | while (index != buffer.len) { |
| 50 | 53 | const amt = try self.read(buffer[index..]); |
| ... | ... | @@ -57,30 +60,43 @@ pub fn InStream(comptime ReadError: type) type { |
| 57 | 60 | /// Returns the number of bytes read. If the number read would be smaller than buf.len, |
| 58 | 61 | /// error.EndOfStream is returned instead. |
| 59 | 62 | pub fn readNoEof(self: *Self, buf: []u8) !void { |
| 60 | const amt_read = try self.readFull(buf); | |
| 63 | const amt_read = try self.readAll(buf); | |
| 61 | 64 | if (amt_read < buf.len) return error.EndOfStream; |
| 62 | 65 | } |
| 63 | 66 | |
| 64 | /// Replaces `buffer` contents by reading from the stream until it is finished. | |
| 65 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and | |
| 66 | /// the contents read from the stream are lost. | |
| 67 | /// Deprecated: use `readAllArrayList`. | |
| 67 | 68 | pub fn readAllBuffer(self: *Self, buffer: *Buffer, max_size: usize) !void { |
| 68 | try buffer.resize(0); | |
| 69 | buffer.list.shrink(0); | |
| 70 | try self.readAllArrayList(&buffer.list, max_size); | |
| 71 | errdefer buffer.shrink(0); | |
| 72 | try buffer.list.append(0); | |
| 73 | } | |
| 69 | 74 | |
| 70 | var actual_buf_len: usize = 0; | |
| 75 | /// Appends to the `std.ArrayList` contents by reading from the stream until end of stream is found. | |
| 76 | /// If the number of bytes appended would exceed `max_append_size`, `error.StreamTooLong` is returned | |
| 77 | /// and the `std.ArrayList` has exactly `max_append_size` bytes appended. | |
| 78 | pub fn readAllArrayList(self: *Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void { | |
| 79 | try array_list.ensureCapacity(math.min(max_append_size, 4096)); | |
| 80 | const original_len = array_list.len; | |
| 81 | var start_index: usize = original_len; | |
| 71 | 82 | while (true) { |
| 72 | const dest_slice = buffer.toSlice()[actual_buf_len..]; | |
| 73 | const bytes_read = try self.readFull(dest_slice); | |
| 74 | actual_buf_len += bytes_read; | |
| 83 | array_list.expandToCapacity(); | |
| 84 | const dest_slice = array_list.span()[start_index..]; | |
| 85 | const bytes_read = try self.readAll(dest_slice); | |
| 86 | start_index += bytes_read; | |
| 87 | ||
| 88 | if (start_index - original_len > max_append_size) { | |
| 89 | array_list.shrink(original_len + max_append_size); | |
| 90 | return error.StreamTooLong; | |
| 91 | } | |
| 75 | 92 | |
| 76 | 93 | if (bytes_read != dest_slice.len) { |
| 77 | buffer.shrink(actual_buf_len); | |
| 94 | array_list.shrink(start_index); | |
| 78 | 95 | return; |
| 79 | 96 | } |
| 80 | 97 | |
| 81 | const new_buf_size = math.min(max_size, actual_buf_len + mem.page_size); | |
| 82 | if (new_buf_size == actual_buf_len) return error.StreamTooLong; | |
| 83 | try buffer.resize(new_buf_size); | |
| 98 | // This will trigger ArrayList to expand superlinearly at whatever its growth rate is. | |
| 99 | try array_list.ensureCapacity(start_index + 1); | |
| 84 | 100 | } |
| 85 | 101 | } |
| 86 | 102 | |
| ... | ... | @@ -89,20 +105,23 @@ pub fn InStream(comptime ReadError: type) type { |
| 89 | 105 | /// Caller owns returned memory. |
| 90 | 106 | /// If this function returns an error, the contents from the stream read so far are lost. |
| 91 | 107 | pub fn readAllAlloc(self: *Self, allocator: *mem.Allocator, max_size: usize) ![]u8 { |
| 92 | var buf = Buffer.initNull(allocator); | |
| 93 | defer buf.deinit(); | |
| 94 | ||
| 95 | try self.readAllBuffer(&buf, max_size); | |
| 96 | return buf.toOwnedSlice(); | |
| 108 | var array_list = std.ArrayList(u8).init(allocator); | |
| 109 | defer array_list.deinit(); | |
| 110 | try self.readAllArrayList(&array_list, max_size); | |
| 111 | return array_list.toOwnedSlice(); | |
| 97 | 112 | } |
| 98 | 113 | |
| 99 | /// Replaces `buffer` contents by reading from the stream until `delimiter` is found. | |
| 114 | /// Replaces the `std.ArrayList` contents by reading from the stream until `delimiter` is found. | |
| 100 | 115 | /// Does not include the delimiter in the result. |
| 101 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents | |
| 102 | /// read from the stream so far are lost. | |
| 103 | pub fn readUntilDelimiterBuffer(self: *Self, buffer: *Buffer, delimiter: u8, max_size: usize) !void { | |
| 104 | try buffer.resize(0); | |
| 105 | ||
| 116 | /// If the `std.ArrayList` length would exceed `max_size`, `error.StreamTooLong` is returned and the | |
| 117 | /// `std.ArrayList` is populated with `max_size` bytes from the stream. | |
| 118 | pub fn readUntilDelimiterArrayList( | |
| 119 | self: *Self, | |
| 120 | array_list: *std.ArrayList(u8), | |
| 121 | delimiter: u8, | |
| 122 | max_size: usize, | |
| 123 | ) !void { | |
| 124 | array_list.shrink(0); | |
| 106 | 125 | while (true) { |
| 107 | 126 | var byte: u8 = try self.readByte(); |
| 108 | 127 | |
| ... | ... | @@ -110,11 +129,11 @@ pub fn InStream(comptime ReadError: type) type { |
| 110 | 129 | return; |
| 111 | 130 | } |
| 112 | 131 | |
| 113 | if (buffer.len() == max_size) { | |
| 132 | if (array_list.len == max_size) { | |
| 114 | 133 | return error.StreamTooLong; |
| 115 | 134 | } |
| 116 | 135 | |
| 117 | try buffer.appendByte(byte); | |
| 136 | try array_list.append(byte); | |
| 118 | 137 | } |
| 119 | 138 | } |
| 120 | 139 | |
| ... | ... | @@ -122,12 +141,16 @@ pub fn InStream(comptime ReadError: type) type { |
| 122 | 141 | /// memory would be greater than `max_size`, returns `error.StreamTooLong`. |
| 123 | 142 | /// Caller owns returned memory. |
| 124 | 143 | /// If this function returns an error, the contents from the stream read so far are lost. |
| 125 | pub fn readUntilDelimiterAlloc(self: *Self, allocator: *mem.Allocator, delimiter: u8, max_size: usize) ![]u8 { | |
| 126 | var buf = Buffer.initNull(allocator); | |
| 127 | defer buf.deinit(); | |
| 128 | ||
| 129 | try self.readUntilDelimiterBuffer(&buf, delimiter, max_size); | |
| 130 | return buf.toOwnedSlice(); | |
| 144 | pub fn readUntilDelimiterAlloc( | |
| 145 | self: *Self, | |
| 146 | allocator: *mem.Allocator, | |
| 147 | delimiter: u8, | |
| 148 | max_size: usize, | |
| 149 | ) ![]u8 { | |
| 150 | var array_list = std.ArrayList(u8).init(allocator); | |
| 151 | defer array_list.deinit(); | |
| 152 | try self.readUntilDelimiterArrayList(&array_list, delimiter, max_size); | |
| 153 | return array_list.toOwnedSlice(); | |
| 131 | 154 | } |
| 132 | 155 | |
| 133 | 156 | /// Reads from the stream until specified byte is found. If the buffer is not |
lib/std/process.zig+9-10| ... | ... | @@ -3,7 +3,6 @@ const builtin = std.builtin; |
| 3 | 3 | const os = std.os; |
| 4 | 4 | const fs = std.fs; |
| 5 | 5 | const BufMap = std.BufMap; |
| 6 | const Buffer = std.Buffer; | |
| 7 | 6 | const mem = std.mem; |
| 8 | 7 | const math = std.math; |
| 9 | 8 | const Allocator = mem.Allocator; |
| ... | ... | @@ -266,7 +265,7 @@ pub const ArgIteratorWindows = struct { |
| 266 | 265 | } |
| 267 | 266 | |
| 268 | 267 | fn internalNext(self: *ArgIteratorWindows, allocator: *Allocator) NextError![]u8 { |
| 269 | var buf = try Buffer.initSize(allocator, 0); | |
| 268 | var buf = std.ArrayList(u8).init(allocator); | |
| 270 | 269 | defer buf.deinit(); |
| 271 | 270 | |
| 272 | 271 | var backslash_count: usize = 0; |
| ... | ... | @@ -282,10 +281,10 @@ pub const ArgIteratorWindows = struct { |
| 282 | 281 | if (quote_is_real) { |
| 283 | 282 | self.seen_quote_count += 1; |
| 284 | 283 | if (self.seen_quote_count == self.quote_count and self.seen_quote_count % 2 == 1) { |
| 285 | try buf.appendByte('"'); | |
| 284 | try buf.append('"'); | |
| 286 | 285 | } |
| 287 | 286 | } else { |
| 288 | try buf.appendByte('"'); | |
| 287 | try buf.append('"'); | |
| 289 | 288 | } |
| 290 | 289 | }, |
| 291 | 290 | '\\' => { |
| ... | ... | @@ -295,7 +294,7 @@ pub const ArgIteratorWindows = struct { |
| 295 | 294 | try self.emitBackslashes(&buf, backslash_count); |
| 296 | 295 | backslash_count = 0; |
| 297 | 296 | if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) { |
| 298 | try buf.appendByte(byte); | |
| 297 | try buf.append(byte); | |
| 299 | 298 | } else { |
| 300 | 299 | return buf.toOwnedSlice(); |
| 301 | 300 | } |
| ... | ... | @@ -303,16 +302,16 @@ pub const ArgIteratorWindows = struct { |
| 303 | 302 | else => { |
| 304 | 303 | try self.emitBackslashes(&buf, backslash_count); |
| 305 | 304 | backslash_count = 0; |
| 306 | try buf.appendByte(byte); | |
| 305 | try buf.append(byte); | |
| 307 | 306 | }, |
| 308 | 307 | } |
| 309 | 308 | } |
| 310 | 309 | } |
| 311 | 310 | |
| 312 | fn emitBackslashes(self: *ArgIteratorWindows, buf: *Buffer, emit_count: usize) !void { | |
| 311 | fn emitBackslashes(self: *ArgIteratorWindows, buf: *std.ArrayList(u8), emit_count: usize) !void { | |
| 313 | 312 | var i: usize = 0; |
| 314 | 313 | while (i < emit_count) : (i += 1) { |
| 315 | try buf.appendByte('\\'); | |
| 314 | try buf.append('\\'); | |
| 316 | 315 | } |
| 317 | 316 | } |
| 318 | 317 | |
| ... | ... | @@ -410,7 +409,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { |
| 410 | 409 | |
| 411 | 410 | // TODO refactor to only make 1 allocation. |
| 412 | 411 | var it = args(); |
| 413 | var contents = try Buffer.initSize(allocator, 0); | |
| 412 | var contents = std.ArrayList(u8).init(allocator); | |
| 414 | 413 | defer contents.deinit(); |
| 415 | 414 | |
| 416 | 415 | var slice_list = std.ArrayList(usize).init(allocator); |
| ... | ... | @@ -419,7 +418,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { |
| 419 | 418 | while (it.next(allocator)) |arg_or_err| { |
| 420 | 419 | const arg = try arg_or_err; |
| 421 | 420 | defer allocator.free(arg); |
| 422 | try contents.append(arg); | |
| 421 | try contents.appendSlice(arg); | |
| 423 | 422 | try slice_list.append(arg.len); |
| 424 | 423 | } |
| 425 | 424 |
src-self-hosted/main.zig-1| ... | ... | @@ -9,7 +9,6 @@ const mem = std.mem; |
| 9 | 9 | const process = std.process; |
| 10 | 10 | const Allocator = mem.Allocator; |
| 11 | 11 | const ArrayList = std.ArrayList; |
| 12 | const Buffer = std.Buffer; | |
| 13 | 12 | |
| 14 | 13 | const c = @import("c.zig"); |
| 15 | 14 | const introspect = @import("introspect.zig"); |
test/tests.zig+6-10| ... | ... | @@ -566,14 +566,13 @@ pub const StackTracesContext = struct { |
| 566 | 566 | } |
| 567 | 567 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", .{ full_exe_path, @errorName(err) }); |
| 568 | 568 | |
| 569 | var stdout = Buffer.initNull(b.allocator); | |
| 570 | var stderr = Buffer.initNull(b.allocator); | |
| 571 | ||
| 572 | 569 | var stdout_file_in_stream = child.stdout.?.inStream(); |
| 573 | 570 | var stderr_file_in_stream = child.stderr.?.inStream(); |
| 574 | 571 | |
| 575 | stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size) catch unreachable; | |
| 576 | stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size) catch unreachable; | |
| 572 | const stdout = stdout_file_in_stream.stream.readAllAlloc(b.allocator, max_stdout_size) catch unreachable; | |
| 573 | defer b.allocator.free(stdout); | |
| 574 | const stderr = stderr_file_in_stream.stream.readAllAlloc(b.allocator, max_stdout_size) catch unreachable; | |
| 575 | defer b.allocator.free(stderr); | |
| 577 | 576 | |
| 578 | 577 | const term = child.wait() catch |err| { |
| 579 | 578 | debug.panic("Unable to spawn {}: {}\n", .{ full_exe_path, @errorName(err) }); |
| ... | ... | @@ -616,11 +615,8 @@ pub const StackTracesContext = struct { |
| 616 | 615 | const got: []const u8 = got_result: { |
| 617 | 616 | var buf = try Buffer.initSize(b.allocator, 0); |
| 618 | 617 | defer buf.deinit(); |
| 619 | const bytes = if (stderr.endsWith("\n")) | |
| 620 | stderr.toSliceConst()[0 .. stderr.len() - 1] | |
| 621 | else | |
| 622 | stderr.toSliceConst()[0..stderr.len()]; | |
| 623 | var it = mem.separate(bytes, "\n"); | |
| 618 | if (stderr.len != 0 and stderr[stderr.len - 1] == '\n') stderr = stderr[0 .. stderr.len - 1]; | |
| 619 | var it = mem.separate(stderr, "\n"); | |
| 624 | 620 | process_lines: while (it.next()) |line| { |
| 625 | 621 | if (line.len == 0) continue; |
| 626 | 622 | const delims = [_][]const u8{ ":", ":", ":", " in " }; |