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 {...@@ -321,7 +321,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
321 var last_action = Action.Open;321 var last_action = Action.Open;
322 var last_columns: ?u8 = null;322 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);
325 defer toc_buf.deinit();325 defer toc_buf.deinit();
326326
327 var toc = toc_buf.outStream();327 var toc = toc_buf.outStream();
...@@ -607,7 +607,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {...@@ -607,7 +607,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
607}607}
608608
609fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {609fn 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);
611 defer buf.deinit();611 defer buf.deinit();
612612
613 const out = buf.outStream();613 const out = buf.outStream();
...@@ -626,7 +626,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {...@@ -626,7 +626,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
626}626}
627627
628fn escapeHtml(allocator: *mem.Allocator, input: []const u8) ![]u8 {628fn 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);
630 defer buf.deinit();630 defer buf.deinit();
631631
632 const out = buf.outStream();632 const out = buf.outStream();
...@@ -672,7 +672,7 @@ test "term color" {...@@ -672,7 +672,7 @@ test "term color" {
672}672}
673673
674fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {674fn 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);
676 defer buf.deinit();676 defer buf.deinit();
677677
678 var out = buf.outStream();678 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 {...@@ -189,16 +189,30 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
189 self.len += items.len;189 self.len += items.len;
190 }190 }
191191
192 /// Append a value to the list `n` times. Allocates more memory192 /// Same as `append` except it returns the number of bytes written, which is always the same
193 /// as necessary.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.
194 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {208 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
195 const old_len = self.len;209 const old_len = self.len;
196 try self.resize(self.len + n);210 try self.resize(self.len + n);
197 mem.set(T, self.items[old_len..self.len], value);211 mem.set(T, self.items[old_len..self.len], value);
198 }212 }
199213
200 /// Adjust the list's length to `new_len`. Doesn't initialize214 /// Adjust the list's length to `new_len`.
201 /// added items if any.215 /// Does not initialize added items if any.
202 pub fn resize(self: *Self, new_len: usize) !void {216 pub fn resize(self: *Self, new_len: usize) !void {
203 try self.ensureCapacity(new_len);217 try self.ensureCapacity(new_len);
204 self.len = new_len;218 self.len = new_len;
...@@ -479,3 +493,14 @@ test "std.ArrayList: ArrayList(T) of struct T" {...@@ -479,3 +493,14 @@ test "std.ArrayList: ArrayList(T) of struct T" {
479 try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.allocator) });493 try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.allocator) });
480 testing.expect(root.sub_items.items[0].integer == 42);494 testing.expect(root.sub_items.items[0].integer == 42);
481}495}
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 {...@@ -1139,7 +1139,7 @@ pub const LibExeObjStep = struct {
1139 out_lib_filename: []const u8,1139 out_lib_filename: []const u8,
1140 out_pdb_filename: []const u8,1140 out_pdb_filename: []const u8,
1141 packages: ArrayList(Pkg),1141 packages: ArrayList(Pkg),
1142 build_options_contents: std.Buffer,1142 build_options_contents: std.ArrayList(u8),
1143 system_linker_hack: bool = false,1143 system_linker_hack: bool = false,
11441144
1145 object_src: []const u8,1145 object_src: []const u8,
...@@ -1274,7 +1274,7 @@ pub const LibExeObjStep = struct {...@@ -1274,7 +1274,7 @@ pub const LibExeObjStep = struct {
1274 .lib_paths = ArrayList([]const u8).init(builder.allocator),1274 .lib_paths = ArrayList([]const u8).init(builder.allocator),
1275 .framework_dirs = ArrayList([]const u8).init(builder.allocator),1275 .framework_dirs = ArrayList([]const u8).init(builder.allocator),
1276 .object_src = undefined,1276 .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),
1278 .c_std = Builder.CStd.C99,1278 .c_std = Builder.CStd.C99,
1279 .override_lib_dir = null,1279 .override_lib_dir = null,
1280 .main_pkg_path = null,1280 .main_pkg_path = null,
...@@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {...@@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {
1847 }1847 }
1848 }1848 }
18491849
1850 if (self.build_options_contents.len() > 0) {1850 if (self.build_options_contents.len > 0) {
1851 const build_options_file = try fs.path.join(1851 const build_options_file = try fs.path.join(
1852 builder.allocator,1852 builder.allocator,
1853 &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },1853 &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
...@@ -1960,22 +1960,22 @@ pub const LibExeObjStep = struct {...@@ -1960,22 +1960,22 @@ pub const LibExeObjStep = struct {
1960 try zig_args.append(cross.cpu.model.name);1960 try zig_args.append(cross.cpu.model.name);
1961 }1961 }
1962 } else {1962 } else {
1963 var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");1963 var mcpu_buffer = std.ArrayList(u8).init(builder.allocator);
1964 try mcpu_buffer.append(cross.cpu.model.name);1964
1965 try mcpu_buffer.outStream().print("-mcpu={}", .{cross.cpu.model.name});
19651966
1966 for (all_features) |feature, i_usize| {1967 for (all_features) |feature, i_usize| {
1967 const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);1968 const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);
1968 const in_cpu_set = populated_cpu_features.isEnabled(i);1969 const in_cpu_set = populated_cpu_features.isEnabled(i);
1969 const in_actual_set = cross.cpu.features.isEnabled(i);1970 const in_actual_set = cross.cpu.features.isEnabled(i);
1970 if (in_cpu_set and !in_actual_set) {1971 if (in_cpu_set and !in_actual_set) {
1971 try mcpu_buffer.appendByte('-');1972 try mcpu_buffer.outStream().print("-{}", .{feature.name});
1972 try mcpu_buffer.append(feature.name);
1973 } else if (!in_cpu_set and in_actual_set) {1973 } else if (!in_cpu_set and in_actual_set) {
1974 try mcpu_buffer.appendByte('+');1974 try mcpu_buffer.outStream().print("+{}", .{feature.name});
1975 try mcpu_buffer.append(feature.name);
1976 }1975 }
1977 }1976 }
1978 try zig_args.append(mcpu_buffer.span());1977
1978 try zig_args.append(mcpu_buffer.toOwnedSlice());
1979 }1979 }
19801980
1981 if (self.target.dynamic_linker.get()) |dynamic_linker| {1981 if (self.target.dynamic_linker.get()) |dynamic_linker| {
lib/std/child_process.zig+10-12
...@@ -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;
...@@ -757,38 +757,36 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1...@@ -757,38 +757,36 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1
757}757}
758758
759/// Caller must dealloc.759/// Caller must dealloc.
760/// Guarantees a null byte at result[result.len].760fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 {
761fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![]u8 {761 var buf = try ArrayListSentineled(u8, 0).initSize(allocator, 0);
762 var buf = try Buffer.initSize(allocator, 0);
763 defer buf.deinit();762 defer buf.deinit();
764763 const buf_stream = buf.outStream();
765 var buf_stream = buf.outStream();
766764
767 for (argv) |arg, arg_i| {765 for (argv) |arg, arg_i| {
768 if (arg_i != 0) try buf.appendByte(' ');766 if (arg_i != 0) try buf_stream.writeByte(' ');
769 if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {767 if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
770 try buf.append(arg);768 try buf_stream.writeAll(arg);
771 continue;769 continue;
772 }770 }
773 try buf.appendByte('"');771 try buf_stream.writeByte('"');
774 var backslash_count: usize = 0;772 var backslash_count: usize = 0;
775 for (arg) |byte| {773 for (arg) |byte| {
776 switch (byte) {774 switch (byte) {
777 '\\' => backslash_count += 1,775 '\\' => backslash_count += 1,
778 '"' => {776 '"' => {
779 try buf_stream.writeByteNTimes('\\', backslash_count * 2 + 1);777 try buf_stream.writeByteNTimes('\\', backslash_count * 2 + 1);
780 try buf.appendByte('"');778 try buf_stream.writeByte('"');
781 backslash_count = 0;779 backslash_count = 0;
782 },780 },
783 else => {781 else => {
784 try buf_stream.writeByteNTimes('\\', backslash_count);782 try buf_stream.writeByteNTimes('\\', backslash_count);
785 try buf.appendByte(byte);783 try buf_stream.writeByte(byte);
786 backslash_count = 0;784 backslash_count = 0;
787 },785 },
788 }786 }
789 }787 }
790 try buf_stream.writeByteNTimes('\\', backslash_count * 2);788 try buf_stream.writeByteNTimes('\\', backslash_count * 2);
791 try buf.appendByte('"');789 try buf_stream.writeByte('"');
792 }790 }
793791
794 return buf.toOwnedSlice();792 return buf.toOwnedSlice();
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;
lib/std/target.zig+4-4
...@@ -967,15 +967,15 @@ pub const Target = struct {...@@ -967,15 +967,15 @@ pub const Target = struct {
967967
968 pub const stack_align = 16;968 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 {
971 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);971 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
972 }972 }
973973
974 pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![:0]u8 {974 pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
975 return std.fmt.allocPrint0(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });975 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
976 }976 }
977977
978 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 {978 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
979 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);979 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
980 }980 }
981981
lib/std/zig/cross_target.zig+9-7
...@@ -495,17 +495,19 @@ pub const CrossTarget = struct {...@@ -495,17 +495,19 @@ pub const CrossTarget = struct {
495 return self.isNativeCpu() and self.isNativeOs() and self.abi == null;495 return self.isNativeCpu() and self.isNativeOs() and self.abi == null;
496 }496 }
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 {
499 if (self.isNative()) {499 if (self.isNative()) {
500 return mem.dupeZ(allocator, u8, "native");500 return mem.dupe(allocator, u8, "native");
501 }501 }
502502
503 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";503 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
504 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";504 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);
507 defer result.deinit();507 defer result.deinit();
508508
509 try result.outStream().print("{}-{}", .{ arch_name, os_name });
510
509 // The zig target syntax does not allow specifying a max os version with no min, so511 // The zig target syntax does not allow specifying a max os version with no min, so
510 // if either are present, we need the min.512 // if either are present, we need the min.
511 if (self.os_version_min != null or self.os_version_max != null) {513 if (self.os_version_min != null or self.os_version_max != null) {
...@@ -532,13 +534,13 @@ pub const CrossTarget = struct {...@@ -532,13 +534,13 @@ pub const CrossTarget = struct {
532 return result.toOwnedSlice();534 return result.toOwnedSlice();
533 }535 }
534536
535 pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 {537 pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
536 // TODO is there anything else worthy of the description that is not538 // TODO is there anything else worthy of the description that is not
537 // already captured in the triple?539 // already captured in the triple?
538 return self.zigTriple(allocator);540 return self.zigTriple(allocator);
539 }541 }
540542
541 pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 {543 pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
542 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());544 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
543 }545 }
544546
...@@ -549,7 +551,7 @@ pub const CrossTarget = struct {...@@ -549,7 +551,7 @@ pub const CrossTarget = struct {
549 pub const VcpkgLinkage = std.builtin.LinkMode;551 pub const VcpkgLinkage = std.builtin.LinkMode;
550552
551 /// Returned slice must be freed by the caller.553 /// 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 {
553 const arch = switch (self.getCpuArch()) {555 const arch = switch (self.getCpuArch()) {
554 .i386 => "x86",556 .i386 => "x86",
555 .x86_64 => "x64",557 .x86_64 => "x64",
...@@ -580,7 +582,7 @@ pub const CrossTarget = struct {...@@ -580,7 +582,7 @@ pub const CrossTarget = struct {
580 .Dynamic => "",582 .Dynamic => "",
581 };583 };
582584
583 return std.fmt.allocPrint0(allocator, "{}-{}{}", .{ arch, os, static_suffix });585 return std.fmt.allocPrint(allocator, "{}-{}{}", .{ arch, os, static_suffix });
584 }586 }
585587
586 pub const Executor = union(enum) {588 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...@@ -2953,7 +2953,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
2953 return error.ParseError;2953 return error.ParseError;
2954 }2954 }
29552955
2956 var buffer = try std.Buffer.initSize(allocator, 0);2956 var buffer = std.ArrayList(u8).init(allocator);
2957 errdefer buffer.deinit();2957 errdefer buffer.deinit();
29582958
2959 anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);2959 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)...@@ -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/errmsg.zig+2-2
...@@ -158,7 +158,7 @@ pub const Msg = struct {...@@ -158,7 +158,7 @@ pub const Msg = struct {
158 parse_error: *const ast.Error,158 parse_error: *const ast.Error,
159 ) !*Msg {159 ) !*Msg {
160 const loc_token = parse_error.loc();160 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());
162 defer text_buf.deinit();162 defer text_buf.deinit();
163163
164 const realpath_copy = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);164 const realpath_copy = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
...@@ -197,7 +197,7 @@ pub const Msg = struct {...@@ -197,7 +197,7 @@ pub const Msg = struct {
197 realpath: []const u8,197 realpath: []const u8,
198 ) !*Msg {198 ) !*Msg {
199 const loc_token = parse_error.loc();199 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);
201 defer text_buf.deinit();201 defer text_buf.deinit();
202202
203 const realpath_copy = try mem.dupe(allocator, u8, realpath);203 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");...@@ -14,11 +14,11 @@ usingnamespace @import("windows_sdk.zig");
1414
15/// See the render function implementation for documentation of the fields.15/// See the render function implementation for documentation of the fields.
16pub const LibCInstallation = struct {16pub const LibCInstallation = struct {
17 include_dir: ?[:0]const u8 = null,17 include_dir: ?[]const u8 = null,
18 sys_include_dir: ?[:0]const u8 = null,18 sys_include_dir: ?[]const u8 = null,
19 crt_dir: ?[:0]const u8 = null,19 crt_dir: ?[]const u8 = null,
20 msvc_lib_dir: ?[:0]const u8 = null,20 msvc_lib_dir: ?[]const u8 = null,
21 kernel32_lib_dir: ?[:0]const u8 = null,21 kernel32_lib_dir: ?[]const u8 = null,
2222
23 pub const FindError = error{23 pub const FindError = error{
24 OutOfMemory,24 OutOfMemory,
...@@ -327,13 +327,12 @@ pub const LibCInstallation = struct {...@@ -327,13 +327,12 @@ pub const LibCInstallation = struct {
327 var search_buf: [2]Search = undefined;327 var search_buf: [2]Search = undefined;
328 const searches = fillSearch(&search_buf, sdk);328 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);
331 defer result_buf.deinit();331 defer result_buf.deinit();
332332
333 for (searches) |search| {333 for (searches) |search| {
334 result_buf.shrink(0);334 result_buf.shrink(0);
335 const stream = result_buf.outStream();335 try result_buf.outStream().print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
336 try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
337336
338 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {337 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
339 error.FileNotFound,338 error.FileNotFound,
...@@ -367,7 +366,7 @@ pub const LibCInstallation = struct {...@@ -367,7 +366,7 @@ pub const LibCInstallation = struct {
367 var search_buf: [2]Search = undefined;366 var search_buf: [2]Search = undefined;
368 const searches = fillSearch(&search_buf, sdk);367 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);
371 defer result_buf.deinit();370 defer result_buf.deinit();
372371
373 const arch_sub_dir = switch (builtin.arch) {372 const arch_sub_dir = switch (builtin.arch) {
...@@ -379,8 +378,7 @@ pub const LibCInstallation = struct {...@@ -379,8 +378,7 @@ pub const LibCInstallation = struct {
379378
380 for (searches) |search| {379 for (searches) |search| {
381 result_buf.shrink(0);380 result_buf.shrink(0);
382 const stream = result_buf.outStream();381 try result_buf.outStream().print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
383 try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
384382
385 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {383 var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
386 error.FileNotFound,384 error.FileNotFound,
...@@ -422,7 +420,7 @@ pub const LibCInstallation = struct {...@@ -422,7 +420,7 @@ pub const LibCInstallation = struct {
422 var search_buf: [2]Search = undefined;420 var search_buf: [2]Search = undefined;
423 const searches = fillSearch(&search_buf, sdk);421 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);
426 defer result_buf.deinit();424 defer result_buf.deinit();
427425
428 const arch_sub_dir = switch (builtin.arch) {426 const arch_sub_dir = switch (builtin.arch) {
...@@ -470,12 +468,10 @@ pub const LibCInstallation = struct {...@@ -470,12 +468,10 @@ pub const LibCInstallation = struct {
470 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;468 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
471 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;469 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
472470
473 var result_buf = try std.Buffer.init(allocator, up2);471 const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });
474 defer result_buf.deinit();472 errdefer allocator.free(dir_path);
475
476 try result_buf.append("\\include");
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) {
479 error.FileNotFound,475 error.FileNotFound,
480 error.NotDir,476 error.NotDir,
481 error.NoDevice,477 error.NoDevice,
...@@ -490,7 +486,7 @@ pub const LibCInstallation = struct {...@@ -490,7 +486,7 @@ pub const LibCInstallation = struct {
490 else => return error.FileSystem,486 else => return error.FileSystem,
491 };487 };
492488
493 self.sys_include_dir = result_buf.toOwnedSlice();489 self.sys_include_dir = dir_path;
494 }490 }
495491
496 fn findNativeMsvcLibDir(492 fn findNativeMsvcLibDir(
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+32-31
...@@ -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");
...@@ -411,12 +411,13 @@ fn printErrMsgToFile(...@@ -411,12 +411,13 @@ fn printErrMsgToFile(
411 const start_loc = tree.tokenLocationPtr(0, first_token);411 const start_loc = tree.tokenLocationPtr(0, first_token);
412 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);412 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
413413
414 var text_buf = try std.Buffer.initSize(allocator, 0);414 var text_buf = std.ArrayList(u8).init(allocator);
415 const out_stream = &text_buf.outStream();415 defer text_buf.deinit();
416 const out_stream = text_buf.outStream();
416 try parse_error.render(&tree.tokens, out_stream);417 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();
420 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });421 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
421422
422 if (!color_on) return;423 if (!color_on) return;
...@@ -448,7 +449,7 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {...@@ -448,7 +449,7 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
448449
449export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {450export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
450 const otoken = self.handle.next() catch {451 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");
452 return stage2_DepNextResult{453 return stage2_DepNextResult{
453 .type_id = .error_,454 .type_id = .error_,
454 .textz = textz.span().ptr,455 .textz = textz.span().ptr,
...@@ -460,7 +461,7 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes...@@ -460,7 +461,7 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes
460 .textz = undefined,461 .textz = undefined,
461 };462 };
462 };463 };
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");
464 return stage2_DepNextResult{465 return stage2_DepNextResult{
465 .type_id = switch (token.id) {466 .type_id = switch (token.id) {
466 .target => .target,467 .target => .target,
...@@ -740,15 +741,15 @@ fn stage2TargetParse(...@@ -740,15 +741,15 @@ fn stage2TargetParse(
740741
741// ABI warning742// ABI warning
742const Stage2LibCInstallation = extern struct {743const Stage2LibCInstallation = extern struct {
743 include_dir: [*:0]const u8,744 include_dir: [*]const u8,
744 include_dir_len: usize,745 include_dir_len: usize,
745 sys_include_dir: [*:0]const u8,746 sys_include_dir: [*]const u8,
746 sys_include_dir_len: usize,747 sys_include_dir_len: usize,
747 crt_dir: [*:0]const u8,748 crt_dir: [*]const u8,
748 crt_dir_len: usize,749 crt_dir_len: usize,
749 msvc_lib_dir: [*:0]const u8,750 msvc_lib_dir: [*]const u8,
750 msvc_lib_dir_len: usize,751 msvc_lib_dir_len: usize,
751 kernel32_lib_dir: [*:0]const u8,752 kernel32_lib_dir: [*]const u8,
752 kernel32_lib_dir_len: usize,753 kernel32_lib_dir_len: usize,
753754
754 fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {755 fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
...@@ -792,19 +793,19 @@ const Stage2LibCInstallation = extern struct {...@@ -792,19 +793,19 @@ const Stage2LibCInstallation = extern struct {
792 fn toStage2(self: Stage2LibCInstallation) LibCInstallation {793 fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
793 var libc: LibCInstallation = .{};794 var libc: LibCInstallation = .{};
794 if (self.include_dir_len != 0) {795 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];
796 }797 }
797 if (self.sys_include_dir_len != 0) {798 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];
799 }800 }
800 if (self.crt_dir_len != 0) {801 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];
802 }803 }
803 if (self.msvc_lib_dir_len != 0) {804 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];
805 }806 }
806 if (self.kernel32_lib_dir_len != 0) {807 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];
808 }809 }
809 return libc;810 return libc;
810 }811 }
...@@ -923,14 +924,14 @@ const Stage2Target = extern struct {...@@ -923,14 +924,14 @@ const Stage2Target = extern struct {
923 var dynamic_linker: ?[*:0]u8 = null;924 var dynamic_linker: ?[*:0]u8 = null;
924 const target = try crossTargetToTarget(cross_target, &dynamic_linker);925 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", .{
927 target.cpu.model.name,928 target.cpu.model.name,
928 target.cpu.features.asBytes(),929 target.cpu.features.asBytes(),
929 });930 });
930 defer cache_hash.deinit();931 defer cache_hash.deinit();
931932
932 const generic_arch_name = target.cpu.arch.genericName();933 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,
934 \\Cpu{{935 \\Cpu{{
935 \\ .arch = .{},936 \\ .arch = .{},
936 \\ .model = &Target.{}.cpu.{},937 \\ .model = &Target.{}.cpu.{},
...@@ -945,7 +946,7 @@ const Stage2Target = extern struct {...@@ -945,7 +946,7 @@ const Stage2Target = extern struct {
945 });946 });
946 defer cpu_builtin_str_buffer.deinit();947 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);
949 defer llvm_features_buffer.deinit();950 defer llvm_features_buffer.deinit();
950951
951 // 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
...@@ -960,17 +961,17 @@ const Stage2Target = extern struct {...@@ -960,17 +961,17 @@ const Stage2Target = extern struct {
960961
961 if (feature.llvm_name) |llvm_name| {962 if (feature.llvm_name) |llvm_name| {
962 const plus_or_minus = "-+"[@boolToInt(is_enabled)];963 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
963 try llvm_features_buffer.appendByte(plus_or_minus);964 try llvm_features_buffer.append(plus_or_minus);
964 try llvm_features_buffer.append(llvm_name);965 try llvm_features_buffer.appendSlice(llvm_name);
965 try llvm_features_buffer.append(",");966 try llvm_features_buffer.appendSlice(",");
966 }967 }
967968
968 if (is_enabled) {969 if (is_enabled) {
969 // TODO some kind of "zig identifier escape" function rather than970 // TODO some kind of "zig identifier escape" function rather than
970 // unconditionally using @"" syntax971 // unconditionally using @"" syntax
971 try cpu_builtin_str_buffer.append(" .@\"");972 try cpu_builtin_str_buffer.appendSlice(" .@\"");
972 try cpu_builtin_str_buffer.append(feature.name);973 try cpu_builtin_str_buffer.appendSlice(feature.name);
973 try cpu_builtin_str_buffer.append("\",\n");974 try cpu_builtin_str_buffer.appendSlice("\",\n");
974 }975 }
975 }976 }
976977
...@@ -989,7 +990,7 @@ const Stage2Target = extern struct {...@@ -989,7 +990,7 @@ const Stage2Target = extern struct {
989 },990 },
990 }991 }
991992
992 try cpu_builtin_str_buffer.append(993 try cpu_builtin_str_buffer.appendSlice(
993 \\ }),994 \\ }),
994 \\};995 \\};
995 \\996 \\
...@@ -998,7 +999,7 @@ const Stage2Target = extern struct {...@@ -998,7 +999,7 @@ const Stage2Target = extern struct {
998 assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));999 assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));
999 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);1000 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,
1002 \\Os{{1003 \\Os{{
1003 \\ .tag = .{},1004 \\ .tag = .{},
1004 \\ .version_range = .{{1005 \\ .version_range = .{{
...@@ -1041,7 +1042,7 @@ const Stage2Target = extern struct {...@@ -1041,7 +1042,7 @@ const Stage2Target = extern struct {
1041 .emscripten,1042 .emscripten,
1042 .uefi,1043 .uefi,
1043 .other,1044 .other,
1044 => try os_builtin_str_buffer.append(" .none = {} }\n"),1045 => try os_builtin_str_buffer.appendSlice(" .none = {} }\n"),
10451046
1046 .freebsd,1047 .freebsd,
1047 .macosx,1048 .macosx,
...@@ -1117,9 +1118,9 @@ const Stage2Target = extern struct {...@@ -1117,9 +1118,9 @@ const Stage2Target = extern struct {
1117 @tagName(target.os.version_range.windows.max),1118 @tagName(target.os.version_range.windows.max),
1118 }),1119 }),
1119 }1120 }
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(
1123 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()],
1124 );1125 );
11251126
src-self-hosted/translate_c.zig+7-7
...@@ -209,7 +209,7 @@ const Scope = struct {...@@ -209,7 +209,7 @@ const Scope = struct {
209209
210pub const Context = struct {210pub const Context = struct {
211 tree: *ast.Tree,211 tree: *ast.Tree,
212 source_buffer: *std.Buffer,212 source_buffer: *std.ArrayList(u8),
213 err: Error,213 err: Error,
214 source_manager: *ZigClangSourceManager,214 source_manager: *ZigClangSourceManager,
215 decl_table: DeclTable,215 decl_table: DeclTable,
...@@ -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
...@@ -296,7 +296,7 @@ pub fn translate(...@@ -296,7 +296,7 @@ pub fn translate(
296 .eof_token = undefined,296 .eof_token = undefined,
297 };297 };
298298
299 var source_buffer = try std.Buffer.initSize(arena, 0);299 var source_buffer = std.ArrayList(u8).init(arena);
300300
301 var context = Context{301 var context = Context{
302 .tree = tree,302 .tree = tree,
...@@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {...@@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {
4309 return RestorePoint{4309 return RestorePoint{
4310 .c = c,4310 .c = c,
4311 .token_index = c.tree.tokens.len,4311 .token_index = c.tree.tokens.len,
4312 .src_buf_index = c.source_buffer.len(),4312 .src_buf_index = c.source_buffer.len,
4313 };4313 };
4314}4314}
43154315
...@@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd...@@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
47714771
4772fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {4772fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
4773 assert(token_id != .Invalid);4773 assert(token_id != .Invalid);
4774 const start_index = c.source_buffer.len();4774 const start_index = c.source_buffer.len;
4775 errdefer c.source_buffer.shrink(start_index);4775 errdefer c.source_buffer.shrink(start_index);
47764776
4777 try c.source_buffer.outStream().print(format, args);4777 try c.source_buffer.outStream().print(format, args);
4778 const end_index = c.source_buffer.len();4778 const end_index = c.source_buffer.len;
4779 const token_index = c.tree.tokens.len;4779 const token_index = c.tree.tokens.len;
4780 const new_token = try c.tree.tokens.addOne();4780 const new_token = try c.tree.tokens.addOne();
4781 errdefer c.tree.tokens.shrink(token_index);4781 errdefer c.tree.tokens.shrink(token_index);
...@@ -4785,7 +4785,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,...@@ -4785,7 +4785,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
4785 .start = start_index,4785 .start = start_index,
4786 .end = end_index,4786 .end = end_index,
4787 };4787 };
4788 try c.source_buffer.appendByte(' ');4788 try c.source_buffer.append(' ');
47894789
4790 return token_index;4790 return token_index;
4791}4791}
src-self-hosted/type.zig+2-2
...@@ -387,10 +387,10 @@ pub const Type = struct {...@@ -387,10 +387,10 @@ pub const Type = struct {
387 };387 };
388 errdefer comp.gpa().destroy(self);388 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());
391 defer name_buf.deinit();391 defer name_buf.deinit();
392392
393 const name_stream = &std.io.BufferOutStream.init(&name_buf).stream;393 const name_stream = name_buf.outStream();
394394
395 switch (key.data) {395 switch (key.data) {
396 .Generic => |generic| {396 .Generic => |generic| {
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();
src/cache_hash.cpp+7-1
...@@ -27,11 +27,17 @@ void cache_init(CacheHash *ch, Buf *manifest_dir) {...@@ -27,11 +27,17 @@ void cache_init(CacheHash *ch, Buf *manifest_dir) {
27void cache_mem(CacheHash *ch, const char *ptr, size_t len) {27void cache_mem(CacheHash *ch, const char *ptr, size_t len) {
28 assert(ch->manifest_file_path == nullptr);28 assert(ch->manifest_file_path == nullptr);
29 assert(ptr != nullptr);29 assert(ptr != nullptr);
30 // + 1 to include the null byte
31 blake2b_update(&ch->blake, ptr, len);30 blake2b_update(&ch->blake, ptr, len);
32}31}
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
34void cache_str(CacheHash *ch, const char *ptr) {39void cache_str(CacheHash *ch, const char *ptr) {
40 // + 1 to include the null byte
35 cache_mem(ch, ptr, strlen(ptr) + 1);41 cache_mem(ch, ptr, strlen(ptr) + 1);
36}42}
3743
src/cache_hash.hpp+1
...@@ -36,6 +36,7 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);...@@ -36,6 +36,7 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);
3636
37// Next, use the hash population functions to add the initial parameters.37// Next, use the hash population functions to add the initial parameters.
38void cache_mem(CacheHash *ch, const char *ptr, size_t len);38void cache_mem(CacheHash *ch, const char *ptr, size_t len);
39void cache_slice(CacheHash *ch, Slice<const char> slice);
39void cache_str(CacheHash *ch, const char *ptr);40void cache_str(CacheHash *ch, const char *ptr);
40void cache_int(CacheHash *ch, int x);41void cache_int(CacheHash *ch, int x);
41void cache_bool(CacheHash *ch, bool x);42void cache_bool(CacheHash *ch, bool x);
src/codegen.cpp+19-11
...@@ -9123,21 +9123,29 @@ static void detect_libc(CodeGen *g) {...@@ -9123,21 +9123,29 @@ static void detect_libc(CodeGen *g) {
9123 g->libc_include_dir_len = 0;9123 g->libc_include_dir_len = 0;
9124 g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);9124 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));
9127 g->libc_include_dir_len += 1;9128 g->libc_include_dir_len += 1;
91289129
9129 if (want_sys_dir) {9130 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));
9131 g->libc_include_dir_len += 1;9133 g->libc_include_dir_len += 1;
9132 }9134 }
91339135
9134 if (want_um_and_shared_dirs != 0) {9136 if (want_um_and_shared_dirs != 0) {
9135 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(9137 Buf *include_dir_parent = buf_alloc();
9136 "%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));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);
9137 g->libc_include_dir_len += 1;9144 g->libc_include_dir_len += 1;
91389145
9139 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(9146 Buf *buff2 = buf_alloc();
9140 "%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));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);
9141 g->libc_include_dir_len += 1;9149 g->libc_include_dir_len += 1;
9142 }9150 }
9143 assert(g->libc_include_dir_len == dir_count);9151 assert(g->libc_include_dir_len == dir_count);
...@@ -10546,11 +10554,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10546,11 +10554,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10546 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);10554 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
10547 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);10555 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
10548 if (g->libc) {10556 if (g->libc) {
10549 cache_str(ch, g->libc->include_dir);10557 cache_slice(ch, Slice<const char>{g->libc->include_dir, g->libc->include_dir_len});
10550 cache_str(ch, g->libc->sys_include_dir);10558 cache_slice(ch, Slice<const char>{g->libc->sys_include_dir, g->libc->sys_include_dir_len});
10551 cache_str(ch, g->libc->crt_dir);10559 cache_slice(ch, Slice<const char>{g->libc->crt_dir, g->libc->crt_dir_len});
10552 cache_str(ch, g->libc->msvc_lib_dir);10560 cache_slice(ch, Slice<const char>{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len});
10553 cache_str(ch, g->libc->kernel32_lib_dir);10561 cache_slice(ch, Slice<const char>{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len});
10554 }10562 }
10555 cache_buf_opt(ch, g->version_script_path);10563 cache_buf_opt(ch, g->version_script_path);
10556 cache_buf_opt(ch, g->override_soname);10564 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...@@ -1595,7 +1595,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1595 } else {1595 } else {
1596 assert(parent->libc != nullptr);1596 assert(parent->libc != nullptr);
1597 Buf *out_buf = buf_alloc();1597 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);
1599 return buf_ptr(out_buf);1600 return buf_ptr(out_buf);
1600 }1601 }
1601}1602}
...@@ -1860,7 +1861,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1860,7 +1861,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1860 if (g->libc_link_lib != nullptr) {1861 if (g->libc_link_lib != nullptr) {
1861 if (g->libc != nullptr) {1862 if (g->libc != nullptr) {
1862 lj->args.append("-L");1863 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)));
1864 }1865 }
18651866
1866 if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {1867 if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
...@@ -2381,14 +2382,26 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -2381,14 +2382,26 @@ static void construct_linker_job_coff(LinkJob *lj) {
2381 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));2382 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
23822383
2383 if (g->libc_link_lib != nullptr && g->libc != nullptr) {2384 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
2386 if (target_abi_is_gnu(g->zig_target->abi)) {2389 if (target_abi_is_gnu(g->zig_target->abi)) {
2387 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));2390 Buf *buff1 = buf_create_from_str("-LIBPATH:");
2388 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));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));
2389 } else {2397 } else {
2390 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));2398 Buf *buff1 = buf_create_from_str("-LIBPATH:");
2391 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));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));
2392 }2405 }
2393 }2406 }
23942407
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 };