#include "prism/util/pm_char.h"
#define PRISM_CHAR_BIT_WHITESPACE (1 << 0)
#define PRISM_CHAR_BIT_INLINE_WHITESPACE (1 << 1)
#define PRISM_CHAR_BIT_REGEXP_OPTION (1 << 2)
#define PRISM_NUMBER_BIT_BINARY_DIGIT (1 << 0)
#define PRISM_NUMBER_BIT_BINARY_NUMBER (1 << 1)
#define PRISM_NUMBER_BIT_OCTAL_DIGIT (1 << 2)
#define PRISM_NUMBER_BIT_OCTAL_NUMBER (1 << 3)
#define PRISM_NUMBER_BIT_DECIMAL_DIGIT (1 << 4)
#define PRISM_NUMBER_BIT_DECIMAL_NUMBER (1 << 5)
#define PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT (1 << 6)
#define PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER (1 << 7)
static const uint8_t pm_byte_table[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
static const uint8_t pm_number_table[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
static inline size_t
pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
if (length <= 0) return 0;
size_t size = 0;
size_t maximum = (size_t) length;
while (size < maximum && (pm_byte_table[string[size]] & kind)) size++;
return size;
}
size_t
pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_WHITESPACE);
}
size_t
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list) {
if (length <= 0) return 0;
size_t size = 0;
size_t maximum = (size_t) length;
while (size < maximum && (pm_byte_table[string[size]] & PRISM_CHAR_BIT_WHITESPACE)) {
if (string[size] == '\n') {
pm_newline_list_append(newline_list, string + size);
}
size++;
}
return size;
}
size_t
pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) {
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_INLINE_WHITESPACE);
}
size_t
pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) {
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_REGEXP_OPTION);
}
static inline bool
pm_char_is_char_kind(const uint8_t b, uint8_t kind) {
return (pm_byte_table[b] & kind) != 0;
}
bool
pm_char_is_whitespace(const uint8_t b) {
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_WHITESPACE);
}
bool
pm_char_is_inline_whitespace(const uint8_t b) {
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_INLINE_WHITESPACE);
}
static inline size_t
pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
if (length <= 0) return 0;
size_t size = 0;
size_t maximum = (size_t) length;
while (size < maximum && (pm_number_table[string[size]] & kind)) size++;
return size;
}
static inline size_t
pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) {
if (length <= 0) return 0;
size_t size = 0;
size_t maximum = (size_t) length;
bool underscore = false;
while (size < maximum && (pm_number_table[string[size]] & kind)) {
if (string[size] == '_') {
if (underscore) *invalid = string + size;
underscore = true;
} else {
underscore = false;
}
size++;
}
if (size > 0 && string[size - 1] == '_') *invalid = string + size - 1;
return size;
}
size_t
pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_BINARY_NUMBER);
}
size_t
pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_OCTAL_NUMBER);
}
size_t
pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) {
return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
}
size_t
pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_DECIMAL_NUMBER);
}
size_t
pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) {
return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
}
size_t
pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER);
}
static inline bool
pm_char_is_number_kind(const uint8_t b, uint8_t kind) {
return (pm_number_table[b] & kind) != 0;
}
bool
pm_char_is_binary_digit(const uint8_t b) {
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_BINARY_DIGIT);
}
bool
pm_char_is_octal_digit(const uint8_t b) {
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_OCTAL_DIGIT);
}
bool
pm_char_is_decimal_digit(const uint8_t b) {
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
}
bool
pm_char_is_hexadecimal_digit(const uint8_t b) {
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
}
#undef PRISM_CHAR_BIT_WHITESPACE
#undef PRISM_CHAR_BIT_INLINE_WHITESPACE
#undef PRISM_CHAR_BIT_REGEXP_OPTION
#undef PRISM_NUMBER_BIT_BINARY_DIGIT
#undef PRISM_NUMBER_BIT_BINARY_NUMBER
#undef PRISM_NUMBER_BIT_OCTAL_DIGIT
#undef PRISM_NUMBER_BIT_OCTAL_NUMBER
#undef PRISM_NUMBER_BIT_DECIMAL_DIGIT
#undef PRISM_NUMBER_BIT_DECIMAL_NUMBER
#undef PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER
#undef PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT