| ... | @@ -1172,23 +1172,12 @@ pub fn printValue( | ... | @@ -1172,23 +1172,12 @@ pub fn printValue( |
| 1172 | }, | 1172 | }, |
| 1173 | else => invalidFmtError(fmt, value), | 1173 | else => invalidFmtError(fmt, value), |
| 1174 | }, | 1174 | }, |
| 1175 | // TODO make this print double quotes and quote-escape the string | | |
| 1176 | // according to zig string syntax rules | | |
| 1177 | 'q' => switch (@typeInfo(T)) { | 1175 | 'q' => switch (@typeInfo(T)) { |
| 1178 | .pointer => |info| switch (info.size) { | 1176 | .pointer => |info| switch (info.size) { |
| 1179 | .one, .slice => { | 1177 | .one, .slice => return printStringEscaped(w, value), |
| 1180 | const slice: []const u8 = value; | 1178 | .many, .c => return printStringEscaped(w, std.mem.span(value)), |
| 1181 | return w.alignBufferOptions(slice, options); | | |
| 1182 | }, | | |
| 1183 | .many, .c => { | | |
| 1184 | const slice: [:0]const u8 = std.mem.span(value); | | |
| 1185 | return w.alignBufferOptions(slice, options); | | |
| 1186 | }, | | |
| 1187 | }, | | |
| 1188 | .array => { | | |
| 1189 | const slice: []const u8 = &value; | | |
| 1190 | return w.alignBufferOptions(slice, options); | | |
| 1191 | }, | 1179 | }, |
| | 1180 | .array => return printStringEscaped(w, &value), |
| 1192 | else => invalidFmtError(fmt, value), | 1181 | else => invalidFmtError(fmt, value), |
| 1193 | }, | 1182 | }, |
| 1194 | 'B' => switch (@typeInfo(T)) { | 1183 | 'B' => switch (@typeInfo(T)) { |
| ... | @@ -1467,6 +1456,14 @@ fn printEnumNonexhaustive(w: *Writer, value: anytype) Error!void { | ... | @@ -1467,6 +1456,14 @@ fn printEnumNonexhaustive(w: *Writer, value: anytype) Error!void { |
| 1467 | try w.writeByte(')'); | 1456 | try w.writeByte(')'); |
| 1468 | } | 1457 | } |
| 1469 | | 1458 | |
| | 1459 | /// Prints a double quote, then escapes a string according to Zig string |
| | 1460 | /// literal rules, then a double quote. |
| | 1461 | pub fn printStringEscaped(w: *Writer, bytes: []const u8) Error!void { |
| | 1462 | try w.writeByte('"'); |
| | 1463 | try std.zig.stringEscape(bytes, w); |
| | 1464 | try w.writeByte('"'); |
| | 1465 | } |
| | 1466 | |
| 1470 | pub fn printVector( | 1467 | pub fn printVector( |
| 1471 | w: *Writer, | 1468 | w: *Writer, |
| 1472 | comptime fmt: []const u8, | 1469 | comptime fmt: []const u8, |
| ... | @@ -2121,6 +2118,11 @@ test "printFloat with comptime_float" { | ... | @@ -2121,6 +2118,11 @@ test "printFloat with comptime_float" { |
| 2121 | try testing.expectFmt("1", "{}", .{1.0}); | 2118 | try testing.expectFmt("1", "{}", .{1.0}); |
| 2122 | } | 2119 | } |
| 2123 | | 2120 | |
| | 2121 | test "{q} format string" { |
| | 2122 | const data: []const u8 = "i\tlike\"cheese\x00\x05cheese"; |
| | 2123 | try testing.expectFmt("hello \"i\\tlike\\\"cheese\\x00\\x05cheese\" world", "hello {q} world", .{data}); |
| | 2124 | } |
| | 2125 | |
| 2124 | fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void { | 2126 | fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void { |
| 2125 | var buffer: [100]u8 = undefined; | 2127 | var buffer: [100]u8 = undefined; |
| 2126 | var w: Writer = .fixed(&buffer); | 2128 | var w: Writer = .fixed(&buffer); |