negated ranges should work (not tested)
This commit is contained in:
parent
4011a10a32
commit
af13a1bf7f
@ -18,25 +18,6 @@ typedef struct {
|
||||
int to;
|
||||
} offshoot_t;
|
||||
|
||||
#define HALT_AND_CATCH_FIRE -1
|
||||
|
||||
#define HOOK_ALL(from, str, to) do { \
|
||||
for (char * s = str; *s != '\00'; s++) { \
|
||||
vector_push(®ex->delta_table, \
|
||||
&(delta_t){state + from, *s, state + to} \
|
||||
); \
|
||||
} \
|
||||
if (do_catch) { \
|
||||
vector_push(®ex->catch_table, \
|
||||
&(offshoot_t){state + from, state + to} \
|
||||
); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EAT(n) do { \
|
||||
s += n; \
|
||||
} while (0)
|
||||
|
||||
static bool is_quantifier(const char c) {
|
||||
for (const char * s = "+*?"; *s != '\00'; s++) {
|
||||
if (*s == c) {
|
||||
@ -192,12 +173,19 @@ static int escape_1_to_N(const char c, char * whitelist) {
|
||||
}
|
||||
|
||||
static int compile_range(const char * const range,
|
||||
char * whitelist) {
|
||||
char * whitelist,
|
||||
bool * is_negative) {
|
||||
assert(range[0] == '[' && "Not a range.");
|
||||
|
||||
int r = 0;
|
||||
const char * s;
|
||||
for (s = range+1; *s != ']'; s++) {
|
||||
if (range[1] == '^') {
|
||||
*is_negative = true;
|
||||
s = range + 2;
|
||||
} else {
|
||||
s = range + 1;
|
||||
}
|
||||
for (; *s != ']'; s++) {
|
||||
assert(*s != '\00' && "Unclosed range.");
|
||||
char c = *s;
|
||||
if (escape_1_to_1(c, whitelist)
|
||||
@ -221,6 +209,26 @@ static int compile_range(const char * const range,
|
||||
return ((s - range) + 1);
|
||||
}
|
||||
|
||||
#define HALT_AND_CATCH_FIRE -1
|
||||
|
||||
#define HOOK_ALL(from, str, to) do { \
|
||||
int hook_to = (is_negative) ? -1 : state + to; \
|
||||
for (char * s = str; *s != '\00'; s++) { \
|
||||
vector_push(®ex->delta_table, \
|
||||
&(delta_t){state + from, *s, hook_to} \
|
||||
); \
|
||||
} \
|
||||
if (do_catch) { \
|
||||
vector_push(®ex->catch_table, \
|
||||
&(offshoot_t){state + from, hook_to} \
|
||||
); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EAT(n) do { \
|
||||
s += n; \
|
||||
} while (0)
|
||||
|
||||
regex_t * regex_compile(const char * const pattern) {
|
||||
regex_t * regex = (regex_t *)malloc(sizeof(regex_t));
|
||||
regex->str = strdup(pattern);
|
||||
@ -231,11 +239,13 @@ regex_t * regex_compile(const char * const pattern) {
|
||||
|
||||
char whitelist[64];
|
||||
bool do_catch;
|
||||
bool is_negative;
|
||||
for (const char * s = pattern; *s != '\00';) {
|
||||
// Get token
|
||||
assert(!is_quantifier(*pattern) && "Pattern starts with quantifier.");
|
||||
whitelist[0] = '\00';
|
||||
do_catch = false;
|
||||
|
||||
switch (*s) {
|
||||
case '.': {
|
||||
do_catch = true;
|
||||
@ -250,7 +260,7 @@ regex_t * regex_compile(const char * const pattern) {
|
||||
}
|
||||
} break;
|
||||
case '[': {
|
||||
EAT(compile_range(s, whitelist)-1);
|
||||
EAT(compile_range(s, whitelist, &is_negative)-1);
|
||||
} break;
|
||||
default: {
|
||||
whitelist[0] = *s;
|
||||
|
Loading…
Reference in New Issue
Block a user