]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-regex.c
Initial Import
[irc/quakenet/newserv.git] / newsearch / ns-regex.c
1 /*
2 * REGEX functionality
3 */
4
5 #include "newsearch.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include <pcre.h>
11
12 struct regex_localdata {
13 struct searchNode *targnode;
14 struct searchNode *patnode;
15 pcre *pcre;
16 pcre_extra *pcre_extra;
17 };
18
19 void *regex_exe(struct searchNode *thenode, int type, void *theinput);
20 void regex_free(struct searchNode *thenode);
21
22 struct searchNode *regex_parse(int type, int argc, char **argv) {
23 struct regex_localdata *localdata;
24 struct searchNode *thenode;
25 struct searchNode *targnode, *patnode;
26 const char *err;
27 int erroffset;
28 pcre *pcre;
29 pcre_extra *pcre_extra;
30
31 if (argc<2) {
32 parseError="regex: usage: regex source pattern";
33 return NULL;
34 }
35
36 if (!(targnode = search_parse(type, argv[0])))
37 return NULL;
38
39 if (!(patnode = search_parse(type, argv[1]))) {
40 (targnode->free)(targnode);
41 return NULL;
42 }
43
44 if (!(patnode->returntype & RETURNTYPE_CONST)) {
45 parseError="regex: only constant regexes allowed";
46 (targnode->free)(targnode);
47 (patnode->free)(patnode);
48 return NULL;
49 }
50
51 if (!(pcre=pcre_compile((char *)(patnode->exe)(patnode,RETURNTYPE_STRING,NULL),
52 PCRE_CASELESS, &err, &erroffset, NULL))) {
53 parseError=err;
54 return NULL;
55 }
56
57 pcre_extra=pcre_study(pcre, 0, &err);
58
59 localdata=(struct regex_localdata *)malloc(sizeof (struct regex_localdata));
60
61 localdata->targnode=targnode;
62 localdata->patnode=patnode;
63 localdata->pcre=pcre;
64 localdata->pcre_extra=pcre_extra;
65
66 thenode = (struct searchNode *)malloc(sizeof (struct searchNode));
67
68 thenode->returntype = RETURNTYPE_BOOL;
69 thenode->localdata = localdata;
70 thenode->exe = regex_exe;
71 thenode->free = regex_free;
72
73 return thenode;
74 }
75
76 void *regex_exe(struct searchNode *thenode, int type, void *theinput) {
77 struct regex_localdata *localdata;
78 char *target;
79
80 localdata = thenode->localdata;
81
82 target = (char *)((localdata->targnode->exe)(localdata->targnode,RETURNTYPE_STRING, theinput));
83
84 if (pcre_exec(localdata->pcre, localdata->pcre_extra,target,strlen(target),0,
85 0,NULL,0)) {
86 /* didn't match */
87 return falseval(type);
88 } else {
89 return trueval(type);
90 }
91 }
92
93 void regex_free(struct searchNode *thenode) {
94 struct regex_localdata *localdata;
95
96 localdata=thenode->localdata;
97
98 if (localdata->pcre_extra)
99 pcre_free(localdata->pcre_extra);
100
101 if (localdata->pcre)
102 pcre_free(localdata->pcre);
103
104 (localdata->patnode->free)(localdata->patnode);
105 (localdata->targnode->free)(localdata->targnode);
106 free(localdata);
107 free(thenode);
108 }
109