authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-02-12 20:44:19+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-01 15:33:10-08:00
logcd7c870bd81391dd97c5c75eb3910382ba7280a1
treed5cd602d13a7936b3b4881de8e36a052c873ee96
parentbee7db77fe65802a41f2812caac4faa7dcb8acd3

std: Deprecate 'x'/'X'/'e'/'E' special cases for u8 slices

Let's follow the road paved by the removal of 'z'/'Z', the Formatter pattern is nice enough to let us remove the remaining four special cases and declare u8 slices free from any special casing!

9 files changed, 140 insertions(+), 46 deletions(-)

lib/std/crypto/25519/curve25519.zig+2-2
...@@ -115,9 +115,9 @@ test "curve25519" {...@@ -115,9 +115,9 @@ test "curve25519" {
115 const p = try Curve25519.basePoint.clampedMul(s);115 const p = try Curve25519.basePoint.clampedMul(s);
116 try p.rejectIdentity();116 try p.rejectIdentity();
117 var buf: [128]u8 = undefined;117 var buf: [128]u8 = undefined;
118 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E6F2A4D1C28EE5C7AD0329268255A468AD407D2672824C0C0EB30EA6EF450145");118 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&p.toBytes())}), "E6F2A4D1C28EE5C7AD0329268255A468AD407D2672824C0C0EB30EA6EF450145");
119 const q = try p.clampedMul(s);119 const q = try p.clampedMul(s);
120 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{q.toBytes()}), "3614E119FFE55EC55B87D6B19971A9F4CBC78EFE80BEC55B96392BABCC712537");120 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&q.toBytes())}), "3614E119FFE55EC55B87D6B19971A9F4CBC78EFE80BEC55B96392BABCC712537");
121121
122 try Curve25519.rejectNonCanonical(s);122 try Curve25519.rejectNonCanonical(s);
123 s[31] |= 0x80;123 s[31] |= 0x80;
lib/std/crypto/25519/ed25519.zig+3-3
...@@ -210,8 +210,8 @@ test "ed25519 key pair creation" {...@@ -210,8 +210,8 @@ test "ed25519 key pair creation" {
210 _ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");210 _ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
211 const key_pair = try Ed25519.KeyPair.create(seed);211 const key_pair = try Ed25519.KeyPair.create(seed);
212 var buf: [256]u8 = undefined;212 var buf: [256]u8 = undefined;
213 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{key_pair.secret_key}), "8052030376D47112BE7F73ED7A019293DD12AD910B654455798B4667D73DE1662D6F7455D97B4A3A10D7293909D1A4F2058CB9A370E43FA8154BB280DB839083");213 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&key_pair.secret_key)}), "8052030376D47112BE7F73ED7A019293DD12AD910B654455798B4667D73DE1662D6F7455D97B4A3A10D7293909D1A4F2058CB9A370E43FA8154BB280DB839083");
214 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{key_pair.public_key}), "2D6F7455D97B4A3A10D7293909D1A4F2058CB9A370E43FA8154BB280DB839083");214 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&key_pair.public_key)}), "2D6F7455D97B4A3A10D7293909D1A4F2058CB9A370E43FA8154BB280DB839083");
215}215}
216216
217test "ed25519 signature" {217test "ed25519 signature" {
...@@ -221,7 +221,7 @@ test "ed25519 signature" {...@@ -221,7 +221,7 @@ test "ed25519 signature" {
221221
222 const sig = try Ed25519.sign("test", key_pair, null);222 const sig = try Ed25519.sign("test", key_pair, null);
223 var buf: [128]u8 = undefined;223 var buf: [128]u8 = undefined;
224 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{sig}), "10A442B4A80CC4225B154F43BEF28D2472CA80221951262EB8E0DF9091575E2687CC486E77263C3418C757522D54F84B0359236ABBBD4ACD20DC297FDCA66808");224 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&sig)}), "10A442B4A80CC4225B154F43BEF28D2472CA80221951262EB8E0DF9091575E2687CC486E77263C3418C757522D54F84B0359236ABBBD4ACD20DC297FDCA66808");
225 try Ed25519.verify(sig, "test", key_pair.public_key);225 try Ed25519.verify(sig, "test", key_pair.public_key);
226 std.testing.expectError(error.InvalidSignature, Ed25519.verify(sig, "TEST", key_pair.public_key));226 std.testing.expectError(error.InvalidSignature, Ed25519.verify(sig, "TEST", key_pair.public_key));
227}227}
lib/std/crypto/25519/edwards25519.zig+1-1
...@@ -450,7 +450,7 @@ test "edwards25519 packing/unpacking" {...@@ -450,7 +450,7 @@ test "edwards25519 packing/unpacking" {
450 var b = Edwards25519.basePoint;450 var b = Edwards25519.basePoint;
451 const pk = try b.mul(s);451 const pk = try b.mul(s);
452 var buf: [128]u8 = undefined;452 var buf: [128]u8 = undefined;
453 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{pk.toBytes()}), "074BC7E0FCBD587FDBC0969444245FADC562809C8F6E97E949AF62484B5B81A6");453 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&pk.toBytes())}), "074BC7E0FCBD587FDBC0969444245FADC562809C8F6E97E949AF62484B5B81A6");
454454
455 const small_order_ss: [7][32]u8 = .{455 const small_order_ss: [7][32]u8 = .{
456 .{456 .{
lib/std/crypto/25519/ristretto255.zig+4-4
...@@ -170,21 +170,21 @@ pub const Ristretto255 = struct {...@@ -170,21 +170,21 @@ pub const Ristretto255 = struct {
170test "ristretto255" {170test "ristretto255" {
171 const p = Ristretto255.basePoint;171 const p = Ristretto255.basePoint;
172 var buf: [256]u8 = undefined;172 var buf: [256]u8 = undefined;
173 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76");173 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&p.toBytes())}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76");
174174
175 var r: [Ristretto255.encoded_length]u8 = undefined;175 var r: [Ristretto255.encoded_length]u8 = undefined;
176 _ = try fmt.hexToBytes(r[0..], "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919");176 _ = try fmt.hexToBytes(r[0..], "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919");
177 var q = try Ristretto255.fromBytes(r);177 var q = try Ristretto255.fromBytes(r);
178 q = q.dbl().add(p);178 q = q.dbl().add(p);
179 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{q.toBytes()}), "E882B131016B52C1D3337080187CF768423EFCCBB517BB495AB812C4160FF44E");179 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&q.toBytes())}), "E882B131016B52C1D3337080187CF768423EFCCBB517BB495AB812C4160FF44E");
180180
181 const s = [_]u8{15} ++ [_]u8{0} ** 31;181 const s = [_]u8{15} ++ [_]u8{0} ** 31;
182 const w = try p.mul(s);182 const w = try p.mul(s);
183 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{w.toBytes()}), "E0C418F7C8D9C4CDD7395B93EA124F3AD99021BB681DFC3302A9D99A2E53E64E");183 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&w.toBytes())}), "E0C418F7C8D9C4CDD7395B93EA124F3AD99021BB681DFC3302A9D99A2E53E64E");
184184
185 std.testing.expect(p.dbl().dbl().dbl().dbl().equivalent(w.add(p)));185 std.testing.expect(p.dbl().dbl().dbl().dbl().equivalent(w.add(p)));
186186
187 const h = [_]u8{69} ** 32 ++ [_]u8{42} ** 32;187 const h = [_]u8{69} ** 32 ++ [_]u8{42} ** 32;
188 const ph = Ristretto255.fromUniform(h);188 const ph = Ristretto255.fromUniform(h);
189 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{ph.toBytes()}), "DCCA54E037A4311EFBEEF413ACD21D35276518970B7A61DC88F8587B493D5E19");189 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&ph.toBytes())}), "DCCA54E037A4311EFBEEF413ACD21D35276518970B7A61DC88F8587B493D5E19");
190}190}
lib/std/crypto/25519/scalar.zig+3-3
...@@ -771,10 +771,10 @@ test "scalar25519" {...@@ -771,10 +771,10 @@ test "scalar25519" {
771 var y = x.toBytes();771 var y = x.toBytes();
772 try rejectNonCanonical(y);772 try rejectNonCanonical(y);
773 var buf: [128]u8 = undefined;773 var buf: [128]u8 = undefined;
774 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{y}), "1E979B917937F3DE71D18077F961F6CEFF01030405060708010203040506070F");774 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&y)}), "1E979B917937F3DE71D18077F961F6CEFF01030405060708010203040506070F");
775775
776 const reduced = reduce(field_size);776 const reduced = reduce(field_size);
777 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{reduced}), "0000000000000000000000000000000000000000000000000000000000000000");777 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&reduced)}), "0000000000000000000000000000000000000000000000000000000000000000");
778}778}
779779
780test "non-canonical scalar25519" {780test "non-canonical scalar25519" {
...@@ -788,5 +788,5 @@ test "mulAdd overflow check" {...@@ -788,5 +788,5 @@ test "mulAdd overflow check" {
788 const c: [32]u8 = [_]u8{0xff} ** 32;788 const c: [32]u8 = [_]u8{0xff} ** 32;
789 const x = mulAdd(a, b, c);789 const x = mulAdd(a, b, c);
790 var buf: [128]u8 = undefined;790 var buf: [128]u8 = undefined;
791 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{x}), "D14DF91389432C25AD60FF9791B9FD1D67BEF517D273ECCE3D9A307C1B419903");791 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&x)}), "D14DF91389432C25AD60FF9791B9FD1D67BEF517D273ECCE3D9A307C1B419903");
792}792}
lib/std/crypto/chacha20.zig+2-2
...@@ -876,7 +876,7 @@ test "crypto.xchacha20" {...@@ -876,7 +876,7 @@ test "crypto.xchacha20" {
876 var ciphertext: [input.len]u8 = undefined;876 var ciphertext: [input.len]u8 = undefined;
877 XChaCha20IETF.xor(ciphertext[0..], input[0..], 0, key, nonce);877 XChaCha20IETF.xor(ciphertext[0..], input[0..], 0, key, nonce);
878 var buf: [2 * ciphertext.len]u8 = undefined;878 var buf: [2 * ciphertext.len]u8 = undefined;
879 testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{ciphertext}), "E0A1BCF939654AFDBDC1746EC49832647C19D891F0D1A81FC0C1703B4514BDEA584B512F6908C2C5E9DD18D5CBC1805DE5803FE3B9CA5F193FB8359E91FAB0C3BB40309A292EB1CF49685C65C4A3ADF4F11DB0CD2B6B67FBC174BC2E860E8F769FD3565BBFAD1C845E05A0FED9BE167C240D");879 testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&ciphertext)}), "E0A1BCF939654AFDBDC1746EC49832647C19D891F0D1A81FC0C1703B4514BDEA584B512F6908C2C5E9DD18D5CBC1805DE5803FE3B9CA5F193FB8359E91FAB0C3BB40309A292EB1CF49685C65C4A3ADF4F11DB0CD2B6B67FBC174BC2E860E8F769FD3565BBFAD1C845E05A0FED9BE167C240D");
880 }880 }
881 {881 {
882 const data = "Additional data";882 const data = "Additional data";
...@@ -885,7 +885,7 @@ test "crypto.xchacha20" {...@@ -885,7 +885,7 @@ test "crypto.xchacha20" {
885 var out: [input.len]u8 = undefined;885 var out: [input.len]u8 = undefined;
886 try xchacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce);886 try xchacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce);
887 var buf: [2 * ciphertext.len]u8 = undefined;887 var buf: [2 * ciphertext.len]u8 = undefined;
888 testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{ciphertext}), "994D2DD32333F48E53650C02C7A2ABB8E018B0836D7175AEC779F52E961780768F815C58F1AA52D211498DB89B9216763F569C9433A6BBFCEFB4D4A49387A4C5207FBB3B5A92B5941294DF30588C6740D39DC16FA1F0E634F7246CF7CDCB978E44347D89381B7A74EB7084F754B90BDE9AAF5A94B8F2A85EFD0B50692AE2D425E234");888 testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&ciphertext)}), "994D2DD32333F48E53650C02C7A2ABB8E018B0836D7175AEC779F52E961780768F815C58F1AA52D211498DB89B9216763F569C9433A6BBFCEFB4D4A49387A4C5207FBB3B5A92B5941294DF30588C6740D39DC16FA1F0E634F7246CF7CDCB978E44347D89381B7A74EB7084F754B90BDE9AAF5A94B8F2A85EFD0B50692AE2D425E234");
889 testing.expectEqualSlices(u8, out[0..], input);889 testing.expectEqualSlices(u8, out[0..], input);
890 ciphertext[0] += 1;890 ciphertext[0] += 1;
891 testing.expectError(error.AuthenticationFailed, xchacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce));891 testing.expectError(error.AuthenticationFailed, xchacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce));
lib/std/fmt.zig+104-26
...@@ -709,6 +709,87 @@ fn formatFloatValue(...@@ -709,6 +709,87 @@ fn formatFloatValue(
709 return formatBuf(buf_stream.getWritten(), options, writer);709 return formatBuf(buf_stream.getWritten(), options, writer);
710}710}
711711
712fn formatSliceHexImpl(comptime uppercase: bool) type {
713 const charset = "0123456789" ++ if (uppercase) "ABCDEF" else "abcdef";
714
715 return struct {
716 pub fn f(
717 bytes: []const u8,
718 comptime fmt: []const u8,
719 options: std.fmt.FormatOptions,
720 writer: anytype,
721 ) !void {
722 var buf: [2]u8 = undefined;
723
724 for (bytes) |c| {
725 buf[0] = charset[c >> 4];
726 buf[1] = charset[c & 15];
727 try writer.writeAll(&buf);
728 }
729 }
730 };
731}
732
733const formatSliceHexLower = formatSliceHexImpl(false).f;
734const formatSliceHexUpper = formatSliceHexImpl(true).f;
735
736/// Return a Formatter for a []const u8 where every byte is formatted as a pair
737/// of lowercase hexadecimal digits.
738pub fn fmtSliceHexLower(bytes: []const u8) std.fmt.Formatter(formatSliceHexLower) {
739 return .{ .data = bytes };
740}
741
742/// Return a Formatter for a []const u8 where every byte is formatted as a pair
743/// of uppercase hexadecimal digits.
744pub fn fmtSliceHexUpper(bytes: []const u8) std.fmt.Formatter(formatSliceHexUpper) {
745 return .{ .data = bytes };
746}
747
748fn formatSliceEscapeImpl(comptime uppercase: bool) type {
749 const charset = "0123456789" ++ if (uppercase) "ABCDEF" else "abcdef";
750
751 return struct {
752 pub fn f(
753 bytes: []const u8,
754 comptime fmt: []const u8,
755 options: std.fmt.FormatOptions,
756 writer: anytype,
757 ) !void {
758 var buf: [4]u8 = undefined;
759
760 buf[0] = '\\';
761 buf[1] = 'x';
762
763 for (bytes) |c| {
764 if (std.ascii.isPrint(c)) {
765 try writer.writeByte(c);
766 } else {
767 buf[2] = charset[c >> 4];
768 buf[3] = charset[c & 15];
769 try writer.writeAll(&buf);
770 }
771 }
772 }
773 };
774}
775
776const formatSliceEscapeLower = formatSliceEscapeImpl(false).f;
777const formatSliceEscapeUpper = formatSliceEscapeImpl(true).f;
778
779/// Return a Formatter for a []const u8 where every non-printable ASCII
780/// character is escaped as \xNN, where NN is the character in lowercase
781/// hexadecimal notation.
782pub fn fmtSliceEscapeLower(bytes: []const u8) std.fmt.Formatter(formatSliceEscapeLower) {
783 return .{ .data = bytes };
784}
785
786/// Return a Formatter for a []const u8 where every non-printable ASCII
787/// character is escaped as \xNN, where NN is the character in uppercase
788/// hexadecimal notation.
789pub fn fmtSliceEscapeUpper(bytes: []const u8) std.fmt.Formatter(formatSliceEscapeUpper) {
790 return .{ .data = bytes };
791}
792
712pub fn formatText(793pub fn formatText(
713 bytes: []const u8,794 bytes: []const u8,
714 comptime fmt: []const u8,795 comptime fmt: []const u8,
...@@ -717,21 +798,18 @@ pub fn formatText(...@@ -717,21 +798,18 @@ pub fn formatText(
717) !void {798) !void {
718 if (comptime std.mem.eql(u8, fmt, "s")) {799 if (comptime std.mem.eql(u8, fmt, "s")) {
719 return formatBuf(bytes, options, writer);800 return formatBuf(bytes, options, writer);
720 } else if (comptime (std.mem.eql(u8, fmt, "x") or std.mem.eql(u8, fmt, "X"))) {801 } else if (comptime (std.mem.eql(u8, fmt, "x"))) {
721 for (bytes) |c| {802 @compileError("specifier 'x' has been deprecated, wrap your argument in std.fmt.fmtSliceHexLower instead");
722 try formatInt(c, 16, fmt[0] == 'X', FormatOptions{ .width = 2, .fill = '0' }, writer);803 } else if (comptime (std.mem.eql(u8, fmt, "X"))) {
723 }804 @compileError("specifier 'X' has been deprecated, wrap your argument in std.fmt.fmtSliceHexUpper instead");
724 return;805 } else if (comptime (std.mem.eql(u8, fmt, "e"))) {
725 } else if (comptime (std.mem.eql(u8, fmt, "e") or std.mem.eql(u8, fmt, "E"))) {806 @compileError("specifier 'e' has been deprecated, wrap your argument in std.fmt.fmtSliceEscapeLower instead");
726 for (bytes) |c| {807 } else if (comptime (std.mem.eql(u8, fmt, "E"))) {
727 if (std.ascii.isPrint(c)) {808 @compileError("specifier 'X' has been deprecated, wrap your argument in std.fmt.fmtSliceEscapeUpper instead");
728 try writer.writeByte(c);809 } else if (comptime std.mem.eql(u8, fmt, "z")) {
729 } else {810 @compileError("specifier 'z' has been deprecated, wrap your argument in std.zig.fmtId instead");
730 try writer.writeAll("\\x");811 } else if (comptime std.mem.eql(u8, fmt, "Z")) {
731 try formatInt(c, 16, fmt[0] == 'E', FormatOptions{ .width = 2, .fill = '0' }, writer);812 @compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead");
732 }
733 }
734 return;
735 } else {813 } else {
736 @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");814 @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
737 }815 }
...@@ -1693,9 +1771,9 @@ test "slice" {...@@ -1693,9 +1771,9 @@ test "slice" {
1693}1771}
16941772
1695test "escape non-printable" {1773test "escape non-printable" {
1696 try expectFmt("abc", "{e}", .{"abc"});1774 try expectFmt("abc", "{s}", .{fmtSliceEscapeLower("abc")});
1697 try expectFmt("ab\\xffc", "{e}", .{"ab\xffc"});1775 try expectFmt("ab\\xffc", "{s}", .{fmtSliceEscapeLower("ab\xffc")});
1698 try expectFmt("ab\\xFFc", "{E}", .{"ab\xffc"});1776 try expectFmt("ab\\xFFc", "{s}", .{fmtSliceEscapeUpper("ab\xffc")});
1699}1777}
17001778
1701test "pointer" {1779test "pointer" {
...@@ -1968,13 +2046,13 @@ test "struct.zero-size" {...@@ -1968,13 +2046,13 @@ test "struct.zero-size" {
19682046
1969test "bytes.hex" {2047test "bytes.hex" {
1970 const some_bytes = "\xCA\xFE\xBA\xBE";2048 const some_bytes = "\xCA\xFE\xBA\xBE";
1971 try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes});2049 try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(some_bytes)});
1972 try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes});2050 try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{fmtSliceHexUpper(some_bytes)});
1973 //Test Slices2051 //Test Slices
1974 try expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]});2052 try expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{fmtSliceHexUpper(some_bytes[0..2])});
1975 try expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]});2053 try expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{fmtSliceHexLower(some_bytes[2..])});
1976 const bytes_with_zeros = "\x00\x0E\xBA\xBE";2054 const bytes_with_zeros = "\x00\x0E\xBA\xBE";
1977 try expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros});2055 try expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(bytes_with_zeros)});
1978}2056}
19792057
1980pub const trim = @compileError("deprecated; use std.mem.trim with std.ascii.spaces instead");2058pub const trim = @compileError("deprecated; use std.mem.trim with std.ascii.spaces instead");
...@@ -2002,9 +2080,9 @@ pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {...@@ -2002,9 +2080,9 @@ pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {
20022080
2003test "hexToBytes" {2081test "hexToBytes" {
2004 var buf: [32]u8 = undefined;2082 var buf: [32]u8 = undefined;
2005 try expectFmt("90" ** 32, "{X}", .{try hexToBytes(&buf, "90" ** 32)});2083 try expectFmt("90" ** 32, "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "90" ** 32))});
2006 try expectFmt("ABCD", "{X}", .{try hexToBytes(&buf, "ABCD")});2084 try expectFmt("ABCD", "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, "ABCD"))});
2007 try expectFmt("", "{X}", .{try hexToBytes(&buf, "")});2085 try expectFmt("", "{s}", .{fmtSliceHexUpper(try hexToBytes(&buf, ""))});
2008 std.testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z"));2086 std.testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z"));
2009 std.testing.expectError(error.InvalidLength, hexToBytes(&buf, "AAA"));2087 std.testing.expectError(error.InvalidLength, hexToBytes(&buf, "AAA"));
2010 std.testing.expectError(error.NoSpaceLeft, hexToBytes(buf[0..1], "ABAB"));2088 std.testing.expectError(error.NoSpaceLeft, hexToBytes(buf[0..1], "ABAB"));
src/Cache.zig+20-4
...@@ -153,7 +153,11 @@ pub const HashHelper = struct {...@@ -153,7 +153,11 @@ pub const HashHelper = struct {
153 hh.hasher.final(&bin_digest);153 hh.hasher.final(&bin_digest);
154154
155 var out_digest: [hex_digest_len]u8 = undefined;155 var out_digest: [hex_digest_len]u8 = undefined;
156 _ = std.fmt.bufPrint(&out_digest, "{x}", .{bin_digest}) catch unreachable;156 _ = std.fmt.bufPrint(
157 &out_digest,
158 "{s}",
159 .{std.fmt.fmtSliceHexLower(&bin_digest)},
160 ) catch unreachable;
157 return out_digest;161 return out_digest;
158 }162 }
159};163};
...@@ -250,7 +254,11 @@ pub const Manifest = struct {...@@ -250,7 +254,11 @@ pub const Manifest = struct {
250 var bin_digest: BinDigest = undefined;254 var bin_digest: BinDigest = undefined;
251 self.hash.hasher.final(&bin_digest);255 self.hash.hasher.final(&bin_digest);
252256
253 _ = std.fmt.bufPrint(&self.hex_digest, "{x}", .{bin_digest}) catch unreachable;257 _ = std.fmt.bufPrint(
258 &self.hex_digest,
259 "{s}",
260 .{std.fmt.fmtSliceHexLower(&bin_digest)},
261 ) catch unreachable;
254262
255 self.hash.hasher = hasher_init;263 self.hash.hasher = hasher_init;
256 self.hash.hasher.update(&bin_digest);264 self.hash.hasher.update(&bin_digest);
...@@ -549,7 +557,11 @@ pub const Manifest = struct {...@@ -549,7 +557,11 @@ pub const Manifest = struct {
549 self.hash.hasher.final(&bin_digest);557 self.hash.hasher.final(&bin_digest);
550558
551 var out_digest: [hex_digest_len]u8 = undefined;559 var out_digest: [hex_digest_len]u8 = undefined;
552 _ = std.fmt.bufPrint(&out_digest, "{x}", .{bin_digest}) catch unreachable;560 _ = std.fmt.bufPrint(
561 &out_digest,
562 "{s}",
563 .{std.fmt.fmtSliceHexLower(&bin_digest)},
564 ) catch unreachable;
553565
554 return out_digest;566 return out_digest;
555 }567 }
...@@ -565,7 +577,11 @@ pub const Manifest = struct {...@@ -565,7 +577,11 @@ pub const Manifest = struct {
565 var encoded_digest: [hex_digest_len]u8 = undefined;577 var encoded_digest: [hex_digest_len]u8 = undefined;
566578
567 for (self.files.items) |file| {579 for (self.files.items) |file| {
568 _ = std.fmt.bufPrint(&encoded_digest, "{x}", .{file.bin_digest}) catch unreachable;580 _ = std.fmt.bufPrint(
581 &encoded_digest,
582 "{s}",
583 .{std.fmt.fmtSliceHexLower(&file.bin_digest)},
584 ) catch unreachable;
569 try writer.print("{d} {d} {d} {s} {s}\n", .{585 try writer.print("{d} {d} {d} {s} {s}\n", .{
570 file.stat.size,586 file.stat.size,
571 file.stat.inode,587 file.stat.inode,
src/translate_c.zig+1-1
...@@ -4608,7 +4608,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N...@@ -4608,7 +4608,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
4608 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {4608 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
4609 return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));4609 return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));
4610 } else {4610 } else {
4611 const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]});4611 const str = try std.fmt.allocPrint(c.arena, "0x{s}", .{std.fmt.fmtSliceHexLower(slice[1 .. slice.len - 1])});
4612 return Tag.integer_literal.create(c.arena, str);4612 return Tag.integer_literal.create(c.arena, str);
4613 }4613 }
4614 },4614 },