authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-24 16:20:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-24 17:01:19-07:00
log92505a7de7f720acc74906a053cd89a33174eb1f
tree679a88feade1d36d53a073ac2d149173a0fae580
parent9dda196eea5fc5f299eb87feb93a8d7e756ba2fa

std: move fmt.bufPrint to mem.print


2 files changed, 166 insertions(+), 118 deletions(-)

lib/std/fmt.zig+113-114
......@@ -6,8 +6,6 @@ const std = @import("std.zig");
66const math = std.math;
77const assert = std.debug.assert;
88const mem = std.mem;
9const meta = std.meta;
10const lossyCast = math.lossyCast;
119const expectFmt = std.testing.expectFmt;
1210const testing = std.testing;
1311const Allocator = std.mem.Allocator;
......@@ -254,6 +252,13 @@ pub fn printInt(buffer: []u8, value: anytype, base: u8, case: Case, options: Opt
254252 return w.end;
255253}
256254
255test printInt {
256 const x: i32 = -3;
257 var buffer: [64]u8 = undefined;
258 const s = buffer[0..printInt(&buffer, x, 10, .lower, .{})];
259 try testing.expectEqualStrings("-3", s);
260}
261
257262/// Converts values in the range [0, 100) to a base 10 string.
258263pub fn digits2(value: u8) [2]u8 {
259264 if (builtin.mode == .ReleaseSmall) {
......@@ -332,63 +337,63 @@ pub fn parseIntWithGenericCharacter(
332337}
333338
334339test parseInt {
335 try std.testing.expectEqual(-10, try parseInt(i32, "-10", 10));
336 try std.testing.expectEqual(10, try parseInt(i32, "+10", 10));
337 try std.testing.expectEqual(10, try parseInt(u32, "+10", 10));
338 try std.testing.expectError(error.Overflow, parseInt(u32, "-10", 10));
339 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, " 10", 10));
340 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "10 ", 10));
341 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "_10_", 10));
342 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0x_10_", 10));
343 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0x10_", 10));
344 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0x_10", 10));
345 try std.testing.expectEqual(255, try parseInt(u8, "255", 10));
346 try std.testing.expectError(error.Overflow, parseInt(u8, "256", 10));
340 try testing.expectEqual(-10, try parseInt(i32, "-10", 10));
341 try testing.expectEqual(10, try parseInt(i32, "+10", 10));
342 try testing.expectEqual(10, try parseInt(u32, "+10", 10));
343 try testing.expectError(error.Overflow, parseInt(u32, "-10", 10));
344 try testing.expectError(error.InvalidCharacter, parseInt(u32, " 10", 10));
345 try testing.expectError(error.InvalidCharacter, parseInt(u32, "10 ", 10));
346 try testing.expectError(error.InvalidCharacter, parseInt(u32, "_10_", 10));
347 try testing.expectError(error.InvalidCharacter, parseInt(u32, "0x_10_", 10));
348 try testing.expectError(error.InvalidCharacter, parseInt(u32, "0x10_", 10));
349 try testing.expectError(error.InvalidCharacter, parseInt(u32, "0x_10", 10));
350 try testing.expectEqual(255, try parseInt(u8, "255", 10));
351 try testing.expectError(error.Overflow, parseInt(u8, "256", 10));
347352
348353 // +0 and -0 should work for unsigned
349 try std.testing.expectEqual(0, try parseInt(u8, "-0", 10));
350 try std.testing.expectEqual(0, try parseInt(u8, "+0", 10));
354 try testing.expectEqual(0, try parseInt(u8, "-0", 10));
355 try testing.expectEqual(0, try parseInt(u8, "+0", 10));
351356
352357 // ensure minInt is parsed correctly
353 try std.testing.expectEqual(math.minInt(i1), try parseInt(i1, "-1", 10));
354 try std.testing.expectEqual(math.minInt(i8), try parseInt(i8, "-128", 10));
355 try std.testing.expectEqual(math.minInt(i43), try parseInt(i43, "-4398046511104", 10));
358 try testing.expectEqual(math.minInt(i1), try parseInt(i1, "-1", 10));
359 try testing.expectEqual(math.minInt(i8), try parseInt(i8, "-128", 10));
360 try testing.expectEqual(math.minInt(i43), try parseInt(i43, "-4398046511104", 10));
356361
357362 // empty string or bare +- is invalid
358 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "", 10));
359 try std.testing.expectError(error.InvalidCharacter, parseInt(i32, "", 10));
360 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "+", 10));
361 try std.testing.expectError(error.InvalidCharacter, parseInt(i32, "+", 10));
362 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "-", 10));
363 try std.testing.expectError(error.InvalidCharacter, parseInt(i32, "-", 10));
363 try testing.expectError(error.InvalidCharacter, parseInt(u32, "", 10));
364 try testing.expectError(error.InvalidCharacter, parseInt(i32, "", 10));
365 try testing.expectError(error.InvalidCharacter, parseInt(u32, "+", 10));
366 try testing.expectError(error.InvalidCharacter, parseInt(i32, "+", 10));
367 try testing.expectError(error.InvalidCharacter, parseInt(u32, "-", 10));
368 try testing.expectError(error.InvalidCharacter, parseInt(i32, "-", 10));
364369
365370 // autodectect the base
366 try std.testing.expectEqual(111, try parseInt(i32, "111", 0));
367 try std.testing.expectEqual(111, try parseInt(i32, "1_1_1", 0));
368 try std.testing.expectEqual(111, try parseInt(i32, "1_1_1", 0));
369 try std.testing.expectEqual(7, try parseInt(i32, "+0b111", 0));
370 try std.testing.expectEqual(7, try parseInt(i32, "+0B111", 0));
371 try std.testing.expectEqual(7, try parseInt(i32, "+0b1_11", 0));
372 try std.testing.expectEqual(73, try parseInt(i32, "+0o111", 0));
373 try std.testing.expectEqual(73, try parseInt(i32, "+0O111", 0));
374 try std.testing.expectEqual(73, try parseInt(i32, "+0o11_1", 0));
375 try std.testing.expectEqual(273, try parseInt(i32, "+0x111", 0));
376 try std.testing.expectEqual(-7, try parseInt(i32, "-0b111", 0));
377 try std.testing.expectEqual(-7, try parseInt(i32, "-0b11_1", 0));
378 try std.testing.expectEqual(-73, try parseInt(i32, "-0o111", 0));
379 try std.testing.expectEqual(-273, try parseInt(i32, "-0x111", 0));
380 try std.testing.expectEqual(-273, try parseInt(i32, "-0X111", 0));
381 try std.testing.expectEqual(-273, try parseInt(i32, "-0x1_11", 0));
371 try testing.expectEqual(111, try parseInt(i32, "111", 0));
372 try testing.expectEqual(111, try parseInt(i32, "1_1_1", 0));
373 try testing.expectEqual(111, try parseInt(i32, "1_1_1", 0));
374 try testing.expectEqual(7, try parseInt(i32, "+0b111", 0));
375 try testing.expectEqual(7, try parseInt(i32, "+0B111", 0));
376 try testing.expectEqual(7, try parseInt(i32, "+0b1_11", 0));
377 try testing.expectEqual(73, try parseInt(i32, "+0o111", 0));
378 try testing.expectEqual(73, try parseInt(i32, "+0O111", 0));
379 try testing.expectEqual(73, try parseInt(i32, "+0o11_1", 0));
380 try testing.expectEqual(273, try parseInt(i32, "+0x111", 0));
381 try testing.expectEqual(-7, try parseInt(i32, "-0b111", 0));
382 try testing.expectEqual(-7, try parseInt(i32, "-0b11_1", 0));
383 try testing.expectEqual(-73, try parseInt(i32, "-0o111", 0));
384 try testing.expectEqual(-273, try parseInt(i32, "-0x111", 0));
385 try testing.expectEqual(-273, try parseInt(i32, "-0X111", 0));
386 try testing.expectEqual(-273, try parseInt(i32, "-0x1_11", 0));
382387
383388 // bare binary/octal/decimal prefix is invalid
384 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0b", 0));
385 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0o", 0));
386 try std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0x", 0));
389 try testing.expectError(error.InvalidCharacter, parseInt(u32, "0b", 0));
390 try testing.expectError(error.InvalidCharacter, parseInt(u32, "0o", 0));
391 try testing.expectError(error.InvalidCharacter, parseInt(u32, "0x", 0));
387392
388393 // edge cases which previously errored due to base overflowing T
389 try std.testing.expectEqual(@as(i2, -2), try std.fmt.parseInt(i2, "-10", 2));
390 try std.testing.expectEqual(@as(i4, -8), try std.fmt.parseInt(i4, "-10", 8));
391 try std.testing.expectEqual(@as(i5, -16), try std.fmt.parseInt(i5, "-10", 16));
394 try testing.expectEqual(@as(i2, -2), try std.fmt.parseInt(i2, "-10", 2));
395 try testing.expectEqual(@as(i4, -8), try std.fmt.parseInt(i4, "-10", 8));
396 try testing.expectEqual(@as(i5, -16), try std.fmt.parseInt(i5, "-10", 16));
392397}
393398
394399fn parseIntWithSign(
......@@ -475,39 +480,39 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, base: u8) ParseIntError!
475480}
476481
477482test parseUnsigned {
478 try std.testing.expectEqual(50124, try parseUnsigned(u16, "050124", 10));
479 try std.testing.expectEqual(65535, try parseUnsigned(u16, "65535", 10));
480 try std.testing.expectEqual(65535, try parseUnsigned(u16, "65_535", 10));
481 try std.testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
483 try testing.expectEqual(50124, try parseUnsigned(u16, "050124", 10));
484 try testing.expectEqual(65535, try parseUnsigned(u16, "65535", 10));
485 try testing.expectEqual(65535, try parseUnsigned(u16, "65_535", 10));
486 try testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
482487
483 try std.testing.expectEqual(0xffffffffffffffff, try parseUnsigned(u64, "0ffffffffffffffff", 16));
484 try std.testing.expectEqual(0xffffffffffffffff, try parseUnsigned(u64, "0f_fff_fff_fff_fff_fff", 16));
485 try std.testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));
488 try testing.expectEqual(0xffffffffffffffff, try parseUnsigned(u64, "0ffffffffffffffff", 16));
489 try testing.expectEqual(0xffffffffffffffff, try parseUnsigned(u64, "0f_fff_fff_fff_fff_fff", 16));
490 try testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));
486491
487 try std.testing.expectEqual(0xDEADBEEF, try parseUnsigned(u32, "DeadBeef", 16));
492 try testing.expectEqual(0xDEADBEEF, try parseUnsigned(u32, "DeadBeef", 16));
488493
489 try std.testing.expectEqual(1, try parseUnsigned(u7, "1", 10));
490 try std.testing.expectEqual(8, try parseUnsigned(u7, "1000", 2));
494 try testing.expectEqual(1, try parseUnsigned(u7, "1", 10));
495 try testing.expectEqual(8, try parseUnsigned(u7, "1000", 2));
491496
492 try std.testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10));
493 try std.testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8));
497 try testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10));
498 try testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8));
494499
495 try std.testing.expectEqual(1442151747, try parseUnsigned(u32, "NUMBER", 36));
500 try testing.expectEqual(1442151747, try parseUnsigned(u32, "NUMBER", 36));
496501
497502 // these numbers should fit even though the base itself doesn't fit in the destination type
498 try std.testing.expectEqual(0, try parseUnsigned(u1, "0", 10));
499 try std.testing.expectEqual(1, try parseUnsigned(u1, "1", 10));
500 try std.testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10));
501 try std.testing.expectEqual(1, try parseUnsigned(u1, "001", 16));
502 try std.testing.expectEqual(3, try parseUnsigned(u2, "3", 16));
503 try std.testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16));
503 try testing.expectEqual(0, try parseUnsigned(u1, "0", 10));
504 try testing.expectEqual(1, try parseUnsigned(u1, "1", 10));
505 try testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10));
506 try testing.expectEqual(1, try parseUnsigned(u1, "001", 16));
507 try testing.expectEqual(3, try parseUnsigned(u2, "3", 16));
508 try testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16));
504509
505510 // parseUnsigned does not expect a sign
506 try std.testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "+0", 10));
507 try std.testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "-0", 10));
511 try testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "+0", 10));
512 try testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "-0", 10));
508513
509514 // test empty string error
510 try std.testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "", 10));
515 try testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "", 10));
511516}
512517
513518/// Parses a number like '2G', '2Gi', or '2GiB'.
......@@ -549,15 +554,15 @@ pub fn parseIntSizeSuffix(buf: []const u8, digit_base: u8) ParseIntError!usize {
549554}
550555
551556test parseIntSizeSuffix {
552 try std.testing.expectEqual(2, try parseIntSizeSuffix("2", 10));
553 try std.testing.expectEqual(2, try parseIntSizeSuffix("2B", 10));
554 try std.testing.expectEqual(2000, try parseIntSizeSuffix("2kB", 10));
555 try std.testing.expectEqual(2000, try parseIntSizeSuffix("2k", 10));
556 try std.testing.expectEqual(2048, try parseIntSizeSuffix("2KiB", 10));
557 try std.testing.expectEqual(2048, try parseIntSizeSuffix("2Ki", 10));
558 try std.testing.expectEqual(10240, try parseIntSizeSuffix("aKiB", 16));
559 try std.testing.expectError(error.InvalidCharacter, parseIntSizeSuffix("", 10));
560 try std.testing.expectError(error.InvalidCharacter, parseIntSizeSuffix("2iB", 10));
557 try testing.expectEqual(2, try parseIntSizeSuffix("2", 10));
558 try testing.expectEqual(2, try parseIntSizeSuffix("2B", 10));
559 try testing.expectEqual(2000, try parseIntSizeSuffix("2kB", 10));
560 try testing.expectEqual(2000, try parseIntSizeSuffix("2k", 10));
561 try testing.expectEqual(2048, try parseIntSizeSuffix("2KiB", 10));
562 try testing.expectEqual(2048, try parseIntSizeSuffix("2Ki", 10));
563 try testing.expectEqual(10240, try parseIntSizeSuffix("aKiB", 16));
564 try testing.expectError(error.InvalidCharacter, parseIntSizeSuffix("", 10));
565 try testing.expectError(error.InvalidCharacter, parseIntSizeSuffix("2iB", 10));
561566}
562567
563568pub const parseFloat = @import("fmt/parse_float.zig").parseFloat;
......@@ -588,28 +593,22 @@ pub fn digitToChar(digit: u8, case: Case) u8 {
588593 };
589594}
590595
591pub const BufPrintError = error{
592 /// As much as possible was written to the buffer, but it was too small to fit all the printed bytes.
593 NoSpaceLeft,
594};
596/// Deprecated in favor of `mem.PrintError`.
597pub const BufPrintError = mem.PrintError;
595598
596/// Print a format string into `buf`. Returns a slice of the bytes printed.
599/// Deprecated in favor of `mem.print`.
597600pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![]u8 {
598 var w: Writer = .fixed(buf);
599 w.print(fmt, args) catch |err| switch (err) {
600 error.WriteFailed => return error.NoSpaceLeft,
601 };
602 return w.buffered();
601 return mem.print(buf, fmt, args);
603602}
604603
604/// Deprecated in favor of `mem.printSentinel`.
605605pub fn bufPrintSentinel(
606606 buf: []u8,
607607 comptime fmt: []const u8,
608608 args: anytype,
609609 comptime sentinel: u8,
610610) BufPrintError![:sentinel]u8 {
611 const result = try bufPrint(buf, fmt ++ [_]u8{sentinel}, args);
612 return result[0 .. result.len - 1 :sentinel];
611 return mem.printSentinel(buf, fmt, args, sentinel);
613612}
614613
615614/// Count the characters needed for format.
......@@ -640,7 +639,7 @@ pub fn allocPrintSentinel(
640639pub inline fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [count(fmt, args):0]u8 {
641640 comptime {
642641 var buf: [count(fmt, args):0]u8 = undefined;
643 _ = bufPrint(&buf, fmt, args) catch unreachable;
642 _ = mem.print(&buf, fmt, args) catch unreachable;
644643 buf[buf.len] = 0;
645644 const final = buf;
646645 return &final;
......@@ -649,12 +648,12 @@ pub inline fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [cou
649648
650649test comptimePrint {
651650 @setEvalBranchQuota(2000);
652 try std.testing.expectEqual(*const [3:0]u8, @TypeOf(comptimePrint("{}", .{100})));
653 try std.testing.expectEqualSlices(u8, "100", comptimePrint("{}", .{100}));
654 try std.testing.expectEqualStrings("30", comptimePrint("{d}", .{30.0}));
655 try std.testing.expectEqualStrings("30.0", comptimePrint("{d:3.1}", .{30.0}));
656 try std.testing.expectEqualStrings("0.05", comptimePrint("{d}", .{0.05}));
657 try std.testing.expectEqualStrings("5e-2", comptimePrint("{e}", .{0.05}));
651 try testing.expectEqual(*const [3:0]u8, @TypeOf(comptimePrint("{}", .{100})));
652 try testing.expectEqualSlices(u8, "100", comptimePrint("{}", .{100}));
653 try testing.expectEqualStrings("30", comptimePrint("{d}", .{30.0}));
654 try testing.expectEqualStrings("30.0", comptimePrint("{d:3.1}", .{30.0}));
655 try testing.expectEqualStrings("0.05", comptimePrint("{d}", .{0.05}));
656 try testing.expectEqualStrings("5e-2", comptimePrint("{e}", .{0.05}));
658657}
659658
660659test "parse u64 digit too big" {
......@@ -667,7 +666,7 @@ test "parse u64 digit too big" {
667666
668667test "parse unsigned comptime" {
669668 comptime {
670 try std.testing.expectEqual(2, try parseUnsigned(usize, "2", 10));
669 try testing.expectEqual(2, try parseUnsigned(usize, "2", 10));
671670 }
672671}
673672
......@@ -772,15 +771,15 @@ test "buffer" {
772771 var buf1: [32]u8 = undefined;
773772 var w: Writer = .fixed(&buf1);
774773 try w.printValue("", .{}, 1234, std.options.fmt_max_depth);
775 try std.testing.expectEqualStrings("1234", w.buffered());
774 try testing.expectEqualStrings("1234", w.buffered());
776775
777776 w = .fixed(&buf1);
778777 try w.printValue("c", .{}, 'a', std.options.fmt_max_depth);
779 try std.testing.expectEqualStrings("a", w.buffered());
778 try testing.expectEqualStrings("a", w.buffered());
780779
781780 w = .fixed(&buf1);
782781 try w.printValue("b", .{}, 0b1100, std.options.fmt_max_depth);
783 try std.testing.expectEqualStrings("1100", w.buffered());
782 try testing.expectEqualStrings("1100", w.buffered());
784783 }
785784}
786785
......@@ -801,7 +800,7 @@ test "array" {
801800
802801 var buf: [100]u8 = undefined;
803802 try expectFmt(
804 try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@intFromPtr(&value)}),
803 try mem.print(buf[0..], "array: [3]u8@{x}\n", .{@intFromPtr(&value)}),
805804 "array: {*}\n",
806805 .{&value},
807806 );
......@@ -1177,7 +1176,7 @@ test bytesToHex {
11771176 const input = "input slice";
11781177 const encoded = bytesToHex(input, .lower);
11791178 var decoded: [input.len]u8 = undefined;
1180 try std.testing.expectEqualSlices(u8, input, try hexToBytes(&decoded, &encoded));
1179 try testing.expectEqualSlices(u8, input, try hexToBytes(&decoded, &encoded));
11811180}
11821181
11831182test hexToBytes {
......@@ -1189,9 +1188,9 @@ test hexToBytes {
11891188 try expectFmt(repeated, "{X}", .{try hexToBytes(&buf, repeated)});
11901189 try expectFmt("ABCD", "{X}", .{try hexToBytes(&buf, "ABCD")});
11911190 try expectFmt("", "{X}", .{try hexToBytes(&buf, "")});
1192 try std.testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z"));
1193 try std.testing.expectError(error.InvalidLength, hexToBytes(&buf, "AAA"));
1194 try std.testing.expectError(error.NoSpaceLeft, hexToBytes(buf[0..1], "ABAB"));
1191 try testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z"));
1192 try testing.expectError(error.InvalidLength, hexToBytes(&buf, "AAA"));
1193 try testing.expectError(error.NoSpaceLeft, hexToBytes(buf[0..1], "ABAB"));
11951194}
11961195
11971196test "positional" {
......@@ -1226,12 +1225,12 @@ test "vector" {
12261225 const vop: @Vector(4, ?*const u64) = [_]?*const u64{ &x[0], null, null, &x[3] };
12271226
12281227 var expect_buffer: [@sizeOf(usize) * 2 * 4 + 64]u8 = undefined;
1229 try expectFmt(try bufPrint(
1228 try expectFmt(try mem.print(
12301229 &expect_buffer,
12311230 "{{ {}, {}, {}, {} }}",
12321231 .{ &x[0], &x[1], &x[2], &x[3] },
12331232 ), "{}", .{vp});
1234 try expectFmt(try bufPrint(
1233 try expectFmt(try mem.print(
12351234 &expect_buffer,
12361235 "{{ {?}, null, null, {?} }}",
12371236 .{ &x[0], &x[3] },
......@@ -1348,18 +1347,18 @@ pub fn hex(x: anytype) [@typeInfo(@TypeOf(x)).int.bits / 4]u8 {
13481347test hex {
13491348 {
13501349 const x = hex(@as(u32, 0xdeadbeef));
1351 try std.testing.expect(x.len == 8);
1352 try std.testing.expectEqualStrings("efbeadde", &x);
1350 try testing.expect(x.len == 8);
1351 try testing.expectEqualStrings("efbeadde", &x);
13531352 }
13541353 {
13551354 const s = "[" ++ hex(@as(u48, 0x12345678_abcd)) ++ "]";
1356 try std.testing.expect(s.len == 14);
1357 try std.testing.expectEqualStrings("[cdab78563412]", s);
1355 try testing.expect(s.len == 14);
1356 try testing.expectEqualStrings("[cdab78563412]", s);
13581357 }
13591358 {
13601359 const s = "[" ++ hex(@as(u64, 0x12345678_abcdef00)) ++ "]";
1361 try std.testing.expect(s.len == 18);
1362 try std.testing.expectEqualStrings("[00efcdab78563412]", s);
1360 try testing.expect(s.len == 18);
1361 try testing.expectEqualStrings("[00efcdab78563412]", s);
13631362 }
13641363}
13651364
lib/std/mem.zig+53-4
......@@ -1,12 +1,14 @@
1const std = @import("std.zig");
1const mem = @This();
2
23const builtin = @import("builtin");
4const native_endian = builtin.cpu.arch.endian();
5
6const std = @import("std.zig");
37const debug = std.debug;
48const assert = debug.assert;
59const math = std.math;
6const mem = @This();
710const testing = std.testing;
8const Endian = std.builtin.Endian;
9const native_endian = builtin.cpu.arch.endian();
11const Endian = std.lang.Endian;
1012
1113/// The standard library currently thoroughly depends on byte size
1214/// being 8 bits. (see the use of u8 throughout allocation code as
......@@ -5152,3 +5154,50 @@ test "read/write(Var)PackedInt" {
51525154 }
51535155 }
51545156}
5157
5158pub const PrintError = error{
5159 /// As much as possible was written to the buffer, but it was too small to
5160 /// fit all the printed bytes.
5161 NoSpaceLeft,
5162};
5163
5164/// Render a formatted string into `buffer`. Returns a slice of `buffer`
5165/// starting at index 0 containing the result, or `error.NoSpaceLeft` if one or
5166/// more bytes were truncated.
5167///
5168/// See `std.Io.Writer.print`.
5169pub fn print(buffer: []u8, comptime format: []const u8, args: anytype) PrintError![]u8 {
5170 var w: std.Io.Writer = .fixed(buffer);
5171 w.print(format, args) catch |err| switch (err) {
5172 error.WriteFailed => return error.NoSpaceLeft,
5173 };
5174 return w.buffered();
5175}
5176
5177test print {
5178 const x: i32 = -1;
5179 const y: []const u8 = "hi";
5180 var buffer: [64]u8 = undefined;
5181 const s = try print(&buffer, "{d}={s}", .{ x, y });
5182 try testing.expectEqualStrings("-1=hi", s);
5183}
5184
5185/// Like `print` but returned slice has the provided sentinel.
5186pub fn printSentinel(
5187 buffer: []u8,
5188 comptime format: []const u8,
5189 args: anytype,
5190 comptime sentinel: u8,
5191) PrintError![:sentinel]u8 {
5192 const result = try print(buffer, format ++ [1]u8{sentinel}, args);
5193 return result[0 .. result.len - 1 :sentinel];
5194}
5195
5196test printSentinel {
5197 const x: i32 = -1;
5198 const y: []const u8 = "hi";
5199 var buffer: [64]u8 = undefined;
5200 const s = try printSentinel(&buffer, "{d}={s}", .{ x, y }, 0);
5201 try testing.expectEqualStrings("-1=hi", s);
5202 try testing.expectEqual(0, s[s.len]);
5203}