int to;
} offshoot_t;
+typedef struct {
+ bool * do_catch;
+ bool * is_negative;
+ int * state;
+ int * width;
+ char * whitelist;
+ regex_t * regex;
+} compiler_state;
+
// ----------------------------------
#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 != '\0'; s++) { \
- vector_push(®ex->delta_table, \
- &(delta_t){state + from, *s, hook_to, width} \
- ); \
- } \
- if (do_catch || is_negative) { \
- vector_push(®ex->catch_table, \
- &(offshoot_t){state + from, hook_to} \
- ); \
- } \
-} while (0)
+void HOOK_ALL( int from,
+ const char * const str,
+ int to,
+ compiler_state * cs) {
+
+ int hook_to = (*cs->is_negative) ? HALT_AND_CATCH_FIRE : *cs->state + to;
+
+ for (const char * s = str; *s != '\0'; s++) {
+ vector_push(&cs->regex->delta_table,
+ &(delta_t){*cs->state + from, *s, hook_to, *cs->width}
+ );
+ }
+ if (cs->do_catch || cs->is_negative) {
+ vector_push(&cs->regex->catch_table,
+ &(offshoot_t){*cs->state + from, hook_to}
+ );
+ }
+}
#define EAT(n) do { \
s += n; \
int state = 0;
- char whitelist[64];
bool do_catch;
bool is_negative;
int width;
+ char whitelist[64];
+
+ compiler_state cs = {
+ .do_catch = &do_catch,
+ .is_negative = &is_negative,
+ .state = &state,
+ .width = &width,
+ .whitelist = whitelist,
+ .regex = regex,
+ };
+
for (const char * s = pattern; *s != '\00';) {
// Get token
assert(!is_quantifier(*pattern) && "Pattern starts with quantifier.");
switch (*s) {
case '=':
case '?': {
- HOOK_ALL(0, whitelist, +1);
+ HOOK_ALL(0, whitelist, +1, &cs);
EAT(1);
} break;
case '*': {
- HOOK_ALL(0, whitelist, 0);
+ HOOK_ALL(0, whitelist, 0, &cs);
EAT(1);
} break;
case '+': {
- HOOK_ALL(0, whitelist, +1);
+ HOOK_ALL(0, whitelist, +1, &cs);
state += 1;
- HOOK_ALL(0, whitelist, 0);
+ HOOK_ALL(0, whitelist, 0, &cs);
EAT(1);
} break;
default: { // Literal
- HOOK_ALL(0, whitelist, +1);
+ HOOK_ALL(0, whitelist, +1, &cs);
state += 1;
} break;
}