]> jfr.im git - irc/quakenet/newserv.git/commitdiff
NEWSEARCH: add concat function 91/head
authorChris Porter <redacted>
Sun, 5 Jul 2020 18:28:35 +0000 (19:28 +0100)
committerChris Porter <redacted>
Sun, 5 Jul 2020 18:28:35 +0000 (19:28 +0100)
newsearch/Makefile
newsearch/newsearch.c
newsearch/newsearch.h
newsearch/ns-concat.c [new file with mode: 0644]

index 97ca7c8ae8678f4e40ae7ab7a015e19ad947383d..0a1c99710b1ab673d26df1981f43a46a6cd393c3 100644 (file)
@@ -6,7 +6,7 @@ LDFLAGS+=$(LIBPCRE)
 .PHONY: all clean distclean
 all: newsearch.so
 
-NSCOMMANDS=ns-not.o ns-and.o ns-or.o ns-eq.o ns-match.o ns-hostmask.o ns-realname.o ns-away.o ns-modes.o ns-nick.o ns-ident.o ns-regex.o ns-host.o ns-channel.o ns-lt.o ns-gt.o ns-timestamp.o ns-country.o ns-authname.o ns-ip.o ns-kill.o ns-gline.o ns-exists.o ns-services.o ns-size.o ns-name.o ns-topic.o ns-oppct.o ns-cumodecount.o ns-cumodepct.o ns-hostpct.o ns-authedpct.o ns-length.o ns-kick.o ns-authts.o ns-channels.o ns-server.o ns-authid.o ns-notice.o newsearch_ast.o ns-any.o ns-channeliter.o ns-var.o ns-all.o ns-cumodes.o ns-cidr.o ns-nickiter.o ns-ipv6.o ns-away.o ns-quit.o ns-killed.o ns-renamed.o ns-age.o ns-newnick.o ns-reason.o ns-message.o
+NSCOMMANDS=ns-not.o ns-and.o ns-or.o ns-eq.o ns-match.o ns-hostmask.o ns-realname.o ns-away.o ns-modes.o ns-nick.o ns-ident.o ns-regex.o ns-host.o ns-channel.o ns-lt.o ns-gt.o ns-timestamp.o ns-country.o ns-authname.o ns-ip.o ns-kill.o ns-gline.o ns-exists.o ns-services.o ns-size.o ns-name.o ns-topic.o ns-oppct.o ns-cumodecount.o ns-cumodepct.o ns-hostpct.o ns-authedpct.o ns-length.o ns-kick.o ns-authts.o ns-channels.o ns-server.o ns-authid.o ns-notice.o newsearch_ast.o ns-any.o ns-channeliter.o ns-var.o ns-all.o ns-cumodes.o ns-cidr.o ns-nickiter.o ns-ipv6.o ns-away.o ns-quit.o ns-killed.o ns-renamed.o ns-age.o ns-newnick.o ns-reason.o ns-message.o ns-concat.o
 
 newsearch.so: newsearch.o formats.o y.tab.o lex.yy.o parser.o ${NSCOMMANDS}
 
index 8e4fa7ebf32dcfffc924a2dadd6278d296c31ba5..230427c3f60804270dc71feae3ea3fa82dcd3463 100644 (file)
@@ -178,6 +178,7 @@ void _init() {
   registerglobalsearchterm("match",match_parse, "usage: (match (X) string)");
   registerglobalsearchterm("regex",regex_parse, "usage: (regex (X) string)");
   registerglobalsearchterm("length",length_parse, "usage: (length string)");
+  registerglobalsearchterm("concat",concat_parse, "usage: (concat (a) b (c))");
   
   /* Nickname operations */
   registersearchterm(reg_nicksearch, "hostmask",hostmask_parse, 0, "The user's nick!user@host; \"hostmask real\" returns nick!user@host\rreal");
index 8de19c28280d98e6bd838fa67bdc50acff356f34..1dac2feec8aea3f7c834c230d2380180ae2b012b 100644 (file)
@@ -114,6 +114,9 @@ struct searchNode *regex_parse(searchCtx *ctx, int argc, char **argv);
 /* Length (STRING -> INT) */
 struct searchNode *length_parse(searchCtx *ctx, int argc, char **argv);
 
+/* String concat (STRING -> STRING) */
+struct searchNode *concat_parse(searchCtx *ctx, int argc, char **argv);
+
 /* kill/gline actions (BOOL) */
 struct searchNode *kill_parse(searchCtx *ctx, int argc, char **argv);
 struct searchNode *gline_parse(searchCtx *ctx, int argc, char **argv);
diff --git a/newsearch/ns-concat.c b/newsearch/ns-concat.c
new file mode 100644 (file)
index 0000000..cce3e26
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * CONCAT functionality
+ */
+
+#include "newsearch.h"
+#include "../lib/irc_string.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUFLEN 1024
+
+struct concat_localdata {
+  char buf[BUFLEN];
+  int count;
+  struct searchNode **nodes;
+};
+
+void concat_free(searchCtx *ctx, struct searchNode *thenode);
+void *concat_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+
+struct searchNode *concat_parse(searchCtx *ctx, int argc, char **argv) {
+  struct concat_localdata *localdata;
+  struct searchNode *thenode;
+  int i;
+
+  if (!(localdata = (struct concat_localdata *)malloc(sizeof(struct concat_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;
+
+  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_STRING;
+  thenode->exe  = concat_exe;
+  thenode->free = concat_free;
+
+  for (i=0;i<argc;i++) {
+    /* 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],RETURNTYPE_STRING);
+
+    /* If a node didn't parse, give up */
+    if (!localdata->nodes[i]) {
+      concat_free(ctx, thenode);
+      return NULL;
+    }
+
+    localdata->count++;
+  }
+
+  return thenode;
+}
+
+void concat_free(searchCtx *ctx, struct searchNode *thenode) {
+  struct concat_localdata *localdata;
+  int i;
+
+  localdata=thenode->localdata;
+
+  for (i=0;i<localdata->count;i++) {
+    if (localdata->nodes[i])
+      (localdata->nodes[i]->free)(ctx, localdata->nodes[i]);
+  }
+
+  free(localdata->nodes);
+  free(localdata);
+  free(thenode);
+}
+
+void *concat_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  struct concat_localdata *localdata;
+  char buf2[BUFLEN];
+
+  localdata=thenode->localdata;
+  localdata->buf[0] = '\0';
+
+  for (int i=0;i<localdata->count;i++) {
+    char *buf = (char *)(localdata->nodes[i]->exe)(ctx, localdata->nodes[i], theinput);
+    /* HACK */
+    snprintf(buf2, BUFLEN, "%s%s", localdata->buf, buf);
+    snprintf(localdata->buf, BUFLEN, "%s", buf2);
+  }
+
+  return localdata->buf;
+}
+