diff options
Diffstat (limited to 'regexset.c')
-rw-r--r-- | regexset.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/regexset.c b/regexset.c new file mode 100644 index 0000000..3eafb74 --- /dev/null +++ b/regexset.c @@ -0,0 +1,60 @@ +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "regexset.h" + +struct regexset_t *regexes; +int rs_count; + +void rs_init() { + regexes = NULL; + rs_count = 0; +} + +static inline 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; + } + + /* 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); + re_error("join", join, error, erroffset); + return NULL; + } + + return rs; +} + +void rs_free() { + for(int i = 0; i < rs_count; i++) { + pcre_free(regexes[i].text); + pcre_free(regexes[i].join); + } +} |