Commit eb4028bf30

Andrew Kelley <andrew@ziglang.org>
2024-07-20 02:39:55
add std.fmt.hex
converts an unsigned integer into an array
1 parent 9d00f69
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).?;
 
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 };
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.
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),
+        }
+    }
+}
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});
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;
 
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
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|
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();