+static char *var_tochar(searchCtx *ctx, char *arg, searchNode **variable) {
+ *variable = ctx->parser(ctx, arg);
+ if (!(*variable = coerceNode(ctx, *variable, RETURNTYPE_STRING)))
+ return NULL;
+
+ if(!((*variable)->returntype & RETURNTYPE_CONST)) {
+ parseError = "only constant variables allowed";
+ ((*variable)->free)(ctx, *variable);
+ return NULL;
+ }
+
+ return (char *)((*variable)->exe)(ctx, *variable, NULL);
+}
+
+void free_val_null(searchCtx *ctx, struct searchNode *thenode) {
+}
+
+struct searchVariable *var_register(searchCtx *ctx, char *arg, int type) {
+ searchNode *variable;
+ struct searchVariable *us;
+ char *var;
+ int i;
+
+ if(ctx->lastvar >= MAX_VARIABLES) {
+ parseError = "Maximum number of variables reached";
+ return NULL;
+ }
+
+ us = &ctx->vars[ctx->lastvar];
+
+ var = var_tochar(ctx, arg, &variable);
+ if(!var)
+ return NULL;
+
+ strlcpy(us->name, var, sizeof(us->name));
+ (variable->free)(ctx, variable);
+
+ for(i=0;i<ctx->lastvar;i++) {
+ if(!strcmp(us->name, ctx->vars[i].name)) {
+ parseError = "variable name already in use";
+ return NULL;
+ }
+ }
+
+ ctx->lastvar++;
+ us->data.returntype = type;
+ us->data.localdata = &us->cdata;
+ us->data.exe = exe_val_null;
+ us->data.free = free_val_null;
+
+ us->cdata.child = NULL;
+ return us;
+}
+
+searchNode *var_get(searchCtx *ctx, char *arg) {
+ searchNode *variable, *found = NULL;
+ int i;
+ char *var = var_tochar(ctx, arg, &variable);
+ if(!var)
+ return NULL;
+
+ for(i=0;i<ctx->lastvar;i++) {
+ if(!strcmp(var, ctx->vars[i].name)) {
+ found = &ctx->vars[i].data;
+ break;
+ }
+ }
+ (variable->free)(ctx, variable);
+
+ if(!found)
+ parseError = "variable not found";
+ return found;
+}
+
+void var_setstr(struct searchVariable *v, char *data) {
+ v->cdata.u.stringbuf = data;
+}
+
+void displaystrerror(replyFunc reply, nick *np, const char *input) {
+ char buf[515];
+
+ if((parseStrErrorPos >= 0) && (parseStrErrorPos < sizeof(buf) - 3)) {
+ int i;
+
+ for(i=0;i<parseStrErrorPos;i++)
+ buf[i] = ' ';
+
+ buf[i++] = '^';
+ buf[i] = '\0';
+
+ reply(np, "%s", input);
+ reply(np, "%s", buf);
+ }
+
+ reply(np, "Parse error: %s", parseStrError);
+}
+
+struct searchNode *argtoconststr(char *command, searchCtx *ctx, char *arg, char **p) {
+ struct searchNode *c;
+ static char errorbuf[512];
+
+ c = ctx->parser(ctx, arg);
+ if (!(c = coerceNode(ctx, c, RETURNTYPE_STRING))) {
+ snprintf(errorbuf, sizeof(errorbuf), "%s: unable to coerce argument to string", command);
+ parseError = errorbuf;
+ return NULL;
+ }
+
+ if (!(c->returntype & RETURNTYPE_CONST)) {
+ snprintf(errorbuf, sizeof(errorbuf), "%s: constant argument required", command);
+ parseError = errorbuf;
+ (c->free)(ctx, c);
+ return NULL;
+ }
+
+ if(p)
+ *p = (char *)(c->exe)(ctx, c, NULL);
+
+ return c;
+}