aboutsummaryrefslogtreecommitdiff
path: root/lib/std/fmt.zig
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2020-08-31 22:31:29 +1000
committerAndrew Kelley <andrew@ziglang.org>2020-09-02 19:18:36 -0400
commitfb3c5b84ede6fa48949c8069bf735ac67ec21091 (patch)
tree2af903eb8b198e73020126a6a864ec88374fad64 /lib/std/fmt.zig
parentc86108dd63349cbd99a8821fb4d628f31958e0ed (diff)
downloadzig-fb3c5b84ede6fa48949c8069bf735ac67ec21091.tar.gz
zig-fb3c5b84ede6fa48949c8069bf735ac67ec21091.zip
std: add fmt option to escape non-printable characters
Diffstat (limited to 'lib/std/fmt.zig')
-rw-r--r--lib/std/fmt.zig17
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index 16d0eaa07a..3067a55759 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -66,6 +66,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool {
/// - output numeric value in hexadecimal notation
/// - `s`: print a pointer-to-many as a c-string, use zero-termination
/// - `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.
+/// - `e` and `E`: if printing a string, escape non-printable characters
/// - `e`: output floating point value in scientific notation
/// - `d`: output numeric value in decimal notation
/// - `b`: output integer value in binary notation
@@ -599,6 +600,16 @@ pub fn formatText(
try formatInt(c, 16, fmt[0] == 'X', FormatOptions{ .width = 2, .fill = '0' }, writer);
}
return;
+ } else if (comptime (std.mem.eql(u8, fmt, "e") or std.mem.eql(u8, fmt, "E"))) {
+ for (bytes) |c| {
+ if (std.ascii.isPrint(c)) {
+ try writer.writeByte(c);
+ } else {
+ try writer.writeAll("\\x");
+ try formatInt(c, 16, fmt[0] == 'E', FormatOptions{ .width = 2, .fill = '0' }, writer);
+ }
+ }
+ return;
} else {
@compileError("Unknown format string: '" ++ fmt ++ "'");
}
@@ -1319,6 +1330,12 @@ test "slice" {
try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
}
+test "escape non-printable" {
+ try testFmt("abc", "{e}", .{"abc"});
+ try testFmt("ab\\xffc", "{e}", .{"ab\xffc"});
+ try testFmt("ab\\xFFc", "{E}", .{"ab\xffc"});
+}
+
test "pointer" {
{
const value = @intToPtr(*align(1) i32, 0xdeadbeef);