authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 13:44:19-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 13:44:19-04:00
logc2e8788259efd33995e151ace355cb5896cc8a85
tree7962a47dd9df3976a7aa8c8c5ad754d27dd55ba4
parente8a1e2a1d8f2903d5951339f7d3e0dbdfc85704c
parent2e806682f451efd26bef0486ddd980ab60de0fa1
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'daurnimator-less-buffer'

closes #4665

31 files changed, 513 insertions(+), 456 deletions(-)

doc/docgen.zig+4-4
......@@ -321,7 +321,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
321321 var last_action = Action.Open;
322322 var last_columns: ?u8 = null;
323323
324 var toc_buf = try std.Buffer.initSize(allocator, 0);
324 var toc_buf = std.ArrayList(u8).init(allocator);
325325 defer toc_buf.deinit();
326326
327327 var toc = toc_buf.outStream();
......@@ -607,7 +607,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
607607}
608608
609609fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
610 var buf = try std.Buffer.initSize(allocator, 0);
610 var buf = std.ArrayList(u8).init(allocator);
611611 defer buf.deinit();
612612
613613 const out = buf.outStream();
......@@ -626,7 +626,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
626626}
627627
628628fn escapeHtml(allocator: *mem.Allocator, input: []const u8) ![]u8 {
629 var buf = try std.Buffer.initSize(allocator, 0);
629 var buf = std.ArrayList(u8).init(allocator);
630630 defer buf.deinit();
631631
632632 const out = buf.outStream();
......@@ -672,7 +672,7 @@ test "term color" {
672672}
673673
674674fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
675 var buf = try std.Buffer.initSize(allocator, 0);
675 var buf = std.ArrayList(u8).init(allocator);
676676 defer buf.deinit();
677677
678678 var out = buf.outStream();
lib/std/array_list.zig+29-4
......@@ -189,16 +189,30 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
189189 self.len += items.len;
190190 }
191191
192 /// Append a value to the list `n` times. Allocates more memory
193 /// as necessary.
192 /// Same as `append` except it returns the number of bytes written, which is always the same
193 /// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
194 /// This function may be called only when `T` is `u8`.
195 fn appendWrite(self: *Self, m: []const u8) !usize {
196 try self.appendSlice(m);
197 return m.len;
198 }
199
200 /// Initializes an OutStream which will append to the list.
201 /// This function may be called only when `T` is `u8`.
202 pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) {
203 return .{ .context = self };
204 }
205
206 /// Append a value to the list `n` times.
207 /// Allocates more memory as necessary.
194208 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
195209 const old_len = self.len;
196210 try self.resize(self.len + n);
197211 mem.set(T, self.items[old_len..self.len], value);
198212 }
199213
200 /// Adjust the list's length to `new_len`. Doesn't initialize
201 /// added items if any.
214 /// Adjust the list's length to `new_len`.
215 /// Does not initialize added items if any.
202216 pub fn resize(self: *Self, new_len: usize) !void {
203217 try self.ensureCapacity(new_len);
204218 self.len = new_len;
......@@ -479,3 +493,14 @@ test "std.ArrayList: ArrayList(T) of struct T" {
479493 try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.allocator) });
480494 testing.expect(root.sub_items.items[0].integer == 42);
481495}
496
497test "std.ArrayList(u8) implements outStream" {
498 var buffer = ArrayList(u8).init(std.testing.allocator);
499 defer buffer.deinit();
500
501 const x: i32 = 42;
502 const y: i32 = 1234;
503 try buffer.outStream().print("x: {}\ny: {}\n", .{ x, y });
504
505 testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.span());
506}
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/build.zig+10-10
......@@ -1139,7 +1139,7 @@ pub const LibExeObjStep = struct {
11391139 out_lib_filename: []const u8,
11401140 out_pdb_filename: []const u8,
11411141 packages: ArrayList(Pkg),
1142 build_options_contents: std.Buffer,
1142 build_options_contents: std.ArrayList(u8),
11431143 system_linker_hack: bool = false,
11441144
11451145 object_src: []const u8,
......@@ -1274,7 +1274,7 @@ pub const LibExeObjStep = struct {
12741274 .lib_paths = ArrayList([]const u8).init(builder.allocator),
12751275 .framework_dirs = ArrayList([]const u8).init(builder.allocator),
12761276 .object_src = undefined,
1277 .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable,
1277 .build_options_contents = std.ArrayList(u8).init(builder.allocator),
12781278 .c_std = Builder.CStd.C99,
12791279 .override_lib_dir = null,
12801280 .main_pkg_path = null,
......@@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {
18471847 }
18481848 }
18491849
1850 if (self.build_options_contents.len() > 0) {
1850 if (self.build_options_contents.len > 0) {
18511851 const build_options_file = try fs.path.join(
18521852 builder.allocator,
18531853 &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
......@@ -1960,22 +1960,22 @@ pub const LibExeObjStep = struct {
19601960 try zig_args.append(cross.cpu.model.name);
19611961 }
19621962 } else {
1963 var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");
1964 try mcpu_buffer.append(cross.cpu.model.name);
1963 var mcpu_buffer = std.ArrayList(u8).init(builder.allocator);
1964
1965 try mcpu_buffer.outStream().print("-mcpu={}", .{cross.cpu.model.name});
19651966
19661967 for (all_features) |feature, i_usize| {
19671968 const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);
19681969 const in_cpu_set = populated_cpu_features.isEnabled(i);
19691970 const in_actual_set = cross.cpu.features.isEnabled(i);
19701971 if (in_cpu_set and !in_actual_set) {
1971 try mcpu_buffer.appendByte('-');
1972 try mcpu_buffer.append(feature.name);
1972 try mcpu_buffer.outStream().print("-{}", .{feature.name});
19731973 } else if (!in_cpu_set and in_actual_set) {
1974 try mcpu_buffer.appendByte('+');
1975 try mcpu_buffer.append(feature.name);
1974 try mcpu_buffer.outStream().print("+{}", .{feature.name});
19761975 }
19771976 }
1978 try zig_args.append(mcpu_buffer.span());
1977
1978 try zig_args.append(mcpu_buffer.toOwnedSlice());
19791979 }
19801980
19811981 if (self.target.dynamic_linker.get()) |dynamic_linker| {
lib/std/child_process.zig+10-12
......@@ -10,7 +10,7 @@ const windows = os.windows;
1010const mem = std.mem;
1111const debug = std.debug;
1212const BufMap = std.BufMap;
13const Buffer = std.Buffer;
13const ArrayListSentineled = std.ArrayListSentineled;
1414const builtin = @import("builtin");
1515const Os = builtin.Os;
1616const TailQueue = std.TailQueue;
......@@ -757,38 +757,36 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1
757757}
758758
759759/// Caller must dealloc.
760/// Guarantees a null byte at result[result.len].
761fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![]u8 {
762 var buf = try Buffer.initSize(allocator, 0);
760fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 {
761 var buf = try ArrayListSentineled(u8, 0).initSize(allocator, 0);
763762 defer buf.deinit();
764
765 var buf_stream = buf.outStream();
763 const buf_stream = buf.outStream();
766764
767765 for (argv) |arg, arg_i| {
768 if (arg_i != 0) try buf.appendByte(' ');
766 if (arg_i != 0) try buf_stream.writeByte(' ');
769767 if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
770 try buf.append(arg);
768 try buf_stream.writeAll(arg);
771769 continue;
772770 }
773 try buf.appendByte('"');
771 try buf_stream.writeByte('"');
774772 var backslash_count: usize = 0;
775773 for (arg) |byte| {
776774 switch (byte) {
777775 '\\' => backslash_count += 1,
778776 '"' => {
779777 try buf_stream.writeByteNTimes('\\', backslash_count * 2 + 1);
780 try buf.appendByte('"');
778 try buf_stream.writeByte('"');
781779 backslash_count = 0;
782780 },
783781 else => {
784782 try buf_stream.writeByteNTimes('\\', backslash_count);
785 try buf.appendByte(byte);
783 try buf_stream.writeByte(byte);
786784 backslash_count = 0;
787785 },
788786 }
789787 }
790788 try buf_stream.writeByteNTimes('\\', backslash_count * 2);
791 try buf.appendByte('"');
789 try buf_stream.writeByte('"');
792790 }
793791
794792 return buf.toOwnedSlice();
lib/std/fs.zig+8-5
......@@ -1416,13 +1416,14 @@ pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAb
14161416
14171417pub const Walker = struct {
14181418 stack: std.ArrayList(StackItem),
1419 name_buffer: std.Buffer,
1419 name_buffer: std.ArrayList(u8),
14201420
14211421 pub const Entry = struct {
14221422 /// The containing directory. This can be used to operate directly on `basename`
14231423 /// rather than `path`, avoiding `error.NameTooLong` for deeply nested paths.
14241424 /// The directory remains open until `next` or `deinit` is called.
14251425 dir: Dir,
1426 /// TODO make this null terminated for API convenience
14261427 basename: []const u8,
14271428
14281429 path: []const u8,
......@@ -1445,8 +1446,8 @@ pub const Walker = struct {
14451446 const dirname_len = top.dirname_len;
14461447 if (try top.dir_it.next()) |base| {
14471448 self.name_buffer.shrink(dirname_len);
1448 try self.name_buffer.appendByte(path.sep);
1449 try self.name_buffer.append(base.name);
1449 try self.name_buffer.append(path.sep);
1450 try self.name_buffer.appendSlice(base.name);
14501451 if (base.kind == .Directory) {
14511452 var new_dir = top.dir_it.dir.openDir(base.name, .{ .iterate = true }) catch |err| switch (err) {
14521453 error.NameTooLong => unreachable, // no path sep in base.name
......@@ -1456,7 +1457,7 @@ pub const Walker = struct {
14561457 errdefer new_dir.close();
14571458 try self.stack.append(StackItem{
14581459 .dir_it = new_dir.iterate(),
1459 .dirname_len = self.name_buffer.len(),
1460 .dirname_len = self.name_buffer.len,
14601461 });
14611462 }
14621463 }
......@@ -1489,9 +1490,11 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {
14891490 var dir = try cwd().openDir(dir_path, .{ .iterate = true });
14901491 errdefer dir.close();
14911492
1492 var name_buffer = try std.Buffer.init(allocator, dir_path);
1493 var name_buffer = std.ArrayList(u8).init(allocator);
14931494 errdefer name_buffer.deinit();
14941495
1496 try name_buffer.appendSlice(dir_path);
1497
14951498 var walker = Walker{
14961499 .stack = std.ArrayList(Walker.StackItem).init(allocator),
14971500 .name_buffer = name_buffer,
lib/std/io/in_stream.zig-1
......@@ -3,7 +3,6 @@ const builtin = std.builtin;
33const math = std.math;
44const assert = std.debug.assert;
55const mem = std.mem;
6const Buffer = std.Buffer;
76const testing = std.testing;
87
98pub fn InStream(
lib/std/net.zig+10-10
......@@ -504,7 +504,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
504504 var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);
505505 defer lookup_addrs.deinit();
506506
507 var canon = std.Buffer.initNull(arena);
507 var canon = std.ArrayListSentineled(u8, 0).initNull(arena);
508508 defer canon.deinit();
509509
510510 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
......@@ -539,7 +539,7 @@ const DAS_ORDER_SHIFT = 0;
539539
540540fn linuxLookupName(
541541 addrs: *std.ArrayList(LookupAddr),
542 canon: *std.Buffer,
542 canon: *std.ArrayListSentineled(u8, 0),
543543 opt_name: ?[]const u8,
544544 family: os.sa_family_t,
545545 flags: u32,
......@@ -798,7 +798,7 @@ fn linuxLookupNameFromNull(
798798
799799fn linuxLookupNameFromHosts(
800800 addrs: *std.ArrayList(LookupAddr),
801 canon: *std.Buffer,
801 canon: *std.ArrayListSentineled(u8, 0),
802802 name: []const u8,
803803 family: os.sa_family_t,
804804 port: u16,
......@@ -868,7 +868,7 @@ pub fn isValidHostName(hostname: []const u8) bool {
868868
869869fn linuxLookupNameFromDnsSearch(
870870 addrs: *std.ArrayList(LookupAddr),
871 canon: *std.Buffer,
871 canon: *std.ArrayListSentineled(u8, 0),
872872 name: []const u8,
873873 family: os.sa_family_t,
874874 port: u16,
......@@ -901,12 +901,12 @@ fn linuxLookupNameFromDnsSearch(
901901 // the full requested name to name_from_dns.
902902 try canon.resize(canon_name.len);
903903 mem.copy(u8, canon.span(), canon_name);
904 try canon.appendByte('.');
904 try canon.append('.');
905905
906906 var tok_it = mem.tokenize(search, " \t");
907907 while (tok_it.next()) |tok| {
908908 canon.shrink(canon_name.len + 1);
909 try canon.append(tok);
909 try canon.appendSlice(tok);
910910 try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);
911911 if (addrs.len != 0) return;
912912 }
......@@ -917,13 +917,13 @@ fn linuxLookupNameFromDnsSearch(
917917
918918const dpc_ctx = struct {
919919 addrs: *std.ArrayList(LookupAddr),
920 canon: *std.Buffer,
920 canon: *std.ArrayListSentineled(u8, 0),
921921 port: u16,
922922};
923923
924924fn linuxLookupNameFromDns(
925925 addrs: *std.ArrayList(LookupAddr),
926 canon: *std.Buffer,
926 canon: *std.ArrayListSentineled(u8, 0),
927927 name: []const u8,
928928 family: os.sa_family_t,
929929 rc: ResolvConf,
......@@ -978,7 +978,7 @@ const ResolvConf = struct {
978978 attempts: u32,
979979 ndots: u32,
980980 timeout: u32,
981 search: std.Buffer,
981 search: std.ArrayListSentineled(u8, 0),
982982 ns: std.ArrayList(LookupAddr),
983983
984984 fn deinit(rc: *ResolvConf) void {
......@@ -993,7 +993,7 @@ const ResolvConf = struct {
993993fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
994994 rc.* = ResolvConf{
995995 .ns = std.ArrayList(LookupAddr).init(allocator),
996 .search = std.Buffer.initNull(allocator),
996 .search = std.ArrayListSentineled(u8, 0).initNull(allocator),
997997 .ndots = 1,
998998 .timeout = 5,
999999 .attempts = 2,
lib/std/std.zig+1-1
......@@ -1,10 +1,10 @@
11pub const AlignedArrayList = @import("array_list.zig").AlignedArrayList;
22pub const ArrayList = @import("array_list.zig").ArrayList;
3pub const ArrayListSentineled = @import("array_list_sentineled.zig").ArrayListSentineled;
34pub const AutoHashMap = @import("hash_map.zig").AutoHashMap;
45pub const BloomFilter = @import("bloom_filter.zig").BloomFilter;
56pub const BufMap = @import("buf_map.zig").BufMap;
67pub const BufSet = @import("buf_set.zig").BufSet;
7pub const Buffer = @import("buffer.zig").Buffer;
88pub const ChildProcess = @import("child_process.zig").ChildProcess;
99pub const DynLib = @import("dynamic_library.zig").DynLib;
1010pub const HashMap = @import("hash_map.zig").HashMap;
lib/std/target.zig+4-4
......@@ -967,15 +967,15 @@ pub const Target = struct {
967967
968968 pub const stack_align = 16;
969969
970 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 {
970 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
971971 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
972972 }
973973
974 pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![:0]u8 {
975 return std.fmt.allocPrint0(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
974 pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
975 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
976976 }
977977
978 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 {
978 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
979979 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
980980 }
981981
lib/std/zig/cross_target.zig+9-7
......@@ -495,17 +495,19 @@ pub const CrossTarget = struct {
495495 return self.isNativeCpu() and self.isNativeOs() and self.abi == null;
496496 }
497497
498 pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 {
498 pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![]u8 {
499499 if (self.isNative()) {
500 return mem.dupeZ(allocator, u8, "native");
500 return mem.dupe(allocator, u8, "native");
501501 }
502502
503503 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
504504 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
505505
506 var result = try std.Buffer.allocPrint(allocator, "{}-{}", .{ arch_name, os_name });
506 var result = std.ArrayList(u8).init(allocator);
507507 defer result.deinit();
508508
509 try result.outStream().print("{}-{}", .{ arch_name, os_name });
510
509511 // The zig target syntax does not allow specifying a max os version with no min, so
510512 // if either are present, we need the min.
511513 if (self.os_version_min != null or self.os_version_max != null) {
......@@ -532,13 +534,13 @@ pub const CrossTarget = struct {
532534 return result.toOwnedSlice();
533535 }
534536
535 pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 {
537 pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
536538 // TODO is there anything else worthy of the description that is not
537539 // already captured in the triple?
538540 return self.zigTriple(allocator);
539541 }
540542
541 pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 {
543 pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
542544 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
543545 }
544546
......@@ -549,7 +551,7 @@ pub const CrossTarget = struct {
549551 pub const VcpkgLinkage = std.builtin.LinkMode;
550552
551553 /// Returned slice must be freed by the caller.
552 pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![:0]u8 {
554 pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![]u8 {
553555 const arch = switch (self.getCpuArch()) {
554556 .i386 => "x86",
555557 .x86_64 => "x64",
......@@ -580,7 +582,7 @@ pub const CrossTarget = struct {
580582 .Dynamic => "",
581583 };
582584
583 return std.fmt.allocPrint0(allocator, "{}-{}{}", .{ arch, os, static_suffix });
585 return std.fmt.allocPrint(allocator, "{}-{}{}", .{ arch, os, static_suffix });
584586 }
585587
586588 pub const Executor = union(enum) {
lib/std/zig/parser_test.zig+1-1
......@@ -2953,7 +2953,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
29532953 return error.ParseError;
29542954 }
29552955
2956 var buffer = try std.Buffer.initSize(allocator, 0);
2956 var buffer = std.ArrayList(u8).init(allocator);
29572957 errdefer buffer.deinit();
29582958
29592959 anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);
src-self-hosted/codegen.zig+2-2
......@@ -45,7 +45,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
4545
4646 // Don't use ZIG_VERSION_STRING here. LLVM misparses it when it includes
4747 // 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 {}.{}.{}", .{
4949 @as(u32, c.ZIG_VERSION_MAJOR),
5050 @as(u32, c.ZIG_VERSION_MINOR),
5151 @as(u32, c.ZIG_VERSION_PATCH),
......@@ -62,7 +62,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
6262 dibuilder,
6363 DW.LANG_C99,
6464 compile_unit_file,
65 producer.span(),
65 producer,
6666 is_optimized,
6767 flags,
6868 runtime_version,
src-self-hosted/compilation.zig+8-8
......@@ -2,7 +2,7 @@ const std = @import("std");
22const io = std.io;
33const mem = std.mem;
44const Allocator = mem.Allocator;
5const Buffer = std.Buffer;
5const ArrayListSentineled = std.ArrayListSentineled;
66const llvm = @import("llvm.zig");
77const c = @import("c.zig");
88const builtin = std.builtin;
......@@ -123,8 +123,8 @@ pub const LlvmHandle = struct {
123123
124124pub const Compilation = struct {
125125 zig_compiler: *ZigCompiler,
126 name: Buffer,
127 llvm_triple: Buffer,
126 name: ArrayListSentineled(u8, 0),
127 llvm_triple: ArrayListSentineled(u8, 0),
128128 root_src_path: ?[]const u8,
129129 target: std.Target,
130130 llvm_target: *llvm.Target,
......@@ -444,7 +444,7 @@ pub const Compilation = struct {
444444 comp.arena_allocator.deinit();
445445 }
446446
447 comp.name = try Buffer.init(comp.arena(), name);
447 comp.name = try ArrayListSentineled(u8, 0).init(comp.arena(), name);
448448 comp.llvm_triple = try util.getLLVMTriple(comp.arena(), target);
449449 comp.llvm_target = try util.llvmTargetFromTriple(comp.llvm_triple);
450450 comp.zig_std_dir = try fs.path.join(comp.arena(), &[_][]const u8{ zig_lib_dir, "std" });
......@@ -1151,7 +1151,7 @@ pub const Compilation = struct {
11511151
11521152 /// If the temporary directory for this compilation has not been created, it creates it.
11531153 /// 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) {
11551155 const tmp_dir = try self.getTmpDir();
11561156 const file_prefix = self.getRandomFileName();
11571157
......@@ -1161,7 +1161,7 @@ pub const Compilation = struct {
11611161 const full_path = try fs.path.join(self.gpa(), &[_][]const u8{ tmp_dir, file_name[0..] });
11621162 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);
11651165 }
11661166
11671167 /// 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 {
12791279 const fn_type = try analyzeFnType(comp, tree_scope, fn_decl.base.parent_scope, fn_decl.fn_proto);
12801280 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);
12831283 var symbol_name_consumed = false;
12841284 errdefer if (!symbol_name_consumed) symbol_name.deinit();
12851285
......@@ -1426,7 +1426,7 @@ fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
14261426 );
14271427 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);
14301430 var symbol_name_consumed = false;
14311431 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 {
3333 break; // advance
3434 },
3535 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) };
3737 },
3838 },
3939 .target => |*target| switch (char) {
......@@ -53,7 +53,7 @@ pub const Tokenizer = struct {
5353 break; // advance
5454 },
5555 else => {
56 try target.appendByte(char);
56 try target.append(char);
5757 break; // advance
5858 },
5959 },
......@@ -62,24 +62,24 @@ pub const Tokenizer = struct {
6262 return self.errorIllegalChar(self.index, char, "bad target escape", .{});
6363 },
6464 ' ', '#', '\\' => {
65 try target.appendByte(char);
65 try target.append(char);
6666 self.state = State{ .target = target.* };
6767 break; // advance
6868 },
6969 '$' => {
70 try target.append(self.bytes[self.index - 1 .. self.index]);
70 try target.appendSlice(self.bytes[self.index - 1 .. self.index]);
7171 self.state = State{ .target_dollar_sign = target.* };
7272 break; // advance
7373 },
7474 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]);
7676 self.state = State{ .target = target.* };
7777 break; // advance
7878 },
7979 },
8080 .target_dollar_sign => |*target| switch (char) {
8181 '$' => {
82 try target.appendByte(char);
82 try target.append(char);
8383 self.state = State{ .target = target.* };
8484 break; // advance
8585 },
......@@ -125,7 +125,7 @@ pub const Tokenizer = struct {
125125 continue;
126126 },
127127 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]);
129129 self.state = State{ .target = target.* };
130130 break;
131131 },
......@@ -144,11 +144,11 @@ pub const Tokenizer = struct {
144144 break; // advance
145145 },
146146 '"' => {
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) };
148148 break; // advance
149149 },
150150 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) };
152152 },
153153 },
154154 .rhs_continuation => switch (char) {
......@@ -181,7 +181,7 @@ pub const Tokenizer = struct {
181181 return Token{ .id = .prereq, .bytes = bytes };
182182 },
183183 else => {
184 try prereq.appendByte(char);
184 try prereq.append(char);
185185 break; // advance
186186 },
187187 },
......@@ -201,7 +201,7 @@ pub const Tokenizer = struct {
201201 break; // advance
202202 },
203203 else => {
204 try prereq.appendByte(char);
204 try prereq.append(char);
205205 break; // advance
206206 },
207207 },
......@@ -218,7 +218,7 @@ pub const Tokenizer = struct {
218218 },
219219 else => {
220220 // 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]);
222222 self.state = State{ .prereq = prereq.* };
223223 break; // advance
224224 },
......@@ -300,25 +300,25 @@ pub const Tokenizer = struct {
300300 }
301301
302302 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);
304304 return Error.InvalidInput;
305305 }
306306
307307 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);
309309 try buffer.outStream().print(fmt, args);
310 try buffer.append(" '");
311 var out = makeOutput(std.Buffer.append, &buffer);
310 try buffer.appendSlice(" '");
311 var out = makeOutput(std.ArrayListSentineled(u8, 0).appendSlice, &buffer);
312312 try printCharValues(&out, bytes);
313 try buffer.append("'");
313 try buffer.appendSlice("'");
314314 try buffer.outStream().print(" at position {}", .{position - (bytes.len - 1)});
315315 self.error_text = buffer.span();
316316 return Error.InvalidInput;
317317 }
318318
319319 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);
321 try buffer.append("illegal char ");
320 var buffer = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0);
321 try buffer.appendSlice("illegal char ");
322322 try printUnderstandableChar(&buffer, char);
323323 try buffer.outStream().print(" at position {}", .{position});
324324 if (fmt.len != 0) try buffer.outStream().print(": " ++ fmt, args);
......@@ -333,18 +333,18 @@ pub const Tokenizer = struct {
333333
334334 const State = union(enum) {
335335 lhs: void,
336 target: std.Buffer,
337 target_reverse_solidus: std.Buffer,
338 target_dollar_sign: std.Buffer,
339 target_colon: std.Buffer,
340 target_colon_reverse_solidus: std.Buffer,
336 target: std.ArrayListSentineled(u8, 0),
337 target_reverse_solidus: std.ArrayListSentineled(u8, 0),
338 target_dollar_sign: std.ArrayListSentineled(u8, 0),
339 target_colon: std.ArrayListSentineled(u8, 0),
340 target_colon_reverse_solidus: std.ArrayListSentineled(u8, 0),
341341 rhs: void,
342342 rhs_continuation: void,
343343 rhs_continuation_linefeed: void,
344 prereq_quote: std.Buffer,
345 prereq: std.Buffer,
346 prereq_continuation: std.Buffer,
347 prereq_continuation_linefeed: std.Buffer,
344 prereq_quote: std.ArrayListSentineled(u8, 0),
345 prereq: std.ArrayListSentineled(u8, 0),
346 prereq_continuation: std.ArrayListSentineled(u8, 0),
347 prereq_continuation_linefeed: std.ArrayListSentineled(u8, 0),
348348 };
349349
350350 const Token = struct {
......@@ -841,28 +841,28 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {
841841 defer arena_allocator.deinit();
842842
843843 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);
845845 var i: usize = 0;
846846 while (true) {
847847 const r = it.next() catch |err| {
848848 switch (err) {
849849 Tokenizer.Error.InvalidInput => {
850 if (i != 0) try buffer.append("\n");
851 try buffer.append("ERROR: ");
852 try buffer.append(it.error_text);
850 if (i != 0) try buffer.appendSlice("\n");
851 try buffer.appendSlice("ERROR: ");
852 try buffer.appendSlice(it.error_text);
853853 },
854854 else => return err,
855855 }
856856 break;
857857 };
858858 const token = r orelse break;
859 if (i != 0) try buffer.append("\n");
860 try buffer.append(@tagName(token.id));
861 try buffer.append(" = {");
859 if (i != 0) try buffer.appendSlice("\n");
860 try buffer.appendSlice(@tagName(token.id));
861 try buffer.appendSlice(" = {");
862862 for (token.bytes) |b| {
863 try buffer.appendByte(printable_char_tab[b]);
863 try buffer.append(printable_char_tab[b]);
864864 }
865 try buffer.append("}");
865 try buffer.appendSlice("}");
866866 i += 1;
867867 }
868868 const got: []const u8 = buffer.span();
......@@ -995,13 +995,13 @@ fn printCharValues(out: var, bytes: []const u8) !void {
995995 }
996996}
997997
998fn printUnderstandableChar(buffer: *std.Buffer, char: u8) !void {
998fn printUnderstandableChar(buffer: *std.ArrayListSentineled(u8, 0), char: u8) !void {
999999 if (!std.ascii.isPrint(char) or char == ' ') {
10001000 try buffer.outStream().print("\\x{X:2}", .{char});
10011001 } else {
1002 try buffer.append("'");
1003 try buffer.appendByte(printable_char_tab[char]);
1004 try buffer.append("'");
1002 try buffer.appendSlice("'");
1003 try buffer.append(printable_char_tab[char]);
1004 try buffer.appendSlice("'");
10051005 }
10061006}
10071007
src-self-hosted/errmsg.zig+2-2
......@@ -158,7 +158,7 @@ pub const Msg = struct {
158158 parse_error: *const ast.Error,
159159 ) !*Msg {
160160 const loc_token = parse_error.loc();
161 var text_buf = try std.Buffer.initSize(comp.gpa(), 0);
161 var text_buf = std.ArrayList(u8).init(comp.gpa());
162162 defer text_buf.deinit();
163163
164164 const realpath_copy = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
......@@ -197,7 +197,7 @@ pub const Msg = struct {
197197 realpath: []const u8,
198198 ) !*Msg {
199199 const loc_token = parse_error.loc();
200 var text_buf = try std.Buffer.initSize(allocator, 0);
200 var text_buf = std.ArrayList(u8).init(allocator);
201201 defer text_buf.deinit();
202202
203203 const realpath_copy = try mem.dupe(allocator, u8, realpath);
src-self-hosted/libc_installation.zig+14-18
......@@ -14,11 +14,11 @@ usingnamespace @import("windows_sdk.zig");
1414
1515/// See the render function implementation for documentation of the fields.
1616pub const LibCInstallation = struct {
17 include_dir: ?[:0]const u8 = null,
18 sys_include_dir: ?[:0]const u8 = null,
19 crt_dir: ?[:0]const u8 = null,
20 msvc_lib_dir: ?[:0]const u8 = null,
21 kernel32_lib_dir: ?[:0]const u8 = null,
17 include_dir: ?[]const u8 = null,
18 sys_include_dir: ?[]const u8 = null,
19 crt_dir: ?[]const u8 = null,
20 msvc_lib_dir: ?[]const u8 = null,
21 kernel32_lib_dir: ?[]const u8 = null,
2222
2323 pub const FindError = error{
2424 OutOfMemory,
......@@ -327,13 +327,12 @@ pub const LibCInstallation = struct {
327327 var search_buf: [2]Search = undefined;
328328 const searches = fillSearch(&search_buf, sdk);
329329
330 var result_buf = try std.Buffer.initSize(allocator, 0);
330 var result_buf = std.ArrayList([]const u8).init(allocator);
331331 defer result_buf.deinit();
332332
333333 for (searches) |search| {
334334 result_buf.shrink(0);
335 const stream = result_buf.outStream();
336 try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
335 try result_buf.outStream().print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
337336
338337 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
339338 error.FileNotFound,
......@@ -367,7 +366,7 @@ pub const LibCInstallation = struct {
367366 var search_buf: [2]Search = undefined;
368367 const searches = fillSearch(&search_buf, sdk);
369368
370 var result_buf = try std.Buffer.initSize(allocator, 0);
369 var result_buf = try std.ArrayList([]const u8).init(allocator);
371370 defer result_buf.deinit();
372371
373372 const arch_sub_dir = switch (builtin.arch) {
......@@ -379,8 +378,7 @@ pub const LibCInstallation = struct {
379378
380379 for (searches) |search| {
381380 result_buf.shrink(0);
382 const stream = result_buf.outStream();
383 try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
381 try result_buf.outStream().print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
384382
385383 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
386384 error.FileNotFound,
......@@ -422,7 +420,7 @@ pub const LibCInstallation = struct {
422420 var search_buf: [2]Search = undefined;
423421 const searches = fillSearch(&search_buf, sdk);
424422
425 var result_buf = try std.Buffer.initSize(allocator, 0);
423 var result_buf = try std.ArrayList([]const u8).init(allocator);
426424 defer result_buf.deinit();
427425
428426 const arch_sub_dir = switch (builtin.arch) {
......@@ -470,12 +468,10 @@ pub const LibCInstallation = struct {
470468 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
471469 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
472470
473 var result_buf = try std.Buffer.init(allocator, up2);
474 defer result_buf.deinit();
475
476 try result_buf.append("\\include");
471 const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });
472 errdefer allocator.free(dir_path);
477473
478 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
474 var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
479475 error.FileNotFound,
480476 error.NotDir,
481477 error.NoDevice,
......@@ -490,7 +486,7 @@ pub const LibCInstallation = struct {
490486 else => return error.FileSystem,
491487 };
492488
493 self.sys_include_dir = result_buf.toOwnedSlice();
489 self.sys_include_dir = dir_path;
494490 }
495491
496492 fn findNativeMsvcLibDir(
src-self-hosted/link.zig+4-4
......@@ -15,10 +15,10 @@ const Context = struct {
1515 link_in_crt: bool,
1616
1717 link_err: error{OutOfMemory}!void,
18 link_msg: std.Buffer,
18 link_msg: std.ArrayListSentineled(u8, 0),
1919
2020 libc: *LibCInstallation,
21 out_file_path: std.Buffer,
21 out_file_path: std.ArrayListSentineled(u8, 0),
2222};
2323
2424pub fn link(comp: *Compilation) !void {
......@@ -34,9 +34,9 @@ pub fn link(comp: *Compilation) !void {
3434 };
3535 defer ctx.arena.deinit();
3636 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());
4040 switch (comp.kind) {
4141 .Exe => {
4242 try ctx.out_file_path.append(comp.target.exeFileExt());
src-self-hosted/package.zig+5-5
......@@ -1,11 +1,11 @@
11const std = @import("std");
22const mem = std.mem;
33const assert = std.debug.assert;
4const Buffer = std.Buffer;
4const ArrayListSentineled = std.ArrayListSentineled;
55
66pub const Package = struct {
7 root_src_dir: Buffer,
8 root_src_path: Buffer,
7 root_src_dir: ArrayListSentineled(u8, 0),
8 root_src_path: ArrayListSentineled(u8, 0),
99
1010 /// relative to root_src_dir
1111 table: Table,
......@@ -17,8 +17,8 @@ pub const Package = struct {
1717 pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
1818 const ptr = try allocator.create(Package);
1919 ptr.* = Package{
20 .root_src_dir = try Buffer.init(allocator, root_src_dir),
21 .root_src_path = try Buffer.init(allocator, root_src_path),
20 .root_src_dir = try ArrayListSentineled(u8, 0).init(allocator, root_src_dir),
21 .root_src_path = try ArrayListSentineled(u8, 0).init(allocator, root_src_path),
2222 .table = Table.init(allocator),
2323 };
2424 return ptr;
src-self-hosted/stage2.zig+32-31
......@@ -8,7 +8,7 @@ const fs = std.fs;
88const process = std.process;
99const Allocator = mem.Allocator;
1010const ArrayList = std.ArrayList;
11const Buffer = std.Buffer;
11const ArrayListSentineled = std.ArrayListSentineled;
1212const Target = std.Target;
1313const CrossTarget = std.zig.CrossTarget;
1414const self_hosted_main = @import("main.zig");
......@@ -411,12 +411,13 @@ fn printErrMsgToFile(
411411 const start_loc = tree.tokenLocationPtr(0, first_token);
412412 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
413413
414 var text_buf = try std.Buffer.initSize(allocator, 0);
415 const out_stream = &text_buf.outStream();
414 var text_buf = std.ArrayList(u8).init(allocator);
415 defer text_buf.deinit();
416 const out_stream = text_buf.outStream();
416417 try parse_error.render(&tree.tokens, out_stream);
417 const text = text_buf.toOwnedSlice();
418 const text = text_buf.span();
418419
419 const stream = &file.outStream();
420 const stream = file.outStream();
420421 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
421422
422423 if (!color_on) return;
......@@ -448,7 +449,7 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
448449
449450export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
450451 const otoken = self.handle.next() catch {
451 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");
452453 return stage2_DepNextResult{
453454 .type_id = .error_,
454455 .textz = textz.span().ptr,
......@@ -460,7 +461,7 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes
460461 .textz = undefined,
461462 };
462463 };
463 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");
464465 return stage2_DepNextResult{
465466 .type_id = switch (token.id) {
466467 .target => .target,
......@@ -740,15 +741,15 @@ fn stage2TargetParse(
740741
741742// ABI warning
742743const Stage2LibCInstallation = extern struct {
743 include_dir: [*:0]const u8,
744 include_dir: [*]const u8,
744745 include_dir_len: usize,
745 sys_include_dir: [*:0]const u8,
746 sys_include_dir: [*]const u8,
746747 sys_include_dir_len: usize,
747 crt_dir: [*:0]const u8,
748 crt_dir: [*]const u8,
748749 crt_dir_len: usize,
749 msvc_lib_dir: [*:0]const u8,
750 msvc_lib_dir: [*]const u8,
750751 msvc_lib_dir_len: usize,
751 kernel32_lib_dir: [*:0]const u8,
752 kernel32_lib_dir: [*]const u8,
752753 kernel32_lib_dir_len: usize,
753754
754755 fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
......@@ -792,19 +793,19 @@ const Stage2LibCInstallation = extern struct {
792793 fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
793794 var libc: LibCInstallation = .{};
794795 if (self.include_dir_len != 0) {
795 libc.include_dir = self.include_dir[0..self.include_dir_len :0];
796 libc.include_dir = self.include_dir[0..self.include_dir_len];
796797 }
797798 if (self.sys_include_dir_len != 0) {
798 libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
799 libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len];
799800 }
800801 if (self.crt_dir_len != 0) {
801 libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
802 libc.crt_dir = self.crt_dir[0..self.crt_dir_len];
802803 }
803804 if (self.msvc_lib_dir_len != 0) {
804 libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
805 libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len];
805806 }
806807 if (self.kernel32_lib_dir_len != 0) {
807 libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
808 libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len];
808809 }
809810 return libc;
810811 }
......@@ -923,14 +924,14 @@ const Stage2Target = extern struct {
923924 var dynamic_linker: ?[*:0]u8 = null;
924925 const target = try crossTargetToTarget(cross_target, &dynamic_linker);
925926
926 var cache_hash = try std.Buffer.allocPrint(allocator, "{}\n{}\n", .{
927 var cache_hash = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, "{}\n{}\n", .{
927928 target.cpu.model.name,
928929 target.cpu.features.asBytes(),
929930 });
930931 defer cache_hash.deinit();
931932
932933 const generic_arch_name = target.cpu.arch.genericName();
933 var cpu_builtin_str_buffer = try std.Buffer.allocPrint(allocator,
934 var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
934935 \\Cpu{{
935936 \\ .arch = .{},
936937 \\ .model = &Target.{}.cpu.{},
......@@ -945,7 +946,7 @@ const Stage2Target = extern struct {
945946 });
946947 defer cpu_builtin_str_buffer.deinit();
947948
948 var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
949 var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
949950 defer llvm_features_buffer.deinit();
950951
951952 // Unfortunately we have to do the work twice, because Clang does not support
......@@ -960,17 +961,17 @@ const Stage2Target = extern struct {
960961
961962 if (feature.llvm_name) |llvm_name| {
962963 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
963 try llvm_features_buffer.appendByte(plus_or_minus);
964 try llvm_features_buffer.append(llvm_name);
965 try llvm_features_buffer.append(",");
964 try llvm_features_buffer.append(plus_or_minus);
965 try llvm_features_buffer.appendSlice(llvm_name);
966 try llvm_features_buffer.appendSlice(",");
966967 }
967968
968969 if (is_enabled) {
969970 // TODO some kind of "zig identifier escape" function rather than
970971 // unconditionally using @"" syntax
971 try cpu_builtin_str_buffer.append(" .@\"");
972 try cpu_builtin_str_buffer.append(feature.name);
973 try cpu_builtin_str_buffer.append("\",\n");
972 try cpu_builtin_str_buffer.appendSlice(" .@\"");
973 try cpu_builtin_str_buffer.appendSlice(feature.name);
974 try cpu_builtin_str_buffer.appendSlice("\",\n");
974975 }
975976 }
976977
......@@ -989,7 +990,7 @@ const Stage2Target = extern struct {
989990 },
990991 }
991992
992 try cpu_builtin_str_buffer.append(
993 try cpu_builtin_str_buffer.appendSlice(
993994 \\ }),
994995 \\};
995996 \\
......@@ -998,7 +999,7 @@ const Stage2Target = extern struct {
998999 assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));
9991000 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
10001001
1001 var os_builtin_str_buffer = try std.Buffer.allocPrint(allocator,
1002 var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
10021003 \\Os{{
10031004 \\ .tag = .{},
10041005 \\ .version_range = .{{
......@@ -1041,7 +1042,7 @@ const Stage2Target = extern struct {
10411042 .emscripten,
10421043 .uefi,
10431044 .other,
1044 => try os_builtin_str_buffer.append(" .none = {} }\n"),
1045 => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"),
10451046
10461047 .freebsd,
10471048 .macosx,
......@@ -1117,9 +1118,9 @@ const Stage2Target = extern struct {
11171118 @tagName(target.os.version_range.windows.max),
11181119 }),
11191120 }
1120 try os_builtin_str_buffer.append("};\n");
1121 try os_builtin_str_buffer.appendSlice("};\n");
11211122
1122 try cache_hash.append(
1123 try cache_hash.appendSlice(
11231124 os_builtin_str_buffer.span()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()],
11241125 );
11251126
src-self-hosted/translate_c.zig+7-7
......@@ -209,7 +209,7 @@ const Scope = struct {
209209
210210pub const Context = struct {
211211 tree: *ast.Tree,
212 source_buffer: *std.Buffer,
212 source_buffer: *std.ArrayList(u8),
213213 err: Error,
214214 source_manager: *ZigClangSourceManager,
215215 decl_table: DeclTable,
......@@ -275,7 +275,7 @@ pub fn translate(
275275
276276 const tree = try tree_arena.allocator.create(ast.Tree);
277277 tree.* = ast.Tree{
278 .source = undefined, // need to use Buffer.toOwnedSlice later
278 .source = undefined, // need to use toOwnedSlice later
279279 .root_node = undefined,
280280 .arena_allocator = tree_arena,
281281 .tokens = undefined, // can't reference the allocator yet
......@@ -296,7 +296,7 @@ pub fn translate(
296296 .eof_token = undefined,
297297 };
298298
299 var source_buffer = try std.Buffer.initSize(arena, 0);
299 var source_buffer = std.ArrayList(u8).init(arena);
300300
301301 var context = Context{
302302 .tree = tree,
......@@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {
43094309 return RestorePoint{
43104310 .c = c,
43114311 .token_index = c.tree.tokens.len,
4312 .src_buf_index = c.source_buffer.len(),
4312 .src_buf_index = c.source_buffer.len,
43134313 };
43144314}
43154315
......@@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
47714771
47724772fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
47734773 assert(token_id != .Invalid);
4774 const start_index = c.source_buffer.len();
4774 const start_index = c.source_buffer.len;
47754775 errdefer c.source_buffer.shrink(start_index);
47764776
47774777 try c.source_buffer.outStream().print(format, args);
4778 const end_index = c.source_buffer.len();
4778 const end_index = c.source_buffer.len;
47794779 const token_index = c.tree.tokens.len;
47804780 const new_token = try c.tree.tokens.addOne();
47814781 errdefer c.tree.tokens.shrink(token_index);
......@@ -4785,7 +4785,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
47854785 .start = start_index,
47864786 .end = end_index,
47874787 };
4788 try c.source_buffer.appendByte(' ');
4788 try c.source_buffer.append(' ');
47894789
47904790 return token_index;
47914791}
src-self-hosted/type.zig+2-2
......@@ -387,10 +387,10 @@ pub const Type = struct {
387387 };
388388 errdefer comp.gpa().destroy(self);
389389
390 var name_buf = try std.Buffer.initSize(comp.gpa(), 0);
390 var name_buf = std.ArrayList(u8).init(comp.gpa());
391391 defer name_buf.deinit();
392392
393 const name_stream = &std.io.BufferOutStream.init(&name_buf).stream;
393 const name_stream = name_buf.outStream();
394394
395395 switch (key.data) {
396396 .Generic => |generic| {
src-self-hosted/util.zig+7-7
......@@ -16,11 +16,11 @@ pub fn getDarwinArchString(self: Target) [:0]const u8 {
1616 }
1717}
1818
19pub fn llvmTargetFromTriple(triple: std.Buffer) !*llvm.Target {
19pub fn llvmTargetFromTriple(triple: [:0]const u8) !*llvm.Target {
2020 var result: *llvm.Target = undefined;
2121 var err_msg: [*:0]u8 = undefined;
22 if (llvm.GetTargetFromTriple(triple.span(), &result, &err_msg) != 0) {
23 std.debug.warn("triple: {s} error: {s}\n", .{ triple.span(), err_msg });
22 if (llvm.GetTargetFromTriple(triple, &result, &err_msg) != 0) {
23 std.debug.warn("triple: {s} error: {s}\n", .{ triple, err_msg });
2424 return error.UnsupportedTarget;
2525 }
2626 return result;
......@@ -34,14 +34,14 @@ pub fn initializeAllTargets() void {
3434 llvm.InitializeAllAsmParsers();
3535}
3636
37pub fn getLLVMTriple(allocator: *std.mem.Allocator, target: std.Target) !std.Buffer {
38 var result = try std.Buffer.initSize(allocator, 0);
39 errdefer result.deinit();
37pub fn getLLVMTriple(allocator: *std.mem.Allocator, target: std.Target) ![:0]u8 {
38 var result = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
39 defer result.deinit();
4040
4141 try result.outStream().print(
4242 "{}-unknown-{}-{}",
4343 .{ @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi) },
4444 );
4545
46 return result;
46 return result.toOwnedSlice();
4747}
src-self-hosted/value.zig+7-7
......@@ -3,7 +3,7 @@ const Scope = @import("scope.zig").Scope;
33const Compilation = @import("compilation.zig").Compilation;
44const ObjectFile = @import("codegen.zig").ObjectFile;
55const llvm = @import("llvm.zig");
6const Buffer = std.Buffer;
6const ArrayListSentineled = std.ArrayListSentineled;
77const assert = std.debug.assert;
88
99/// Values are ref-counted, heap-allocated, and copy-on-write
......@@ -131,9 +131,9 @@ pub const Value = struct {
131131
132132 /// The main external name that is used in the .o file.
133133 /// 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 {
137137 const self = try comp.gpa().create(FnProto);
138138 self.* = FnProto{
139139 .base = Value{
......@@ -171,7 +171,7 @@ pub const Value = struct {
171171
172172 /// The main external name that is used in the .o file.
173173 /// TODO https://github.com/ziglang/zig/issues/265
174 symbol_name: Buffer,
174 symbol_name: ArrayListSentineled(u8, 0),
175175
176176 /// parent should be the top level decls or container decls
177177 fndef_scope: *Scope.FnDef,
......@@ -183,13 +183,13 @@ pub const Value = struct {
183183 block_scope: ?*Scope.Block,
184184
185185 /// Path to the object file that contains this function
186 containing_object: Buffer,
186 containing_object: ArrayListSentineled(u8, 0),
187187
188188 link_set_node: *std.TailQueue(?*Value.Fn).Node,
189189
190190 /// Creates a Fn value with 1 ref
191191 /// 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 {
193193 const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
194194 link_set_node.* = Compilation.FnLinkSet.Node{
195195 .data = null,
......@@ -209,7 +209,7 @@ pub const Value = struct {
209209 .child_scope = &fndef_scope.base,
210210 .block_scope = null,
211211 .symbol_name = symbol_name,
212 .containing_object = Buffer.initNull(comp.gpa()),
212 .containing_object = ArrayListSentineled(u8, 0).initNull(comp.gpa()),
213213 .link_set_node = link_set_node,
214214 };
215215 fn_type.base.base.ref();
src/cache_hash.cpp+7-1
......@@ -27,11 +27,17 @@ void cache_init(CacheHash *ch, Buf *manifest_dir) {
2727void cache_mem(CacheHash *ch, const char *ptr, size_t len) {
2828 assert(ch->manifest_file_path == nullptr);
2929 assert(ptr != nullptr);
30 // + 1 to include the null byte
3130 blake2b_update(&ch->blake, ptr, len);
3231}
3332
33void cache_slice(CacheHash *ch, Slice<const char> slice) {
34 // mix the length into the hash so that two juxtaposed cached slices can't collide
35 cache_usize(ch, slice.len);
36 cache_mem(ch, slice.ptr, slice.len);
37}
38
3439void cache_str(CacheHash *ch, const char *ptr) {
40 // + 1 to include the null byte
3541 cache_mem(ch, ptr, strlen(ptr) + 1);
3642}
3743
src/cache_hash.hpp+1
......@@ -36,6 +36,7 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);
3636
3737// Next, use the hash population functions to add the initial parameters.
3838void cache_mem(CacheHash *ch, const char *ptr, size_t len);
39void cache_slice(CacheHash *ch, Slice<const char> slice);
3940void cache_str(CacheHash *ch, const char *ptr);
4041void cache_int(CacheHash *ch, int x);
4142void cache_bool(CacheHash *ch, bool x);
src/codegen.cpp+19-11
......@@ -9123,21 +9123,29 @@ static void detect_libc(CodeGen *g) {
91239123 g->libc_include_dir_len = 0;
91249124 g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
91259125
9126 g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
9126 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(
9127 g->libc->include_dir, g->libc->include_dir_len));
91279128 g->libc_include_dir_len += 1;
91289129
91299130 if (want_sys_dir) {
9130 g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
9131 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(
9132 g->libc->sys_include_dir, g->libc->sys_include_dir_len));
91319133 g->libc_include_dir_len += 1;
91329134 }
91339135
91349136 if (want_um_and_shared_dirs != 0) {
9135 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
9136 "%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
9137 Buf *include_dir_parent = buf_alloc();
9138 os_path_join(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len),
9139 buf_create_from_str(".."), include_dir_parent);
9140
9141 Buf *buff1 = buf_alloc();
9142 os_path_join(include_dir_parent, buf_create_from_str("um"), buff1);
9143 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff1);
91379144 g->libc_include_dir_len += 1;
91389145
9139 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
9140 "%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
9146 Buf *buff2 = buf_alloc();
9147 os_path_join(include_dir_parent, buf_create_from_str("shared"), buff2);
9148 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff2);
91419149 g->libc_include_dir_len += 1;
91429150 }
91439151 assert(g->libc_include_dir_len == dir_count);
......@@ -10546,11 +10554,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1054610554 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
1054710555 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
1054810556 if (g->libc) {
10549 cache_str(ch, g->libc->include_dir);
10550 cache_str(ch, g->libc->sys_include_dir);
10551 cache_str(ch, g->libc->crt_dir);
10552 cache_str(ch, g->libc->msvc_lib_dir);
10553 cache_str(ch, g->libc->kernel32_lib_dir);
10557 cache_slice(ch, Slice<const char>{g->libc->include_dir, g->libc->include_dir_len});
10558 cache_slice(ch, Slice<const char>{g->libc->sys_include_dir, g->libc->sys_include_dir_len});
10559 cache_slice(ch, Slice<const char>{g->libc->crt_dir, g->libc->crt_dir_len});
10560 cache_slice(ch, Slice<const char>{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len});
10561 cache_slice(ch, Slice<const char>{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len});
1055410562 }
1055510563 cache_buf_opt(ch, g->version_script_path);
1055610564 cache_buf_opt(ch, g->override_soname);
src/link.cpp+20-7
......@@ -1595,7 +1595,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
15951595 } else {
15961596 assert(parent->libc != nullptr);
15971597 Buf *out_buf = buf_alloc();
1598 os_path_join(buf_create_from_str(parent->libc->crt_dir), buf_create_from_str(file), out_buf);
1598 os_path_join(buf_create_from_mem(parent->libc->crt_dir, parent->libc->crt_dir_len),
1599 buf_create_from_str(file), out_buf);
15991600 return buf_ptr(out_buf);
16001601 }
16011602}
......@@ -1860,7 +1861,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
18601861 if (g->libc_link_lib != nullptr) {
18611862 if (g->libc != nullptr) {
18621863 lj->args.append("-L");
1863 lj->args.append(g->libc->crt_dir);
1864 lj->args.append(buf_ptr(buf_create_from_mem(g->libc->crt_dir, g->libc->crt_dir_len)));
18641865 }
18651866
18661867 if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
......@@ -2381,14 +2382,26 @@ static void construct_linker_job_coff(LinkJob *lj) {
23812382 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
23822383
23832384 if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2384 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
2385 Buf *buff0 = buf_create_from_str("-LIBPATH:");
2386 buf_append_mem(buff0, g->libc->crt_dir, g->libc->crt_dir_len);
2387 lj->args.append(buf_ptr(buff0));
23852388
23862389 if (target_abi_is_gnu(g->zig_target->abi)) {
2387 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));
2388 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));
2390 Buf *buff1 = buf_create_from_str("-LIBPATH:");
2391 buf_append_mem(buff1, g->libc->sys_include_dir, g->libc->sys_include_dir_len);
2392 lj->args.append(buf_ptr(buff1));
2393
2394 Buf *buff2 = buf_create_from_str("-LIBPATH:");
2395 buf_append_mem(buff2, g->libc->include_dir, g->libc->include_dir_len);
2396 lj->args.append(buf_ptr(buff2));
23892397 } else {
2390 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));
2391 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));
2398 Buf *buff1 = buf_create_from_str("-LIBPATH:");
2399 buf_append_mem(buff1, g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len);
2400 lj->args.append(buf_ptr(buff1));
2401
2402 Buf *buff2 = buf_create_from_str("-LIBPATH:");
2403 buf_append_mem(buff2, g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len);
2404 lj->args.append(buf_ptr(buff2));
23922405 }
23932406 }
23942407
test/standalone/brace_expansion/main.zig+16-16
......@@ -4,7 +4,7 @@ const mem = std.mem;
44const debug = std.debug;
55const assert = debug.assert;
66const testing = std.testing;
7const Buffer = std.Buffer;
7const ArrayListSentineled = std.ArrayListSentineled;
88const ArrayList = std.ArrayList;
99const maxInt = std.math.maxInt;
1010
......@@ -111,7 +111,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
111111 }
112112}
113113
114fn expandString(input: []const u8, output: *Buffer) !void {
114fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
115115 const tokens = try tokenize(input);
116116 if (tokens.len == 1) {
117117 return output.resize(0);
......@@ -125,7 +125,7 @@ fn expandString(input: []const u8, output: *Buffer) !void {
125125 else => return error.InvalidInput,
126126 }
127127
128 var result_list = ArrayList(Buffer).init(global_allocator);
128 var result_list = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
129129 defer result_list.deinit();
130130
131131 try expandNode(root, &result_list);
......@@ -133,41 +133,41 @@ fn expandString(input: []const u8, output: *Buffer) !void {
133133 try output.resize(0);
134134 for (result_list.span()) |buf, i| {
135135 if (i != 0) {
136 try output.appendByte(' ');
136 try output.append(' ');
137137 }
138 try output.append(buf.span());
138 try output.appendSlice(buf.span());
139139 }
140140}
141141
142142const ExpandNodeError = error{OutOfMemory};
143143
144fn expandNode(node: Node, output: *ArrayList(Buffer)) ExpandNodeError!void {
144fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void {
145145 assert(output.len == 0);
146146 switch (node) {
147147 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));
149149 },
150150 Node.Combine => |pair| {
151151 const a_node = pair[0];
152152 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);
155155 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);
158158 try expandNode(b_node, &child_list_b);
159159
160160 for (child_list_a.span()) |buf_a| {
161161 for (child_list_b.span()) |buf_b| {
162 var combined_buf = try Buffer.initFromBuffer(buf_a);
163 try combined_buf.append(buf_b.span());
162 var combined_buf = try ArrayListSentineled(u8, 0).initFromBuffer(buf_a);
163 try combined_buf.appendSlice(buf_b.span());
164164 try output.append(combined_buf);
165165 }
166166 }
167167 },
168168 Node.List => |list| {
169169 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);
171171 try expandNode(child_node, &child_list);
172172
173173 for (child_list.span()) |buf| {
......@@ -187,13 +187,13 @@ pub fn main() !void {
187187
188188 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);
191191 defer stdin_buf.deinit();
192192
193193 var stdin_adapter = stdin_file.inStream();
194194 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);
197197 defer result_buf.deinit();
198198
199199 try expandString(stdin_buf.span(), &result_buf);
......@@ -218,7 +218,7 @@ test "invalid inputs" {
218218}
219219
220220fn 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;
222222 defer output_buf.deinit();
223223
224224 testing.expectError(expected_err, expandString(test_input, &output_buf));
......@@ -251,7 +251,7 @@ test "valid inputs" {
251251}
252252
253253fn 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;
255255 defer result.deinit();
256256
257257 expandString(test_input, &result) catch unreachable;
test/tests.zig+9-10
......@@ -4,7 +4,6 @@ const debug = std.debug;
44const warn = debug.warn;
55const build = std.build;
66const CrossTarget = std.zig.CrossTarget;
7const Buffer = std.Buffer;
87const io = std.io;
98const fs = std.fs;
109const mem = std.mem;
......@@ -640,7 +639,7 @@ pub const StackTracesContext = struct {
640639 // - replace address with symbolic string
641640 // - skip empty lines
642641 const got: []const u8 = got_result: {
643 var buf = try Buffer.initSize(b.allocator, 0);
642 var buf = ArrayList(u8).init(b.allocator);
644643 defer buf.deinit();
645644 if (stderr.len != 0 and stderr[stderr.len - 1] == '\n') stderr = stderr[0 .. stderr.len - 1];
646645 var it = mem.separate(stderr, "\n");
......@@ -652,21 +651,21 @@ pub const StackTracesContext = struct {
652651 var pos: usize = if (std.Target.current.os.tag == .windows) 2 else 0;
653652 for (delims) |delim, i| {
654653 marks[i] = mem.indexOfPos(u8, line, pos, delim) orelse {
655 try buf.append(line);
656 try buf.append("\n");
654 try buf.appendSlice(line);
655 try buf.appendSlice("\n");
657656 continue :process_lines;
658657 };
659658 pos = marks[i] + delim.len;
660659 }
661660 pos = mem.lastIndexOfScalar(u8, line[0..marks[0]], fs.path.sep) orelse {
662 try buf.append(line);
663 try buf.append("\n");
661 try buf.appendSlice(line);
662 try buf.appendSlice("\n");
664663 continue :process_lines;
665664 };
666 try buf.append(line[pos + 1 .. marks[2] + delims[2].len]);
667 try buf.append(" [address]");
668 try buf.append(line[marks[3]..]);
669 try buf.append("\n");
665 try buf.appendSlice(line[pos + 1 .. marks[2] + delims[2].len]);
666 try buf.appendSlice(" [address]");
667 try buf.appendSlice(line[marks[3]..]);
668 try buf.appendSlice("\n");
670669 }
671670 break :got_result buf.toOwnedSlice();
672671 };