authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-08-31 22:31:29+10:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-02 19:18:36-04:00
logfb3c5b84ede6fa48949c8069bf735ac67ec21091
tree2af903eb8b198e73020126a6a864ec88374fad64
parentc86108dd63349cbd99a8821fb4d628f31958e0ed

std: add fmt option to escape non-printable characters


1 files changed, 17 insertions(+), 0 deletions(-)

lib/std/fmt.zig+17
...@@ -66,6 +66,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool {...@@ -66,6 +66,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool {
66/// - output numeric value in hexadecimal notation66/// - output numeric value in hexadecimal notation
67/// - `s`: print a pointer-to-many as a c-string, use zero-termination67/// - `s`: print a pointer-to-many as a c-string, use zero-termination
68/// - `B` and `Bi`: output a memory size in either metric (1000) or power-of-two (1024) based notation. works for both float and integer values.68/// - `B` and `Bi`: output a memory size in either metric (1000) or power-of-two (1024) based notation. works for both float and integer values.
69/// - `e` and `E`: if printing a string, escape non-printable characters
69/// - `e`: output floating point value in scientific notation70/// - `e`: output floating point value in scientific notation
70/// - `d`: output numeric value in decimal notation71/// - `d`: output numeric value in decimal notation
71/// - `b`: output integer value in binary notation72/// - `b`: output integer value in binary notation
...@@ -599,6 +600,16 @@ pub fn formatText(...@@ -599,6 +600,16 @@ pub fn formatText(
599 try formatInt(c, 16, fmt[0] == 'X', FormatOptions{ .width = 2, .fill = '0' }, writer);600 try formatInt(c, 16, fmt[0] == 'X', FormatOptions{ .width = 2, .fill = '0' }, writer);
600 }601 }
601 return;602 return;
603 } else if (comptime (std.mem.eql(u8, fmt, "e") or std.mem.eql(u8, fmt, "E"))) {
604 for (bytes) |c| {
605 if (std.ascii.isPrint(c)) {
606 try writer.writeByte(c);
607 } else {
608 try writer.writeAll("\\x");
609 try formatInt(c, 16, fmt[0] == 'E', FormatOptions{ .width = 2, .fill = '0' }, writer);
610 }
611 }
612 return;
602 } else {613 } else {
603 @compileError("Unknown format string: '" ++ fmt ++ "'");614 @compileError("Unknown format string: '" ++ fmt ++ "'");
604 }615 }
...@@ -1319,6 +1330,12 @@ test "slice" {...@@ -1319,6 +1330,12 @@ test "slice" {
1319 try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});1330 try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
1320}1331}
13211332
1333test "escape non-printable" {
1334 try testFmt("abc", "{e}", .{"abc"});
1335 try testFmt("ab\\xffc", "{e}", .{"ab\xffc"});
1336 try testFmt("ab\\xFFc", "{E}", .{"ab\xffc"});
1337}
1338
1322test "pointer" {1339test "pointer" {
1323 {1340 {
1324 const value = @intToPtr(*align(1) i32, 0xdeadbeef);1341 const value = @intToPtr(*align(1) i32, 0xdeadbeef);