| author | |
| committer | |
| log | e1f7e3563fa84b08e707a3dcea610560d179c63d |
| tree | 1f1a84d58a8ca26432ff379f3467a450a4544764 |
| parent | 5b9147ed59b22edf7f891cf30e8b77223121da4f |
3 files changed, 16 insertions(+), 7 deletions(-)
doc/langref.html.in+11-2| ... | ... | @@ -754,12 +754,21 @@ |
| 754 | 754 | </tr> |
| 755 | 755 | <tr> |
| 756 | 756 | <th scope="row"><code>\u{NNNNNN}</code></th> |
| 757 | <td>hexadecimal Unicode scalar value UTF-8 encoded (1 or more digits)</td> | |
| 757 | <td>hexadecimal Unicode code point (1 or more digits)</td> | |
| 758 | 758 | </tr> |
| 759 | 759 | </tbody> |
| 760 | 760 | </table> |
| 761 | 761 | </div> |
| 762 | <p>Note that the maximum valid Unicode scalar value is {#syntax#}0x10ffff{#endsyntax#}.</p> | |
| 762 | <p> | |
| 763 | Note that the highest Unicode code point is {#syntax#}0x10ffff{#endsyntax#}. Character | |
| 764 | literals are integers ({#syntax#}'A'{#endsyntax#} = {#syntax#}65{#endsyntax#} and | |
| 765 | {#syntax#}'\u{10000}'{#endsyntax#} = {#syntax#}0x10000{#endsyntax#} = {#syntax#}65536{#endsyntax#}), | |
| 766 | and <code>\u</code> escapes in string literals are encoded as UTF-8 | |
| 767 | ({#syntax#}"A"{#endsyntax#} = {#syntax#}"\u{41}"{#endsyntax#} = {#syntax#}"\x41"{#endsyntax#} | |
| 768 | and {#syntax#}"\u{10000}"{#endsyntax#} = {#syntax#}"\xF0\x90\x80\x80"{#endsyntax#}). | |
| 769 | <code>\u</code> escapes can be used for surrogate code points, which are not Unicode | |
| 770 | scalar values or technically allowed in UTF-8 as defined by the Unicode standard, but can be useful in practice. | |
| 771 | </p> | |
| 763 | 772 | {#header_close#} |
| 764 | 773 | {#header_open|Multiline String Literals#} |
| 765 | 774 | <p> |
lib/compiler/Maker/Package/Manifest.zig+1-1| ... | ... | @@ -508,7 +508,7 @@ const Parse = struct { |
| 508 | 508 | try p.appendErrorOff( |
| 509 | 509 | token, |
| 510 | 510 | offset + @as(u32, @intCast(bad_index)), |
| 511 | "unicode escape does not correspond to a valid unicode scalar value", | |
| 511 | "unicode escape does not correspond to a unicode code point", | |
| 512 | 512 | .{}, |
| 513 | 513 | ); |
| 514 | 514 | }, |
lib/std/zig/string_literal.zig+4-4| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | const std = @import("../std.zig"); |
| 2 | 2 | const assert = std.debug.assert; |
| 3 | const utf8Encode = std.unicode.utf8Encode; | |
| 4 | 3 | const Writer = std.Io.Writer; |
| 5 | 4 | |
| 6 | 5 | pub const ParseError = error{ |
| ... | ... | @@ -63,7 +62,7 @@ pub const Error = union(enum) { |
| 63 | 62 | .{self.raw_string[bad_index]}, |
| 64 | 63 | ), |
| 65 | 64 | .invalid_unicode_codepoint => try writer.writeAll( |
| 66 | "unicode escape does not correspond to a valid unicode scalar value", | |
| 65 | "unicode escape does not correspond to a unicode code point", | |
| 67 | 66 | ), |
| 68 | 67 | .expected_lbrace => |bad_index| try writer.print( |
| 69 | 68 | "expected '{{', found '{c}'", |
| ... | ... | @@ -334,8 +333,8 @@ pub fn parseWrite(writer: *Writer, bytes: []const u8) Writer.Error!Result { |
| 334 | 333 | .success => |codepoint| { |
| 335 | 334 | if (bytes[escape_char_index] == 'u') { |
| 336 | 335 | var buf: [4]u8 = undefined; |
| 337 | const len = utf8Encode(codepoint, &buf) catch { | |
| 338 | return .{ .failure = .{ .invalid_unicode_codepoint = escape_char_index + 1 } }; | |
| 336 | const len = std.unicode.wtf8Encode(codepoint, &buf) catch |err| switch (err) { | |
| 337 | error.CodepointTooLarge => unreachable, // Checked in `parseEscapeSequence`. | |
| 339 | 338 | }; |
| 340 | 339 | try writer.writeAll(buf[0..len]); |
| 341 | 340 | } else { |
| ... | ... | @@ -385,4 +384,5 @@ test parseAlloc { |
| 385 | 384 | try expect(eql(u8, "foo", try parseAlloc(alloc, "\"foo\""))); |
| 386 | 385 | try expect(eql(u8, "foo", try parseAlloc(alloc, "\"f\x6f\x6f\""))); |
| 387 | 386 | try expect(eql(u8, "f💯", try parseAlloc(alloc, "\"f\u{1f4af}\""))); |
| 387 | try expect(eql(u8, "\xed\xa0\x80", try parseAlloc(alloc, "\"\\u{d800}\""))); | |
| 388 | 388 | } |