]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-all.c
Add iterators to newsearch, along with an example channel iterator function.
[irc/quakenet/newserv.git] / newsearch / ns-all.c
1 /*
2 * ALL functionality
3 */
4
5 #include "newsearch.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 void all_free(searchCtx *ctx, struct searchNode *thenode);
11 void *all_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
12
13 #define MAX_ITERATIONS 1000
14
15 struct all_localdata {
16 searchNode *genfn;
17 searchNode *lambdafn;
18 int hitlimit;
19 };
20
21 struct searchNode *all_parse(searchCtx *ctx, int type, int argc, char **argv) {
22 searchNode *thenode;
23 struct all_localdata *localdata;
24
25 if(argc < 2) {
26 parseError = "all: usage: all (generatorfn x) (fn ... (var x) ...)";
27 return NULL;
28 }
29
30 if(!(localdata=(struct all_localdata *)malloc(sizeof(struct all_localdata)))) {
31 parseError = "malloc: could not allocate memory for this search.";
32 return NULL;
33 }
34
35 localdata->hitlimit = 0;
36
37 if(!(localdata->genfn=ctx->parser(ctx, type, argv[0]))) {
38 free(localdata);
39 return NULL;
40 }
41
42 localdata->lambdafn = ctx->parser(ctx, type, argv[1]);
43 if(!(localdata->lambdafn = coerceNode(ctx, localdata->lambdafn, RETURNTYPE_BOOL))) {
44 (localdata->genfn->free)(ctx, localdata->genfn);
45 free(localdata);
46 return NULL;
47 }
48
49 if(!(thenode=(struct searchNode *)malloc(sizeof(struct searchNode)))) {
50 parseError = "malloc: could not allocate memory for this search.";
51 (localdata->genfn->free)(ctx, localdata->genfn);
52 (localdata->lambdafn->free)(ctx, localdata->lambdafn);
53 free(localdata);
54 return NULL;
55 }
56
57 thenode->returntype = RETURNTYPE_BOOL;
58 thenode->localdata = localdata;
59 thenode->exe = all_exe;
60 thenode->free = all_free;
61
62 return thenode;
63 }
64
65 void all_free(searchCtx *ctx, struct searchNode *thenode) {
66 struct all_localdata *localdata = thenode->localdata;
67
68 if(localdata->hitlimit)
69 ctx->reply(senderNSExtern, "Warning: your expression hit the maximum iteration count and was terminated early.");
70
71 (localdata->genfn->free)(ctx, localdata->genfn);
72 (localdata->lambdafn->free)(ctx, localdata->lambdafn);
73
74 free(localdata);
75 free(thenode);
76 }
77
78 void *all_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
79 struct all_localdata *localdata = thenode->localdata;
80 int i;
81
82 if(localdata->hitlimit)
83 return (void *)0;
84
85 for(i=0;i<MAX_ITERATIONS;i++) {
86 if(!(localdata->genfn->exe)(ctx, localdata->genfn, theinput))
87 return (void *)1;
88
89 if(!(localdata->lambdafn->exe)(ctx, localdata->lambdafn, theinput))
90 return (void *)0;
91 }
92
93 localdata->hitlimit = 1;
94 return (void *)0;
95 }