]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-lt.c
merge
[irc/quakenet/newserv.git] / newsearch / ns-lt.c
1 /*
2 * LT functionality
3 */
4
5 #include "newsearch.h"
6 #include "../lib/irc_string.h"
7
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 struct lt_localdata {
12 int type;
13 int count;
14 struct searchNode **nodes;
15 };
16
17 void lt_free(searchCtx *ctx, struct searchNode *thenode);
18 void *lt_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
19
20 struct searchNode *lt_parse(searchCtx *ctx, int argc, char **argv) {
21 struct lt_localdata *localdata;
22 struct searchNode *thenode;
23 int i;
24
25 if (!(localdata = (struct lt_localdata *)malloc(sizeof(struct lt_localdata)))) {
26 parseError = "malloc: could not allocate memory for this search.";
27 return NULL;
28 }
29 if (!(localdata->nodes = (struct searchNode **)malloc(sizeof(struct searchNode *) * argc))) {
30 /* couldn't malloc() memory for localdata->nodes, so free localdata to avoid leakage */
31 parseError = "malloc: could not allocate memory for this search.";
32 free(localdata);
33 return NULL;
34 }
35 localdata->count = 0;
36
37 if (!(thenode = (struct searchNode *)malloc(sizeof(struct searchNode)))) {
38 /* couldn't malloc() memory for thenode, so free localdata and localdata->nodes 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->localdata = localdata;
46 thenode->returntype = RETURNTYPE_BOOL;
47 thenode->exe = lt_exe;
48 thenode->free = lt_free;
49
50 for (i=0;i<argc;i++) {
51 /* Parse the node.. */
52 localdata->nodes[i] = ctx->parser(ctx, argv[i]);
53
54 /* Subsequent nodes get coerced to match the type of the first node */
55 if (i)
56 localdata->nodes[i]=coerceNode(ctx, localdata->nodes[i],localdata->type);
57
58 /* If a node didn't parse, give up */
59 if (!localdata->nodes[i]) {
60 lt_free(ctx, thenode);
61 return NULL;
62 }
63
64 if (!i) {
65 /* First arg determines the type */
66 localdata->type = localdata->nodes[0]->returntype & RETURNTYPE_TYPE;
67 }
68
69 localdata->count++;
70 }
71
72 return thenode;
73 }
74
75 void lt_free(searchCtx *ctx, struct searchNode *thenode) {
76 struct lt_localdata *localdata;
77 int i;
78
79 localdata=thenode->localdata;
80
81 for (i=0;i<localdata->count;i++) {
82 if (localdata->nodes[i])
83 (localdata->nodes[i]->free)(ctx, localdata->nodes[i]);
84 }
85
86 free(localdata->nodes);
87 free(localdata);
88 free(thenode);
89 }
90
91 void *lt_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
92 int i;
93 char *strval;
94 int intval;
95 struct lt_localdata *localdata;
96
97 localdata=thenode->localdata;
98
99 if (localdata->count==0)
100 return (void *)1;
101
102 switch (localdata->type) {
103 case RETURNTYPE_INT:
104 case RETURNTYPE_BOOL:
105 intval = (int)((long)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput));
106 for (i=1;i<localdata->count;i++) {
107 if ((int)((long)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput) <= intval))
108 return (void *)0;
109 }
110 return (void *)1;
111
112 case RETURNTYPE_STRING:
113 strval = (char *)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput);
114 for (i=1;i<localdata->count;i++) {
115 if (ircd_strcmp(strval, (char *)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput)) >= 0)
116 return (void *)0;
117 }
118 return (void *)1;
119
120 default:
121 return (void *)0;
122 }
123 }
124