summaryrefslogtreecommitdiff
path: root/regexset.c
diff options
context:
space:
mode:
Diffstat (limited to 'regexset.c')
-rw-r--r--regexset.c60
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 = &regexes[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);
+ }
+}