]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-and.c
SearchCtx should contain 'type' - this is to make life easier when defining new searc...
[irc/quakenet/newserv.git] / newsearch / ns-and.c
1 /*
2 * AND functionality
3 */
4
5 #include "newsearch.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 void and_free(searchCtx *ctx, struct searchNode *thenode);
11 void *and_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
12
13 struct and_localdata {
14 int count;
15 searchNode **nodes;
16 };
17
18 struct searchNode *and_parse(searchCtx *ctx, int argc, char **argv) {
19 searchNode *thenode, *subnode;
20 struct and_localdata *localdata;
21 int i;
22
23 /* Set up our local data - a list of nodes to AND together */
24 if (!(localdata=(struct and_localdata *)malloc(sizeof(struct and_localdata)))) {
25 parseError = "malloc: could not allocate memory for this search.";
26 return NULL;
27 }
28 if (!(localdata->nodes=(searchNode **)malloc(argc * sizeof(searchNode *)))) {
29 /* couldn't malloc() memory for localdata->nodes, so free localdata to avoid leakage */
30 parseError = "malloc: could not allocate memory for this search.";
31 free(localdata);
32 return NULL;
33 }
34 localdata->count=0;
35
36 /* Allocate our actual node */
37 if (!(thenode=(struct searchNode *)malloc(sizeof(struct searchNode)))) {
38 /* couldn't malloc() memory for thenode, so free localdata->nodes and localdata to avoid leakage */
39 parseError = "malloc: could not allocate memory for this search.";
40 free(localdata->nodes);
41 free(localdata);
42 return NULL;
43 }
44
45 thenode->returntype = RETURNTYPE_BOOL;
46 thenode->localdata = localdata;
47 thenode->exe = and_exe;
48 thenode->free = and_free;
49
50 for (i=0;i<argc;i++) {
51 subnode=ctx->parser(ctx, argv[i]); /* Propogate the search type */
52 subnode=coerceNode(ctx, subnode, RETURNTYPE_BOOL); /* Needs to return BOOL */
53 if (subnode) {
54 localdata->nodes[localdata->count++] = subnode;
55 } else {
56 and_free(ctx, thenode); /* ?? */
57 return NULL;
58 }
59 }
60
61 return thenode;
62 }
63
64 void and_free(searchCtx *ctx, struct searchNode *thenode) {
65 struct and_localdata *localdata;
66 int i;
67
68 localdata=thenode->localdata;
69 for (i=0;i<localdata->count;i++) {
70 (localdata->nodes[i]->free)(ctx, localdata->nodes[i]);
71 }
72
73 free(localdata->nodes);
74 free(localdata);
75 free(thenode);
76 }
77
78 void *and_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
79 int i;
80 struct and_localdata *localdata;
81
82 localdata=thenode->localdata;
83
84 for (i=0;i<localdata->count;i++) {
85 if (!(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput))
86 return NULL;
87 }
88 return (void *)1;
89 }