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; }