mirror of
https://github.com/ziglang/zig.git
synced 2025-12-27 08:33:15 +00:00
commit
c2e8788259
@ -321,7 +321,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
var last_action = Action.Open;
|
||||
var last_columns: ?u8 = null;
|
||||
|
||||
var toc_buf = try std.Buffer.initSize(allocator, 0);
|
||||
var toc_buf = std.ArrayList(u8).init(allocator);
|
||||
defer toc_buf.deinit();
|
||||
|
||||
var toc = toc_buf.outStream();
|
||||
@ -607,7 +607,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
}
|
||||
|
||||
fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
var buf = std.ArrayList(u8).init(allocator);
|
||||
defer buf.deinit();
|
||||
|
||||
const out = buf.outStream();
|
||||
@ -626,7 +626,7 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
||||
}
|
||||
|
||||
fn escapeHtml(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
var buf = std.ArrayList(u8).init(allocator);
|
||||
defer buf.deinit();
|
||||
|
||||
const out = buf.outStream();
|
||||
@ -672,7 +672,7 @@ test "term color" {
|
||||
}
|
||||
|
||||
fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
var buf = std.ArrayList(u8).init(allocator);
|
||||
defer buf.deinit();
|
||||
|
||||
var out = buf.outStream();
|
||||
|
||||
@ -189,16 +189,30 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
|
||||
self.len += items.len;
|
||||
}
|
||||
|
||||
/// Append a value to the list `n` times. Allocates more memory
|
||||
/// as necessary.
|
||||
/// Same as `append` except it returns the number of bytes written, which is always the same
|
||||
/// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
|
||||
/// This function may be called only when `T` is `u8`.
|
||||
fn appendWrite(self: *Self, m: []const u8) !usize {
|
||||
try self.appendSlice(m);
|
||||
return m.len;
|
||||
}
|
||||
|
||||
/// Initializes an OutStream which will append to the list.
|
||||
/// This function may be called only when `T` is `u8`.
|
||||
pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) {
|
||||
return .{ .context = self };
|
||||
}
|
||||
|
||||
/// Append a value to the list `n` times.
|
||||
/// Allocates more memory as necessary.
|
||||
pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
|
||||
const old_len = self.len;
|
||||
try self.resize(self.len + n);
|
||||
mem.set(T, self.items[old_len..self.len], value);
|
||||
}
|
||||
|
||||
/// Adjust the list's length to `new_len`. Doesn't initialize
|
||||
/// added items if any.
|
||||
/// Adjust the list's length to `new_len`.
|
||||
/// Does not initialize added items if any.
|
||||
pub fn resize(self: *Self, new_len: usize) !void {
|
||||
try self.ensureCapacity(new_len);
|
||||
self.len = new_len;
|
||||
@ -479,3 +493,14 @@ test "std.ArrayList: ArrayList(T) of struct T" {
|
||||
try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.allocator) });
|
||||
testing.expect(root.sub_items.items[0].integer == 42);
|
||||
}
|
||||
|
||||
test "std.ArrayList(u8) implements outStream" {
|
||||
var buffer = ArrayList(u8).init(std.testing.allocator);
|
||||
defer buffer.deinit();
|
||||
|
||||
const x: i32 = 42;
|
||||
const y: i32 = 1234;
|
||||
try buffer.outStream().print("x: {}\ny: {}\n", .{ x, y });
|
||||
|
||||
testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.span());
|
||||
}
|
||||
|
||||
224
lib/std/array_list_sentineled.zig
Normal file
224
lib/std/array_list_sentineled.zig
Normal file
@ -0,0 +1,224 @@
|
||||
const std = @import("std.zig");
|
||||
const debug = std.debug;
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
const assert = debug.assert;
|
||||
const testing = std.testing;
|
||||
const ArrayList = std.ArrayList;
|
||||
|
||||
/// A contiguous, growable list of items in memory, with a sentinel after them.
|
||||
/// The sentinel is maintained when appending, resizing, etc.
|
||||
/// If you do not need a sentinel, consider using `ArrayList` instead.
|
||||
pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
|
||||
return struct {
|
||||
list: ArrayList(T),
|
||||
|
||||
const Self = @This();
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init(allocator: *Allocator, m: []const T) !Self {
|
||||
var self = try initSize(allocator, m.len);
|
||||
mem.copy(T, self.list.items, m);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Initialize memory to size bytes of undefined values.
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initSize(allocator: *Allocator, size: usize) !Self {
|
||||
var self = initNull(allocator);
|
||||
try self.resize(size);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Initialize with capacity to hold at least num bytes.
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
|
||||
var self = Self{ .list = try ArrayList(T).initCapacity(allocator, num + 1) };
|
||||
self.list.appendAssumeCapacity(sentinel);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
/// None of the other operations are valid until you do one of these:
|
||||
/// * `replaceContents`
|
||||
/// * `resize`
|
||||
pub fn initNull(allocator: *Allocator) Self {
|
||||
return Self{ .list = ArrayList(T).init(allocator) };
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initFromBuffer(buffer: Self) !Self {
|
||||
return Self.init(buffer.list.allocator, buffer.span());
|
||||
}
|
||||
|
||||
/// Takes ownership of the passed in slice. The slice must have been
|
||||
/// allocated with `allocator`.
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn fromOwnedSlice(allocator: *Allocator, slice: []T) !Self {
|
||||
var self = Self{ .list = ArrayList(T).fromOwnedSlice(allocator, slice) };
|
||||
try self.list.append(sentinel);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// The caller owns the returned memory. The list becomes null and is safe to `deinit`.
|
||||
pub fn toOwnedSlice(self: *Self) [:sentinel]T {
|
||||
const allocator = self.list.allocator;
|
||||
const result = self.list.toOwnedSlice();
|
||||
self.* = initNull(allocator);
|
||||
return result[0 .. result.len - 1 :sentinel];
|
||||
}
|
||||
|
||||
/// Only works when `T` is `u8`.
|
||||
pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Self {
|
||||
const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) {
|
||||
error.Overflow => return error.OutOfMemory,
|
||||
};
|
||||
var self = try Self.initSize(allocator, size);
|
||||
assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size);
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.list.deinit();
|
||||
}
|
||||
|
||||
pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :sentinel]) {
|
||||
return self.list.span()[0..self.len() :sentinel];
|
||||
}
|
||||
|
||||
pub fn shrink(self: *Self, new_len: usize) void {
|
||||
assert(new_len <= self.len());
|
||||
self.list.shrink(new_len + 1);
|
||||
self.list.items[self.len()] = sentinel;
|
||||
}
|
||||
|
||||
pub fn resize(self: *Self, new_len: usize) !void {
|
||||
try self.list.resize(new_len + 1);
|
||||
self.list.items[self.len()] = sentinel;
|
||||
}
|
||||
|
||||
pub fn isNull(self: Self) bool {
|
||||
return self.list.len == 0;
|
||||
}
|
||||
|
||||
pub fn len(self: Self) usize {
|
||||
return self.list.len - 1;
|
||||
}
|
||||
|
||||
pub fn capacity(self: Self) usize {
|
||||
return if (self.list.items.len > 0)
|
||||
self.list.items.len - 1
|
||||
else
|
||||
0;
|
||||
}
|
||||
|
||||
pub fn appendSlice(self: *Self, m: []const T) !void {
|
||||
const old_len = self.len();
|
||||
try self.resize(old_len + m.len);
|
||||
mem.copy(T, self.list.span()[old_len..], m);
|
||||
}
|
||||
|
||||
pub fn append(self: *Self, byte: T) !void {
|
||||
const old_len = self.len();
|
||||
try self.resize(old_len + 1);
|
||||
self.list.span()[old_len] = byte;
|
||||
}
|
||||
|
||||
pub fn eql(self: Self, m: []const T) bool {
|
||||
return mem.eql(T, self.span(), m);
|
||||
}
|
||||
|
||||
pub fn startsWith(self: Self, m: []const T) bool {
|
||||
if (self.len() < m.len) return false;
|
||||
return mem.eql(T, self.list.items[0..m.len], m);
|
||||
}
|
||||
|
||||
pub fn endsWith(self: Self, m: []const T) bool {
|
||||
const l = self.len();
|
||||
if (l < m.len) return false;
|
||||
const start = l - m.len;
|
||||
return mem.eql(T, self.list.items[start..l], m);
|
||||
}
|
||||
|
||||
pub fn replaceContents(self: *Self, m: []const T) !void {
|
||||
try self.resize(m.len);
|
||||
mem.copy(T, self.list.span(), m);
|
||||
}
|
||||
|
||||
/// Initializes an OutStream which will append to the list.
|
||||
/// This function may be called only when `T` is `u8`.
|
||||
pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) {
|
||||
return .{ .context = self };
|
||||
}
|
||||
|
||||
/// Same as `append` except it returns the number of bytes written, which is always the same
|
||||
/// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
|
||||
/// This function may be called only when `T` is `u8`.
|
||||
pub fn appendWrite(self: *Self, m: []const u8) !usize {
|
||||
try self.appendSlice(m);
|
||||
return m.len;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "simple" {
|
||||
var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
|
||||
defer buf.deinit();
|
||||
|
||||
testing.expect(buf.len() == 0);
|
||||
try buf.appendSlice("hello");
|
||||
try buf.appendSlice(" ");
|
||||
try buf.appendSlice("world");
|
||||
testing.expect(buf.eql("hello world"));
|
||||
testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span()));
|
||||
|
||||
var buf2 = try ArrayListSentineled(u8, 0).initFromBuffer(buf);
|
||||
defer buf2.deinit();
|
||||
testing.expect(buf.eql(buf2.span()));
|
||||
|
||||
testing.expect(buf.startsWith("hell"));
|
||||
testing.expect(buf.endsWith("orld"));
|
||||
|
||||
try buf2.resize(4);
|
||||
testing.expect(buf.startsWith(buf2.span()));
|
||||
}
|
||||
|
||||
test "initSize" {
|
||||
var buf = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 3);
|
||||
defer buf.deinit();
|
||||
testing.expect(buf.len() == 3);
|
||||
try buf.appendSlice("hello");
|
||||
testing.expect(mem.eql(u8, buf.span()[3..], "hello"));
|
||||
}
|
||||
|
||||
test "initCapacity" {
|
||||
var buf = try ArrayListSentineled(u8, 0).initCapacity(testing.allocator, 10);
|
||||
defer buf.deinit();
|
||||
testing.expect(buf.len() == 0);
|
||||
testing.expect(buf.capacity() >= 10);
|
||||
const old_cap = buf.capacity();
|
||||
try buf.appendSlice("hello");
|
||||
testing.expect(buf.len() == 5);
|
||||
testing.expect(buf.capacity() == old_cap);
|
||||
testing.expect(mem.eql(u8, buf.span(), "hello"));
|
||||
}
|
||||
|
||||
test "print" {
|
||||
var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
|
||||
defer buf.deinit();
|
||||
|
||||
try buf.outStream().print("Hello {} the {}", .{ 2, "world" });
|
||||
testing.expect(buf.eql("Hello 2 the world"));
|
||||
}
|
||||
|
||||
test "outStream" {
|
||||
var buffer = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 0);
|
||||
defer buffer.deinit();
|
||||
const buf_stream = buffer.outStream();
|
||||
|
||||
const x: i32 = 42;
|
||||
const y: i32 = 1234;
|
||||
try buf_stream.print("x: {}\ny: {}\n", .{ x, y });
|
||||
|
||||
testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n"));
|
||||
}
|
||||
@ -1,218 +0,0 @@
|
||||
const std = @import("std.zig");
|
||||
const debug = std.debug;
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
const assert = debug.assert;
|
||||
const testing = std.testing;
|
||||
const ArrayList = std.ArrayList;
|
||||
|
||||
/// A buffer that allocates memory and maintains a null byte at the end.
|
||||
pub const Buffer = struct {
|
||||
list: ArrayList(u8),
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init(allocator: *Allocator, m: []const u8) !Buffer {
|
||||
var self = try initSize(allocator, m.len);
|
||||
mem.copy(u8, self.list.items, m);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Initialize memory to size bytes of undefined values.
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initSize(allocator: *Allocator, size: usize) !Buffer {
|
||||
var self = initNull(allocator);
|
||||
try self.resize(size);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Initialize with capacity to hold at least num bytes.
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initCapacity(allocator: *Allocator, num: usize) !Buffer {
|
||||
var self = Buffer{ .list = try ArrayList(u8).initCapacity(allocator, num + 1) };
|
||||
self.list.appendAssumeCapacity(0);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
/// None of the other operations are valid until you do one of these:
|
||||
/// * ::replaceContents
|
||||
/// * ::resize
|
||||
pub fn initNull(allocator: *Allocator) Buffer {
|
||||
return Buffer{ .list = ArrayList(u8).init(allocator) };
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initFromBuffer(buffer: Buffer) !Buffer {
|
||||
return Buffer.init(buffer.list.allocator, buffer.span());
|
||||
}
|
||||
|
||||
/// Buffer takes ownership of the passed in slice. The slice must have been
|
||||
/// allocated with `allocator`.
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn fromOwnedSlice(allocator: *Allocator, slice: []u8) !Buffer {
|
||||
var self = Buffer{ .list = ArrayList(u8).fromOwnedSlice(allocator, slice) };
|
||||
try self.list.append(0);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// The caller owns the returned memory. The Buffer becomes null and
|
||||
/// is safe to `deinit`.
|
||||
pub fn toOwnedSlice(self: *Buffer) [:0]u8 {
|
||||
const allocator = self.list.allocator;
|
||||
const result = self.list.toOwnedSlice();
|
||||
self.* = initNull(allocator);
|
||||
return result[0 .. result.len - 1 :0];
|
||||
}
|
||||
|
||||
pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer {
|
||||
const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) {
|
||||
error.Overflow => return error.OutOfMemory,
|
||||
};
|
||||
var self = try Buffer.initSize(allocator, size);
|
||||
assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size);
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Buffer) void {
|
||||
self.list.deinit();
|
||||
}
|
||||
|
||||
pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :0]) {
|
||||
return self.list.span()[0..self.len() :0];
|
||||
}
|
||||
|
||||
pub const toSlice = @compileError("deprecated; use span()");
|
||||
pub const toSliceConst = @compileError("deprecated; use span()");
|
||||
|
||||
pub fn shrink(self: *Buffer, new_len: usize) void {
|
||||
assert(new_len <= self.len());
|
||||
self.list.shrink(new_len + 1);
|
||||
self.list.items[self.len()] = 0;
|
||||
}
|
||||
|
||||
pub fn resize(self: *Buffer, new_len: usize) !void {
|
||||
try self.list.resize(new_len + 1);
|
||||
self.list.items[self.len()] = 0;
|
||||
}
|
||||
|
||||
pub fn isNull(self: Buffer) bool {
|
||||
return self.list.len == 0;
|
||||
}
|
||||
|
||||
pub fn len(self: Buffer) usize {
|
||||
return self.list.len - 1;
|
||||
}
|
||||
|
||||
pub fn capacity(self: Buffer) usize {
|
||||
return if (self.list.items.len > 0)
|
||||
self.list.items.len - 1
|
||||
else
|
||||
0;
|
||||
}
|
||||
|
||||
pub fn append(self: *Buffer, m: []const u8) !void {
|
||||
const old_len = self.len();
|
||||
try self.resize(old_len + m.len);
|
||||
mem.copy(u8, self.list.span()[old_len..], m);
|
||||
}
|
||||
|
||||
pub fn appendByte(self: *Buffer, byte: u8) !void {
|
||||
const old_len = self.len();
|
||||
try self.resize(old_len + 1);
|
||||
self.list.span()[old_len] = byte;
|
||||
}
|
||||
|
||||
pub fn eql(self: Buffer, m: []const u8) bool {
|
||||
return mem.eql(u8, self.span(), m);
|
||||
}
|
||||
|
||||
pub fn startsWith(self: Buffer, m: []const u8) bool {
|
||||
if (self.len() < m.len) return false;
|
||||
return mem.eql(u8, self.list.items[0..m.len], m);
|
||||
}
|
||||
|
||||
pub fn endsWith(self: Buffer, m: []const u8) bool {
|
||||
const l = self.len();
|
||||
if (l < m.len) return false;
|
||||
const start = l - m.len;
|
||||
return mem.eql(u8, self.list.items[start..l], m);
|
||||
}
|
||||
|
||||
pub fn replaceContents(self: *Buffer, m: []const u8) !void {
|
||||
try self.resize(m.len);
|
||||
mem.copy(u8, self.list.span(), m);
|
||||
}
|
||||
|
||||
pub fn outStream(self: *Buffer) std.io.OutStream(*Buffer, error{OutOfMemory}, appendWrite) {
|
||||
return .{ .context = self };
|
||||
}
|
||||
|
||||
/// Same as `append` except it returns the number of bytes written, which is always the same
|
||||
/// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
|
||||
pub fn appendWrite(self: *Buffer, m: []const u8) !usize {
|
||||
try self.append(m);
|
||||
return m.len;
|
||||
}
|
||||
};
|
||||
|
||||
test "simple Buffer" {
|
||||
var buf = try Buffer.init(testing.allocator, "");
|
||||
defer buf.deinit();
|
||||
|
||||
testing.expect(buf.len() == 0);
|
||||
try buf.append("hello");
|
||||
try buf.append(" ");
|
||||
try buf.append("world");
|
||||
testing.expect(buf.eql("hello world"));
|
||||
testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span()));
|
||||
|
||||
var buf2 = try Buffer.initFromBuffer(buf);
|
||||
defer buf2.deinit();
|
||||
testing.expect(buf.eql(buf2.span()));
|
||||
|
||||
testing.expect(buf.startsWith("hell"));
|
||||
testing.expect(buf.endsWith("orld"));
|
||||
|
||||
try buf2.resize(4);
|
||||
testing.expect(buf.startsWith(buf2.span()));
|
||||
}
|
||||
|
||||
test "Buffer.initSize" {
|
||||
var buf = try Buffer.initSize(testing.allocator, 3);
|
||||
defer buf.deinit();
|
||||
testing.expect(buf.len() == 3);
|
||||
try buf.append("hello");
|
||||
testing.expect(mem.eql(u8, buf.span()[3..], "hello"));
|
||||
}
|
||||
|
||||
test "Buffer.initCapacity" {
|
||||
var buf = try Buffer.initCapacity(testing.allocator, 10);
|
||||
defer buf.deinit();
|
||||
testing.expect(buf.len() == 0);
|
||||
testing.expect(buf.capacity() >= 10);
|
||||
const old_cap = buf.capacity();
|
||||
try buf.append("hello");
|
||||
testing.expect(buf.len() == 5);
|
||||
testing.expect(buf.capacity() == old_cap);
|
||||
testing.expect(mem.eql(u8, buf.span(), "hello"));
|
||||
}
|
||||
|
||||
test "Buffer.print" {
|
||||
var buf = try Buffer.init(testing.allocator, "");
|
||||
defer buf.deinit();
|
||||
|
||||
try buf.outStream().print("Hello {} the {}", .{ 2, "world" });
|
||||
testing.expect(buf.eql("Hello 2 the world"));
|
||||
}
|
||||
|
||||
test "Buffer.outStream" {
|
||||
var buffer = try Buffer.initSize(testing.allocator, 0);
|
||||
defer buffer.deinit();
|
||||
const buf_stream = buffer.outStream();
|
||||
|
||||
const x: i32 = 42;
|
||||
const y: i32 = 1234;
|
||||
try buf_stream.print("x: {}\ny: {}\n", .{ x, y });
|
||||
|
||||
testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n"));
|
||||
}
|
||||
@ -1139,7 +1139,7 @@ pub const LibExeObjStep = struct {
|
||||
out_lib_filename: []const u8,
|
||||
out_pdb_filename: []const u8,
|
||||
packages: ArrayList(Pkg),
|
||||
build_options_contents: std.Buffer,
|
||||
build_options_contents: std.ArrayList(u8),
|
||||
system_linker_hack: bool = false,
|
||||
|
||||
object_src: []const u8,
|
||||
@ -1274,7 +1274,7 @@ pub const LibExeObjStep = struct {
|
||||
.lib_paths = ArrayList([]const u8).init(builder.allocator),
|
||||
.framework_dirs = ArrayList([]const u8).init(builder.allocator),
|
||||
.object_src = undefined,
|
||||
.build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable,
|
||||
.build_options_contents = std.ArrayList(u8).init(builder.allocator),
|
||||
.c_std = Builder.CStd.C99,
|
||||
.override_lib_dir = null,
|
||||
.main_pkg_path = null,
|
||||
@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (self.build_options_contents.len() > 0) {
|
||||
if (self.build_options_contents.len > 0) {
|
||||
const build_options_file = try fs.path.join(
|
||||
builder.allocator,
|
||||
&[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
|
||||
@ -1960,22 +1960,22 @@ pub const LibExeObjStep = struct {
|
||||
try zig_args.append(cross.cpu.model.name);
|
||||
}
|
||||
} else {
|
||||
var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");
|
||||
try mcpu_buffer.append(cross.cpu.model.name);
|
||||
var mcpu_buffer = std.ArrayList(u8).init(builder.allocator);
|
||||
|
||||
try mcpu_buffer.outStream().print("-mcpu={}", .{cross.cpu.model.name});
|
||||
|
||||
for (all_features) |feature, i_usize| {
|
||||
const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);
|
||||
const in_cpu_set = populated_cpu_features.isEnabled(i);
|
||||
const in_actual_set = cross.cpu.features.isEnabled(i);
|
||||
if (in_cpu_set and !in_actual_set) {
|
||||
try mcpu_buffer.appendByte('-');
|
||||
try mcpu_buffer.append(feature.name);
|
||||
try mcpu_buffer.outStream().print("-{}", .{feature.name});
|
||||
} else if (!in_cpu_set and in_actual_set) {
|
||||
try mcpu_buffer.appendByte('+');
|
||||
try mcpu_buffer.append(feature.name);
|
||||
try mcpu_buffer.outStream().print("+{}", .{feature.name});
|
||||
}
|
||||
}
|
||||
try zig_args.append(mcpu_buffer.span());
|
||||
|
||||
try zig_args.append(mcpu_buffer.toOwnedSlice());
|
||||
}
|
||||
|
||||
if (self.target.dynamic_linker.get()) |dynamic_linker| {
|
||||
|
||||
@ -10,7 +10,7 @@ const windows = os.windows;
|
||||
const mem = std.mem;
|
||||
const debug = std.debug;
|
||||
const BufMap = std.BufMap;
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayListSentineled = std.ArrayListSentineled;
|
||||
const builtin = @import("builtin");
|
||||
const Os = builtin.Os;
|
||||
const TailQueue = std.TailQueue;
|
||||
@ -757,38 +757,36 @@ fn windowsCreateProcess(app_name: [*:0]u16, cmd_line: [*:0]u16, envp_ptr: ?[*]u1
|
||||
}
|
||||
|
||||
/// Caller must dealloc.
|
||||
/// Guarantees a null byte at result[result.len].
|
||||
fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![]u8 {
|
||||
var buf = try Buffer.initSize(allocator, 0);
|
||||
fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 {
|
||||
var buf = try ArrayListSentineled(u8, 0).initSize(allocator, 0);
|
||||
defer buf.deinit();
|
||||
|
||||
var buf_stream = buf.outStream();
|
||||
const buf_stream = buf.outStream();
|
||||
|
||||
for (argv) |arg, arg_i| {
|
||||
if (arg_i != 0) try buf.appendByte(' ');
|
||||
if (arg_i != 0) try buf_stream.writeByte(' ');
|
||||
if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
|
||||
try buf.append(arg);
|
||||
try buf_stream.writeAll(arg);
|
||||
continue;
|
||||
}
|
||||
try buf.appendByte('"');
|
||||
try buf_stream.writeByte('"');
|
||||
var backslash_count: usize = 0;
|
||||
for (arg) |byte| {
|
||||
switch (byte) {
|
||||
'\\' => backslash_count += 1,
|
||||
'"' => {
|
||||
try buf_stream.writeByteNTimes('\\', backslash_count * 2 + 1);
|
||||
try buf.appendByte('"');
|
||||
try buf_stream.writeByte('"');
|
||||
backslash_count = 0;
|
||||
},
|
||||
else => {
|
||||
try buf_stream.writeByteNTimes('\\', backslash_count);
|
||||
try buf.appendByte(byte);
|
||||
try buf_stream.writeByte(byte);
|
||||
backslash_count = 0;
|
||||
},
|
||||
}
|
||||
}
|
||||
try buf_stream.writeByteNTimes('\\', backslash_count * 2);
|
||||
try buf.appendByte('"');
|
||||
try buf_stream.writeByte('"');
|
||||
}
|
||||
|
||||
return buf.toOwnedSlice();
|
||||
|
||||
@ -1416,13 +1416,14 @@ pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAb
|
||||
|
||||
pub const Walker = struct {
|
||||
stack: std.ArrayList(StackItem),
|
||||
name_buffer: std.Buffer,
|
||||
name_buffer: std.ArrayList(u8),
|
||||
|
||||
pub const Entry = struct {
|
||||
/// The containing directory. This can be used to operate directly on `basename`
|
||||
/// rather than `path`, avoiding `error.NameTooLong` for deeply nested paths.
|
||||
/// The directory remains open until `next` or `deinit` is called.
|
||||
dir: Dir,
|
||||
/// TODO make this null terminated for API convenience
|
||||
basename: []const u8,
|
||||
|
||||
path: []const u8,
|
||||
@ -1445,8 +1446,8 @@ pub const Walker = struct {
|
||||
const dirname_len = top.dirname_len;
|
||||
if (try top.dir_it.next()) |base| {
|
||||
self.name_buffer.shrink(dirname_len);
|
||||
try self.name_buffer.appendByte(path.sep);
|
||||
try self.name_buffer.append(base.name);
|
||||
try self.name_buffer.append(path.sep);
|
||||
try self.name_buffer.appendSlice(base.name);
|
||||
if (base.kind == .Directory) {
|
||||
var new_dir = top.dir_it.dir.openDir(base.name, .{ .iterate = true }) catch |err| switch (err) {
|
||||
error.NameTooLong => unreachable, // no path sep in base.name
|
||||
@ -1456,7 +1457,7 @@ pub const Walker = struct {
|
||||
errdefer new_dir.close();
|
||||
try self.stack.append(StackItem{
|
||||
.dir_it = new_dir.iterate(),
|
||||
.dirname_len = self.name_buffer.len(),
|
||||
.dirname_len = self.name_buffer.len,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1489,9 +1490,11 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {
|
||||
var dir = try cwd().openDir(dir_path, .{ .iterate = true });
|
||||
errdefer dir.close();
|
||||
|
||||
var name_buffer = try std.Buffer.init(allocator, dir_path);
|
||||
var name_buffer = std.ArrayList(u8).init(allocator);
|
||||
errdefer name_buffer.deinit();
|
||||
|
||||
try name_buffer.appendSlice(dir_path);
|
||||
|
||||
var walker = Walker{
|
||||
.stack = std.ArrayList(Walker.StackItem).init(allocator),
|
||||
.name_buffer = name_buffer,
|
||||
|
||||
@ -3,7 +3,6 @@ const builtin = std.builtin;
|
||||
const math = std.math;
|
||||
const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
const Buffer = std.Buffer;
|
||||
const testing = std.testing;
|
||||
|
||||
pub fn InStream(
|
||||
|
||||
@ -504,7 +504,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
|
||||
var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);
|
||||
defer lookup_addrs.deinit();
|
||||
|
||||
var canon = std.Buffer.initNull(arena);
|
||||
var canon = std.ArrayListSentineled(u8, 0).initNull(arena);
|
||||
defer canon.deinit();
|
||||
|
||||
try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
|
||||
@ -539,7 +539,7 @@ const DAS_ORDER_SHIFT = 0;
|
||||
|
||||
fn linuxLookupName(
|
||||
addrs: *std.ArrayList(LookupAddr),
|
||||
canon: *std.Buffer,
|
||||
canon: *std.ArrayListSentineled(u8, 0),
|
||||
opt_name: ?[]const u8,
|
||||
family: os.sa_family_t,
|
||||
flags: u32,
|
||||
@ -798,7 +798,7 @@ fn linuxLookupNameFromNull(
|
||||
|
||||
fn linuxLookupNameFromHosts(
|
||||
addrs: *std.ArrayList(LookupAddr),
|
||||
canon: *std.Buffer,
|
||||
canon: *std.ArrayListSentineled(u8, 0),
|
||||
name: []const u8,
|
||||
family: os.sa_family_t,
|
||||
port: u16,
|
||||
@ -868,7 +868,7 @@ pub fn isValidHostName(hostname: []const u8) bool {
|
||||
|
||||
fn linuxLookupNameFromDnsSearch(
|
||||
addrs: *std.ArrayList(LookupAddr),
|
||||
canon: *std.Buffer,
|
||||
canon: *std.ArrayListSentineled(u8, 0),
|
||||
name: []const u8,
|
||||
family: os.sa_family_t,
|
||||
port: u16,
|
||||
@ -901,12 +901,12 @@ fn linuxLookupNameFromDnsSearch(
|
||||
// the full requested name to name_from_dns.
|
||||
try canon.resize(canon_name.len);
|
||||
mem.copy(u8, canon.span(), canon_name);
|
||||
try canon.appendByte('.');
|
||||
try canon.append('.');
|
||||
|
||||
var tok_it = mem.tokenize(search, " \t");
|
||||
while (tok_it.next()) |tok| {
|
||||
canon.shrink(canon_name.len + 1);
|
||||
try canon.append(tok);
|
||||
try canon.appendSlice(tok);
|
||||
try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);
|
||||
if (addrs.len != 0) return;
|
||||
}
|
||||
@ -917,13 +917,13 @@ fn linuxLookupNameFromDnsSearch(
|
||||
|
||||
const dpc_ctx = struct {
|
||||
addrs: *std.ArrayList(LookupAddr),
|
||||
canon: *std.Buffer,
|
||||
canon: *std.ArrayListSentineled(u8, 0),
|
||||
port: u16,
|
||||
};
|
||||
|
||||
fn linuxLookupNameFromDns(
|
||||
addrs: *std.ArrayList(LookupAddr),
|
||||
canon: *std.Buffer,
|
||||
canon: *std.ArrayListSentineled(u8, 0),
|
||||
name: []const u8,
|
||||
family: os.sa_family_t,
|
||||
rc: ResolvConf,
|
||||
@ -978,7 +978,7 @@ const ResolvConf = struct {
|
||||
attempts: u32,
|
||||
ndots: u32,
|
||||
timeout: u32,
|
||||
search: std.Buffer,
|
||||
search: std.ArrayListSentineled(u8, 0),
|
||||
ns: std.ArrayList(LookupAddr),
|
||||
|
||||
fn deinit(rc: *ResolvConf) void {
|
||||
@ -993,7 +993,7 @@ const ResolvConf = struct {
|
||||
fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
|
||||
rc.* = ResolvConf{
|
||||
.ns = std.ArrayList(LookupAddr).init(allocator),
|
||||
.search = std.Buffer.initNull(allocator),
|
||||
.search = std.ArrayListSentineled(u8, 0).initNull(allocator),
|
||||
.ndots = 1,
|
||||
.timeout = 5,
|
||||
.attempts = 2,
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
pub const AlignedArrayList = @import("array_list.zig").AlignedArrayList;
|
||||
pub const ArrayList = @import("array_list.zig").ArrayList;
|
||||
pub const ArrayListSentineled = @import("array_list_sentineled.zig").ArrayListSentineled;
|
||||
pub const AutoHashMap = @import("hash_map.zig").AutoHashMap;
|
||||
pub const BloomFilter = @import("bloom_filter.zig").BloomFilter;
|
||||
pub const BufMap = @import("buf_map.zig").BufMap;
|
||||
pub const BufSet = @import("buf_set.zig").BufSet;
|
||||
pub const Buffer = @import("buffer.zig").Buffer;
|
||||
pub const ChildProcess = @import("child_process.zig").ChildProcess;
|
||||
pub const DynLib = @import("dynamic_library.zig").DynLib;
|
||||
pub const HashMap = @import("hash_map.zig").HashMap;
|
||||
|
||||
@ -967,15 +967,15 @@ pub const Target = struct {
|
||||
|
||||
pub const stack_align = 16;
|
||||
|
||||
pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 {
|
||||
pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
|
||||
return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
|
||||
}
|
||||
|
||||
pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![:0]u8 {
|
||||
return std.fmt.allocPrint0(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
|
||||
pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
|
||||
return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
|
||||
}
|
||||
|
||||
pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 {
|
||||
pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
|
||||
return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
|
||||
}
|
||||
|
||||
|
||||
@ -495,17 +495,19 @@ pub const CrossTarget = struct {
|
||||
return self.isNativeCpu() and self.isNativeOs() and self.abi == null;
|
||||
}
|
||||
|
||||
pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 {
|
||||
pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![]u8 {
|
||||
if (self.isNative()) {
|
||||
return mem.dupeZ(allocator, u8, "native");
|
||||
return mem.dupe(allocator, u8, "native");
|
||||
}
|
||||
|
||||
const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
|
||||
const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
|
||||
|
||||
var result = try std.Buffer.allocPrint(allocator, "{}-{}", .{ arch_name, os_name });
|
||||
var result = std.ArrayList(u8).init(allocator);
|
||||
defer result.deinit();
|
||||
|
||||
try result.outStream().print("{}-{}", .{ arch_name, os_name });
|
||||
|
||||
// The zig target syntax does not allow specifying a max os version with no min, so
|
||||
// if either are present, we need the min.
|
||||
if (self.os_version_min != null or self.os_version_max != null) {
|
||||
@ -532,13 +534,13 @@ pub const CrossTarget = struct {
|
||||
return result.toOwnedSlice();
|
||||
}
|
||||
|
||||
pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 {
|
||||
pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
|
||||
// TODO is there anything else worthy of the description that is not
|
||||
// already captured in the triple?
|
||||
return self.zigTriple(allocator);
|
||||
}
|
||||
|
||||
pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 {
|
||||
pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
|
||||
return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
|
||||
}
|
||||
|
||||
@ -549,7 +551,7 @@ pub const CrossTarget = struct {
|
||||
pub const VcpkgLinkage = std.builtin.LinkMode;
|
||||
|
||||
/// Returned slice must be freed by the caller.
|
||||
pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![:0]u8 {
|
||||
pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![]u8 {
|
||||
const arch = switch (self.getCpuArch()) {
|
||||
.i386 => "x86",
|
||||
.x86_64 => "x64",
|
||||
@ -580,7 +582,7 @@ pub const CrossTarget = struct {
|
||||
.Dynamic => "",
|
||||
};
|
||||
|
||||
return std.fmt.allocPrint0(allocator, "{}-{}{}", .{ arch, os, static_suffix });
|
||||
return std.fmt.allocPrint(allocator, "{}-{}{}", .{ arch, os, static_suffix });
|
||||
}
|
||||
|
||||
pub const Executor = union(enum) {
|
||||
|
||||
@ -2953,7 +2953,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
var buffer = try std.Buffer.initSize(allocator, 0);
|
||||
var buffer = std.ArrayList(u8).init(allocator);
|
||||
errdefer buffer.deinit();
|
||||
|
||||
anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);
|
||||
|
||||
@ -45,7 +45,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
||||
|
||||
// Don't use ZIG_VERSION_STRING here. LLVM misparses it when it includes
|
||||
// the git revision.
|
||||
const producer = try std.Buffer.allocPrint(&code.arena.allocator, "zig {}.{}.{}", .{
|
||||
const producer = try std.fmt.allocPrintZ(&code.arena.allocator, "zig {}.{}.{}", .{
|
||||
@as(u32, c.ZIG_VERSION_MAJOR),
|
||||
@as(u32, c.ZIG_VERSION_MINOR),
|
||||
@as(u32, c.ZIG_VERSION_PATCH),
|
||||
@ -62,7 +62,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
||||
dibuilder,
|
||||
DW.LANG_C99,
|
||||
compile_unit_file,
|
||||
producer.span(),
|
||||
producer,
|
||||
is_optimized,
|
||||
flags,
|
||||
runtime_version,
|
||||
|
||||
@ -2,7 +2,7 @@ const std = @import("std");
|
||||
const io = std.io;
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayListSentineled = std.ArrayListSentineled;
|
||||
const llvm = @import("llvm.zig");
|
||||
const c = @import("c.zig");
|
||||
const builtin = std.builtin;
|
||||
@ -123,8 +123,8 @@ pub const LlvmHandle = struct {
|
||||
|
||||
pub const Compilation = struct {
|
||||
zig_compiler: *ZigCompiler,
|
||||
name: Buffer,
|
||||
llvm_triple: Buffer,
|
||||
name: ArrayListSentineled(u8, 0),
|
||||
llvm_triple: ArrayListSentineled(u8, 0),
|
||||
root_src_path: ?[]const u8,
|
||||
target: std.Target,
|
||||
llvm_target: *llvm.Target,
|
||||
@ -444,7 +444,7 @@ pub const Compilation = struct {
|
||||
comp.arena_allocator.deinit();
|
||||
}
|
||||
|
||||
comp.name = try Buffer.init(comp.arena(), name);
|
||||
comp.name = try ArrayListSentineled(u8, 0).init(comp.arena(), name);
|
||||
comp.llvm_triple = try util.getLLVMTriple(comp.arena(), target);
|
||||
comp.llvm_target = try util.llvmTargetFromTriple(comp.llvm_triple);
|
||||
comp.zig_std_dir = try fs.path.join(comp.arena(), &[_][]const u8{ zig_lib_dir, "std" });
|
||||
@ -1151,7 +1151,7 @@ pub const Compilation = struct {
|
||||
|
||||
/// If the temporary directory for this compilation has not been created, it creates it.
|
||||
/// Then it creates a random file name in that dir and returns it.
|
||||
pub fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !Buffer {
|
||||
pub fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !ArrayListSentineled(u8, 0) {
|
||||
const tmp_dir = try self.getTmpDir();
|
||||
const file_prefix = self.getRandomFileName();
|
||||
|
||||
@ -1161,7 +1161,7 @@ pub const Compilation = struct {
|
||||
const full_path = try fs.path.join(self.gpa(), &[_][]const u8{ tmp_dir, file_name[0..] });
|
||||
errdefer self.gpa().free(full_path);
|
||||
|
||||
return Buffer.fromOwnedSlice(self.gpa(), full_path);
|
||||
return ArrayListSentineled(u8, 0).fromOwnedSlice(self.gpa(), full_path);
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
const fn_type = try analyzeFnType(comp, tree_scope, fn_decl.base.parent_scope, fn_decl.fn_proto);
|
||||
defer fn_type.base.base.deref(comp);
|
||||
|
||||
var symbol_name = try std.Buffer.init(comp.gpa(), fn_decl.base.name);
|
||||
var symbol_name = try std.ArrayListSentineled(u8, 0).init(comp.gpa(), fn_decl.base.name);
|
||||
var symbol_name_consumed = false;
|
||||
errdefer if (!symbol_name_consumed) symbol_name.deinit();
|
||||
|
||||
@ -1426,7 +1426,7 @@ fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
);
|
||||
defer fn_type.base.base.deref(comp);
|
||||
|
||||
var symbol_name = try std.Buffer.init(comp.gpa(), fn_decl.base.name);
|
||||
var symbol_name = try std.ArrayListSentineled(u8, 0).init(comp.gpa(), fn_decl.base.name);
|
||||
var symbol_name_consumed = false;
|
||||
defer if (!symbol_name_consumed) symbol_name.deinit();
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ pub const Tokenizer = struct {
|
||||
break; // advance
|
||||
},
|
||||
else => {
|
||||
self.state = State{ .target = try std.Buffer.initSize(&self.arena.allocator, 0) };
|
||||
self.state = State{ .target = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0) };
|
||||
},
|
||||
},
|
||||
.target => |*target| switch (char) {
|
||||
@ -53,7 +53,7 @@ pub const Tokenizer = struct {
|
||||
break; // advance
|
||||
},
|
||||
else => {
|
||||
try target.appendByte(char);
|
||||
try target.append(char);
|
||||
break; // advance
|
||||
},
|
||||
},
|
||||
@ -62,24 +62,24 @@ pub const Tokenizer = struct {
|
||||
return self.errorIllegalChar(self.index, char, "bad target escape", .{});
|
||||
},
|
||||
' ', '#', '\\' => {
|
||||
try target.appendByte(char);
|
||||
try target.append(char);
|
||||
self.state = State{ .target = target.* };
|
||||
break; // advance
|
||||
},
|
||||
'$' => {
|
||||
try target.append(self.bytes[self.index - 1 .. self.index]);
|
||||
try target.appendSlice(self.bytes[self.index - 1 .. self.index]);
|
||||
self.state = State{ .target_dollar_sign = target.* };
|
||||
break; // advance
|
||||
},
|
||||
else => {
|
||||
try target.append(self.bytes[self.index - 1 .. self.index + 1]);
|
||||
try target.appendSlice(self.bytes[self.index - 1 .. self.index + 1]);
|
||||
self.state = State{ .target = target.* };
|
||||
break; // advance
|
||||
},
|
||||
},
|
||||
.target_dollar_sign => |*target| switch (char) {
|
||||
'$' => {
|
||||
try target.appendByte(char);
|
||||
try target.append(char);
|
||||
self.state = State{ .target = target.* };
|
||||
break; // advance
|
||||
},
|
||||
@ -125,7 +125,7 @@ pub const Tokenizer = struct {
|
||||
continue;
|
||||
},
|
||||
else => {
|
||||
try target.append(self.bytes[self.index - 2 .. self.index + 1]);
|
||||
try target.appendSlice(self.bytes[self.index - 2 .. self.index + 1]);
|
||||
self.state = State{ .target = target.* };
|
||||
break;
|
||||
},
|
||||
@ -144,11 +144,11 @@ pub const Tokenizer = struct {
|
||||
break; // advance
|
||||
},
|
||||
'"' => {
|
||||
self.state = State{ .prereq_quote = try std.Buffer.initSize(&self.arena.allocator, 0) };
|
||||
self.state = State{ .prereq_quote = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0) };
|
||||
break; // advance
|
||||
},
|
||||
else => {
|
||||
self.state = State{ .prereq = try std.Buffer.initSize(&self.arena.allocator, 0) };
|
||||
self.state = State{ .prereq = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0) };
|
||||
},
|
||||
},
|
||||
.rhs_continuation => switch (char) {
|
||||
@ -181,7 +181,7 @@ pub const Tokenizer = struct {
|
||||
return Token{ .id = .prereq, .bytes = bytes };
|
||||
},
|
||||
else => {
|
||||
try prereq.appendByte(char);
|
||||
try prereq.append(char);
|
||||
break; // advance
|
||||
},
|
||||
},
|
||||
@ -201,7 +201,7 @@ pub const Tokenizer = struct {
|
||||
break; // advance
|
||||
},
|
||||
else => {
|
||||
try prereq.appendByte(char);
|
||||
try prereq.append(char);
|
||||
break; // advance
|
||||
},
|
||||
},
|
||||
@ -218,7 +218,7 @@ pub const Tokenizer = struct {
|
||||
},
|
||||
else => {
|
||||
// not continuation
|
||||
try prereq.append(self.bytes[self.index - 1 .. self.index + 1]);
|
||||
try prereq.appendSlice(self.bytes[self.index - 1 .. self.index + 1]);
|
||||
self.state = State{ .prereq = prereq.* };
|
||||
break; // advance
|
||||
},
|
||||
@ -300,25 +300,25 @@ pub const Tokenizer = struct {
|
||||
}
|
||||
|
||||
fn errorf(self: *Tokenizer, comptime fmt: []const u8, args: var) Error {
|
||||
self.error_text = (try std.Buffer.allocPrint(&self.arena.allocator, fmt, args)).span();
|
||||
self.error_text = try std.fmt.allocPrintZ(&self.arena.allocator, fmt, args);
|
||||
return Error.InvalidInput;
|
||||
}
|
||||
|
||||
fn errorPosition(self: *Tokenizer, position: usize, bytes: []const u8, comptime fmt: []const u8, args: var) Error {
|
||||
var buffer = try std.Buffer.initSize(&self.arena.allocator, 0);
|
||||
var buffer = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0);
|
||||
try buffer.outStream().print(fmt, args);
|
||||
try buffer.append(" '");
|
||||
var out = makeOutput(std.Buffer.append, &buffer);
|
||||
try buffer.appendSlice(" '");
|
||||
var out = makeOutput(std.ArrayListSentineled(u8, 0).appendSlice, &buffer);
|
||||
try printCharValues(&out, bytes);
|
||||
try buffer.append("'");
|
||||
try buffer.appendSlice("'");
|
||||
try buffer.outStream().print(" at position {}", .{position - (bytes.len - 1)});
|
||||
self.error_text = buffer.span();
|
||||
return Error.InvalidInput;
|
||||
}
|
||||
|
||||
fn errorIllegalChar(self: *Tokenizer, position: usize, char: u8, comptime fmt: []const u8, args: var) Error {
|
||||
var buffer = try std.Buffer.initSize(&self.arena.allocator, 0);
|
||||
try buffer.append("illegal char ");
|
||||
var buffer = try std.ArrayListSentineled(u8, 0).initSize(&self.arena.allocator, 0);
|
||||
try buffer.appendSlice("illegal char ");
|
||||
try printUnderstandableChar(&buffer, char);
|
||||
try buffer.outStream().print(" at position {}", .{position});
|
||||
if (fmt.len != 0) try buffer.outStream().print(": " ++ fmt, args);
|
||||
@ -333,18 +333,18 @@ pub const Tokenizer = struct {
|
||||
|
||||
const State = union(enum) {
|
||||
lhs: void,
|
||||
target: std.Buffer,
|
||||
target_reverse_solidus: std.Buffer,
|
||||
target_dollar_sign: std.Buffer,
|
||||
target_colon: std.Buffer,
|
||||
target_colon_reverse_solidus: std.Buffer,
|
||||
target: std.ArrayListSentineled(u8, 0),
|
||||
target_reverse_solidus: std.ArrayListSentineled(u8, 0),
|
||||
target_dollar_sign: std.ArrayListSentineled(u8, 0),
|
||||
target_colon: std.ArrayListSentineled(u8, 0),
|
||||
target_colon_reverse_solidus: std.ArrayListSentineled(u8, 0),
|
||||
rhs: void,
|
||||
rhs_continuation: void,
|
||||
rhs_continuation_linefeed: void,
|
||||
prereq_quote: std.Buffer,
|
||||
prereq: std.Buffer,
|
||||
prereq_continuation: std.Buffer,
|
||||
prereq_continuation_linefeed: std.Buffer,
|
||||
prereq_quote: std.ArrayListSentineled(u8, 0),
|
||||
prereq: std.ArrayListSentineled(u8, 0),
|
||||
prereq_continuation: std.ArrayListSentineled(u8, 0),
|
||||
prereq_continuation_linefeed: std.ArrayListSentineled(u8, 0),
|
||||
};
|
||||
|
||||
const Token = struct {
|
||||
@ -841,28 +841,28 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {
|
||||
defer arena_allocator.deinit();
|
||||
|
||||
var it = Tokenizer.init(arena, input);
|
||||
var buffer = try std.Buffer.initSize(arena, 0);
|
||||
var buffer = try std.ArrayListSentineled(u8, 0).initSize(arena, 0);
|
||||
var i: usize = 0;
|
||||
while (true) {
|
||||
const r = it.next() catch |err| {
|
||||
switch (err) {
|
||||
Tokenizer.Error.InvalidInput => {
|
||||
if (i != 0) try buffer.append("\n");
|
||||
try buffer.append("ERROR: ");
|
||||
try buffer.append(it.error_text);
|
||||
if (i != 0) try buffer.appendSlice("\n");
|
||||
try buffer.appendSlice("ERROR: ");
|
||||
try buffer.appendSlice(it.error_text);
|
||||
},
|
||||
else => return err,
|
||||
}
|
||||
break;
|
||||
};
|
||||
const token = r orelse break;
|
||||
if (i != 0) try buffer.append("\n");
|
||||
try buffer.append(@tagName(token.id));
|
||||
try buffer.append(" = {");
|
||||
if (i != 0) try buffer.appendSlice("\n");
|
||||
try buffer.appendSlice(@tagName(token.id));
|
||||
try buffer.appendSlice(" = {");
|
||||
for (token.bytes) |b| {
|
||||
try buffer.appendByte(printable_char_tab[b]);
|
||||
try buffer.append(printable_char_tab[b]);
|
||||
}
|
||||
try buffer.append("}");
|
||||
try buffer.appendSlice("}");
|
||||
i += 1;
|
||||
}
|
||||
const got: []const u8 = buffer.span();
|
||||
@ -995,13 +995,13 @@ fn printCharValues(out: var, bytes: []const u8) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn printUnderstandableChar(buffer: *std.Buffer, char: u8) !void {
|
||||
fn printUnderstandableChar(buffer: *std.ArrayListSentineled(u8, 0), char: u8) !void {
|
||||
if (!std.ascii.isPrint(char) or char == ' ') {
|
||||
try buffer.outStream().print("\\x{X:2}", .{char});
|
||||
} else {
|
||||
try buffer.append("'");
|
||||
try buffer.appendByte(printable_char_tab[char]);
|
||||
try buffer.append("'");
|
||||
try buffer.appendSlice("'");
|
||||
try buffer.append(printable_char_tab[char]);
|
||||
try buffer.appendSlice("'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ pub const Msg = struct {
|
||||
parse_error: *const ast.Error,
|
||||
) !*Msg {
|
||||
const loc_token = parse_error.loc();
|
||||
var text_buf = try std.Buffer.initSize(comp.gpa(), 0);
|
||||
var text_buf = std.ArrayList(u8).init(comp.gpa());
|
||||
defer text_buf.deinit();
|
||||
|
||||
const realpath_copy = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
|
||||
@ -197,7 +197,7 @@ pub const Msg = struct {
|
||||
realpath: []const u8,
|
||||
) !*Msg {
|
||||
const loc_token = parse_error.loc();
|
||||
var text_buf = try std.Buffer.initSize(allocator, 0);
|
||||
var text_buf = std.ArrayList(u8).init(allocator);
|
||||
defer text_buf.deinit();
|
||||
|
||||
const realpath_copy = try mem.dupe(allocator, u8, realpath);
|
||||
|
||||
@ -14,11 +14,11 @@ usingnamespace @import("windows_sdk.zig");
|
||||
|
||||
/// See the render function implementation for documentation of the fields.
|
||||
pub const LibCInstallation = struct {
|
||||
include_dir: ?[:0]const u8 = null,
|
||||
sys_include_dir: ?[:0]const u8 = null,
|
||||
crt_dir: ?[:0]const u8 = null,
|
||||
msvc_lib_dir: ?[:0]const u8 = null,
|
||||
kernel32_lib_dir: ?[:0]const u8 = null,
|
||||
include_dir: ?[]const u8 = null,
|
||||
sys_include_dir: ?[]const u8 = null,
|
||||
crt_dir: ?[]const u8 = null,
|
||||
msvc_lib_dir: ?[]const u8 = null,
|
||||
kernel32_lib_dir: ?[]const u8 = null,
|
||||
|
||||
pub const FindError = error{
|
||||
OutOfMemory,
|
||||
@ -327,13 +327,12 @@ pub const LibCInstallation = struct {
|
||||
var search_buf: [2]Search = undefined;
|
||||
const searches = fillSearch(&search_buf, sdk);
|
||||
|
||||
var result_buf = try std.Buffer.initSize(allocator, 0);
|
||||
var result_buf = std.ArrayList([]const u8).init(allocator);
|
||||
defer result_buf.deinit();
|
||||
|
||||
for (searches) |search| {
|
||||
result_buf.shrink(0);
|
||||
const stream = result_buf.outStream();
|
||||
try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
|
||||
try result_buf.outStream().print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
|
||||
|
||||
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
|
||||
error.FileNotFound,
|
||||
@ -367,7 +366,7 @@ pub const LibCInstallation = struct {
|
||||
var search_buf: [2]Search = undefined;
|
||||
const searches = fillSearch(&search_buf, sdk);
|
||||
|
||||
var result_buf = try std.Buffer.initSize(allocator, 0);
|
||||
var result_buf = try std.ArrayList([]const u8).init(allocator);
|
||||
defer result_buf.deinit();
|
||||
|
||||
const arch_sub_dir = switch (builtin.arch) {
|
||||
@ -379,8 +378,7 @@ pub const LibCInstallation = struct {
|
||||
|
||||
for (searches) |search| {
|
||||
result_buf.shrink(0);
|
||||
const stream = result_buf.outStream();
|
||||
try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
|
||||
try result_buf.outStream().print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
|
||||
|
||||
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
|
||||
error.FileNotFound,
|
||||
@ -422,7 +420,7 @@ pub const LibCInstallation = struct {
|
||||
var search_buf: [2]Search = undefined;
|
||||
const searches = fillSearch(&search_buf, sdk);
|
||||
|
||||
var result_buf = try std.Buffer.initSize(allocator, 0);
|
||||
var result_buf = try std.ArrayList([]const u8).init(allocator);
|
||||
defer result_buf.deinit();
|
||||
|
||||
const arch_sub_dir = switch (builtin.arch) {
|
||||
@ -470,12 +468,10 @@ pub const LibCInstallation = struct {
|
||||
const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
|
||||
const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
|
||||
|
||||
var result_buf = try std.Buffer.init(allocator, up2);
|
||||
defer result_buf.deinit();
|
||||
const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });
|
||||
errdefer allocator.free(dir_path);
|
||||
|
||||
try result_buf.append("\\include");
|
||||
|
||||
var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) {
|
||||
var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) {
|
||||
error.FileNotFound,
|
||||
error.NotDir,
|
||||
error.NoDevice,
|
||||
@ -490,7 +486,7 @@ pub const LibCInstallation = struct {
|
||||
else => return error.FileSystem,
|
||||
};
|
||||
|
||||
self.sys_include_dir = result_buf.toOwnedSlice();
|
||||
self.sys_include_dir = dir_path;
|
||||
}
|
||||
|
||||
fn findNativeMsvcLibDir(
|
||||
|
||||
@ -15,10 +15,10 @@ const Context = struct {
|
||||
link_in_crt: bool,
|
||||
|
||||
link_err: error{OutOfMemory}!void,
|
||||
link_msg: std.Buffer,
|
||||
link_msg: std.ArrayListSentineled(u8, 0),
|
||||
|
||||
libc: *LibCInstallation,
|
||||
out_file_path: std.Buffer,
|
||||
out_file_path: std.ArrayListSentineled(u8, 0),
|
||||
};
|
||||
|
||||
pub fn link(comp: *Compilation) !void {
|
||||
@ -34,9 +34,9 @@ pub fn link(comp: *Compilation) !void {
|
||||
};
|
||||
defer ctx.arena.deinit();
|
||||
ctx.args = std.ArrayList([*:0]const u8).init(&ctx.arena.allocator);
|
||||
ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator);
|
||||
ctx.link_msg = std.ArrayListSentineled(u8, 0).initNull(&ctx.arena.allocator);
|
||||
|
||||
ctx.out_file_path = try std.Buffer.init(&ctx.arena.allocator, comp.name.span());
|
||||
ctx.out_file_path = try std.ArrayListSentineled(u8, 0).init(&ctx.arena.allocator, comp.name.span());
|
||||
switch (comp.kind) {
|
||||
.Exe => {
|
||||
try ctx.out_file_path.append(comp.target.exeFileExt());
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const assert = std.debug.assert;
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayListSentineled = std.ArrayListSentineled;
|
||||
|
||||
pub const Package = struct {
|
||||
root_src_dir: Buffer,
|
||||
root_src_path: Buffer,
|
||||
root_src_dir: ArrayListSentineled(u8, 0),
|
||||
root_src_path: ArrayListSentineled(u8, 0),
|
||||
|
||||
/// relative to root_src_dir
|
||||
table: Table,
|
||||
@ -17,8 +17,8 @@ pub const Package = struct {
|
||||
pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
|
||||
const ptr = try allocator.create(Package);
|
||||
ptr.* = Package{
|
||||
.root_src_dir = try Buffer.init(allocator, root_src_dir),
|
||||
.root_src_path = try Buffer.init(allocator, root_src_path),
|
||||
.root_src_dir = try ArrayListSentineled(u8, 0).init(allocator, root_src_dir),
|
||||
.root_src_path = try ArrayListSentineled(u8, 0).init(allocator, root_src_path),
|
||||
.table = Table.init(allocator),
|
||||
};
|
||||
return ptr;
|
||||
|
||||
@ -8,7 +8,7 @@ const fs = std.fs;
|
||||
const process = std.process;
|
||||
const Allocator = mem.Allocator;
|
||||
const ArrayList = std.ArrayList;
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayListSentineled = std.ArrayListSentineled;
|
||||
const Target = std.Target;
|
||||
const CrossTarget = std.zig.CrossTarget;
|
||||
const self_hosted_main = @import("main.zig");
|
||||
@ -411,12 +411,13 @@ fn printErrMsgToFile(
|
||||
const start_loc = tree.tokenLocationPtr(0, first_token);
|
||||
const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
|
||||
|
||||
var text_buf = try std.Buffer.initSize(allocator, 0);
|
||||
const out_stream = &text_buf.outStream();
|
||||
var text_buf = std.ArrayList(u8).init(allocator);
|
||||
defer text_buf.deinit();
|
||||
const out_stream = text_buf.outStream();
|
||||
try parse_error.render(&tree.tokens, out_stream);
|
||||
const text = text_buf.toOwnedSlice();
|
||||
const text = text_buf.span();
|
||||
|
||||
const stream = &file.outStream();
|
||||
const stream = file.outStream();
|
||||
try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
|
||||
|
||||
if (!color_on) return;
|
||||
@ -448,7 +449,7 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
|
||||
|
||||
export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
|
||||
const otoken = self.handle.next() catch {
|
||||
const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
|
||||
const textz = std.ArrayListSentineled(u8, 0).init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
|
||||
return stage2_DepNextResult{
|
||||
.type_id = .error_,
|
||||
.textz = textz.span().ptr,
|
||||
@ -460,7 +461,7 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes
|
||||
.textz = undefined,
|
||||
};
|
||||
};
|
||||
const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
|
||||
const textz = std.ArrayListSentineled(u8, 0).init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
|
||||
return stage2_DepNextResult{
|
||||
.type_id = switch (token.id) {
|
||||
.target => .target,
|
||||
@ -740,15 +741,15 @@ fn stage2TargetParse(
|
||||
|
||||
// ABI warning
|
||||
const Stage2LibCInstallation = extern struct {
|
||||
include_dir: [*:0]const u8,
|
||||
include_dir: [*]const u8,
|
||||
include_dir_len: usize,
|
||||
sys_include_dir: [*:0]const u8,
|
||||
sys_include_dir: [*]const u8,
|
||||
sys_include_dir_len: usize,
|
||||
crt_dir: [*:0]const u8,
|
||||
crt_dir: [*]const u8,
|
||||
crt_dir_len: usize,
|
||||
msvc_lib_dir: [*:0]const u8,
|
||||
msvc_lib_dir: [*]const u8,
|
||||
msvc_lib_dir_len: usize,
|
||||
kernel32_lib_dir: [*:0]const u8,
|
||||
kernel32_lib_dir: [*]const u8,
|
||||
kernel32_lib_dir_len: usize,
|
||||
|
||||
fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
|
||||
@ -792,19 +793,19 @@ const Stage2LibCInstallation = extern struct {
|
||||
fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
|
||||
var libc: LibCInstallation = .{};
|
||||
if (self.include_dir_len != 0) {
|
||||
libc.include_dir = self.include_dir[0..self.include_dir_len :0];
|
||||
libc.include_dir = self.include_dir[0..self.include_dir_len];
|
||||
}
|
||||
if (self.sys_include_dir_len != 0) {
|
||||
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
|
||||
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len];
|
||||
}
|
||||
if (self.crt_dir_len != 0) {
|
||||
libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
|
||||
libc.crt_dir = self.crt_dir[0..self.crt_dir_len];
|
||||
}
|
||||
if (self.msvc_lib_dir_len != 0) {
|
||||
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
|
||||
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len];
|
||||
}
|
||||
if (self.kernel32_lib_dir_len != 0) {
|
||||
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
|
||||
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len];
|
||||
}
|
||||
return libc;
|
||||
}
|
||||
@ -923,14 +924,14 @@ const Stage2Target = extern struct {
|
||||
var dynamic_linker: ?[*:0]u8 = null;
|
||||
const target = try crossTargetToTarget(cross_target, &dynamic_linker);
|
||||
|
||||
var cache_hash = try std.Buffer.allocPrint(allocator, "{}\n{}\n", .{
|
||||
var cache_hash = try std.ArrayListSentineled(u8, 0).allocPrint(allocator, "{}\n{}\n", .{
|
||||
target.cpu.model.name,
|
||||
target.cpu.features.asBytes(),
|
||||
});
|
||||
defer cache_hash.deinit();
|
||||
|
||||
const generic_arch_name = target.cpu.arch.genericName();
|
||||
var cpu_builtin_str_buffer = try std.Buffer.allocPrint(allocator,
|
||||
var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
|
||||
\\Cpu{{
|
||||
\\ .arch = .{},
|
||||
\\ .model = &Target.{}.cpu.{},
|
||||
@ -945,7 +946,7 @@ const Stage2Target = extern struct {
|
||||
});
|
||||
defer cpu_builtin_str_buffer.deinit();
|
||||
|
||||
var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
|
||||
var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
|
||||
defer llvm_features_buffer.deinit();
|
||||
|
||||
// Unfortunately we have to do the work twice, because Clang does not support
|
||||
@ -960,17 +961,17 @@ const Stage2Target = extern struct {
|
||||
|
||||
if (feature.llvm_name) |llvm_name| {
|
||||
const plus_or_minus = "-+"[@boolToInt(is_enabled)];
|
||||
try llvm_features_buffer.appendByte(plus_or_minus);
|
||||
try llvm_features_buffer.append(llvm_name);
|
||||
try llvm_features_buffer.append(",");
|
||||
try llvm_features_buffer.append(plus_or_minus);
|
||||
try llvm_features_buffer.appendSlice(llvm_name);
|
||||
try llvm_features_buffer.appendSlice(",");
|
||||
}
|
||||
|
||||
if (is_enabled) {
|
||||
// TODO some kind of "zig identifier escape" function rather than
|
||||
// unconditionally using @"" syntax
|
||||
try cpu_builtin_str_buffer.append(" .@\"");
|
||||
try cpu_builtin_str_buffer.append(feature.name);
|
||||
try cpu_builtin_str_buffer.append("\",\n");
|
||||
try cpu_builtin_str_buffer.appendSlice(" .@\"");
|
||||
try cpu_builtin_str_buffer.appendSlice(feature.name);
|
||||
try cpu_builtin_str_buffer.appendSlice("\",\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -989,7 +990,7 @@ const Stage2Target = extern struct {
|
||||
},
|
||||
}
|
||||
|
||||
try cpu_builtin_str_buffer.append(
|
||||
try cpu_builtin_str_buffer.appendSlice(
|
||||
\\ }),
|
||||
\\};
|
||||
\\
|
||||
@ -998,7 +999,7 @@ const Stage2Target = extern struct {
|
||||
assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));
|
||||
llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
|
||||
|
||||
var os_builtin_str_buffer = try std.Buffer.allocPrint(allocator,
|
||||
var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
|
||||
\\Os{{
|
||||
\\ .tag = .{},
|
||||
\\ .version_range = .{{
|
||||
@ -1041,7 +1042,7 @@ const Stage2Target = extern struct {
|
||||
.emscripten,
|
||||
.uefi,
|
||||
.other,
|
||||
=> try os_builtin_str_buffer.append(" .none = {} }\n"),
|
||||
=> try os_builtin_str_buffer.appendSlice(" .none = {} }\n"),
|
||||
|
||||
.freebsd,
|
||||
.macosx,
|
||||
@ -1117,9 +1118,9 @@ const Stage2Target = extern struct {
|
||||
@tagName(target.os.version_range.windows.max),
|
||||
}),
|
||||
}
|
||||
try os_builtin_str_buffer.append("};\n");
|
||||
try os_builtin_str_buffer.appendSlice("};\n");
|
||||
|
||||
try cache_hash.append(
|
||||
try cache_hash.appendSlice(
|
||||
os_builtin_str_buffer.span()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()],
|
||||
);
|
||||
|
||||
|
||||
@ -209,7 +209,7 @@ const Scope = struct {
|
||||
|
||||
pub const Context = struct {
|
||||
tree: *ast.Tree,
|
||||
source_buffer: *std.Buffer,
|
||||
source_buffer: *std.ArrayList(u8),
|
||||
err: Error,
|
||||
source_manager: *ZigClangSourceManager,
|
||||
decl_table: DeclTable,
|
||||
@ -275,7 +275,7 @@ pub fn translate(
|
||||
|
||||
const tree = try tree_arena.allocator.create(ast.Tree);
|
||||
tree.* = ast.Tree{
|
||||
.source = undefined, // need to use Buffer.toOwnedSlice later
|
||||
.source = undefined, // need to use toOwnedSlice later
|
||||
.root_node = undefined,
|
||||
.arena_allocator = tree_arena,
|
||||
.tokens = undefined, // can't reference the allocator yet
|
||||
@ -296,7 +296,7 @@ pub fn translate(
|
||||
.eof_token = undefined,
|
||||
};
|
||||
|
||||
var source_buffer = try std.Buffer.initSize(arena, 0);
|
||||
var source_buffer = std.ArrayList(u8).init(arena);
|
||||
|
||||
var context = Context{
|
||||
.tree = tree,
|
||||
@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {
|
||||
return RestorePoint{
|
||||
.c = c,
|
||||
.token_index = c.tree.tokens.len,
|
||||
.src_buf_index = c.source_buffer.len(),
|
||||
.src_buf_index = c.source_buffer.len,
|
||||
};
|
||||
}
|
||||
|
||||
@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
|
||||
|
||||
fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
|
||||
assert(token_id != .Invalid);
|
||||
const start_index = c.source_buffer.len();
|
||||
const start_index = c.source_buffer.len;
|
||||
errdefer c.source_buffer.shrink(start_index);
|
||||
|
||||
try c.source_buffer.outStream().print(format, args);
|
||||
const end_index = c.source_buffer.len();
|
||||
const end_index = c.source_buffer.len;
|
||||
const token_index = c.tree.tokens.len;
|
||||
const new_token = try c.tree.tokens.addOne();
|
||||
errdefer c.tree.tokens.shrink(token_index);
|
||||
@ -4785,7 +4785,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
|
||||
.start = start_index,
|
||||
.end = end_index,
|
||||
};
|
||||
try c.source_buffer.appendByte(' ');
|
||||
try c.source_buffer.append(' ');
|
||||
|
||||
return token_index;
|
||||
}
|
||||
|
||||
@ -387,10 +387,10 @@ pub const Type = struct {
|
||||
};
|
||||
errdefer comp.gpa().destroy(self);
|
||||
|
||||
var name_buf = try std.Buffer.initSize(comp.gpa(), 0);
|
||||
var name_buf = std.ArrayList(u8).init(comp.gpa());
|
||||
defer name_buf.deinit();
|
||||
|
||||
const name_stream = &std.io.BufferOutStream.init(&name_buf).stream;
|
||||
const name_stream = name_buf.outStream();
|
||||
|
||||
switch (key.data) {
|
||||
.Generic => |generic| {
|
||||
|
||||
@ -16,11 +16,11 @@ pub fn getDarwinArchString(self: Target) [:0]const u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn llvmTargetFromTriple(triple: std.Buffer) !*llvm.Target {
|
||||
pub fn llvmTargetFromTriple(triple: [:0]const u8) !*llvm.Target {
|
||||
var result: *llvm.Target = undefined;
|
||||
var err_msg: [*:0]u8 = undefined;
|
||||
if (llvm.GetTargetFromTriple(triple.span(), &result, &err_msg) != 0) {
|
||||
std.debug.warn("triple: {s} error: {s}\n", .{ triple.span(), err_msg });
|
||||
if (llvm.GetTargetFromTriple(triple, &result, &err_msg) != 0) {
|
||||
std.debug.warn("triple: {s} error: {s}\n", .{ triple, err_msg });
|
||||
return error.UnsupportedTarget;
|
||||
}
|
||||
return result;
|
||||
@ -34,14 +34,14 @@ pub fn initializeAllTargets() void {
|
||||
llvm.InitializeAllAsmParsers();
|
||||
}
|
||||
|
||||
pub fn getLLVMTriple(allocator: *std.mem.Allocator, target: std.Target) !std.Buffer {
|
||||
var result = try std.Buffer.initSize(allocator, 0);
|
||||
errdefer result.deinit();
|
||||
pub fn getLLVMTriple(allocator: *std.mem.Allocator, target: std.Target) ![:0]u8 {
|
||||
var result = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
|
||||
defer result.deinit();
|
||||
|
||||
try result.outStream().print(
|
||||
"{}-unknown-{}-{}",
|
||||
.{ @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi) },
|
||||
);
|
||||
|
||||
return result;
|
||||
return result.toOwnedSlice();
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ const Scope = @import("scope.zig").Scope;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const ObjectFile = @import("codegen.zig").ObjectFile;
|
||||
const llvm = @import("llvm.zig");
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayListSentineled = std.ArrayListSentineled;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
/// Values are ref-counted, heap-allocated, and copy-on-write
|
||||
@ -131,9 +131,9 @@ pub const Value = struct {
|
||||
|
||||
/// The main external name that is used in the .o file.
|
||||
/// TODO https://github.com/ziglang/zig/issues/265
|
||||
symbol_name: Buffer,
|
||||
symbol_name: ArrayListSentineled(u8, 0),
|
||||
|
||||
pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {
|
||||
pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: ArrayListSentineled(u8, 0)) !*FnProto {
|
||||
const self = try comp.gpa().create(FnProto);
|
||||
self.* = FnProto{
|
||||
.base = Value{
|
||||
@ -171,7 +171,7 @@ pub const Value = struct {
|
||||
|
||||
/// The main external name that is used in the .o file.
|
||||
/// TODO https://github.com/ziglang/zig/issues/265
|
||||
symbol_name: Buffer,
|
||||
symbol_name: ArrayListSentineled(u8, 0),
|
||||
|
||||
/// parent should be the top level decls or container decls
|
||||
fndef_scope: *Scope.FnDef,
|
||||
@ -183,13 +183,13 @@ pub const Value = struct {
|
||||
block_scope: ?*Scope.Block,
|
||||
|
||||
/// Path to the object file that contains this function
|
||||
containing_object: Buffer,
|
||||
containing_object: ArrayListSentineled(u8, 0),
|
||||
|
||||
link_set_node: *std.TailQueue(?*Value.Fn).Node,
|
||||
|
||||
/// Creates a Fn value with 1 ref
|
||||
/// Takes ownership of symbol_name
|
||||
pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {
|
||||
pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: ArrayListSentineled(u8, 0)) !*Fn {
|
||||
const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
|
||||
link_set_node.* = Compilation.FnLinkSet.Node{
|
||||
.data = null,
|
||||
@ -209,7 +209,7 @@ pub const Value = struct {
|
||||
.child_scope = &fndef_scope.base,
|
||||
.block_scope = null,
|
||||
.symbol_name = symbol_name,
|
||||
.containing_object = Buffer.initNull(comp.gpa()),
|
||||
.containing_object = ArrayListSentineled(u8, 0).initNull(comp.gpa()),
|
||||
.link_set_node = link_set_node,
|
||||
};
|
||||
fn_type.base.base.ref();
|
||||
|
||||
@ -27,11 +27,17 @@ void cache_init(CacheHash *ch, Buf *manifest_dir) {
|
||||
void cache_mem(CacheHash *ch, const char *ptr, size_t len) {
|
||||
assert(ch->manifest_file_path == nullptr);
|
||||
assert(ptr != nullptr);
|
||||
// + 1 to include the null byte
|
||||
blake2b_update(&ch->blake, ptr, len);
|
||||
}
|
||||
|
||||
void cache_slice(CacheHash *ch, Slice<const char> slice) {
|
||||
// mix the length into the hash so that two juxtaposed cached slices can't collide
|
||||
cache_usize(ch, slice.len);
|
||||
cache_mem(ch, slice.ptr, slice.len);
|
||||
}
|
||||
|
||||
void cache_str(CacheHash *ch, const char *ptr) {
|
||||
// + 1 to include the null byte
|
||||
cache_mem(ch, ptr, strlen(ptr) + 1);
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);
|
||||
|
||||
// Next, use the hash population functions to add the initial parameters.
|
||||
void cache_mem(CacheHash *ch, const char *ptr, size_t len);
|
||||
void cache_slice(CacheHash *ch, Slice<const char> slice);
|
||||
void cache_str(CacheHash *ch, const char *ptr);
|
||||
void cache_int(CacheHash *ch, int x);
|
||||
void cache_bool(CacheHash *ch, bool x);
|
||||
|
||||
@ -9123,21 +9123,29 @@ static void detect_libc(CodeGen *g) {
|
||||
g->libc_include_dir_len = 0;
|
||||
g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
|
||||
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(
|
||||
g->libc->include_dir, g->libc->include_dir_len));
|
||||
g->libc_include_dir_len += 1;
|
||||
|
||||
if (want_sys_dir) {
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_create_from_mem(
|
||||
g->libc->sys_include_dir, g->libc->sys_include_dir_len));
|
||||
g->libc_include_dir_len += 1;
|
||||
}
|
||||
|
||||
if (want_um_and_shared_dirs != 0) {
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
|
||||
"%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
|
||||
Buf *include_dir_parent = buf_alloc();
|
||||
os_path_join(buf_create_from_mem(g->libc->include_dir, g->libc->include_dir_len),
|
||||
buf_create_from_str(".."), include_dir_parent);
|
||||
|
||||
Buf *buff1 = buf_alloc();
|
||||
os_path_join(include_dir_parent, buf_create_from_str("um"), buff1);
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff1);
|
||||
g->libc_include_dir_len += 1;
|
||||
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
|
||||
"%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
|
||||
Buf *buff2 = buf_alloc();
|
||||
os_path_join(include_dir_parent, buf_create_from_str("shared"), buff2);
|
||||
g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buff2);
|
||||
g->libc_include_dir_len += 1;
|
||||
}
|
||||
assert(g->libc_include_dir_len == dir_count);
|
||||
@ -10546,11 +10554,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
|
||||
cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
|
||||
cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
|
||||
if (g->libc) {
|
||||
cache_str(ch, g->libc->include_dir);
|
||||
cache_str(ch, g->libc->sys_include_dir);
|
||||
cache_str(ch, g->libc->crt_dir);
|
||||
cache_str(ch, g->libc->msvc_lib_dir);
|
||||
cache_str(ch, g->libc->kernel32_lib_dir);
|
||||
cache_slice(ch, Slice<const char>{g->libc->include_dir, g->libc->include_dir_len});
|
||||
cache_slice(ch, Slice<const char>{g->libc->sys_include_dir, g->libc->sys_include_dir_len});
|
||||
cache_slice(ch, Slice<const char>{g->libc->crt_dir, g->libc->crt_dir_len});
|
||||
cache_slice(ch, Slice<const char>{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len});
|
||||
cache_slice(ch, Slice<const char>{g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len});
|
||||
}
|
||||
cache_buf_opt(ch, g->version_script_path);
|
||||
cache_buf_opt(ch, g->override_soname);
|
||||
|
||||
27
src/link.cpp
27
src/link.cpp
@ -1595,7 +1595,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
|
||||
} else {
|
||||
assert(parent->libc != nullptr);
|
||||
Buf *out_buf = buf_alloc();
|
||||
os_path_join(buf_create_from_str(parent->libc->crt_dir), buf_create_from_str(file), out_buf);
|
||||
os_path_join(buf_create_from_mem(parent->libc->crt_dir, parent->libc->crt_dir_len),
|
||||
buf_create_from_str(file), out_buf);
|
||||
return buf_ptr(out_buf);
|
||||
}
|
||||
}
|
||||
@ -1860,7 +1861,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
if (g->libc_link_lib != nullptr) {
|
||||
if (g->libc != nullptr) {
|
||||
lj->args.append("-L");
|
||||
lj->args.append(g->libc->crt_dir);
|
||||
lj->args.append(buf_ptr(buf_create_from_mem(g->libc->crt_dir, g->libc->crt_dir_len)));
|
||||
}
|
||||
|
||||
if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
|
||||
@ -2381,14 +2382,26 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
|
||||
|
||||
if (g->libc_link_lib != nullptr && g->libc != nullptr) {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
|
||||
Buf *buff0 = buf_create_from_str("-LIBPATH:");
|
||||
buf_append_mem(buff0, g->libc->crt_dir, g->libc->crt_dir_len);
|
||||
lj->args.append(buf_ptr(buff0));
|
||||
|
||||
if (target_abi_is_gnu(g->zig_target->abi)) {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));
|
||||
Buf *buff1 = buf_create_from_str("-LIBPATH:");
|
||||
buf_append_mem(buff1, g->libc->sys_include_dir, g->libc->sys_include_dir_len);
|
||||
lj->args.append(buf_ptr(buff1));
|
||||
|
||||
Buf *buff2 = buf_create_from_str("-LIBPATH:");
|
||||
buf_append_mem(buff2, g->libc->include_dir, g->libc->include_dir_len);
|
||||
lj->args.append(buf_ptr(buff2));
|
||||
} else {
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));
|
||||
lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));
|
||||
Buf *buff1 = buf_create_from_str("-LIBPATH:");
|
||||
buf_append_mem(buff1, g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len);
|
||||
lj->args.append(buf_ptr(buff1));
|
||||
|
||||
Buf *buff2 = buf_create_from_str("-LIBPATH:");
|
||||
buf_append_mem(buff2, g->libc->kernel32_lib_dir, g->libc->kernel32_lib_dir_len);
|
||||
lj->args.append(buf_ptr(buff2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ const mem = std.mem;
|
||||
const debug = std.debug;
|
||||
const assert = debug.assert;
|
||||
const testing = std.testing;
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayListSentineled = std.ArrayListSentineled;
|
||||
const ArrayList = std.ArrayList;
|
||||
const maxInt = std.math.maxInt;
|
||||
|
||||
@ -111,7 +111,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
|
||||
}
|
||||
}
|
||||
|
||||
fn expandString(input: []const u8, output: *Buffer) !void {
|
||||
fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
|
||||
const tokens = try tokenize(input);
|
||||
if (tokens.len == 1) {
|
||||
return output.resize(0);
|
||||
@ -125,7 +125,7 @@ fn expandString(input: []const u8, output: *Buffer) !void {
|
||||
else => return error.InvalidInput,
|
||||
}
|
||||
|
||||
var result_list = ArrayList(Buffer).init(global_allocator);
|
||||
var result_list = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
|
||||
defer result_list.deinit();
|
||||
|
||||
try expandNode(root, &result_list);
|
||||
@ -133,41 +133,41 @@ fn expandString(input: []const u8, output: *Buffer) !void {
|
||||
try output.resize(0);
|
||||
for (result_list.span()) |buf, i| {
|
||||
if (i != 0) {
|
||||
try output.appendByte(' ');
|
||||
try output.append(' ');
|
||||
}
|
||||
try output.append(buf.span());
|
||||
try output.appendSlice(buf.span());
|
||||
}
|
||||
}
|
||||
|
||||
const ExpandNodeError = error{OutOfMemory};
|
||||
|
||||
fn expandNode(node: Node, output: *ArrayList(Buffer)) ExpandNodeError!void {
|
||||
fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void {
|
||||
assert(output.len == 0);
|
||||
switch (node) {
|
||||
Node.Scalar => |scalar| {
|
||||
try output.append(try Buffer.init(global_allocator, scalar));
|
||||
try output.append(try ArrayListSentineled(u8, 0).init(global_allocator, scalar));
|
||||
},
|
||||
Node.Combine => |pair| {
|
||||
const a_node = pair[0];
|
||||
const b_node = pair[1];
|
||||
|
||||
var child_list_a = ArrayList(Buffer).init(global_allocator);
|
||||
var child_list_a = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
|
||||
try expandNode(a_node, &child_list_a);
|
||||
|
||||
var child_list_b = ArrayList(Buffer).init(global_allocator);
|
||||
var child_list_b = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
|
||||
try expandNode(b_node, &child_list_b);
|
||||
|
||||
for (child_list_a.span()) |buf_a| {
|
||||
for (child_list_b.span()) |buf_b| {
|
||||
var combined_buf = try Buffer.initFromBuffer(buf_a);
|
||||
try combined_buf.append(buf_b.span());
|
||||
var combined_buf = try ArrayListSentineled(u8, 0).initFromBuffer(buf_a);
|
||||
try combined_buf.appendSlice(buf_b.span());
|
||||
try output.append(combined_buf);
|
||||
}
|
||||
}
|
||||
},
|
||||
Node.List => |list| {
|
||||
for (list.span()) |child_node| {
|
||||
var child_list = ArrayList(Buffer).init(global_allocator);
|
||||
var child_list = ArrayList(ArrayListSentineled(u8, 0)).init(global_allocator);
|
||||
try expandNode(child_node, &child_list);
|
||||
|
||||
for (child_list.span()) |buf| {
|
||||
@ -187,13 +187,13 @@ pub fn main() !void {
|
||||
|
||||
global_allocator = &arena.allocator;
|
||||
|
||||
var stdin_buf = try Buffer.initSize(global_allocator, 0);
|
||||
var stdin_buf = try ArrayListSentineled(u8, 0).initSize(global_allocator, 0);
|
||||
defer stdin_buf.deinit();
|
||||
|
||||
var stdin_adapter = stdin_file.inStream();
|
||||
try stdin_adapter.stream.readAllBuffer(&stdin_buf, maxInt(usize));
|
||||
|
||||
var result_buf = try Buffer.initSize(global_allocator, 0);
|
||||
var result_buf = try ArrayListSentineled(u8, 0).initSize(global_allocator, 0);
|
||||
defer result_buf.deinit();
|
||||
|
||||
try expandString(stdin_buf.span(), &result_buf);
|
||||
@ -218,7 +218,7 @@ test "invalid inputs" {
|
||||
}
|
||||
|
||||
fn expectError(test_input: []const u8, expected_err: anyerror) void {
|
||||
var output_buf = Buffer.initSize(global_allocator, 0) catch unreachable;
|
||||
var output_buf = ArrayListSentineled(u8, 0).initSize(global_allocator, 0) catch unreachable;
|
||||
defer output_buf.deinit();
|
||||
|
||||
testing.expectError(expected_err, expandString(test_input, &output_buf));
|
||||
@ -251,7 +251,7 @@ test "valid inputs" {
|
||||
}
|
||||
|
||||
fn expectExpansion(test_input: []const u8, expected_result: []const u8) void {
|
||||
var result = Buffer.initSize(global_allocator, 0) catch unreachable;
|
||||
var result = ArrayListSentineled(u8, 0).initSize(global_allocator, 0) catch unreachable;
|
||||
defer result.deinit();
|
||||
|
||||
expandString(test_input, &result) catch unreachable;
|
||||
|
||||
@ -4,7 +4,6 @@ const debug = std.debug;
|
||||
const warn = debug.warn;
|
||||
const build = std.build;
|
||||
const CrossTarget = std.zig.CrossTarget;
|
||||
const Buffer = std.Buffer;
|
||||
const io = std.io;
|
||||
const fs = std.fs;
|
||||
const mem = std.mem;
|
||||
@ -640,7 +639,7 @@ pub const StackTracesContext = struct {
|
||||
// - replace address with symbolic string
|
||||
// - skip empty lines
|
||||
const got: []const u8 = got_result: {
|
||||
var buf = try Buffer.initSize(b.allocator, 0);
|
||||
var buf = ArrayList(u8).init(b.allocator);
|
||||
defer buf.deinit();
|
||||
if (stderr.len != 0 and stderr[stderr.len - 1] == '\n') stderr = stderr[0 .. stderr.len - 1];
|
||||
var it = mem.separate(stderr, "\n");
|
||||
@ -652,21 +651,21 @@ pub const StackTracesContext = struct {
|
||||
var pos: usize = if (std.Target.current.os.tag == .windows) 2 else 0;
|
||||
for (delims) |delim, i| {
|
||||
marks[i] = mem.indexOfPos(u8, line, pos, delim) orelse {
|
||||
try buf.append(line);
|
||||
try buf.append("\n");
|
||||
try buf.appendSlice(line);
|
||||
try buf.appendSlice("\n");
|
||||
continue :process_lines;
|
||||
};
|
||||
pos = marks[i] + delim.len;
|
||||
}
|
||||
pos = mem.lastIndexOfScalar(u8, line[0..marks[0]], fs.path.sep) orelse {
|
||||
try buf.append(line);
|
||||
try buf.append("\n");
|
||||
try buf.appendSlice(line);
|
||||
try buf.appendSlice("\n");
|
||||
continue :process_lines;
|
||||
};
|
||||
try buf.append(line[pos + 1 .. marks[2] + delims[2].len]);
|
||||
try buf.append(" [address]");
|
||||
try buf.append(line[marks[3]..]);
|
||||
try buf.append("\n");
|
||||
try buf.appendSlice(line[pos + 1 .. marks[2] + delims[2].len]);
|
||||
try buf.appendSlice(" [address]");
|
||||
try buf.appendSlice(line[marks[3]..]);
|
||||
try buf.appendSlice("\n");
|
||||
}
|
||||
break :got_result buf.toOwnedSlice();
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user