| ... | ... | @@ -12,7 +12,7 @@ pub fn formatId( |
| 12 | 12 | return writer.writeAll(bytes); |
| 13 | 13 | } |
| 14 | 14 | try writer.writeAll("@\""); |
| 15 | | try formatEscapes(bytes, fmt, options, writer); |
| 15 | try formatEscapes(bytes, "", options, writer); |
| 16 | 16 | try writer.writeByte('"'); |
| 17 | 17 | } |
| 18 | 18 | |
| ... | ... | @@ -32,6 +32,9 @@ pub fn isValidId(bytes: []const u8) bool { |
| 32 | 32 | return std.zig.Token.getKeyword(bytes) == null; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | /// Print the string as escaped contents of a double quoted or single-quoted string. |
| 36 | /// Format `{}` treats contents as a double-quoted string. |
| 37 | /// Format `{'}` treats contents as a single-quoted string. |
| 35 | 38 | pub fn formatEscapes( |
| 36 | 39 | bytes: []const u8, |
| 37 | 40 | comptime fmt: []const u8, |
| ... | ... | @@ -43,8 +46,24 @@ pub fn formatEscapes( |
| 43 | 46 | '\r' => try writer.writeAll("\\r"), |
| 44 | 47 | '\t' => try writer.writeAll("\\t"), |
| 45 | 48 | '\\' => try writer.writeAll("\\\\"), |
| 46 | | '"' => try writer.writeAll("\\\""), |
| 47 | | '\'' => try writer.writeAll("\\'"), |
| 49 | '"' => { |
| 50 | if (fmt.len == 1 and fmt[0] == '\'') { |
| 51 | try writer.writeByte('"'); |
| 52 | } else if (fmt.len == 0) { |
| 53 | try writer.writeAll("\\\""); |
| 54 | } else { |
| 55 | @compileError("expected {} or {'}, found {" ++ fmt ++ "}"); |
| 56 | } |
| 57 | }, |
| 58 | '\'' => { |
| 59 | if (fmt.len == 1 and fmt[0] == '\'') { |
| 60 | try writer.writeAll("\\'"); |
| 61 | } else if (fmt.len == 0) { |
| 62 | try writer.writeByte('\''); |
| 63 | } else { |
| 64 | @compileError("expected {} or {'}, found {" ++ fmt ++ "}"); |
| 65 | } |
| 66 | }, |
| 48 | 67 | ' ', '!', '#'...'&', '('...'[', ']'...'~' => try writer.writeByte(byte), |
| 49 | 68 | // Use hex escapes for rest any unprintable characters. |
| 50 | 69 | else => { |
| ... | ... | @@ -54,7 +73,10 @@ pub fn formatEscapes( |
| 54 | 73 | }; |
| 55 | 74 | } |
| 56 | 75 | |
| 57 | | /// Return a Formatter for Zig Escapes |
| 76 | /// Return a Formatter for Zig Escapes of a double quoted string. |
| 77 | /// The format specifier must be one of: |
| 78 | /// * `{}` treats contents as a double-quoted string. |
| 79 | /// * `{'}` treats contents as a single-quoted string. |
| 58 | 80 | pub fn fmtEscapes(bytes: []const u8) std.fmt.Formatter(formatEscapes) { |
| 59 | 81 | return .{ .data = bytes }; |
| 60 | 82 | } |
| ... | ... | @@ -67,6 +89,9 @@ test "escape invalid identifiers" { |
| 67 | 89 | try expectFmt("@\"11\\x0f23\"", "{}", .{fmtId("11\x0F23")}); |
| 68 | 90 | try expectFmt("\\x0f", "{}", .{fmtEscapes("\x0f")}); |
| 69 | 91 | try expectFmt( |
| 70 | | \\" \\ hi \x07 \x11 \" derp \'" |
| 92 | \\" \\ hi \x07 \x11 " derp \'" |
| 93 | , "\"{'}\"", .{fmtEscapes(" \\ hi \x07 \x11 \" derp '")}); |
| 94 | try expectFmt( |
| 95 | \\" \\ hi \x07 \x11 \" derp '" |
| 71 | 96 | , "\"{}\"", .{fmtEscapes(" \\ hi \x07 \x11 \" derp '")}); |
| 72 | 97 | } |