X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/bdb8b1471a6c9b2438328c810785a2de668d5530..3e1b768066a16c4b899b9cbdd7911be883151a05:/newsearch/newsearch_ast.c diff --git a/newsearch/newsearch_ast.c b/newsearch/newsearch_ast.c index f79f019b..c872579e 100644 --- a/newsearch/newsearch_ast.c +++ b/newsearch/newsearch_ast.c @@ -1,6 +1,7 @@ #include "newsearch.h" #include "../lib/sstring.h" #include "../lib/strlfunc.h" +#include "../lib/stringbuf.h" #include #include @@ -10,12 +11,6 @@ typedef union exprunion { char *literal; } exprunion; -typedef struct searchASTCache { - searchASTExpr *tree; - searchASTExpr *cache[AST_RECENT]; - int nextpos; -} searchASTCache; - /* comares either a string and a string or an expression and an expression */ static searchASTExpr *compareloc(searchASTExpr *expr, exprunion *loc) { if(expr->type == AST_NODE_LITERAL) { @@ -39,8 +34,8 @@ static searchASTExpr *treesearch(searchASTExpr *expr, exprunion *loc) { if(expr->type == AST_NODE_CHILD) { int i; - for(i=0;iu.child->argc;i++) { - searchASTExpr *d = treesearch(expr->u.child->argv[i], loc); + for(i=0;iu.child.argc;i++) { + searchASTExpr *d = treesearch(&expr->u.child.argv[i], loc); if(d) return d; } @@ -76,7 +71,7 @@ static void cachepush(searchASTCache *cache, searchASTExpr *expr) { } /* ast parser, the way we pass context around is very very hacky... */ -searchNode *search_astparse(searchCtx *ctx, int type, char *loc) { +searchNode *search_astparse(searchCtx *ctx, char *loc) { searchASTCache *cache = ctx->arg; searchASTExpr *expr = cachesearch(cache, (exprunion *)&loc); searchNode *node; @@ -100,13 +95,13 @@ searchNode *search_astparse(searchCtx *ctx, int type, char *loc) { node->free = literal_free; return node; case AST_NODE_CHILD: - v = (char **)malloc(expr->u.child->argc * sizeof(char *)); + v = (char **)malloc(expr->u.child.argc * sizeof(char *)); if(!v) { parseError = "malloc: could not allocate memory for this search."; return NULL; } - for(i=0;iu.child->argc;i++) { - searchASTExpr *child = expr->u.child->argv[i]; + for(i=0;iu.child.argc;i++) { + searchASTExpr *child = &expr->u.child.argv[i]; cachepush(cache, child); switch(child->type) { @@ -123,7 +118,7 @@ searchNode *search_astparse(searchCtx *ctx, int type, char *loc) { } } - node = expr->u.child->fn(ctx, type, expr->u.child->argc, v); + node = expr->u.child.fn(ctx, expr->u.child.argc, v); free(v); return node; default: @@ -132,7 +127,39 @@ searchNode *search_astparse(searchCtx *ctx, int type, char *loc) { } } -int ast_nicksearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc wall, NickDisplayFunc display, int limit) { +int ast_nicksearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc wall, NickDisplayFunc display, HeaderFunc header, void *headerarg, int limit, array *targets) { + searchCtx ctx; + searchASTCache cache; + searchNode *search; + char buf[1024]; + + memset(&cache, 0, sizeof(cache)); + cache.tree = tree; + + newsearch_ctxinit(&ctx, search_astparse, reply, wall, &cache, reg_nicksearch, sender, display, limit, targets); + + buf[0] = '\0'; + if (!targets) + reply(sender, "Parsing: %s", ast_printtree(buf, sizeof(buf), tree, reg_nicksearch)); + search = ctx.parser(&ctx, (char *)tree); + if(!search) { + if (!targets) + reply(sender, "Parse error: %s", parseError); + return CMD_ERROR; + } + + if (!targets) + reply(sender, "Executing..."); + if(header) + header(sender, headerarg); + nicksearch_exe(search, &ctx); + + (search->free)(&ctx, search); + + return CMD_OK; +} + +int ast_whowassearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc wall, WhowasDisplayFunc display, HeaderFunc header, void *headerarg, int limit, array *targets) { searchCtx ctx; searchASTCache cache; searchNode *search; @@ -141,79 +168,134 @@ int ast_nicksearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc memset(&cache, 0, sizeof(cache)); cache.tree = tree; - ctx.reply = reply; - ctx.wall = wall; - ctx.parser = search_astparse; - ctx.arg = (void *)&cache; + newsearch_ctxinit(&ctx, search_astparse, reply, wall, &cache, reg_whowassearch, sender, display, limit, targets); + + buf[0] = '\0'; + reply(sender, "Parsing: %s", ast_printtree(buf, sizeof(buf), tree, reg_whowassearch)); + search = ctx.parser(&ctx, (char *)tree); + if(!search) { + reply(sender, "Parse error: %s", parseError); + return CMD_ERROR; + } + + reply(sender, "Executing..."); + if(header) + header(sender, headerarg); + whowassearch_exe(search, &ctx); + + (search->free)(&ctx, search); + + return CMD_OK; +} + +int ast_chansearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc wall, ChanDisplayFunc display, HeaderFunc header, void *headerarg, int limit, array *targets) { + searchCtx ctx; + searchASTCache cache; + searchNode *search; + char buf[1024]; + + newsearch_ctxinit(&ctx, search_astparse, reply, wall, &cache, reg_chansearch, sender, display, limit, targets); + + memset(&cache, 0, sizeof(cache)); + cache.tree = tree; buf[0] = '\0'; - reply(sender, "Parsing: %s", ast_printtree(buf, sizeof(buf), tree)); - search = ctx.parser(&ctx, SEARCHTYPE_NICK, (char *)tree); + reply(sender, "Parsing: %s", ast_printtree(buf, sizeof(buf), tree, reg_chansearch)); + search = ctx.parser(&ctx, (char *)tree); if(!search) { reply(sender, "Parse error: %s", parseError); return CMD_ERROR; } reply(sender, "Executing..."); - nicksearch_exe(search, &ctx, sender, display, limit); + if(header) + header(sender, headerarg); + chansearch_exe(search, &ctx); (search->free)(&ctx, search); return CMD_OK; } -int ast_chansearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc wall, ChanDisplayFunc display, int limit) { +int ast_usersearch(searchASTExpr *tree, replyFunc reply, void *sender, wallFunc wall, UserDisplayFunc display, HeaderFunc header, void *headerarg, int limit, array *targets) { searchCtx ctx; searchASTCache cache; searchNode *search; char buf[1024]; - ctx.reply = reply; - ctx.wall = wall; - ctx.parser = search_astparse; - ctx.arg = (void *)&cache; + memset(&cache, 0, sizeof(cache)); + cache.tree = tree; + + newsearch_ctxinit(&ctx, search_astparse, reply, wall, &cache, reg_usersearch, sender, display, limit, targets); buf[0] = '\0'; - reply(sender, "Parsing: %s", ast_printtree(buf, sizeof(buf), tree)); - search = ctx.parser(&ctx, SEARCHTYPE_CHANNEL, (char *)tree); + reply(sender, "Parsing: %s", ast_printtree(buf, sizeof(buf), tree, reg_usersearch)); + search = ctx.parser(&ctx, (char *)tree); if(!search) { reply(sender, "Parse error: %s", parseError); return CMD_ERROR; } reply(sender, "Executing..."); - chansearch_exe(search, &ctx, sender, display, limit); + if(header) + header(sender, headerarg); + usersearch_exe(search, &ctx); (search->free)(&ctx, search); return CMD_OK; } -/* horribly, horribly inefficient -- don't call me very often! */ -char *ast_printtree(char *buf, size_t bufsize, searchASTExpr *expr) { + +/* horribly inefficient -- don't call me very often! */ +static char *ast_printtree_real(StringBuf *buf, searchASTExpr *expr, searchCmd *cmd) { char lbuf[256]; if(expr->type == AST_NODE_CHILD) { int i; - sstring *command = getcommandname(searchTree, (void *)expr->u.child->fn); - char *space = expr->u.child->argc>0?" ":""; + sstring *command = getcommandname(cmd->searchtree, (void *)expr->u.child.fn); if(command) { - snprintf(lbuf, sizeof(lbuf), "(%s%s", command->content, space); + snprintf(lbuf, sizeof(lbuf), "(%s", command->content); } else { - snprintf(lbuf, sizeof(lbuf), "(%p%s", expr->u.child->fn, space); + snprintf(lbuf, sizeof(lbuf), "(%p", expr->u.child.fn); } - strlcat(buf, lbuf, bufsize); + sbaddstr(buf, lbuf); - for(i=0;iu.child->argc;i++) - ast_printtree(buf, bufsize, expr->u.child->argv[i]); + for(i=0;iu.child.argc;i++) { + sbaddchar(buf, ' '); + ast_printtree_real(buf, &expr->u.child.argv[i], cmd); + } + sbaddchar(buf, ')'); - strlcat(buf, ")", bufsize); } else if(expr->type == AST_NODE_LITERAL) { - snprintf(lbuf, sizeof(lbuf), " %s", expr->u.literal); - strlcat(buf, lbuf, bufsize); + char *p; + + sbaddchar(buf, '"'); + + for(p=expr->u.literal;*p;p++) { + if(*p == '\\' || *p == '"') + sbaddchar(buf, '\\'); + sbaddchar(buf, *p); + } + + sbaddchar(buf, '"'); } else { - strlcat(buf, " ??? ", bufsize); + sbaddstr(buf, "???"); } - return buf; + return buf->buf; +} + +char *ast_printtree(char *buf, size_t bufsize, searchASTExpr *expr, searchCmd *cmd) { + StringBuf b; + char *p; + + b.capacity = bufsize; + b.len = 0; + b.buf = buf; + + p = ast_printtree_real(&b, expr, cmd); + + sbterminate(&b); + return p; }