diff --git a/doc/docgen.zig b/doc/docgen.zig index be62cab076ac..9e4c8173c0d9 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -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(); diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index cbbec0b4f373..87bf3c51dfa3 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -189,6 +189,22 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { self.len += items.len; } + pub usingnamespace if (T == u8) + struct { + /// 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. + fn appendWrite(self: *Self, m: []const u8) !usize { + try self.appendSlice(m); + return m.len; + } + + pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) { + return .{ .context = self }; + } + } + else + struct {}; + /// Append a value to the list `n` times. Allocates more memory /// as necessary. pub fn appendNTimes(self: *Self, value: T, n: usize) !void { @@ -479,3 +495,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()); +} diff --git a/lib/std/build.zig b/lib/std/build.zig index 858f6bd6f0de..626638647e0b 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -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,23 @@ 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); + errdefer mcpu_buffer.deinit(); + + 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| { diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 3013133b11e4..8e341a07b80a 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -758,37 +758,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 { +fn windowsCreateCommandLine(allocator: *mem.Allocator, argv: []const []const u8) ![:0]u8 { var buf = try Buffer.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(); diff --git a/lib/std/target.zig b/lib/std/target.zig index 8e1b9f8736ea..3f18791eb968 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -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); } diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index bea69b397802..9099519274e5 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -495,16 +495,18 @@ 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 }); - defer result.deinit(); + var result = std.ArrayList(u8).init(allocator); + errdefer 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. @@ -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) { diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 136e323fe654..91921786a268 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -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); diff --git a/src-self-hosted/errmsg.zig b/src-self-hosted/errmsg.zig index 606c8c4b3a91..5775c1df83f0 100644 --- a/src-self-hosted/errmsg.zig +++ b/src-self-hosted/errmsg.zig @@ -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); diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig index 9aa7b39c9b41..f802cbd6065a 100644 --- a/src-self-hosted/libc_installation.zig +++ b/src-self-hosted/libc_installation.zig @@ -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,15 +327,20 @@ 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); - 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 }); - - var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) { + const dir_path = try fs.path.join( + allocator, + &[_][]const u8{ + search.path, + "Include", + search.version, + "ucrt", + }, + ); + var found = false; + defer if (!found) allocator.free(dir_path); + + var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -350,7 +355,8 @@ pub const LibCInstallation = struct { else => return error.FileSystem, }; - self.include_dir = result_buf.toOwnedSlice(); + found = true; + self.include_dir = dir_path; return; } @@ -367,9 +373,6 @@ 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); - defer result_buf.deinit(); - const arch_sub_dir = switch (builtin.arch) { .i386 => "x86", .x86_64 => "x64", @@ -378,11 +381,20 @@ 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 }); - - var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) { + const dir_path = try fs.path.join( + allocator, + &[_][]const u8{ + search.path, + "Lib", + search.version, + "ucrt", + arch_sub_dir, + }, + ); + var found = false; + defer if (!found) allocator.free(dir_path); + + var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -397,7 +409,8 @@ pub const LibCInstallation = struct { else => return error.FileSystem, }; - self.crt_dir = result_buf.toOwnedSlice(); + found = true; + self.crt_dir = dir_path; return; } return error.LibCRuntimeNotFound; @@ -421,10 +434,6 @@ 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); - defer result_buf.deinit(); - const arch_sub_dir = switch (builtin.arch) { .i386 => "x86", .x86_64 => "x64", @@ -433,11 +442,20 @@ pub const LibCInstallation = struct { }; for (searches) |search| { - result_buf.shrink(0); - const stream = result_buf.outStream(); - try stream.print("{}\\Lib\\{}\\um\\{}", .{ search.path, search.version, arch_sub_dir }); - - var dir = fs.cwd().openDir(result_buf.span(), .{}) catch |err| switch (err) { + const dir_path = try fs.path.join( + allocator, + &[_][]const u8{ + search.path, + "Lib", + search.version, + "um", + arch_sub_dir, + }, + ); + var found = false; + defer if (!found) allocator.free(dir_path); + + var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -452,7 +470,8 @@ pub const LibCInstallation = struct { else => return error.FileSystem, }; - self.kernel32_lib_dir = result_buf.toOwnedSlice(); + found = true; + self.kernel32_lib_dir = dir_path; return; } return error.LibCKernel32LibNotFound; @@ -470,12 +489,16 @@ 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(); - - try result_buf.append("\\include"); + const dir_path = try fs.path.join( + allocator, + &[_][]const u8{ + up2, + "include", + }, + ); + errdefer allocator.free(dir_path); - 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 +513,7 @@ pub const LibCInstallation = struct { else => return error.FileSystem, }; - self.sys_include_dir = result_buf.toOwnedSlice(); + self.sys_include_dir = dir_path; } fn findNativeMsvcLibDir( diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index fcf9634097b7..e2be750f57b2 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -411,10 +411,11 @@ 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); + 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(); try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text }); @@ -741,15 +742,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 { @@ -793,19 +794,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; } diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index f1d7d665468c..48a8d7fca9ad 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -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, @@ -296,7 +296,8 @@ pub fn translate( .eof_token = undefined, }; - var source_buffer = try std.Buffer.initSize(arena, 0); + var source_buffer = std.ArrayList(u8).init(arena); + errdefer source_buffer.deinit(); var context = Context{ .tree = tree, @@ -4289,7 +4290,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, }; } @@ -4751,11 +4752,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); @@ -4765,7 +4766,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; } diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 70ed754cea75..6adad9fa67f8 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -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| { diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp index 3cff34ea5c4f..c12d8f29ef8a 100644 --- a/src/cache_hash.cpp +++ b/src/cache_hash.cpp @@ -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 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); } diff --git a/src/cache_hash.hpp b/src/cache_hash.hpp index 9e4c41b1e003..ba2434076a88 100644 --- a/src/cache_hash.hpp +++ b/src/cache_hash.hpp @@ -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 slice); void cache_str(CacheHash *ch, const char *ptr); void cache_int(CacheHash *ch, int x); void cache_bool(CacheHash *ch, bool x); diff --git a/src/codegen.cpp b/src/codegen.cpp index d36e398bf7ef..2c2bf7c36ba6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9123,21 +9123,26 @@ static void detect_libc(CodeGen *g) { g->libc_include_dir_len = 0; g->libc_include_dir_list = heap::c_allocator.allocate(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 +10551,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{g->libc->include_dir, g->libc->include_dir_len}); + cache_slice(ch, Slice{g->libc->sys_include_dir, g->libc->sys_include_dir_len}); + cache_slice(ch, Slice{g->libc->crt_dir, g->libc->crt_dir_len}); + cache_slice(ch, Slice{g->libc->msvc_lib_dir, g->libc->msvc_lib_dir_len}); + cache_slice(ch, Slice{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); diff --git a/src/link.cpp b/src/link.cpp index ed6275ec3a45..73e429aa0b9c 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1594,7 +1594,7 @@ 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); } } @@ -1859,7 +1859,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)) { @@ -2380,14 +2380,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)); } }