#include <stdlib.h>
struct eq_localdata {
+ int type;
int count;
struct searchNode **nodes;
};
-void eq_free(struct searchNode *thenode);
-void *eq_exe(struct searchNode *thenode, int type, void *theinput);
+void eq_free(searchCtx *ctx, struct searchNode *thenode);
+void *eq_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
-struct searchNode *eq_parse(int type, int argc, char **argv) {
+struct searchNode *eq_parse(searchCtx *ctx, int argc, char **argv) {
struct eq_localdata *localdata;
struct searchNode *thenode;
int i;
- localdata = (struct eq_localdata *)malloc(sizeof(struct eq_localdata));
- localdata->nodes = (struct searchNode **)malloc(sizeof(struct searchNode *) * argc);
+ if (!(localdata = (struct eq_localdata *)malloc(sizeof(struct eq_localdata)))) {
+ parseError = "malloc: could not allocate memory for this search.";
+ return NULL;
+ }
+ if (!(localdata->nodes = (struct searchNode **)malloc(sizeof(struct searchNode *) * argc))) {
+ /* couldn't malloc() memory for localdata->nodes, so free localdata to avoid leakage */
+ parseError = "malloc: could not allocate memory for this search.";
+ free(localdata);
+ return NULL;
+ }
localdata->count = 0;
- thenode = (struct searchNode *)malloc(sizeof(struct searchNode));
+ if (!(thenode = (struct searchNode *)malloc(sizeof(struct searchNode)))) {
+ /* couldn't malloc() memory for thenode, so free localdata and localdata->nodes to avoid leakage */
+ parseError = "malloc: could not allocate memory for this search.";
+ free(localdata->nodes);
+ free(localdata);
+ return NULL;
+ }
thenode->localdata = localdata;
thenode->returntype = RETURNTYPE_BOOL;
thenode->free = eq_free;
for (i=0;i<argc;i++) {
- if (!(localdata->nodes[i] = search_parse(type, argv[i]))) {
- eq_free(thenode);
+ /* Parse the node.. */
+ localdata->nodes[i] = ctx->parser(ctx, argv[i]);
+
+ /* Subsequent nodes get coerced to match the type of the first node */
+ if (i)
+ localdata->nodes[i]=coerceNode(ctx,localdata->nodes[i],localdata->type);
+
+ /* If a node didn't parse, give up */
+ if (!localdata->nodes[i]) {
+ eq_free(ctx, thenode);
return NULL;
}
+
+ if (!i) {
+ /* First arg determines the type */
+ localdata->type = localdata->nodes[0]->returntype & RETURNTYPE_TYPE;
+ }
+
localdata->count++;
}
return thenode;
}
-void eq_free(struct searchNode *thenode) {
+void eq_free(searchCtx *ctx, struct searchNode *thenode) {
struct eq_localdata *localdata;
int i;
localdata=thenode->localdata;
for (i=0;i<localdata->count;i++) {
- (localdata->nodes[i]->free)(localdata->nodes[i]);
+ if (localdata->nodes[i])
+ (localdata->nodes[i]->free)(ctx, localdata->nodes[i]);
}
free(localdata->nodes);
free(thenode);
}
-void *eq_exe(struct searchNode *thenode, int type, void *theinput) {
+void *eq_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
int i;
char *strval;
int intval;
localdata=thenode->localdata;
if (localdata->count==0)
- return trueval(type);
+ return (void *)1;
- switch (localdata->nodes[0]->returntype & RETURNTYPE_TYPE) {
+ switch (localdata->type) {
case RETURNTYPE_INT:
- intval = (int)(localdata->nodes[0]->exe)(localdata->nodes[0], RETURNTYPE_INT, theinput);
+ intval = (int)((long)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput));
for (i=1;i<localdata->count;i++) {
- if ((int)(localdata->nodes[i]->exe)(localdata->nodes[i], RETURNTYPE_INT, theinput) != intval)
- return falseval(type);
+ if ((int)((long)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput) != intval))
+ return (void *)0;
}
-
- return trueval(type);
+ return (void *)1;
case RETURNTYPE_BOOL:
- intval = (int)(localdata->nodes[0]->exe)(localdata->nodes[0], RETURNTYPE_BOOL, theinput);
+ intval = (int)((long)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput));
for (i=1;i<localdata->count;i++) {
- rval=(int)(localdata->nodes[i]->exe)(localdata->nodes[i], RETURNTYPE_BOOL, theinput);
+ rval=(int)((long)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput));
if ((rval && !intval) || (!rval && intval)) { /* LOGICAL XOR GOES HERE FS */
- return falseval(type);
+ return (void *)0;
}
}
-
- return trueval(type);
+ return (void *)1;
case RETURNTYPE_STRING:
- strval = (char *)(localdata->nodes[0]->exe)(localdata->nodes[0], RETURNTYPE_STRING, theinput);
+ strval = (char *)(localdata->nodes[0]->exe)(ctx, localdata->nodes[0], theinput);
for (i=1;i<localdata->count;i++) {
- if (ircd_strcmp(strval, (char *)(localdata->nodes[i]->exe)(localdata->nodes[i], RETURNTYPE_STRING, theinput)))
- return falseval(type);
+ if (ircd_strcmp(strval, (char *)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput)))
+ return (void *)0;
}
-
- return trueval(type);
+ return (void *)1;
default:
- return falseval(type);
+ return (void *)0;
}
}