From f0026e5019bfc6de23e9dcac99d5d14103432ec9 Mon Sep 17 00:00:00 2001 From: pfg Date: Mon, 8 Jun 2020 17:20:22 -0700 Subject: [PATCH 1/2] support printing codepoints as {c} --- lib/std/fmt.zig | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 671f25a94389..a6b8b29137b6 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -530,8 +530,10 @@ pub fn formatIntValue( } else if (comptime std.mem.eql(u8, fmt, "c")) { if (@TypeOf(int_value).bit_count <= 8) { return formatAsciiChar(@as(u8, int_value), options, out_stream); + } else if (@TypeOf(int_value).bit_count <= 32) { + return formatUnicodeCodepoint(@as(u21, int_value), options, out_stream); } else { - @compileError("Cannot print integer that is larger than 8 bits as a ascii"); + @compileError("Cannot print character that is larger than 21 bits as unicode codepoint"); } } else if (comptime std.mem.eql(u8, fmt, "b")) { radix = 2; @@ -590,6 +592,19 @@ pub fn formatAsciiChar( return out_stream.writeAll(@as(*const [1]u8, &c)); } +pub fn formatUnicodeCodepoint( + c: u21, + options: FormatOptions, + out_stream: var, +) !void { + var result: [4]u8 = undefined; + const len = std.unicode.utf8Encode(c, &result) catch |e| switch (e) { + error.CodepointTooLarge => return out_stream.writeAll(""), + error.Utf8CannotEncodeSurrogateHalf => return out_stream.writeAll(""), + }; + return out_stream.writeAll(result[0..len]); +} + pub fn formatBuf( buf: []const u8, options: FormatOptions, @@ -1197,6 +1212,10 @@ test "int.specifier" { const value: u8 = 'a'; try testFmt("u8: a\n", "u8: {c}\n", .{value}); } + { + const value: u21 = 'あ'; + try testFmt("u8: あ\n", "u8: {c}\n", .{value}); + } { const value: u8 = 0b1100; try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value}); From 175d5bf638be7a2fe895c7e491b791933d566ef6 Mon Sep 17 00:00:00 2001 From: pfg Date: Mon, 8 Jun 2020 17:24:46 -0700 Subject: [PATCH 2/2] {c} codepoint error test --- lib/std/fmt.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index a6b8b29137b6..a68a45bb65ba 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -1214,7 +1214,11 @@ test "int.specifier" { } { const value: u21 = 'あ'; - try testFmt("u8: あ\n", "u8: {c}\n", .{value}); + try testFmt("codepoint: あ\n", "codepoint: {c}\n", .{value}); + } + { + const value: u21 = 2097151; + try testFmt("codepoint: \n", "codepoint: {c}\n", .{value}); } { const value: u8 = 0b1100;