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) {
}
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)
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);
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;
}
} break;
case '[': {
- EAT(compile_range(s, whitelist)-1);
+ EAT(compile_range(s, whitelist, &is_negative)-1);
} break;
default: {
whitelist[0] = *s;