1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
const std = @import("std");
pub fn isNameChar(char: u8) bool {
return switch(char) {
'0'...'9', 'A'...'Z', 'a'...'z', '_' => true,
else => false
};
}
pub fn read_name(buffer: []const u8) struct { []const u8, []const u8 } {
for (buffer, 0..) |char, index| {
if (!isNameChar(char)) {
return .{ buffer[0..index], buffer[index..] };
}
}
return .{ buffer[0..buffer.len], buffer[buffer.len..] };
}
pub fn read_first_from_literal(buffer: []const u8) !struct { u8, []const u8 } {
if (buffer[0] != '\\') {
return .{ buffer[0], buffer[1..] } ;
}
if (buffer.len > 1 and buffer[1] != 'x') {
return switch(buffer[1]) {
't' => return .{ '\t', buffer[2..] },
'n' => return .{ '\n', buffer[2..] },
'r' => return .{ '\r', buffer[2..] },
'\'' => return .{ '\'', buffer[2..] },
'\\' => return .{ '\\', buffer[2..] },
else => return error.InvalidEscapeSequence,
};
}
if (buffer.len > 4 and buffer[1] == 'x') {
return .{ try std.fmt.parseInt(u8, buffer[2..4], 16), buffer[4..] };
}
return error.InvalidEscapeSequnce;
}
|