diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 06de7aa6f4..c68170b2c1 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -2522,7 +2522,7 @@ pub const InstallDir = union(enum) { /// function. pub fn makeTempPath(b: *Build) []const u8 { const rand_int = std.crypto.random.int(u64); - const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ hex64(rand_int); + const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); const result_path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch @panic("OOM"); b.cache_root.handle.makePath(tmp_dir_sub_path) catch |err| { std.debug.print("unable to make tmp path '{s}': {s}\n", .{ @@ -2532,18 +2532,9 @@ pub fn makeTempPath(b: *Build) []const u8 { return result_path; } -/// There are a few copies of this function in miscellaneous places. Would be nice to find -/// a home for them. +/// Deprecated; use `std.fmt.hex` instead. pub fn hex64(x: u64) [16]u8 { - const hex_charset = "0123456789abcdef"; - var result: [16]u8 = undefined; - var i: usize = 0; - while (i < 8) : (i += 1) { - const byte: u8 = @truncate(x >> @as(u6, @intCast(8 * i))); - result[i * 2 + 0] = hex_charset[byte >> 4]; - result[i * 2 + 1] = hex_charset[byte & 15]; - } - return result; + return std.fmt.hex(x); } /// A pair of target query and fully resolved target. diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 7c872db170..6131912b1b 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -457,7 +457,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { const rand_int = std.crypto.random.int(u64); const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ - std.Build.hex64(rand_int) ++ fs.path.sep_str ++ + std.fmt.hex(rand_int) ++ fs.path.sep_str ++ basename; const tmp_sub_path_dirname = fs.path.dirname(tmp_sub_path).?; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index d79d4647b1..0712ce8083 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -743,7 +743,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { // We do not know the final output paths yet, use temp paths to run the command. const rand_int = std.crypto.random.int(u64); - const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.Build.hex64(rand_int); + const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); for (output_placeholders.items) |placeholder| { const output_components = .{ tmp_dir_path, placeholder.output.basename }; diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index a4407a8cd2..6283c9453e 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -2718,3 +2718,38 @@ test "recursive format function" { var r = R{ .Leaf = 1 }; try expectFmt("Leaf(1)\n", "{}\n", .{&r}); } + +pub const hex_charset = "0123456789abcdef"; + +/// Converts an unsigned integer of any multiple of u8 to an array of lowercase +/// hex bytes. +pub fn hex(x: anytype) [@sizeOf(@TypeOf(x)) * 2]u8 { + comptime assert(@typeInfo(@TypeOf(x)).Int.signedness == .unsigned); + var result: [@sizeOf(@TypeOf(x)) * 2]u8 = undefined; + var i: usize = 0; + while (i < result.len / 2) : (i += 1) { + const byte: u8 = @truncate(x >> @intCast(8 * i)); + result[i * 2 + 0] = hex_charset[byte >> 4]; + result[i * 2 + 1] = hex_charset[byte & 15]; + } + return result; +} + +test hex { + { + const x = hex(@as(u32, 0xdeadbeef)); + try std.testing.expect(x.len == 8); + switch (builtin.cpu.arch.endian()) { + .little => try std.testing.expectEqualStrings("efbeadde", &x), + .big => try std.testing.expectEqualStrings("deadbeef", &x), + } + } + { + const s = "[" ++ hex(@as(u64, 0x12345678_abcdef00)) ++ "]"; + try std.testing.expect(s.len == 18); + switch (builtin.cpu.arch.endian()) { + .little => try std.testing.expectEqualStrings("[00efcdab78563412]", s), + .big => try std.testing.expectEqualStrings("[12345678abcdef00]", s), + } + } +} diff --git a/src/Compilation.zig b/src/Compilation.zig index b1c1851a6c..a36ab2a47e 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2106,7 +2106,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { const tmp_artifact_directory = d: { const s = std.fs.path.sep_str; tmp_dir_rand_int = std.crypto.random.int(u64); - const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int); + const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); const path = try comp.local_cache_directory.join(gpa, &.{tmp_dir_sub_path}); errdefer gpa.free(path); @@ -2298,7 +2298,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { } else unreachable; const s = std.fs.path.sep_str; - const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int); + const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); const o_sub_path = "o" ++ s ++ digest; // Work around windows `AccessDenied` if any files within this diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index f6e5c2e222..28030e3879 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -445,7 +445,7 @@ fn runResource( const s = fs.path.sep_str; const cache_root = f.job_queue.global_cache; const rand_int = std.crypto.random.int(u64); - const tmp_dir_sub_path = "tmp" ++ s ++ Manifest.hex64(rand_int); + const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(rand_int); const package_sub_path = blk: { const tmp_directory_path = try cache_root.join(arena, &.{tmp_dir_sub_path}); diff --git a/src/Package/Manifest.zig b/src/Package/Manifest.zig index 3bcb4a7958..d9c39f5ab3 100644 --- a/src/Package/Manifest.zig +++ b/src/Package/Manifest.zig @@ -1,3 +1,12 @@ +const Manifest = @This(); +const std = @import("std"); +const mem = std.mem; +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const Ast = std.zig.Ast; +const testing = std.testing; +const hex_charset = std.fmt.hex_charset; + pub const max_bytes = 10 * 1024 * 1024; pub const basename = "build.zig.zon"; pub const Hash = std.crypto.hash.sha2.Sha256; @@ -153,24 +162,6 @@ pub fn copyErrorsIntoBundle( } } -const hex_charset = "0123456789abcdef"; - -pub fn hex64(x: u64) [16]u8 { - var result: [16]u8 = undefined; - var i: usize = 0; - while (i < 8) : (i += 1) { - const byte = @as(u8, @truncate(x >> @as(u6, @intCast(8 * i)))); - result[i * 2 + 0] = hex_charset[byte >> 4]; - result[i * 2 + 1] = hex_charset[byte & 15]; - } - return result; -} - -test hex64 { - const s = "[" ++ hex64(0x12345678_abcdef00) ++ "]"; - try std.testing.expectEqualStrings("[00efcdab78563412]", s); -} - pub fn hexDigest(digest: Digest) MultiHashHexDigest { var result: MultiHashHexDigest = undefined; @@ -590,14 +581,6 @@ const Parse = struct { } }; -const Manifest = @This(); -const std = @import("std"); -const mem = std.mem; -const Allocator = std.mem.Allocator; -const assert = std.debug.assert; -const Ast = std.zig.Ast; -const testing = std.testing; - test "basic" { const gpa = testing.allocator; diff --git a/src/link.zig b/src/link.zig index cf780c76fa..fd74f078ac 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1031,7 +1031,7 @@ pub fn spawnLld( error.NameTooLong => err: { const s = fs.path.sep_str; const rand_int = std.crypto.random.int(u64); - const rsp_path = "tmp" ++ s ++ Package.Manifest.hex64(rand_int) ++ ".rsp"; + const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; const rsp_file = try comp.local_cache_directory.handle.createFileZ(rsp_path, .{}); defer comp.local_cache_directory.handle.deleteFileZ(rsp_path) catch |err| diff --git a/src/main.zig b/src/main.zig index 64cbbdffe4..561dd2f28e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4746,7 +4746,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { // the strategy is to choose a temporary file name ahead of time, and then // read this file in the parent to obtain the results, in the case the child // exits with code 3. - const results_tmp_file_nonce = Package.Manifest.hex64(std.crypto.random.int(u64)); + const results_tmp_file_nonce = std.fmt.hex(std.crypto.random.int(u64)); try child_argv.append("-Z" ++ results_tmp_file_nonce); var color: Color = .auto; @@ -7196,8 +7196,7 @@ fn createDependenciesModule( // Atomically create the file in a directory named after the hash of its contents. const basename = "dependencies.zig"; const rand_int = std.crypto.random.int(u64); - const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ - Package.Manifest.hex64(rand_int); + const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); { var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); defer tmp_dir.close();