]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-eq.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / newsearch / ns-eq.c
CommitLineData
c86edd1d
Q
1/*
2 * EQ functionality
3 */
4
5#include "newsearch.h"
4ad1cf7a 6#include "../lib/irc_string.h"
c86edd1d
Q
7
8#include <stdio.h>
9#include <stdlib.h>
10
11struct eq_localdata {
c7f7a584 12 int type;
c86edd1d
Q
13 int count;
14 struct searchNode **nodes;
15};
16
c8be5183
CP
17void eq_free(searchCtx *ctx, struct searchNode *thenode);
18void *eq_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
c86edd1d 19
f33f3f52 20struct searchNode *eq_parse(searchCtx *ctx, int argc, char **argv) {
c86edd1d
Q
21 struct eq_localdata *localdata;
22 struct searchNode *thenode;
23 int i;
24
9ce4f0be
IB
25 if (!(localdata = (struct eq_localdata *)malloc(sizeof(struct eq_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 }
c86edd1d
Q
35 localdata->count = 0;
36
9ce4f0be
IB
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 }
c86edd1d
Q
44
45 thenode->localdata = localdata;
46 thenode->returntype = RETURNTYPE_BOOL;
47 thenode->exe = eq_exe;
48 thenode->free = eq_free;
49
50 for (i=0;i<argc;i++) {
c7f7a584 51 /* Parse the node.. */
f33f3f52 52 localdata->nodes[i] = ctx->parser(ctx, argv[i]);
c7f7a584 53
54 /* Subsequent nodes get coerced to match the type of the first node */
55 if (i)
c8be5183 56 localdata->nodes[i]=coerceNode(ctx,localdata->nodes[i],localdata->type);
c7f7a584 57
58 /* If a node didn't parse, give up */
59 if (!localdata->nodes[i]) {
c8be5183 60 eq_free(ctx, thenode);
c86edd1d
Q
61 return NULL;
62 }
c7f7a584 63
64 if (!i) {
65 /* First arg determines the type */
66 localdata->type = localdata->nodes[0]->returntype & RETURNTYPE_TYPE;
67 }
68
c86edd1d
Q
69 localdata->count++;
70 }
71
72 return thenode;
73}
74
c8be5183 75void eq_free(searchCtx *ctx, struct searchNode *thenode) {
c86edd1d
Q
76 struct eq_localdata *localdata;
77 int i;
78
79 localdata=thenode->localdata;
80
81 for (i=0;i<localdata->count;i++) {
c7f7a584 82 if (localdata->nodes[i])
c8be5183 83 (localdata->nodes[i]->free)(ctx, localdata->nodes[i]);
c86edd1d
Q
84 }
85
86 free(localdata->nodes);
87 free(localdata);
88 free(thenode);
89}
90
c8be5183 91void *eq_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
c86edd1d
Q
92 int i;
93 char *strval;
94 int intval;
95 int rval;
96 struct eq_localdata *localdata;
97
98 localdata=thenode->localdata;
99
100 if (localdata->count==0)
c7f7a584 101 return (void *)1;
c86edd1d 102
c7f7a584 103 switch (localdata->type) {
c86edd1d 104 case RETURNTYPE_INT:
c8be5183 105 intval = (int)((long)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput));
c86edd1d 106 for (i=1;i<localdata->count;i++) {
c8be5183 107 if ((int)((long)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput) != intval))
c7f7a584 108 return (void *)0;
c86edd1d 109 }
c7f7a584 110 return (void *)1;
c86edd1d
Q
111
112 case RETURNTYPE_BOOL:
c8be5183 113 intval = (int)((long)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput));
c86edd1d 114 for (i=1;i<localdata->count;i++) {
c8be5183 115 rval=(int)((long)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput));
c86edd1d 116 if ((rval && !intval) || (!rval && intval)) { /* LOGICAL XOR GOES HERE FS */
c7f7a584 117 return (void *)0;
c86edd1d
Q
118 }
119 }
c7f7a584 120 return (void *)1;
c86edd1d
Q
121
122 case RETURNTYPE_STRING:
c8be5183 123 strval = (char *)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput);
c86edd1d 124 for (i=1;i<localdata->count;i++) {
c8be5183 125 if (ircd_strcmp(strval, (char *)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput)))
c7f7a584 126 return (void *)0;
c86edd1d 127 }
c7f7a584 128 return (void *)1;
c86edd1d
Q
129
130 default:
c7f7a584 131 return (void *)0;
c86edd1d
Q
132 }
133}
134