diff options
| -rw-r--r-- | main.c | 12 | ||||
| -rw-r--r-- | regex.c | 31 | ||||
| -rw-r--r-- | regex.h | 8 |
3 files changed, 42 insertions, 9 deletions
@@ -531,8 +531,9 @@ done:; int search_next_regex(TxtLoc l, Str src, TxtLoc *out) { RegEx re = { 0 }; ReSearch s = { 0 }; - if (re_comp_ex(&re, src, &e.scratch, &e.scratch, RE_COMP_NO_GROUPS)) { - /* TODO: report parse error */ + int err = re_comp_ex(&re, src, &e.scratch, &e.scratch, RE_COMP_NO_GROUPS); + if (err) { + e.msg = str_printf(&e.scratch, "Regex error: %s", re_comp_strerror(err)); return 0; } TxtLoc t = l; @@ -561,8 +562,9 @@ search_from_start: int search_prev_regex(TxtLoc start, Str src, TxtLoc *out) { RegEx re = { 0 }; ReSearch s = { 0 }; - if (re_comp_ex(&re, src, &e.scratch, &e.scratch, RE_COMP_NO_GROUPS)) { - /* TODO: report parse error */ + int err = re_comp_ex(&re, src, &e.scratch, &e.scratch, RE_COMP_NO_GROUPS); + if (err) { + e.msg = str_printf(&e.scratch, "Regex error: %s", re_comp_strerror(err)); return 0; } int match_found = 0; @@ -1251,4 +1253,4 @@ int main(int argc, const char **argv) { vui_fini(); arena_free(&e.scratch); return 0; -}
\ No newline at end of file +} @@ -33,6 +33,7 @@ typedef struct { Arena *perm, *scratch; DYNARR(u32) lbl; ReCompFlags flags; + ReCompErr err; Str s; int i; } ReParser; @@ -90,7 +91,10 @@ ReNode *re_parse_group(ReParser *s) { /* TODO */ skip(s, 1); ReNode *n = re_new_node(s, N_GROUP, re_parse_expr(s), NULL); - if (ch(s) != ')') FAIL_WITH_MSG("expected )"); + if (ch(s) != ')') { + s->err = RE_COMP_ENORPAREN; + return NULL; + } skip(s, 1); return n; } @@ -177,7 +181,7 @@ ReNode *re_parse_atom(ReParser *s) { } break; case 0: /* should never happen? */ - FAIL_WITH_MSG("atom parsed at end"); + s->err = RE_COMP_EEOF; return NULL; default: { ReNode *n = re_new_node_char(s, ch(s)); @@ -586,14 +590,33 @@ int re_comp_ex(RegEx *re, Str src, Arena *perm, Arena *scratch, ReCompFlags flag .perm = perm, .scratch = scratch, .s = src, - .flags = flags + .flags = flags, + .err = RE_COMP_ENONE }; ReNode *n = re_parse_expr(&s); + if (!s.err) { + if (s.s.n > 0 && s.s.s[s.s.n - 1] == ')') { + s.err = RE_COMP_ENOLPAREN; + } + } if (re_comp_node(&s, n)) return -1; if (re_comp_fin(&s)) return -1; - return 0; + return s.err; +} + +const char *re_comp_strerror(ReCompErr err) { + switch (err) { + case RE_COMP_ENONE: + return "success"; + case RE_COMP_ENORPAREN: + return "no closing )"; + case RE_COMP_ENOLPAREN: + return "no opening ("; + case RE_COMP_EEOF: + return "unexpected end of pattern"; + } } int re_comp(RegEx *re, Str src, Arena *perm, Arena *scratch) { @@ -111,8 +111,16 @@ typedef enum { RE_COMP_NO_GROUPS = 1 } ReCompFlags; +typedef enum { + RE_COMP_ENONE, + RE_COMP_ENORPAREN, + RE_COMP_ENOLPAREN, + RE_COMP_EEOF, +} ReCompErr; + int re_comp(RegEx *re, Str src, Arena *perm, Arena *scratch); int re_comp_ex(RegEx *re, Str src, Arena *perm, Arena *scratch, ReCompFlags flags); +const char *re_comp_strerror(ReCompErr err); void re_search_start(ReSearch *s, RegEx *re, Arena *a); void re_search_chunk(ReSearch *s, const char *buf, size_t n); |
