1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "regexset.h"
struct regexset_t *regexes;
int rs_count;
const unsigned char *rs_pcre_tables;
void rs_init() {
regexes = NULL;
rs_count = 0;
rs_pcre_tables = pcre_maketables();
}
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, const char *kick) {
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, rs_pcre_tables);
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, rs_pcre_tables);
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);
rs->kick = pcre_compile(kick, 0, &error, &erroffset, rs_pcre_tables);
if(rs->kick == NULL) {
pcre_free(rs->text);
pcre_free(rs->join);
if(rs->text_e) {
pcre_free(rs->text_e);
pcre_free(rs->join_e);
}
re_error("kick", kick, error, erroffset);
return NULL;
}
rs->kick_e = pcre_study(rs->kick, 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);
pcre_free(regexes[i].kick);
if(regexes[i].kick_e)
pcre_free(regexes[i].kick_e);
}
free(regexes);
regexes = NULL;
pcre_free((void*)rs_pcre_tables);
rs_pcre_tables = NULL;
}
|