Function parseEscapeSequence [src]
Parse an escape sequence from slice[offset..]. If parsing is successful,
offset is updated to reflect the characters consumed.
Prototype
pub fn parseEscapeSequence(slice: []const u8, offset: *usize) ParsedCharLiteral
Parameters
slice: []const u8
offset: *usize
Source
pub fn parseEscapeSequence(slice: []const u8, offset: *usize) ParsedCharLiteral {
assert(slice.len > offset.*);
assert(slice[offset.*] == '\\');
if (slice.len == offset.* + 1)
return .{ .failure = .{ .invalid_escape_character = offset.* + 1 } };
offset.* += 2;
switch (slice[offset.* - 1]) {
'n' => return .{ .success = '\n' },
'r' => return .{ .success = '\r' },
'\\' => return .{ .success = '\\' },
't' => return .{ .success = '\t' },
'\'' => return .{ .success = '\'' },
'"' => return .{ .success = '"' },
'x' => {
var value: u8 = 0;
var i: usize = offset.*;
while (i < offset.* + 2) : (i += 1) {
if (i == slice.len) return .{ .failure = .{ .expected_hex_digit = i } };
const c = slice[i];
switch (c) {
'0'...'9' => {
value *= 16;
value += c - '0';
},
'a'...'f' => {
value *= 16;
value += c - 'a' + 10;
},
'A'...'F' => {
value *= 16;
value += c - 'A' + 10;
},
else => {
return .{ .failure = .{ .expected_hex_digit = i } };
},
}
}
offset.* = i;
return .{ .success = value };
},
'u' => {
var i: usize = offset.*;
if (i >= slice.len or slice[i] != '{') return .{ .failure = .{ .expected_lbrace = i } };
i += 1;
if (i >= slice.len) return .{ .failure = .{ .expected_hex_digit_or_rbrace = i } };
if (slice[i] == '}') return .{ .failure = .{ .empty_unicode_escape_sequence = i } };
var value: u32 = 0;
while (i < slice.len) : (i += 1) {
const c = slice[i];
switch (c) {
'0'...'9' => {
value *= 16;
value += c - '0';
},
'a'...'f' => {
value *= 16;
value += c - 'a' + 10;
},
'A'...'F' => {
value *= 16;
value += c - 'A' + 10;
},
'}' => {
i += 1;
break;
},
else => return .{ .failure = .{ .expected_hex_digit_or_rbrace = i } },
}
if (value > 0x10ffff) {
return .{ .failure = .{ .invalid_unicode_codepoint = i } };
}
} else {
return .{ .failure = .{ .expected_rbrace = i } };
}
offset.* = i;
return .{ .success = @as(u21, @intCast(value)) };
},
else => return .{ .failure = .{ .invalid_escape_character = offset.* - 1 } },
}
}