]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-regex.c
merge
[irc/quakenet/newserv.git] / newsearch / ns-regex.c
CommitLineData
c86edd1d
Q
1/*
2 * REGEX functionality
3 */
4
5#include "newsearch.h"
6
7#include <stdio.h>
8#include <stdlib.h>
4ad1cf7a 9#include <string.h>
c86edd1d
Q
10#include <pcre.h>
11
12struct regex_localdata {
13 struct searchNode *targnode;
14 struct searchNode *patnode;
15 pcre *pcre;
16 pcre_extra *pcre_extra;
17};
18
c8be5183
CP
19void *regex_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
20void regex_free(searchCtx *ctx, struct searchNode *thenode);
c86edd1d 21
f33f3f52 22struct searchNode *regex_parse(searchCtx *ctx, int argc, char **argv) {
c86edd1d
Q
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
f33f3f52 36 targnode=ctx->parser(ctx, argv[0]);
c8be5183 37 if (!(targnode = coerceNode(ctx,targnode, RETURNTYPE_STRING)))
c86edd1d
Q
38 return NULL;
39
f33f3f52 40 patnode=ctx->parser(ctx, argv[1]);
c8be5183
CP
41 if (!(patnode = coerceNode(ctx,patnode, RETURNTYPE_STRING))) {
42 (targnode->free)(ctx, targnode);
c86edd1d
Q
43 return NULL;
44 }
45
46 if (!(patnode->returntype & RETURNTYPE_CONST)) {
47 parseError="regex: only constant regexes allowed";
c8be5183
CP
48 (targnode->free)(ctx, targnode);
49 (patnode->free)(ctx, patnode);
c86edd1d
Q
50 return NULL;
51 }
52
c8be5183 53 if (!(pcre=pcre_compile((char *)(patnode->exe)(ctx, patnode,NULL),
c86edd1d
Q
54 PCRE_CASELESS, &err, &erroffset, NULL))) {
55 parseError=err;
56 return NULL;
57 }
58
59 pcre_extra=pcre_study(pcre, 0, &err);
60
9ce4f0be
IB
61 if (!(localdata=(struct regex_localdata *)malloc(sizeof (struct regex_localdata)))) {
62 parseError = "malloc: could not allocate memory for this search.";
63 /* make sure we pcre_free() if we're not going to use them */
64 if (pcre_extra)
65 pcre_free(pcre_extra);
66
67 if (pcre)
68 pcre_free(pcre);
69 return NULL;
70 }
c86edd1d
Q
71
72 localdata->targnode=targnode;
73 localdata->patnode=patnode;
74 localdata->pcre=pcre;
75 localdata->pcre_extra=pcre_extra;
76
9ce4f0be
IB
77 if (!(thenode = (struct searchNode *)malloc(sizeof (struct searchNode)))) {
78 /* couldn't malloc() memory for thenode, so free the pcre's and localdata to avoid leakage */
79 parseError = "malloc: could not allocate memory for this search.";
80 if (localdata->pcre_extra)
81 pcre_free(localdata->pcre_extra);
82
83 if (localdata->pcre)
84 pcre_free(localdata->pcre);
85
86 free(localdata);
87 return NULL;
88 }
c86edd1d
Q
89
90 thenode->returntype = RETURNTYPE_BOOL;
91 thenode->localdata = localdata;
92 thenode->exe = regex_exe;
93 thenode->free = regex_free;
94
95 return thenode;
96}
97
c8be5183 98void *regex_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
c86edd1d
Q
99 struct regex_localdata *localdata;
100 char *target;
101
102 localdata = thenode->localdata;
103
c8be5183 104 target = (char *)((localdata->targnode->exe)(ctx, localdata->targnode,theinput));
c86edd1d
Q
105
106 if (pcre_exec(localdata->pcre, localdata->pcre_extra,target,strlen(target),0,
107 0,NULL,0)) {
108 /* didn't match */
c7f7a584 109 return (void *)0;
c86edd1d 110 } else {
c7f7a584 111 return (void *)1;
c86edd1d
Q
112 }
113}
114
c8be5183 115void regex_free(searchCtx *ctx, struct searchNode *thenode) {
c86edd1d
Q
116 struct regex_localdata *localdata;
117
118 localdata=thenode->localdata;
119
120 if (localdata->pcre_extra)
121 pcre_free(localdata->pcre_extra);
122
123 if (localdata->pcre)
124 pcre_free(localdata->pcre);
125
c8be5183
CP
126 (localdata->patnode->free)(ctx, localdata->patnode);
127 (localdata->targnode->free)(ctx, localdata->targnode);
c86edd1d
Q
128 free(localdata);
129 free(thenode);
130}
131