#include #include #include #include #include "regexset.h" struct regexset_t *regexes; int rs_count; void rs_init() { regexes = NULL; rs_count = 0; } static void re_error(const char *name, const char *pattern, const char *error, int erroffset) { fprintf(stderr, "RE \"%s\" failed to compile: %s\n", name, error); fprintf(stderr, "%s\n", pattern); for(int i = 0; i < erroffset; i++) fprintf(stderr, " "); fprintf(stderr, "^\n"); regexes = realloc(regexes, --rs_count * sizeof(struct regexset_t)); } struct regexset_t *rs_add(const char *text, const char *join) { regexes = realloc(regexes, ++rs_count * sizeof(struct regexset_t)); if(!regexes) { /* If we end up here, we cannot free any previously compiled pcre patterns. */ char *error = strerror(errno); fprintf(stderr, "Could not (re)allocate memory for regex sets: %s\n", error); return NULL; } /* Fetch the last struct. */ struct regexset_t *rs = ®exes[rs_count-1]; const char *error; int erroffset; rs->text = pcre_compile(text, 0, &error, &erroffset, NULL); if(rs->text == NULL) { re_error("text", text, error, erroffset); return NULL; } rs->text_e = pcre_study(rs->text, 0, &error); /* Free compiled patterns from this point when failing. */ rs->join = pcre_compile(join, 0, &error, &erroffset, NULL); if(rs->join == NULL) { pcre_free(rs->text); if(rs->text_e) pcre_free(rs->text_e); re_error("join", join, error, erroffset); return NULL; } rs->join_e = pcre_study(rs->join, 0, &error); return rs; } struct regexset_t *rs_get(int index) { return (index < rs_count ? ®exes[index] : NULL); } void rs_free() { for(int i = 0; i < rs_count; i++) { pcre_free(regexes[i].text); if(regexes[i].text_e) pcre_free(regexes[i].text_e); pcre_free(regexes[i].join); if(regexes[i].join_e) pcre_free(regexes[i].join_e); } free(regexes); regexes = NULL; }