authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 12:44:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 13:30:07-04:00
log2e806682f451efd26bef0486ddd980ab60de0fa1
tree7962a47dd9df3976a7aa8c8c5ad754d27dd55ba4
parent553f0e0546e0ceecf2ff735443d9a2c2f282b8db
signaturelock-open Commit is signed but in an unrecognized format.

(breaking) std.Buffer => std.ArrayListSentineled(u8, 0)

This new name (and the fact that it is a function returning a type) will make it more clear which use cases are better suited for ArrayList and which are better suited for ArrayListSentineled. Also for consistency with ArrayList, * `append` => `appendSlice` * `appendByte` => `append` Thanks daurnimator for pointing out the confusion of std.Buffer.

18 files changed, 362 insertions(+), 355 deletions(-)

lib/std/array_list_sentineled.zig created+224
...@@ -0,0 +1,224 @@
1const std = @import("std.zig");
2const debug = std.debug;
3const mem = std.mem;
4const Allocator = mem.Allocator;
5const assert = debug.assert;
6const testing = std.testing;
7const ArrayList = std.ArrayList;
8
9/// A contiguous, growable list of items in memory, with a sentinel after them.
10/// The sentinel is maintained when appending, resizing, etc.
11/// If you do not need a sentinel, consider using `ArrayList` instead.
12pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
13 return struct {
14 list: ArrayList(T),
15
16 const Self = @This();
17
18 /// Must deinitialize with deinit.
19 pub fn init(allocator: *Allocator, m: []const T) !Self {
20 var self = try initSize(allocator, m.len);
21 mem.copy(T, self.list.items, m);
22 return self;
23 }
24
25 /// Initialize memory to size bytes of undefined values.
26 /// Must deinitialize with deinit.
27 pub fn initSize(allocator: *Allocator, size: usize) !Self {
28 var self = initNull(allocator);
29 try self.resize(size);
30 return self;
31 }
32
33 /// Initialize with capacity to hold at least num bytes.
34 /// Must deinitialize with deinit.
35 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
36 var self = Self{ .list = try ArrayList(T).initCapacity(allocator, num + 1) };
37 self.list.appendAssumeCapacity(sentinel);
38 return self;
39 }
40
41 /// Must deinitialize with deinit.
42 /// None of the other operations are valid until you do one of these:
43 /// * `replaceContents`
44 /// * `resize`
45 pub fn initNull(allocator: *Allocator) Self {
46 return Self{ .list = ArrayList(T).init(allocator) };
47 }
48
49 /// Must deinitialize with deinit.
50 pub fn initFromBuffer(buffer: Self) !Self {
51 return Self.init(buffer.list.allocator, buffer.span());
52 }
53
54 /// Takes ownership of the passed in slice. The slice must have been
55 /// allocated with `allocator`.
56 /// Must deinitialize with deinit.
57 pub fn fromOwnedSlice(allocator: *Allocator, slice: []T) !Self {
58 var self = Self{ .list = ArrayList(T).fromOwnedSlice(allocator, slice) };
59 try self.list.append(sentinel);
60 return self;
61 }
62
63 /// The caller owns the returned memory. The list becomes null and is safe to `deinit`.
64 pub fn toOwnedSlice(self: *Self) [:sentinel]T {
65 const allocator = self.list.allocator;
66 const result = self.list.toOwnedSlice();
67 self.* = initNull(allocator);
68 return result[0 .. result.len - 1 :sentinel];
69 }
70
71 /// Only works when `T` is `u8`.
72 pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Self {
73 const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) {
74 error.Overflow => return error.OutOfMemory,
75 };
76 var self = try Self.initSize(allocator, size);
77 assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size);
78 return self;
79 }
80
81 pub fn deinit(self: *Self) void {
82 self.list.deinit();
83 }
84
85 pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :sentinel]) {
86 return self.list.span()[0..self.len() :sentinel];
87 }
88
89 pub fn shrink(self: *Self, new_len: usize) void {
90 assert(new_len <= self.len());
91 self.list.shrink(new_len + 1);
92 self.list.items[self.len()] = sentinel;
93 }
94
95 pub fn resize(self: *Self, new_len: usize) !void {
96 try self.list.resize(new_len + 1);
97 self.list.items[self.len()] = sentinel;
98 }
99
100 pub fn isNull(self: Self) bool {
101 return self.list.len == 0;
102 }
103
104 pub fn len(self: Self) usize {
105 return self.list.len - 1;
106 }
107
108 pub fn capacity(self: Self) usize {
109 return if (self.list.items.len > 0)
110 self.list.items.len - 1
111 else
112 0;
113 }
114
115 pub fn appendSlice(self: *Self, m: []const T) !void {
116 const old_len = self.len();
117 try self.resize(old_len + m.len);
118 mem.copy(T, self.list.span()[old_len..], m);
119 }
120
121 pub fn append(self: *Self, byte: T) !void {
122 const old_len = self.len();
123 try self.resize(old_len + 1);
124 self.list.span()[old_len] = byte;
125 }
126
127 pub fn eql(self: Self, m: []const T) bool {
128 return mem.eql(T, self.span(), m);
129 }
130
131 pub fn startsWith(self: Self, m: []const T) bool {
132 if (self.len() < m.len) return false;
133 return mem.eql(T, self.list.items[0..m.len], m);
134 }
135
136 pub fn endsWith(self: Self, m: []const T) bool {
137 const l = self.len();
138 if (l < m.len) return false;
139 const start = l - m.len;
140 return mem.eql(T, self.list.items[start..l], m);
141 }
142
143 pub fn replaceContents(self: *Self, m: []const T) !void {
144 try self.resize(m.len);
145 mem.copy(T, self.list.span(), m);
146 }
147
148 /// Initializes an OutStream which will append to the list.
149 /// This function may be called only when `T` is `u8`.
150 pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) {
151 return .{ .context = self };
152 }
153
154 /// Same as `append` except it returns the number of bytes written, which is always the same
155 /// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
156 /// This function may be called only when `T` is `u8`.
157 pub fn appendWrite(self: *Self, m: []const u8) !usize {
158 try self.appendSlice(m);
159 return m.len;
160 }
161 };
162}
163
164test "simple" {
165 var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
166 defer buf.deinit();
167
168 testing.expect(buf.len() == 0);
169 try buf.appendSlice("hello");
170 try buf.appendSlice(" ");
171 try buf.appendSlice("world");
172 testing.expect(buf.eql("hello world"));
173 testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span()));
174
175 var buf2 = try ArrayListSentineled(u8, 0).initFromBuffer(buf);
176 defer buf2.deinit();
177 testing.expect(buf.eql(buf2.span()));
178
179 testing.expect(buf.startsWith("hell"));
180 testing.expect(buf.endsWith("orld"));
181
182 try buf2.resize(4);
183 testing.expect(buf.startsWith(buf2.span()));
184}
185
186test "initSize" {
187 var buf = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 3);
188 defer buf.deinit();
189 testing.expect(buf.len() == 3);
190 try buf.appendSlice("hello");
191 testing.expect(mem.eql(u8, buf.span()[3..], "hello"));
192}
193
194test "initCapacity" {
195 var buf = try ArrayListSentineled(u8, 0).initCapacity(testing.allocator, 10);
196 defer buf.deinit();
197 testing.expect(buf.len() == 0);
198 testing.expect(buf.capacity() >= 10);
199 const old_cap = buf.capacity();
200 try buf.appendSlice("hello");
201 testing.expect(buf.len() == 5);
202 testing.expect(buf.capacity() == old_cap);
203 testing.expect(mem.eql(u8, buf.span(), "hello"));
204}
205
206test "print" {
207 var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
208 defer buf.deinit();
209
210 try buf.outStream().print("Hello {} the {}", .{ 2, "world" });
211 testing.expect(buf.eql("Hello 2 the world"));
212}
213
214test "outStream" {
215 var buffer = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 0);
216 defer buffer.deinit();
217 const buf_stream = buffer.outStream();
218
219 const x: i32 = 42;
220 const y: i32 = 1234;
221 try buf_stream.print("x: {}\ny: {}\n", .{ x, y });
222
223 testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n"));
224}
lib/std/buffer.zig deleted-218
...@@ -1,218 +0,0 @@
1const std = @import("std.zig");
2const debug = std.debug;
3const mem = std.mem;
4const Allocator = mem.Allocator;
5const assert = debug.assert;
6const testing = std.testing;
7const ArrayList = std.ArrayList;
8
9/// A buffer that allocates memory and maintains a null byte at the end.
10pub const Buffer = struct {
11 list: ArrayList(u8),
12
13 /// Must deinitialize with deinit.
14 pub fn init(allocator: *Allocator, m: []const u8) !Buffer {
15 var self = try initSize(allocator, m.len);
16 mem.copy(u8, self.list.items, m);
17 return self;
18 }
19
20 /// Initialize memory to size bytes of undefined values.
21 /// Must deinitialize with deinit.
22 pub fn initSize(allocator: *Allocator, size: usize) !Buffer {
23 var self = initNull(allocator);
24 try self.resize(size);
25 return self;
26 }
27
28 /// Initialize with capacity to hold at least num bytes.
29 /// Must deinitialize with deinit.
30 pub fn initCapacity(allocator: *Allocator, num: usize) !Buffer {
31 var self = Buffer{ .list = try ArrayList(u8).initCapacity(allocator, num + 1) };
32 self.list.appendAssumeCapacity(0);
33 return self;
34 }
35
36 /// Must deinitialize with deinit.
37 /// None of the other operations are valid until you do one of these:
38 /// * ::replaceContents
39 /// * ::resize
40 pub fn initNull(allocator: *Allocator) Buffer {
41 return Buffer{ .list = ArrayList(u8).init(allocator) };
42 }
43
44 /// Must deinitialize with deinit.
45 pub fn initFromBuffer(buffer: Buffer) !Buffer {
46 return Buffer.init(buffer.list.allocator, buffer.span());
47 }
48
49 /// Buffer takes ownership of the passed in slice. The slice must have been
50 /// allocated with `allocator`.
51 /// Must deinitialize with deinit.
52 pub fn fromOwnedSlice(allocator: *Allocator, slice: []u8) !Buffer {
53 var self = Buffer{ .list = ArrayList(u8).fromOwnedSlice(allocator, slice) };
54 try self.list.append(0);
55 return self;
56 }
57
58 /// The caller owns the returned memory. The Buffer becomes null and
59 /// is safe to `deinit`.
60 pub fn toOwnedSlice(self: *Buffer) [:0]u8 {
61 const allocator = self.list.allocator;
62 const result = self.list.toOwnedSlice();
63 self.* = initNull(allocator);
64 return result[0 .. result.len - 1 :0];
65 }
66
67 pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer {
68 const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) {
69 error.Overflow => return error.OutOfMemory,
70 };
71 var self = try Buffer.initSize(allocator, size);
72 assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size);
73 return self;
74 }
75
76 pub fn deinit(self: *Buffer) void {
77 self.list.deinit();
78 }
79
80 pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :0]) {
81 return self.list.span()[0..self.len() :0];
82 }
83
84 pub const toSlice = @compileError("deprecated; use span()");
85 pub const toSliceConst = @compileError("deprecated; use span()");
86
87 pub fn shrink(self: *Buffer, new_len: usize) void {
88 assert(new_len <= self.len());
89 self.list.shrink(new_len + 1);
90 self.list.items[self.len()] = 0;
91 }
92
93 pub fn resize(self: *Buffer, new_len: usize) !void {
94 try self.list.resize(new_len + 1);
95 self.list.items[self.len()] = 0;
96 }
97
98 pub fn isNull(self: Buffer) bool {
99 return self.list.len == 0;
100 }
101
102 pub fn len(self: Buffer) usize {
103 return self.list.len - 1;
104 }
105
106 pub fn capacity(self: Buffer) usize {
107 return if (self.list.items.len > 0)
108 self.list.items.len - 1
109 else
110 0;
111 }
112
113 pub fn append(self: *Buffer, m: []const u8) !void {
114 const old_len = self.len();
115 try self.resize(old_len + m.len);
116 mem.copy(u8, self.list.span()[old_len..], m);
117 }
118
119 pub fn appendByte(self: *Buffer, byte: u8) !void {
120 const old_len = self.len();
121 try self.resize(old_len + 1);
122 self.list.span()[old_len] = byte;
123 }
124
125 pub fn eql(self: Buffer, m: []const u8) bool {
126 return mem.eql(u8, self.span(), m);
127 }
128
129 pub fn startsWith(self: Buffer, m: []const u8) bool {
130 if (self.len() < m.len) return false;
131 return mem.eql(u8, self.list.items[0..m.len], m);
132 }
133
134 pub fn endsWith(self: Buffer, m: []const u8) bool {
135 const l = self.len();
136 if (l < m.len) return false;
137 const start = l - m.len;
138 return mem.eql(u8, self.list.items[start..l], m);
139 }
140
141 pub fn replaceContents(self: *Buffer, m: []const u8) !void {
142 try self.resize(m.len);
143 mem.copy(u8, self.list.span(), m);
144 }
145
146 pub fn outStream(self: *Buffer) std.io.OutStream(*Buffer, error{OutOfMemory}, appendWrite) {
147 return .{ .context = self };
148 }
149
150 /// Same as `append` except it returns the number of bytes written, which is always the same
151 /// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
152 pub fn appendWrite(self: *Buffer, m: []const u8) !usize {
153 try self.append(m);
154 return m.len;
155 }
156};
157
158test "simple Buffer" {
159 var buf = try Buffer.init(testing.allocator, "");
160 defer buf.deinit();
161
162 testing.expect(buf.len() == 0);
163 try buf.append("hello");
164 try buf.append(" ");
165 try buf.append("world");
166 testing.expect(buf.eql("hello world"));
167 testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span()));
168
169 var buf2 = try Buffer.initFromBuffer(buf);
170 defer buf2.deinit();
171 testing.expect(buf.eql(buf2.span()));
172
173 testing.expect(buf.startsWith("hell"));
174 testing.expect(buf.endsWith("orld"));
175
176 try buf2.resize(4);
177 testing.expect(buf.startsWith(buf2.span()));
178}
179
180test "Buffer.initSize" {
181 var buf = try Buffer.initSize(testing.allocator, 3);
182 defer buf.deinit();
183 testing.expect(buf.len() == 3);
184 try buf.append("hello");
185 testing.expect(mem.eql(u8, buf.span()[3..], "hello"));
186}
187
188test "Buffer.initCapacity" {
189 var buf = try Buffer.initCapacity(testing.allocator, 10);
190 defer buf.deinit();
191 testing.expect(buf.len() == 0);
192 testing.expect(buf.capacity() >= 10);
193 const old_cap = buf.capacity();
194 try buf.append("hello");
195 testing.expect(buf.len() == 5);
196 testing.expect(buf.capacity() == old_cap);
197 testing.expect(mem.eql(u8, buf.span(), "hello"));
198}
199
200test "Buffer.print" {
201 var buf = try Buffer.init(testing.allocator, "");
202 defer buf.deinit();
203
204 try buf.outStream().print("Hello {} the {}", .{ 2, "world" });
205 testing.expect(buf.eql("Hello 2 the world"));
206}
207
208test "Buffer.outStream" {
209 var buffer = try Buffer.initSize(testing.allocator, 0);
210 defer buffer.deinit();
211 const buf_stream = buffer.outStream();
212
213 const x: i32 = 42;
214 const y: i32 = 1234;
215 try buf_stream.print("x: {}\ny: {}\n", .{ x, y });
216
217 testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n"));
218}
lib/std/child_process.zig+2-2
...@@ -10,7 +10,7 @@ const windows = os.windows;...@@ -10,7 +10,7 @@ const windows = os.windows;
10const mem = std.mem;10const mem = std.mem;
11const debug = std.debug;11const debug = std.debug;
12const BufMap = std.BufMap;12const BufMap = std.BufMap;
13const Buffer = std.Buffer;13const ArrayListSentineled = std.ArrayListSentineled;
14const builtin = @import("builtin");14const builtin = @import("builtin");
15const Os = builtin.Os;15const Os = builtin.Os;
16const TailQueue = std.TailQueue;16const TailQueue = std.TailQueue;
...@@ -758,7 +758,7 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1...@@ -758,7 +758,7 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1
758758
759/// Caller must dealloc.759/// Caller must dealloc.
760fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 {760fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 {
761 var buf = try Buffer.initSize(allocator, 0);761 var buf = try ArrayListSentineled(u8, 0).initSize(allocator, 0);
762 defer buf.deinit();762 defer buf.deinit();
763 const buf_stream = buf.outStream();763 const buf_stream = buf.outStream();
764764
lib/std/fs.zig+8-5
...@@ -1416,13 +1416,14 @@ pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAb...@@ -1416,13 +1416,14 @@ pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAb
14161416
1417pub const Walker = struct {1417pub const Walker = struct {
1418 stack: std.ArrayList(StackItem),1418 stack: std.ArrayList(StackItem),
1419 name_buffer: std.Buffer,1419 name_buffer: std.ArrayList(u8),
14201420
1421 pub const Entry = struct {1421 pub const Entry = struct {
1422 /// The containing directory. This can be used to operate directly on `basename`1422 /// The containing directory. This can be used to operate directly on `basename`
1423 /// rather than `path`, avoiding `error.NameTooLong` for deeply nested paths.1423 /// rather than `path`, avoiding `error.NameTooLong` for deeply nested paths.
1424 /// The directory remains open until `next` or `deinit` is called.1424 /// The directory remains open until `next` or `deinit` is called.
1425 dir: Dir,1425 dir: Dir,
1426 /// TODO make this null terminated for API convenience
1426 basename: []const u8,1427 basename: []const u8,
14271428
1428 path: []const u8,1429 path: []const u8,
...@@ -1445,8 +1446,8 @@ pub const Walker = struct {...@@ -1445,8 +1446,8 @@ pub const Walker = struct {
1445 const dirname_len = top.dirname_len;1446 const dirname_len = top.dirname_len;
1446 if (try top.dir_it.next()) |base| {1447 if (try top.dir_it.next()) |base| {
1447 self.name_buffer.shrink(dirname_len);1448 self.name_buffer.shrink(dirname_len);
1448 try self.name_buffer.appendByte(path.sep);1449 try self.name_buffer.append(path.sep);
1449 try self.name_buffer.append(base.name);1450 try self.name_buffer.appendSlice(base.name);
1450 if (base.kind == .Directory) {1451 if (base.kind == .Directory) {
1451 var new_dir = top.dir_it.dir.openDir(base.name, .{ .iterate = true }) catch |err| switch (err) {1452 var new_dir = top.dir_it.dir.openDir(base.name, .{ .iterate = true }) catch |err| switch (err) {
1452 error.NameTooLong => unreachable, // no path sep in base.name1453 error.NameTooLong => unreachable, // no path sep in base.name
...@@ -1456,7 +1457,7 @@ pub const Walker = struct {...@@ -1456,7 +1457,7 @@ pub const Walker = struct {
1456 errdefer new_dir.close();1457 errdefer new_dir.close();
1457 try self.stack.append(StackItem{1458 try self.stack.append(StackItem{
1458 .dir_it = new_dir.iterate(),1459 .dir_it = new_dir.iterate(),
1459 .dirname_len = self.name_buffer.len(),1460 .dirname_len = self.name_buffer.len,
1460 });1461 });
1461 }1462 }
1462 }1463 }
...@@ -1489,9 +1490,11 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {...@@ -1489,9 +1490,11 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {
1489 var dir = try cwd().openDir(dir_path, .{ .iterate = true });1490 var dir = try cwd().openDir(dir_path, .{ .iterate = true });
1490 errdefer dir.close();1491 errdefer dir.close();
14911492
1492 var name_buffer = try std.Buffer.init(allocator, dir_path);1493 var name_buffer = std.ArrayList(u8).init(allocator);
1493 errdefer name_buffer.deinit();1494 errdefer name_buffer.deinit();
14941495
1496 try name_buffer.appendSlice(dir_path);
1497
1495 var walker = Walker{1498 var walker = Walker{
1496 .stack = std.ArrayList(Walker.StackItem).init(allocator),1499 .stack = std.ArrayList(Walker.StackItem).init(allocator),
1497 .name_buffer = name_buffer,1500 .name_buffer = name_buffer,
lib/std/io/in_stream.zig-1
...@@ -3,7 +3,6 @@ const builtin = std.builtin;...@@ -3,7 +3,6 @@ const builtin = std.builtin;
3const math = std.math;3const math = std.math;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const mem = std.mem;5const mem = std.mem;
6const Buffer = std.Buffer;
7const testing = std.testing;6const testing = std.testing;
87
9pub fn InStream(8pub fn InStream(
lib/std/net.zig+10-10
...@@ -504,7 +504,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -504,7 +504,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
504 var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);504 var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);
505 defer lookup_addrs.deinit();505 defer lookup_addrs.deinit();
506506
507 var canon = std.Buffer.initNull(arena);507 var canon = std.ArrayListSentineled(u8, 0).initNull(arena);
508 defer canon.deinit();508 defer canon.deinit();
509509
510 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);510 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
...@@ -539,7 +539,7 @@ const DAS_ORDER_SHIFT = 0;...@@ -539,7 +539,7 @@ const DAS_ORDER_SHIFT = 0;
539539
540fn linuxLookupName(540fn linuxLookupName(
541 addrs: *std.ArrayList(LookupAddr),541 addrs: *std.ArrayList(LookupAddr),
542 canon: *std.Buffer,542 canon: *std.ArrayListSentineled(u8, 0),
543 opt_name: ?[]const u8,543 opt_name: ?[]const u8,
544 family: os.sa_family_t,544 family: os.sa_family_t,
545 flags: u32,545 flags: u32,
...@@ -798,7 +798,7 @@ fn linuxLookupNameFromNull(...@@ -798,7 +798,7 @@ fn linuxLookupNameFromNull(
798798
799fn linuxLookupNameFromHosts(799fn linuxLookupNameFromHosts(
800 addrs: *std.ArrayList(LookupAddr),800 addrs: *std.ArrayList(LookupAddr),
801 canon: *std.Buffer,801 canon: *std.ArrayListSentineled(u8, 0),
802 name: []const u8,802 name: []const u8,
803 family: os.sa_family_t,803 family: os.sa_family_t,
804 port: u16,804 port: u16,
...@@ -868,7 +868,7 @@ pub fn isValidHostName(hostname: []const u8) bool {...@@ -868,7 +868,7 @@ pub fn isValidHostName(hostname: []const u8) bool {
868868
869fn linuxLookupNameFromDnsSearch(869fn linuxLookupNameFromDnsSearch(
870 addrs: *std.ArrayList(LookupAddr),870 addrs: *std.ArrayList(LookupAddr),
871 canon: *std.Buffer,871 canon: *std.ArrayListSentineled(u8, 0),
872 name: []const u8,872 name: []const u8,
873 family: os.sa_family_t,873 family: os.sa_family_t,
874 port: u16,874 port: u16,
...@@ -901,12 +901,12 @@ fn linuxLookupNameFromDnsSearch(...@@ -901,12 +901,12 @@ fn linuxLookupNameFromDnsSearch(
901 // the full requested name to name_from_dns.901 // the full requested name to name_from_dns.
902 try canon.resize(canon_name.len);902 try canon.resize(canon_name.len);
903 mem.copy(u8, canon.span(), canon_name);903 mem.copy(u8, canon.span(), canon_name);
904 try canon.appendByte('.');904 try canon.append('.');
905905
906 var tok_it = mem.tokenize(search, " \t");906 var tok_it = mem.tokenize(search, " \t");
907 while (tok_it.next()) |tok| {907 while (tok_it.next()) |tok| {
908 canon.shrink(canon_name.len + 1);908 canon.shrink(canon_name.len + 1);
909 try canon.append(tok);909 try canon.appendSlice(tok);
910 try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);910 try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);
911 if (addrs.len != 0) return;911 if (addrs.len != 0) return;
912 }912 }
...@@ -917,13 +917,13 @@ fn linuxLookupNameFromDnsSearch(...@@ -917,13 +917,13 @@ fn linuxLookupNameFromDnsSearch(
917917
918const dpc_ctx = struct {918const dpc_ctx = struct {
919 addrs: *std.ArrayList(LookupAddr),919 addrs: *std.ArrayList(LookupAddr),
920 canon: *std.Buffer,920 canon: *std.ArrayListSentineled(u8, 0),
921 port: u16,921 port: u16,
922};922};
923923
924fn linuxLookupNameFromDns(924fn linuxLookupNameFromDns(
925 addrs: *std.ArrayList(LookupAddr),925 addrs: *std.ArrayList(LookupAddr),
926 canon: *std.Buffer,926 canon: *std.ArrayListSentineled(u8, 0),
927 name: []const u8,927 name: []const u8,
928 family: os.sa_family_t,928 family: os.sa_family_t,
929 rc: ResolvConf,929 rc: ResolvConf,
...@@ -978,7 +978,7 @@ const ResolvConf = struct {...@@ -978,7 +978,7 @@ const ResolvConf = struct {
978 attempts: u32,978 attempts: u32,
979 ndots: u32,979 ndots: u32,
980 timeout: u32,980 timeout: u32,
981 search: std.Buffer,981 search: std.ArrayListSentineled(u8, 0),
982 ns: std.ArrayList(LookupAddr),982 ns: std.ArrayList(LookupAddr),
983983
984 fn deinit(rc: *ResolvConf) void {984 fn deinit(rc: *ResolvConf) void {
...@@ -993,7 +993,7 @@ const ResolvConf = struct {...@@ -993,7 +993,7 @@ const ResolvConf = struct {
993fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {993fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
994 rc.* = ResolvConf{994 rc.* = ResolvConf{
995 .ns = std.ArrayList(LookupAddr).init(allocator),995 .ns = std.ArrayList(LookupAddr).init(allocator),
996 .search = std.Buffer.initNull(allocator),996 .search = std.ArrayListSentineled(u8, 0).initNull(allocator),
997 .ndots = 1,997 .ndots = 1,
998 .timeout = 5,998 .timeout = 5,
999 .attempts = 2,999 .attempts = 2,
lib/std/std.zig+1-1
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1pub const AlignedArrayList = @import("array_list.zig").AlignedArrayList;1pub const AlignedArrayList = @import("array_list.zig").AlignedArrayList;
2pub const ArrayList = @import("array_list.zig").ArrayList;2pub const ArrayList = @import("array_list.zig").ArrayList;
3pub const ArrayListSentineled = @import("array_list_sentineled.zig").ArrayListSentineled;
3pub const AutoHashMap = @import("hash_map.zig").AutoHashMap;4pub const AutoHashMap = @import("hash_map.zig").AutoHashMap;
4pub const BloomFilter = @import("bloom_filter.zig").BloomFilter;5pub const BloomFilter = @import("bloom_filter.zig").BloomFilter;
5pub const BufMap = @import("buf_map.zig").BufMap;6pub const BufMap = @import("buf_map.zig").BufMap;
6pub const BufSet = @import("buf_set.zig").BufSet;7pub const BufSet = @import("buf_set.zig").BufSet;
7pub const Buffer = @import("buffer.zig").Buffer;
8pub const ChildProcess = @import("child_process.zig").ChildProcess;8pub const ChildProcess = @import("child_process.zig").ChildProcess;
9pub const DynLib = @import("dynamic_library.zig").DynLib;9pub const DynLib = @import("dynamic_library.zig").DynLib;
10pub const HashMap = @import("hash_map.zig").HashMap;10pub const HashMap = @import("hash_map.zig").HashMap;
src-self-hosted/codegen.zig+2-2
...@@ -45,7 +45,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)...@@ -45,7 +45,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
4545
46 // Don't use ZIG_VERSION_STRING here. LLVM misparses it when it includes46 // Don't use ZIG_VERSION_STRING here. LLVM misparses it when it includes
47 // the git revision.47 // the git revision.
48 const producer = try std.Buffer.allocPrint(&code.arena.allocator, "zig {}.{}.{}", .{48 const producer = try std.fmt.allocPrintZ(&code.arena.allocator, "zig {}.{}.{}", .{
49 @as(u32, c.ZIG_VERSION_MAJOR),49 @as(u32, c.ZIG_VERSION_MAJOR),
50 @as(u32, c.ZIG_VERSION_MINOR),50 @as(u32, c.ZIG_VERSION_MINOR),
51 @as(u32, c.ZIG_VERSION_PATCH),51 @as(u32, c.ZIG_VERSION_PATCH),
...@@ -62,7 +62,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)...@@ -62,7 +62,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
62 dibuilder,62 dibuilder,
63 DW.LANG_C99,63 DW.LANG_C99,
64 compile_unit_file,64 compile_unit_file,
65 producer.span(),65 producer,
66 is_optimized,66 is_optimized,
67 flags,67 flags,
68 runtime_version,68 runtime_version,
src-self-hosted/compilation.zig+8-8
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const io = std.io;2const io = std.io;
3const mem = std.mem;3const mem = std.mem;
4const Allocator = mem.Allocator;4const Allocator = mem.Allocator;
5const Buffer = std.Buffer;5const ArrayListSentineled = std.ArrayListSentineled;
6const llvm = @import("llvm.zig");6const llvm = @import("llvm.zig");
7const c = @import("c.zig");7const c = @import("c.zig");
8const builtin = std.builtin;8const builtin = std.builtin;
...@@ -123,8 +123,8 @@ pub const LlvmHandle = struct {...@@ -123,8 +123,8 @@ pub const LlvmHandle = struct {
123123
124pub const Compilation = struct {124pub const Compilation = struct {
125 zig_compiler: *ZigCompiler,125 zig_compiler: *ZigCompiler,
126 name: Buffer,126 name: ArrayListSentineled(u8, 0),
127 llvm_triple: Buffer,127 llvm_triple: ArrayListSentineled(u8, 0),
128 root_src_path: ?[]const u8,128 root_src_path: ?[]const u8,
129 target: std.Target,129 target: std.Target,
130 llvm_target: *llvm.Target,130 llvm_target: *llvm.Target,
...@@ -444,7 +444,7 @@ pub const Compilation = struct {...@@ -444,7 +444,7 @@ pub const Compilation = struct {
444 comp.arena_allocator.deinit();444 comp.arena_allocator.deinit();
445 }445 }
446446
447 comp.name = try Buffer.init(comp.arena(), name);447 comp.name = try ArrayListSentineled(u8, 0).init(comp.arena(), name);
448 comp.llvm_triple = try util.getLLVMTriple(comp.arena(), target);448 comp.llvm_triple = try util.getLLVMTriple(comp.arena(), target);
449 comp.llvm_target = try util.llvmTargetFromTriple(comp.llvm_triple);449 comp.llvm_target = try util.llvmTargetFromTriple(comp.llvm_triple);
450 comp.zig_std_dir = try fs.path.join(comp.arena(), &[_][]const u8{ zig_lib_dir, "std" });450 comp.zig_std_dir = try fs.path.join(comp.arena(), &[_][]const u8{ zig_lib_dir, "std" });
...@@ -1151,7 +1151,7 @@ pub const Compilation = struct {...@@ -1151,7 +1151,7 @@ pub const Compilation = struct {
11511151
1152 /// If the temporary directory for this compilation has not been created, it creates it.1152 /// If the temporary directory for this compilation has not been created, it creates it.
1153 /// Then it creates a random file name in that dir and returns it.1153 /// Then it creates a random file name in that dir and returns it.
1154 pub fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !Buffer {1154 pub fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !ArrayListSentineled(u8, 0) {
1155 const tmp_dir = try self.getTmpDir();1155 const tmp_dir = try self.getTmpDir();
1156 const file_prefix = self.getRandomFileName();1156 const file_prefix = self.getRandomFileName();
11571157
...@@ -1161,7 +1161,7 @@ pub const Compilation = struct {...@@ -1161,7 +1161,7 @@ pub const Compilation = struct {
1161 const full_path = try fs.path.join(self.gpa(), &[_][]const u8{ tmp_dir, file_name[0..] });1161 const full_path = try fs.path.join(self.gpa(), &[_][]const u8{ tmp_dir, file_name[0..] });
1162 errdefer self.gpa().free(full_path);1162 errdefer self.gpa().free(full_path);
11631163
1164 return Buffer.fromOwnedSlice(self.gpa(), full_path);1164 return ArrayListSentineled(u8, 0).fromOwnedSlice(self.gpa(), full_path);
1165 }1165 }
11661166
1167 /// If the temporary directory for this Compilation has not been created, creates it.1167 /// If the temporary directory for this Compilation has not been created, creates it.
...@@ -1279,7 +1279,7 @@ fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {...@@ -1279,7 +1279,7 @@ fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
1279 const fn_type = try analyzeFnType(comp, tree_scope, fn_decl.base.parent_scope, fn_decl.fn_proto);1279 const fn_type = try analyzeFnType(comp, tree_scope, fn_decl.base.parent_scope, fn_decl.fn_proto);
1280 defer fn_type.base.base.deref(comp);1280 defer fn_type.base.base.deref(comp);
12811281
1282 var symbol_name = try std.Buffer.init(comp.gpa(), fn_decl.base.name);1282 var symbol_name = try std.ArrayListSentineled(u8, 0).init(comp.gpa(), fn_decl.base.name);
1283 var symbol_name_consumed = false;1283 var symbol_name_consumed = false;
1284 errdefer if (!symbol_name_consumed) symbol_name.deinit();1284 errdefer if (!symbol_name_consumed) symbol_name.deinit();
12851285
...@@ -1426,7 +1426,7 @@ fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {...@@ -1426,7 +1426,7 @@ fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
1426 );1426 );
1427 defer fn_type.base.base.deref(comp);1427 defer fn_type.base.base.deref(comp);
14281428
1429 var symbol_name = try std.Buffer.init(comp.gpa(), fn_decl.base.name);1429 var symbol_name = try std.ArrayListSentineled(u8, 0).init(comp.gpa(), fn_decl.base.name);
1430 var symbol_name_consumed = false;1430 var symbol_name_consumed = false;
1431 defer if (!symbol_name_consumed) symbol_name.deinit();1431 defer if (!symbol_name_consumed) symbol_name.deinit();
14321432
src-self-hosted/dep_tokenizer.zig+41-41
...@@ -33,7 +33,7 @@ pub const Tokenizer = struct {...@@ -33,7 +33,7 @@ pub const Tokenizer = struct {
33 break; // advance33 break; // advance
34 },34 },
35 else => {35 else => {
36 self.state = State{ .target = try std.Buffer.initSize(&self.arena.allocator, 0) };36 self.state = State{ .target = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0) };
37 },37 },
38 },38 },
39 .target => |*target| switch (char) {39 .target => |*target| switch (char) {
...@@ -53,7 +53,7 @@ pub const Tokenizer = struct {...@@ -53,7 +53,7 @@ pub const Tokenizer = struct {
53 break; // advance53 break; // advance
54 },54 },
55 else => {55 else => {
56 try target.appendByte(char);56 try target.append(char);
57 break; // advance57 break; // advance
58 },58 },
59 },59 },
...@@ -62,24 +62,24 @@ pub const Tokenizer = struct {...@@ -62,24 +62,24 @@ pub const Tokenizer = struct {
62 return self.errorIllegalChar(self.index, char, "bad target escape", .{});62 return self.errorIllegalChar(self.index, char, "bad target escape", .{});
63 },63 },
64 ' ', '#', '\\' => {64 ' ', '#', '\\' => {
65 try target.appendByte(char);65 try target.append(char);
66 self.state = State{ .target = target.* };66 self.state = State{ .target = target.* };
67 break; // advance67 break; // advance
68 },68 },
69 '$' => {69 '$' => {
70 try target.append(self.bytes[self.index - 1 .. self.index]);70 try target.appendSlice(self.bytes[self.index - 1 .. self.index]);
71 self.state = State{ .target_dollar_sign = target.* };71 self.state = State{ .target_dollar_sign = target.* };
72 break; // advance72 break; // advance
73 },73 },
74 else => {74 else => {
75 try target.append(self.bytes[self.index - 1 .. self.index + 1]);75 try target.appendSlice(self.bytes[self.index - 1 .. self.index + 1]);
76 self.state = State{ .target = target.* };76 self.state = State{ .target = target.* };
77 break; // advance77 break; // advance
78 },78 },
79 },79 },
80 .target_dollar_sign => |*target| switch (char) {80 .target_dollar_sign => |*target| switch (char) {
81 '$' => {81 '$' => {
82 try target.appendByte(char);82 try target.append(char);
83 self.state = State{ .target = target.* };83 self.state = State{ .target = target.* };
84 break; // advance84 break; // advance
85 },85 },
...@@ -125,7 +125,7 @@ pub const Tokenizer = struct {...@@ -125,7 +125,7 @@ pub const Tokenizer = struct {
125 continue;125 continue;
126 },126 },
127 else => {127 else => {
128 try target.append(self.bytes[self.index - 2 .. self.index + 1]);128 try target.appendSlice(self.bytes[self.index - 2 .. self.index + 1]);
129 self.state = State{ .target = target.* };129 self.state = State{ .target = target.* };
130 break;130 break;
131 },131 },
...@@ -144,11 +144,11 @@ pub const Tokenizer = struct {...@@ -144,11 +144,11 @@ pub const Tokenizer = struct {
144 break; // advance144 break; // advance
145 },145 },
146 '"' => {146 '"' => {
147 self.state = State{ .prereq_quote = try std.Buffer.initSize(&self.arena.allocator, 0) };147 self.state = State{ .prereq_quote = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0) };
148 break; // advance148 break; // advance
149 },149 },
150 else => {150 else => {
151 self.state = State{ .prereq = try std.Buffer.initSize(&self.arena.allocator, 0) };151 self.state = State{ .prereq = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0) };
152 },152 },
153 },153 },
154 .rhs_continuation => switch (char) {154 .rhs_continuation => switch (char) {
...@@ -181,7 +181,7 @@ pub const Tokenizer = struct {...@@ -181,7 +181,7 @@ pub const Tokenizer = struct {
181 return Token{ .id = .prereq, .bytes = bytes };181 return Token{ .id = .prereq, .bytes = bytes };
182 },182 },
183 else => {183 else => {
184 try prereq.appendByte(char);184 try prereq.append(char);
185 break; // advance185 break; // advance
186 },186 },
187 },187 },
...@@ -201,7 +201,7 @@ pub const Tokenizer = struct {...@@ -201,7 +201,7 @@ pub const Tokenizer = struct {
201 break; // advance201 break; // advance
202 },202 },
203 else => {203 else => {
204 try prereq.appendByte(char);204 try prereq.append(char);
205 break; // advance205 break; // advance
206 },206 },
207 },207 },
...@@ -218,7 +218,7 @@ pub const Tokenizer = struct {...@@ -218,7 +218,7 @@ pub const Tokenizer = struct {
218 },218 },
219 else => {219 else => {
220 // not continuation220 // not continuation
221 try prereq.append(self.bytes[self.index - 1 .. self.index + 1]);221 try prereq.appendSlice(self.bytes[self.index - 1 .. self.index + 1]);
222 self.state = State{ .prereq = prereq.* };222 self.state = State{ .prereq = prereq.* };
223 break; // advance223 break; // advance
224 },224 },
...@@ -300,25 +300,25 @@ pub const Tokenizer = struct {...@@ -300,25 +300,25 @@ pub const Tokenizer = struct {
300 }300 }
301301
302 fn errorf(self: *Tokenizer, comptime fmt: []const u8, args: var) Error {302 fn errorf(self: *Tokenizer, comptime fmt: []const u8, args: var) Error {
303 self.error_text = (try std.Buffer.allocPrint(&self.arena.allocator, fmt, args)).span();303 self.error_text = try std.fmt.allocPrintZ(&self.arena.allocator, fmt, args);
304 return Error.InvalidInput;304 return Error.InvalidInput;
305 }305 }
306306
307 fn errorPosition(self: *Tokenizer, position: usize, bytes: []const u8, comptime fmt: []const u8, args: var) Error {307 fn errorPosition(self: *Tokenizer, position: usize, bytes: []const u8, comptime fmt: []const u8, args: var) Error {
308 var buffer = try std.Buffer.initSize(&self.arena.allocator, 0);308 var buffer = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0);
309 try buffer.outStream().print(fmt, args);309 try buffer.outStream().print(fmt, args);
310 try buffer.append(" '");310 try buffer.appendSlice(" '");
311 var out = makeOutput(std.Buffer.append, &buffer);311 var out = makeOutput(std.ArrayListSentineled(u8, 0).appendSlice, &buffer);
312 try printCharValues(&out, bytes);312 try printCharValues(&out, bytes);
313 try buffer.append("'");313 try buffer.appendSlice("'");
314 try buffer.outStream().print(" at position {}", .{position - (bytes.len - 1)});314 try buffer.outStream().print(" at position {}", .{position - (bytes.len - 1)});
315 self.error_text = buffer.span();315 self.error_text = buffer.span();
316 return Error.InvalidInput;316 return Error.InvalidInput;
317 }317 }
318318
319 fn errorIllegalChar(self: *Tokenizer, position: usize, char: u8, comptime fmt: []const u8, args: var) Error {319 fn errorIllegalChar(self: *Tokenizer, position: usize, char: u8, comptime fmt: []const u8, args: var) Error {
320 var buffer = try std.Buffer.initSize(&self.arena.allocator, 0);320 var buffer = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0);
321 try buffer.append("illegal char ");321 try buffer.appendSlice("illegal char ");
322 try printUnderstandableChar(&buffer, char);322 try printUnderstandableChar(&buffer, char);
323 try buffer.outStream().print(" at position {}", .{position});323 try buffer.outStream().print(" at position {}", .{position});
324 if (fmt.len != 0) try buffer.outStream().print(": " ++ fmt, args);324 if (fmt.len != 0) try buffer.outStream().print(": " ++ fmt, args);
...@@ -333,18 +333,18 @@ pub const Tokenizer = struct {...@@ -333,18 +333,18 @@ pub const Tokenizer = struct {
333333
334 const State = union(enum) {334 const State = union(enum) {
335 lhs: void,335 lhs: void,
336 target: std.Buffer,336 target: std.ArrayListSentineled(u8, 0),
337 target_reverse_solidus: std.Buffer,337 target_reverse_solidus: std.ArrayListSentineled(u8, 0),
338 target_dollar_sign: std.Buffer,338 target_dollar_sign: std.ArrayListSentineled(u8, 0),
339 target_colon: std.Buffer,339 target_colon: std.ArrayListSentineled(u8, 0),
340 target_colon_reverse_solidus: std.Buffer,340 target_colon_reverse_solidus: std.ArrayListSentineled(u8, 0),
341 rhs: void,341 rhs: void,
342 rhs_continuation: void,342 rhs_continuation: void,
343 rhs_continuation_linefeed: void,343 rhs_continuation_linefeed: void,
344 prereq_quote: std.Buffer,344 prereq_quote: std.ArrayListSentineled(u8, 0),
345 prereq: std.Buffer,345 prereq: std.ArrayListSentineled(u8, 0),
346 prereq_continuation: std.Buffer,346 prereq_continuation: std.ArrayListSentineled(u8, 0),
347 prereq_continuation_linefeed: std.Buffer,347 prereq_continuation_linefeed: std.ArrayListSentineled(u8, 0),
348 };348 };
349349
350 const Token = struct {350 const Token = struct {
...@@ -841,28 +841,28 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {...@@ -841,28 +841,28 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {
841 defer arena_allocator.deinit();841 defer arena_allocator.deinit();
842842
843 var it = Tokenizer.init(arena, input);843 var it = Tokenizer.init(arena, input);
844 var buffer = try std.Buffer.initSize(arena, 0);844 var buffer = try std.ArrayListSentineled(u8, 0).initSize(arena, 0);
845 var i: usize = 0;845 var i: usize = 0;
846 while (true) {846 while (true) {
847 const r = it.next() catch |err| {847 const r = it.next() catch |err| {
848 switch (err) {848 switch (err) {
849 Tokenizer.Error.InvalidInput => {849 Tokenizer.Error.InvalidInput => {
850 if (i != 0) try buffer.append("\n");850 if (i != 0) try buffer.appendSlice("\n");
851 try buffer.append("ERROR: ");851 try buffer.appendSlice("ERROR: ");
852 try buffer.append(it.error_text);852 try buffer.appendSlice(it.error_text);
853 },853 },
854 else => return err,854 else => return err,
855 }855 }
856 break;856 break;
857 };857 };
858 const token = r orelse break;858 const token = r orelse break;
859 if (i != 0) try buffer.append("\n");859 if (i != 0) try buffer.appendSlice("\n");
860 try buffer.append(@tagName(token.id));860 try buffer.appendSlice(@tagName(token.id));
861 try buffer.append(" = {");861 try buffer.appendSlice(" = {");
862 for (token.bytes) |b| {862 for (token.bytes) |b| {
863 try buffer.appendByte(printable_char_tab[b]);863 try buffer.append(printable_char_tab[b]);
864 }864 }
865 try buffer.append("}");865 try buffer.appendSlice("}");
866 i += 1;866 i += 1;
867 }867 }
868 const got: []const u8 = buffer.span();868 const got: []const u8 = buffer.span();
...@@ -995,13 +995,13 @@ fn printCharValues(out: var, bytes: []const u8) !void {...@@ -995,13 +995,13 @@ fn printCharValues(out: var, bytes: []const u8) !void {
995 }995 }
996}996}
997997
998fn printUnderstandableChar(buffer: *std.Buffer, char: u8) !void {998fn printUnderstandableChar(buffer: *std.ArrayListSentineled(u8, 0), char: u8) !void {
999 if (!std.ascii.isPrint(char) or char == ' ') {999 if (!std.ascii.isPrint(char) or char == ' ') {
1000 try buffer.outStream().print("\\x{X:2}", .{char});1000 try buffer.outStream().print("\\x{X:2}", .{char});
1001 } else {1001 } else {
1002 try buffer.append("'");1002 try buffer.appendSlice("'");
1003 try buffer.appendByte(printable_char_tab[char]);1003 try buffer.append(printable_char_tab[char]);
1004 try buffer.append("'");1004 try buffer.appendSlice("'");
1005 }1005 }
1006}1006}
10071007
src-self-hosted/link.zig+4-4
...@@ -15,10 +15,10 @@ const Context = struct {...@@ -15,10 +15,10 @@ const Context = struct {
15 link_in_crt: bool,15 link_in_crt: bool,
1616
17 link_err: error{OutOfMemory}!void,17 link_err: error{OutOfMemory}!void,
18 link_msg: std.Buffer,18 link_msg: std.ArrayListSentineled(u8, 0),
1919
20 libc: *LibCInstallation,20 libc: *LibCInstallation,
21 out_file_path: std.Buffer,21 out_file_path: std.ArrayListSentineled(u8, 0),
22};22};
2323
24pub fn link(comp: *Compilation) !void {24pub fn link(comp: *Compilation) !void {
...@@ -34,9 +34,9 @@ pub fn link(comp: *Compilation) !void {...@@ -34,9 +34,9 @@ pub fn link(comp: *Compilation) !void {
34 };34 };
35 defer ctx.arena.deinit();35 defer ctx.arena.deinit();
36 ctx.args = std.ArrayList([*:0]const u8).init(&ctx.arena.allocator);36 ctx.args = std.ArrayList([*:0]const u8).init(&ctx.arena.allocator);
37 ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator);37 ctx.link_msg = std.ArrayListSentineled(u8, 0).initNull(&ctx.arena.allocator);
3838
39 ctx.out_file_path = try std.Buffer.init(&ctx.arena.allocator, comp.name.span());39 ctx.out_file_path = try std.ArrayListSentineled(u8, 0).init(&ctx.arena.allocator, comp.name.span());
40 switch (comp.kind) {40 switch (comp.kind) {
41 .Exe => {41 .Exe => {
42 try ctx.out_file_path.append(comp.target.exeFileExt());42 try ctx.out_file_path.append(comp.target.exeFileExt());
src-self-hosted/package.zig+5-5
...@@ -1,11 +1,11 @@...@@ -1,11 +1,11 @@
1const std = @import("std");1const std = @import("std");
2const mem = std.mem;2const mem = std.mem;
3const assert = std.debug.assert;3const assert = std.debug.assert;
4const Buffer = std.Buffer;4const ArrayListSentineled = std.ArrayListSentineled;
55
6pub const Package = struct {6pub const Package = struct {
7 root_src_dir: Buffer,7 root_src_dir: ArrayListSentineled(u8, 0),
8 root_src_path: Buffer,8 root_src_path: ArrayListSentineled(u8, 0),
99
10 /// relative to root_src_dir10 /// relative to root_src_dir
11 table: Table,11 table: Table,
...@@ -17,8 +17,8 @@ pub const Package = struct {...@@ -17,8 +17,8 @@ pub const Package = struct {
17 pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {17 pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
18 const ptr = try allocator.create(Package);18 const ptr = try allocator.create(Package);
19 ptr.* = Package{19 ptr.* = Package{
20 .root_src_dir = try Buffer.init(allocator, root_src_dir),20 .root_src_dir = try ArrayListSentineled(u8, 0).init(allocator, root_src_dir),
21 .root_src_path = try Buffer.init(allocator, root_src_path),21 .root_src_path = try ArrayListSentineled(u8, 0).init(allocator, root_src_path),
22 .table = Table.init(allocator),22 .table = Table.init(allocator),
23 };23 };
24 return ptr;24 return ptr;
src-self-hosted/stage2.zig+17-17
...@@ -8,7 +8,7 @@ const fs = std.fs;...@@ -8,7 +8,7 @@ const fs = std.fs;
8const process = std.process;8const process = std.process;
9const Allocator = mem.Allocator;9const Allocator = mem.Allocator;
10const ArrayList = std.ArrayList;10const ArrayList = std.ArrayList;
11const Buffer = std.Buffer;11const ArrayListSentineled = std.ArrayListSentineled;
12const Target = std.Target;12const Target = std.Target;
13const CrossTarget = std.zig.CrossTarget;13const CrossTarget = std.zig.CrossTarget;
14const self_hosted_main = @import("main.zig");14const self_hosted_main = @import("main.zig");
...@@ -449,7 +449,7 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {...@@ -449,7 +449,7 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
449449
450export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {450export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
451 const otoken = self.handle.next() catch {451 const otoken = self.handle.next() catch {
452 const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");452 const textz = std.ArrayListSentineled(u8, 0).init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
453 return stage2_DepNextResult{453 return stage2_DepNextResult{
454 .type_id = .error_,454 .type_id = .error_,
455 .textz = textz.span().ptr,455 .textz = textz.span().ptr,
...@@ -461,7 +461,7 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes...@@ -461,7 +461,7 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes
461 .textz = undefined,461 .textz = undefined,
462 };462 };
463 };463 };
464 const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");464 const textz = std.ArrayListSentineled(u8, 0).init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
465 return stage2_DepNextResult{465 return stage2_DepNextResult{
466 .type_id = switch (token.id) {466 .type_id = switch (token.id) {
467 .target => .target,467 .target => .target,
...@@ -924,14 +924,14 @@ const Stage2Target = extern struct {...@@ -924,14 +924,14 @@ const Stage2Target = extern struct {
924 var dynamic_linker: ?[*:0]u8 = null;924 var dynamic_linker: ?[*:0]u8 = null;
925 const target = try crossTargetToTarget(cross_target, &dynamic_linker);925 const target = try crossTargetToTarget(cross_target, &dynamic_linker);
926926
927 var cache_hash = try std.Buffer.allocPrint(allocator, "{}\n{}\n", .{927 var cache_hash = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, "{}\n{}\n", .{
928 target.cpu.model.name,928 target.cpu.model.name,
929 target.cpu.features.asBytes(),929 target.cpu.features.asBytes(),
930 });930 });
931 defer cache_hash.deinit();931 defer cache_hash.deinit();
932932
933 const generic_arch_name = target.cpu.arch.genericName();933 const generic_arch_name = target.cpu.arch.genericName();
934 var cpu_builtin_str_buffer = try std.Buffer.allocPrint(allocator,934 var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
935 \\Cpu{{935 \\Cpu{{
936 \\ .arch = .{},936 \\ .arch = .{},
937 \\ .model = &Target.{}.cpu.{},937 \\ .model = &Target.{}.cpu.{},
...@@ -946,7 +946,7 @@ const Stage2Target = extern struct {...@@ -946,7 +946,7 @@ const Stage2Target = extern struct {
946 });946 });
947 defer cpu_builtin_str_buffer.deinit();947 defer cpu_builtin_str_buffer.deinit();
948948
949 var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);949 var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
950 defer llvm_features_buffer.deinit();950 defer llvm_features_buffer.deinit();
951951
952 // Unfortunately we have to do the work twice, because Clang does not support952 // Unfortunately we have to do the work twice, because Clang does not support
...@@ -961,17 +961,17 @@ const Stage2Target = extern struct {...@@ -961,17 +961,17 @@ const Stage2Target = extern struct {
961961
962 if (feature.llvm_name) |llvm_name| {962 if (feature.llvm_name) |llvm_name| {
963 const plus_or_minus = "-+"[@boolToInt(is_enabled)];963 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
964 try llvm_features_buffer.appendByte(plus_or_minus);964 try llvm_features_buffer.append(plus_or_minus);
965 try llvm_features_buffer.append(llvm_name);965 try llvm_features_buffer.appendSlice(llvm_name);
966 try llvm_features_buffer.append(",");966 try llvm_features_buffer.appendSlice(",");
967 }967 }
968968
969 if (is_enabled) {969 if (is_enabled) {
970 // TODO some kind of "zig identifier escape" function rather than970 // TODO some kind of "zig identifier escape" function rather than
971 // unconditionally using @"" syntax971 // unconditionally using @"" syntax
972 try cpu_builtin_str_buffer.append(" .@\"");972 try cpu_builtin_str_buffer.appendSlice(" .@\"");
973 try cpu_builtin_str_buffer.append(feature.name);973 try cpu_builtin_str_buffer.appendSlice(feature.name);
974 try cpu_builtin_str_buffer.append("\",\n");974 try cpu_builtin_str_buffer.appendSlice("\",\n");
975 }975 }
976 }976 }
977977
...@@ -990,7 +990,7 @@ const Stage2Target = extern struct {...@@ -990,7 +990,7 @@ const Stage2Target = extern struct {
990 },990 },
991 }991 }
992992
993 try cpu_builtin_str_buffer.append(993 try cpu_builtin_str_buffer.appendSlice(
994 \\ }),994 \\ }),
995 \\};995 \\};
996 \\996 \\
...@@ -999,7 +999,7 @@ const Stage2Target = extern struct {...@@ -999,7 +999,7 @@ const Stage2Target = extern struct {
999 assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));999 assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));
1000 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);1000 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
10011001
1002 var os_builtin_str_buffer = try std.Buffer.allocPrint(allocator,1002 var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
1003 \\Os{{1003 \\Os{{
1004 \\ .tag = .{},1004 \\ .tag = .{},
1005 \\ .version_range = .{{1005 \\ .version_range = .{{
...@@ -1042,7 +1042,7 @@ const Stage2Target = extern struct {...@@ -1042,7 +1042,7 @@ const Stage2Target = extern struct {
1042 .emscripten,1042 .emscripten,
1043 .uefi,1043 .uefi,
1044 .other,1044 .other,
1045 => try os_builtin_str_buffer.append(" .none = {} }\n"),1045 => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"),
10461046
1047 .freebsd,1047 .freebsd,
1048 .macosx,1048 .macosx,
...@@ -1118,9 +1118,9 @@ const Stage2Target = extern struct {...@@ -1118,9 +1118,9 @@ const Stage2Target = extern struct {
1118 @tagName(target.os.version_range.windows.max),1118 @tagName(target.os.version_range.windows.max),
1119 }),1119 }),
1120 }1120 }
1121 try os_builtin_str_buffer.append("};\n");1121 try os_builtin_str_buffer.appendSlice("};\n");
11221122
1123 try cache_hash.append(1123 try cache_hash.appendSlice(
1124 os_builtin_str_buffer.span()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()],1124 os_builtin_str_buffer.span()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()],
1125 );1125 );
11261126
src-self-hosted/translate_c.zig+1-1
...@@ -275,7 +275,7 @@ pub fn translate(...@@ -275,7 +275,7 @@ pub fn translate(
275275
276 const tree = try tree_arena.allocator.create(ast.Tree);276 const tree = try tree_arena.allocator.create(ast.Tree);
277 tree.* = ast.Tree{277 tree.* = ast.Tree{
278 .source = undefined, // need to use Buffer.toOwnedSlice later278 .source = undefined, // need to use toOwnedSlice later
279 .root_node = undefined,279 .root_node = undefined,
280 .arena_allocator = tree_arena,280 .arena_allocator = tree_arena,
281 .tokens = undefined, // can't reference the allocator yet281 .tokens = undefined, // can't reference the allocator yet
src-self-hosted/util.zig+7-7
...@@ -16,11 +16,11 @@ pub fn getDarwinArchString(self: Target) [:0]const u8 {...@@ -16,11 +16,11 @@ pub fn getDarwinArchString(self: Target) [:0]const u8 {
16 }16 }
17}17}
1818
19pub fn llvmTargetFromTriple(triple: std.Buffer) !*llvm.Target {19pub fn llvmTargetFromTriple(triple: [:0]const u8) !*llvm.Target {
20 var result: *llvm.Target = undefined;20 var result: *llvm.Target = undefined;
21 var err_msg: [*:0]u8 = undefined;21 var err_msg: [*:0]u8 = undefined;
22 if (llvm.GetTargetFromTriple(triple.span(), &result, &err_msg) != 0) {22 if (llvm.GetTargetFromTriple(triple, &result, &err_msg) != 0) {
23 std.debug.warn("triple: {s} error: {s}\n", .{ triple.span(), err_msg });23 std.debug.warn("triple: {s} error: {s}\n", .{ triple, err_msg });
24 return error.UnsupportedTarget;24 return error.UnsupportedTarget;
25 }25 }
26 return result;26 return result;
...@@ -34,14 +34,14 @@ pub fn initializeAllTargets() void {...@@ -34,14 +34,14 @@ pub fn initializeAllTargets() void {
34 llvm.InitializeAllAsmParsers();34 llvm.InitializeAllAsmParsers();
35}35}
3636
37pub fn getLLVMTriple(allocator: *std.mem.Allocator, target: std.Target) !std.Buffer {37pub fn getLLVMTriple(allocator: *std.mem.Allocator, target: std.Target) ![:0]u8 {
38 var result = try std.Buffer.initSize(allocator, 0);38 var result = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
39 errdefer result.deinit();39 defer result.deinit();
4040
41 try result.outStream().print(41 try result.outStream().print(
42 "{}-unknown-{}-{}",42 "{}-unknown-{}-{}",
43 .{ @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi) },43 .{ @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi) },
44 );44 );
4545
46 return result;46 return result.toOwnedSlice();
47}47}
src-self-hosted/value.zig+7-7
...@@ -3,7 +3,7 @@ const Scope = @import("scope.zig").Scope;...@@ -3,7 +3,7 @@ const Scope = @import("scope.zig").Scope;
3const Compilation = @import("compilation.zig").Compilation;3const Compilation = @import("compilation.zig").Compilation;
4const ObjectFile = @import("codegen.zig").ObjectFile;4const ObjectFile = @import("codegen.zig").ObjectFile;
5const llvm = @import("llvm.zig");5const llvm = @import("llvm.zig");
6const Buffer = std.Buffer;6const ArrayListSentineled = std.ArrayListSentineled;
7const assert = std.debug.assert;7const assert = std.debug.assert;
88
9/// Values are ref-counted, heap-allocated, and copy-on-write9/// Values are ref-counted, heap-allocated, and copy-on-write
...@@ -131,9 +131,9 @@ pub const Value = struct {...@@ -131,9 +131,9 @@ pub const Value = struct {
131131
132 /// The main external name that is used in the .o file.132 /// The main external name that is used in the .o file.
133 /// TODO https://github.com/ziglang/zig/issues/265133 /// TODO https://github.com/ziglang/zig/issues/265
134 symbol_name: Buffer,134 symbol_name: ArrayListSentineled(u8, 0),
135135
136 pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {136 pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: ArrayListSentineled(u8, 0)) !*FnProto {
137 const self = try comp.gpa().create(FnProto);137 const self = try comp.gpa().create(FnProto);
138 self.* = FnProto{138 self.* = FnProto{
139 .base = Value{139 .base = Value{
...@@ -171,7 +171,7 @@ pub const Value = struct {...@@ -171,7 +171,7 @@ pub const Value = struct {
171171
172 /// The main external name that is used in the .o file.172 /// The main external name that is used in the .o file.
173 /// TODO https://github.com/ziglang/zig/issues/265173 /// TODO https://github.com/ziglang/zig/issues/265
174 symbol_name: Buffer,174 symbol_name: ArrayListSentineled(u8, 0),
175175
176 /// parent should be the top level decls or container decls176 /// parent should be the top level decls or container decls
177 fndef_scope: *Scope.FnDef,177 fndef_scope: *Scope.FnDef,
...@@ -183,13 +183,13 @@ pub const Value = struct {...@@ -183,13 +183,13 @@ pub const Value = struct {
183 block_scope: ?*Scope.Block,183 block_scope: ?*Scope.Block,
184184
185 /// Path to the object file that contains this function185 /// Path to the object file that contains this function
186 containing_object: Buffer,186 containing_object: ArrayListSentineled(u8, 0),
187187
188 link_set_node: *std.TailQueue(?*Value.Fn).Node,188 link_set_node: *std.TailQueue(?*Value.Fn).Node,
189189
190 /// Creates a Fn value with 1 ref190 /// Creates a Fn value with 1 ref
191 /// Takes ownership of symbol_name191 /// Takes ownership of symbol_name
192 pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {192 pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: ArrayListSentineled(u8, 0)) !*Fn {
193 const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);193 const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
194 link_set_node.* = Compilation.FnLinkSet.Node{194 link_set_node.* = Compilation.FnLinkSet.Node{
195 .data = null,195 .data = null,
...@@ -209,7 +209,7 @@ pub const Value = struct {...@@ -209,7 +209,7 @@ pub const Value = struct {
209 .child_scope = &fndef_scope.base,209 .child_scope = &fndef_scope.base,
210 .block_scope = null,210 .block_scope = null,
211 .symbol_name = symbol_name,211 .symbol_name = symbol_name,
212 .containing_object = Buffer.initNull(comp.gpa()),212 .containing_object = ArrayListSentineled(u8, 0).initNull(comp.gpa()),
213 .link_set_node = link_set_node,213 .link_set_node = link_set_node,
214 };214 };
215 fn_type.base.base.ref();215 fn_type.base.base.ref();
test/standalone/brace_expansion/main.zig+16-16
...@@ -4,7 +4,7 @@ const mem = std.mem;...@@ -4,7 +4,7 @@ const mem = std.mem;
4const debug = std.debug;4const debug = std.debug;
5const assert = debug.assert;5const assert = debug.assert;
6const testing = std.testing;6const testing = std.testing;
7const Buffer = std.Buffer;7const ArrayListSentineled = std.ArrayListSentineled;
8const ArrayList = std.ArrayList;8const ArrayList = std.ArrayList;
9const maxInt = std.math.maxInt;9const maxInt = std.math.maxInt;
1010
...@@ -111,7 +111,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {...@@ -111,7 +111,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
111 }111 }
112}112}
113113
114fn expandString(input: []const u8, output: *Buffer) !void {114fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
115 const tokens = try tokenize(input);115 const tokens = try tokenize(input);
116 if (tokens.len == 1) {116 if (tokens.len == 1) {
117 return output.resize(0);117 return output.resize(0);
...@@ -125,7 +125,7 @@ fn expandString(input: []const u8, output: *Buffer) !void {...@@ -125,7 +125,7 @@ fn expandString(input: []const u8, output: *Buffer) !void {
125 else => return error.InvalidInput,125 else => return error.InvalidInput,
126 }126 }
127127
128 var result_list = ArrayList(Buffer).init(global_allocator);128 var result_list = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
129 defer result_list.deinit();129 defer result_list.deinit();
130130
131 try expandNode(root, &result_list);131 try expandNode(root, &result_list);
...@@ -133,41 +133,41 @@ fn expandString(input: []const u8, output: *Buffer) !void {...@@ -133,41 +133,41 @@ fn expandString(input: []const u8, output: *Buffer) !void {
133 try output.resize(0);133 try output.resize(0);
134 for (result_list.span()) |buf, i| {134 for (result_list.span()) |buf, i| {
135 if (i != 0) {135 if (i != 0) {
136 try output.appendByte(' ');136 try output.append(' ');
137 }137 }
138 try output.append(buf.span());138 try output.appendSlice(buf.span());
139 }139 }
140}140}
141141
142const ExpandNodeError = error{OutOfMemory};142const ExpandNodeError = error{OutOfMemory};
143143
144fn expandNode(node: Node, output: *ArrayList(Buffer)) ExpandNodeError!void {144fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void {
145 assert(output.len == 0);145 assert(output.len == 0);
146 switch (node) {146 switch (node) {
147 Node.Scalar => |scalar| {147 Node.Scalar => |scalar| {
148 try output.append(try Buffer.init(global_allocator, scalar));148 try output.append(try ArrayListSentineled(u8, 0).init(global_allocator, scalar));
149 },149 },
150 Node.Combine => |pair| {150 Node.Combine => |pair| {
151 const a_node = pair[0];151 const a_node = pair[0];
152 const b_node = pair[1];152 const b_node = pair[1];
153153
154 var child_list_a = ArrayList(Buffer).init(global_allocator);154 var child_list_a = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
155 try expandNode(a_node, &child_list_a);155 try expandNode(a_node, &child_list_a);
156156
157 var child_list_b = ArrayList(Buffer).init(global_allocator);157 var child_list_b = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
158 try expandNode(b_node, &child_list_b);158 try expandNode(b_node, &child_list_b);
159159
160 for (child_list_a.span()) |buf_a| {160 for (child_list_a.span()) |buf_a| {
161 for (child_list_b.span()) |buf_b| {161 for (child_list_b.span()) |buf_b| {
162 var combined_buf = try Buffer.initFromBuffer(buf_a);162 var combined_buf = try ArrayListSentineled(u8, 0).initFromBuffer(buf_a);
163 try combined_buf.append(buf_b.span());163 try combined_buf.appendSlice(buf_b.span());
164 try output.append(combined_buf);164 try output.append(combined_buf);
165 }165 }
166 }166 }
167 },167 },
168 Node.List => |list| {168 Node.List => |list| {
169 for (list.span()) |child_node| {169 for (list.span()) |child_node| {
170 var child_list = ArrayList(Buffer).init(global_allocator);170 var child_list = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
171 try expandNode(child_node, &child_list);171 try expandNode(child_node, &child_list);
172172
173 for (child_list.span()) |buf| {173 for (child_list.span()) |buf| {
...@@ -187,13 +187,13 @@ pub fn main() !void {...@@ -187,13 +187,13 @@ pub fn main() !void {
187187
188 global_allocator = &arena.allocator;188 global_allocator = &arena.allocator;
189189
190 var stdin_buf = try Buffer.initSize(global_allocator, 0);190 var stdin_buf = try ArrayListSentineled(u8, 0).initSize(global_allocator, 0);
191 defer stdin_buf.deinit();191 defer stdin_buf.deinit();
192192
193 var stdin_adapter = stdin_file.inStream();193 var stdin_adapter = stdin_file.inStream();
194 try stdin_adapter.stream.readAllBuffer(&stdin_buf, maxInt(usize));194 try stdin_adapter.stream.readAllBuffer(&stdin_buf, maxInt(usize));
195195
196 var result_buf = try Buffer.initSize(global_allocator, 0);196 var result_buf = try ArrayListSentineled(u8, 0).initSize(global_allocator, 0);
197 defer result_buf.deinit();197 defer result_buf.deinit();
198198
199 try expandString(stdin_buf.span(), &result_buf);199 try expandString(stdin_buf.span(), &result_buf);
...@@ -218,7 +218,7 @@ test "invalid inputs" {...@@ -218,7 +218,7 @@ test "invalid inputs" {
218}218}
219219
220fn expectError(test_input: []const u8, expected_err: anyerror) void {220fn expectError(test_input: []const u8, expected_err: anyerror) void {
221 var output_buf = Buffer.initSize(global_allocator, 0) catch unreachable;221 var output_buf = ArrayListSentineled(u8, 0).initSize(global_allocator, 0) catch unreachable;
222 defer output_buf.deinit();222 defer output_buf.deinit();
223223
224 testing.expectError(expected_err, expandString(test_input, &output_buf));224 testing.expectError(expected_err, expandString(test_input, &output_buf));
...@@ -251,7 +251,7 @@ test "valid inputs" {...@@ -251,7 +251,7 @@ test "valid inputs" {
251}251}
252252
253fn expectExpansion(test_input: []const u8, expected_result: []const u8) void {253fn expectExpansion(test_input: []const u8, expected_result: []const u8) void {
254 var result = Buffer.initSize(global_allocator, 0) catch unreachable;254 var result = ArrayListSentineled(u8, 0).initSize(global_allocator, 0) catch unreachable;
255 defer result.deinit();255 defer result.deinit();
256256
257 expandString(test_input, &result) catch unreachable;257 expandString(test_input, &result) catch unreachable;
test/tests.zig+9-10
...@@ -4,7 +4,6 @@ const debug = std.debug;...@@ -4,7 +4,6 @@ const debug = std.debug;
4const warn = debug.warn;4const warn = debug.warn;
5const build = std.build;5const build = std.build;
6const CrossTarget = std.zig.CrossTarget;6const CrossTarget = std.zig.CrossTarget;
7const Buffer = std.Buffer;
8const io = std.io;7const io = std.io;
9const fs = std.fs;8const fs = std.fs;
10const mem = std.mem;9const mem = std.mem;
...@@ -640,7 +639,7 @@ pub const StackTracesContext = struct {...@@ -640,7 +639,7 @@ pub const StackTracesContext = struct {
640 // - replace address with symbolic string639 // - replace address with symbolic string
641 // - skip empty lines640 // - skip empty lines
642 const got: []const u8 = got_result: {641 const got: []const u8 = got_result: {
643 var buf = try Buffer.initSize(b.allocator, 0);642 var buf = ArrayList(u8).init(b.allocator);
644 defer buf.deinit();643 defer buf.deinit();
645 if (stderr.len != 0 and stderr[stderr.len - 1] == '\n') stderr = stderr[0 .. stderr.len - 1];644 if (stderr.len != 0 and stderr[stderr.len - 1] == '\n') stderr = stderr[0 .. stderr.len - 1];
646 var it = mem.separate(stderr, "\n");645 var it = mem.separate(stderr, "\n");
...@@ -652,21 +651,21 @@ pub const StackTracesContext = struct {...@@ -652,21 +651,21 @@ pub const StackTracesContext = struct {
652 var pos: usize = if (std.Target.current.os.tag == .windows) 2 else 0;651 var pos: usize = if (std.Target.current.os.tag == .windows) 2 else 0;
653 for (delims) |delim, i| {652 for (delims) |delim, i| {
654 marks[i] = mem.indexOfPos(u8, line, pos, delim) orelse {653 marks[i] = mem.indexOfPos(u8, line, pos, delim) orelse {
655 try buf.append(line);654 try buf.appendSlice(line);
656 try buf.append("\n");655 try buf.appendSlice("\n");
657 continue :process_lines;656 continue :process_lines;
658 };657 };
659 pos = marks[i] + delim.len;658 pos = marks[i] + delim.len;
660 }659 }
661 pos = mem.lastIndexOfScalar(u8, line[0..marks[0]], fs.path.sep) orelse {660 pos = mem.lastIndexOfScalar(u8, line[0..marks[0]], fs.path.sep) orelse {
662 try buf.append(line);661 try buf.appendSlice(line);
663 try buf.append("\n");662 try buf.appendSlice("\n");
664 continue :process_lines;663 continue :process_lines;
665 };664 };
666 try buf.append(line[pos + 1 .. marks[2] + delims[2].len]);665 try buf.appendSlice(line[pos + 1 .. marks[2] + delims[2].len]);
667 try buf.append(" [address]");666 try buf.appendSlice(" [address]");
668 try buf.append(line[marks[3]..]);667 try buf.appendSlice(line[marks[3]..]);
669 try buf.append("\n");668 try buf.appendSlice("\n");
670 }669 }
671 break :got_result buf.toOwnedSlice();670 break :got_result buf.toOwnedSlice();
672 };671 };