#include "../lib/strlfunc.h"
#include "../lib/array.h"
#include "newsearch.h"
+#include "parser.h"
MODULE_VERSION("");
searchCmd *reg_nicksearch, *reg_chansearch, *reg_usersearch;
void displaycommandhelp(nick *, Command *);
+void displaystrerror(replyFunc, nick *, const char *);
searchCmd *registersearchcommand(char *name, int level, CommandHandler cmd, void *defaultdisplayfunc) {
searchCmd *acmd;
/* Nickname operations */
registersearchterm(reg_nicksearch, "hostmask",hostmask_parse, 0, "The user's nick!user@host; \"hostmask real\" returns nick!user@host\rreal"); /* nick only */
registersearchterm(reg_nicksearch, "realname",realname_parse, 0, "User's current realname"); /* nick only */
+ registersearchterm(reg_nicksearch, "away",away_parse, 0, "User's current away message"); /* nick only */
registersearchterm(reg_nicksearch, "authname",authname_parse, 0, "User's current authname or false"); /* nick only */
registersearchterm(reg_nicksearch, "authts",authts_parse, 0, "User's Auth timestamp"); /* nick only */
registersearchterm(reg_nicksearch, "ident",ident_parse, 0, "User's current ident"); /* nick only */
registersearchterm(reg_nicksearch, "server",server_parse, 0, "Server Name. Either (server string) or (match (server) string)"); /* nick only */
registersearchterm(reg_nicksearch, "authid",authid_parse, 0, "User's Auth ID"); /* nick only */
registersearchterm(reg_nicksearch, "cidr",cidr_parse, 0, "CIDR matching"); /* nick only */
+ registersearchterm(reg_nicksearch, "ipvsix",ipv6_parse, 0, "IPv6 user"); /* nick only */
/* Channel operations */
registersearchterm(reg_chansearch, "exists",exists_parse, 0, "Returns if channel exists on network. Note: newserv may store data on empty channels"); /* channel only */
registersearchterm(reg_chansearch, "name",name_parse, 0, "Channel Name"); /* channel only */
registersearchterm(reg_chansearch, "topic",topic_parse, 0, "Channel topic"); /* channel only */
registersearchterm(reg_chansearch, "oppct",oppct_parse, 0, "Percentage Opped"); /* channel only */
+ registersearchterm(reg_chansearch, "cumodecount",cumodecount_parse, 0, "Count of users with given channel modes"); /* channel only */
+ registersearchterm(reg_chansearch, "cumodepct",cumodepct_parse, 0, "Percentage of users with given channel modes"); /* channel only */
registersearchterm(reg_chansearch, "uniquehostpct",hostpct_parse, 0, "uniquehost percent"); /* channel only */
registersearchterm(reg_chansearch, "authedpct",authedpct_parse, 0, "Percentage of authed users"); /* channel only */
registersearchterm(reg_chansearch, "kick",kick_parse, 0, "KICK users channels in newsearch result. Note: evaluation order"); /* channel only */
/* Functions that work on strings?! */
registersearchterm(reg_nicksearch, "cumodes", cumodes_parse, 0, "usage: (cumodes (var x) <modes>)");
+ registersearchterm(reg_chansearch, "cumodes", cumodes_parse, 0, "usage: (cumodes (var x) <modes>)");
/* Notice functionality */
registersearchterm(reg_chansearch,"notice",notice_parse, 0, "NOTICE users in newsearch result. Note: evaluation order");
break;
case 's':
+ if (subset == NULL) {
+ reply(sender,"Error: -s switch not supported for this search.");
+ return CMD_ERROR;
+ }
if (cargc<*arg) {
reply(sender,"Error: -s switch requires an argument (for help, see help <searchcmd>)");
return CMD_ERROR;
int do_nicksearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
nick *sender = source;
- struct searchNode *search;
int limit=500;
int arg=0;
NickDisplayFunc display=defaultnickfn;
- searchCtx ctx;
int ret;
+#ifndef NEWSEARCH_NEWPARSER
+ searchCtx ctx;
+ struct searchNode *search;
+#else
+ parsertree *tree;
+#endif
if (cargc<1) {
reply( sender, "Usage: [flags] <criteria>");
rejoinline(cargv[arg],cargc-arg);
}
+#ifndef NEWSEARCH_NEWPARSER
newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_nicksearch, sender, display, limit);
-
if (!(search = ctx.parser(&ctx, cargv[arg]))) {
reply(sender,"Parse error: %s",parseError);
return CMD_ERROR;
nicksearch_exe(search, &ctx);
(search->free)(&ctx, search);
+#else
+ tree = parse_string(reg_nicksearch, cargv[arg]);
+ if(!tree) {
+ displaystrerror(reply, sender, cargv[arg]);
+ return CMD_ERROR;
+ }
+
+ ast_nicksearch(tree->root, reply, sender, wall, display, NULL, NULL, limit);
+
+ parse_free(tree);
+#endif
return CMD_OK;
}
int do_chansearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
nick *sender = source;
- struct searchNode *search;
int limit=500;
int arg=0;
ChanDisplayFunc display=defaultchanfn;
- searchCtx ctx;
int ret;
+#ifndef NEWSEARCH_NEWPARSER
+ struct searchNode *search;
+ searchCtx ctx;
+#else
+ parsertree *tree;
+#endif
if (cargc<1) {
reply( sender, "Usage: [flags] <criteria>");
rejoinline(cargv[arg],cargc-arg);
}
+#ifndef NEWSEARCH_NEWPARSER
newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_chansearch, sender, display, limit);
if (!(search = ctx.parser(&ctx, cargv[arg]))) {
reply(sender,"Parse error: %s",parseError);
chansearch_exe(search, &ctx);
(search->free)(&ctx, search);
+#else
+ tree = parse_string(reg_chansearch, cargv[arg]);
+ if(!tree) {
+ displaystrerror(reply, sender, cargv[arg]);
+ return CMD_ERROR;
+ }
+
+ ast_chansearch(tree->root, reply, sender, wall, display, NULL, NULL, limit);
+
+ parse_free(tree);
+#endif
return CMD_OK;
}
int do_usersearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
nick *sender = source;
- struct searchNode *search;
int limit=500;
int arg=0;
UserDisplayFunc display=defaultuserfn;
- searchCtx ctx;
int ret;
+#ifndef NEWSEARCH_NEWPARSER
+ struct searchNode *search;
+ searchCtx ctx;
+#else
+ parsertree *tree;
+#endif
if (cargc<1) {
reply( sender, "Usage: [flags] <criteria>");
rejoinline(cargv[arg],cargc-arg);
}
+#ifndef NEWSEARCH_NEWPARSER
newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_usersearch, sender, display, limit);
if (!(search = ctx.parser(&ctx, cargv[arg]))) {
usersearch_exe(search, &ctx);
(search->free)(&ctx, search);
+#else
+ tree = parse_string(reg_usersearch, cargv[arg]);
+ if(!tree) {
+ displaystrerror(reply, sender, cargv[arg]);
+ return CMD_ERROR;
+ }
+
+ ast_usersearch(tree->root, reply, sender, wall, display, NULL, NULL, limit);
+
+ parse_free(tree);
+#endif
return CMD_OK;
}
return 1;
}
-/* search_parse:
- * Given an input string, return a searchNode.
- */
-
struct searchNode *search_parse(searchCtx *ctx, char *cinput) {
/* OK, we need to split the input into chunks on spaces and brackets.. */
char *argvector[100];
return NULL;
}
- thenode->localdata = getsstring(input,512);
+ thenode->localdata = getsstring(thestring,512);
thenode->returntype = RETURNTYPE_CONST | RETURNTYPE_STRING;
thenode->exe = literal_exe;
thenode->free = literal_free;
void var_setstr(struct searchVariable *v, char *data) {
v->cdata.u.stringbuf = data;
}
+
+#ifdef NEWSEARCH_NEWPARSER
+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);
+}
+#endif
+
+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;
+}