]> Pileus Git - ~andy/lamechat/commitdiff
Add watch groups.
authorAndy Spencer <andy.spencer@spacex.com>
Sun, 17 Feb 2019 01:53:12 +0000 (17:53 -0800)
committerAndy Spencer <andy753421@gmail.com>
Thu, 4 Apr 2019 19:49:38 +0000 (19:49 +0000)
util.c
util.h
view.c
view.h

diff --git a/util.c b/util.c
index 83812380473278e771a16b18831b3c9500ca0dfc..8294048ffd5fbe8c2f5606d416077b3eb045069e 100644 (file)
--- a/util.c
+++ b/util.c
@@ -258,6 +258,15 @@ void *alloc0(int size)
        return data;
 }
 
+void free0(void *ptr)
+{
+       void **pptr = (void**)ptr;
+       if (*pptr) {
+               free(*pptr);
+               *pptr = NULL;
+       }
+}
+
 void append(buf_t *buf, const char *data, int len)
 {
        if (buf->len + len + 1 > buf->max) {
@@ -478,8 +487,10 @@ void idle_set(idle_t *idle, int first, int next)
 /* Regular expressions */
 void reg_set(reg_t *reg, const char *pattern, int size)
 {
-       if (!pattern)
+       if (!pattern) {
+               reg_clr(reg);
                return;
+       }
        if (!reg->regex)
                reg->regex = new0(regex_t);
        if (size != reg->size) {
@@ -493,17 +504,21 @@ void reg_set(reg_t *reg, const char *pattern, int size)
 
 void reg_clr(reg_t *reg)
 {
-       if (!reg->pattern)
-               return;
-       regfree(reg->regex);
-       free(reg->regex);
-       free(reg->pattern);
+       if (reg->regex)
+               regfree(reg->regex);
+       free0(&reg->regex);
+       free0(&reg->pattern);
+       free0(&reg->start);
+       free0(&reg->stop);
+       memset(reg, 0, sizeof(*reg));
 }
 
 int reg_match(reg_t *reg, const char *text)
 {
        if (!reg->regex)
-               return 0;
+               return 1;
+       if (!reg->size)
+              return !regexec(reg->regex, text, 0, 0, 0);
        int si = 0, mi = 0;
        regmatch_t match = {};
        while (mi < reg->size && text[si] &&
diff --git a/util.h b/util.h
index bcae22b1f636d2d6578fb4b9f9acbbdcf087b83c..3bffe784998eb1efeeb62bb018daa45345d1b6c9 100644 (file)
--- a/util.h
+++ b/util.h
@@ -80,6 +80,7 @@ void escape(char *dst, const char *src, int len);
 
 /* Memory functions */
 void *alloc0(int size);
+void free0(void *ptr);
 void append(buf_t *buf, const char *data, int len);
 void release(buf_t *buf);
 const char *reset(buf_t *buf);
diff --git a/view.c b/view.c
index d9d557f91727c1fc88455cb4cd7ec5806d023c82..b5c705284b61f72179e91d8bf487cfdaa33883cc 100644 (file)
--- a/view.c
+++ b/view.c
@@ -59,6 +59,7 @@
 
 /* View types */
 typedef struct window_t window_t;
+typedef struct watch_t  watch_t;
 
 typedef struct window_t {
        char      *name;
@@ -77,6 +78,14 @@ typedef struct window_t {
        window_t  *next;
 } window_t;
 
+typedef struct watch_t {
+       char    *name;
+       char     desc[512];
+       reg_t    regex;
+       short    color;
+       watch_t *next;
+} watch_t;
+
 typedef struct {
        const char *value;
        const char *desc;
@@ -128,7 +137,6 @@ static int    full;
 static int    date;
 static int    draw;
 static int    view;
-static reg_t  watch;
 
 static char   cmd_buf[4096];
 static int    cmd_pos;
@@ -155,11 +163,12 @@ static window_t   sys_win;
 static window_t  *focus;
 static window_t  *windows;
 
+static watch_t   *watches;
+
 static int   ncolors = 1;
 static short colors[256+1][256+1];
 static short color_title;
 static short color_date;
-static short color_watch;
 static short color_error;
 
 static const char *themes[][2] = {
@@ -169,7 +178,7 @@ static const char *themes[][2] = {
 };
 
 static const char *abbrevs[][2] = {
-       [ABBREV_NONE]     { "none",     "Do not abbreivate"       },
+       [ABBREV_NONE]     { "none",     "Do not abbreviate"       },
        [ABBREV_FIRST]    { "first",    "First name only"         },
        [ABBREV_LAST]     { "last",     "Last name only"          },
        [ABBREV_FLAST]    { "flast",    "First initial last name" },
@@ -304,7 +313,7 @@ static int in_window(message_t *msg, window_t *win)
                return 0;
        if (win->channel && win->channel != msg->channel)
                return 0;
-       if (reg_match(&win->filter, msg->channel->name))
+       if (!reg_match(&win->filter, msg->channel->name))
                return 0;
        return 1;
 }
@@ -453,6 +462,67 @@ static channel_t *find_channel(const char *name)
        return NULL;
 }
 
+/* Watch functions */
+static watch_t *add_watch(const char *name)
+{
+       watch_t *watch = new0(watch_t);
+       strset(&watch->name, name);
+
+       watch_t **last = &watches;
+       while (*last)
+               last = &(*last)->next;
+       *last = watch;
+       return watch;
+}
+
+static watch_t *find_watch(const char *name)
+{
+       for (watch_t *watch = watches; watch; watch = watch->next)
+               if (match(watch->name, name))
+                       return watch;
+       return NULL;
+}
+
+static void set_watch(const char *text)
+{
+       static char name[64];
+       static char regex[512];
+       static int  color;
+       sscanf(text, "%s %d %[^\n]", name, &color, regex);
+
+       watch_t *watch = find_watch(name);
+       if (!watch)
+               watch = add_watch(name);
+       reg_set(&watch->regex, regex, MATCHES);
+       watch->color = color;
+}
+
+static void watch_run(const char *text)
+{
+       for (watch_t *watch = watches; watch; watch = watch->next)
+               reg_match(&watch->regex, text);
+}
+
+static void watch_end(void)
+{
+       for (watch_t *watch = watches; watch; watch = watch->next)
+               watch->regex.count = 0;
+}
+
+static void watch_on(int pos)
+{
+       for (watch_t *watch = watches; watch; watch = watch->next)
+               if (reg_check(&watch->regex, pos) & MATCH_START)
+                       attron(color(watch->color, -1) | A_BOLD);
+}
+
+static void watch_off(int pos)
+{
+       for (watch_t *watch = watches; watch; watch = watch->next)
+               if (reg_check(&watch->regex, pos) & MATCH_STOP)
+                       attroff(color(watch->color, -1) | A_BOLD);
+}
+
 /* Print functions */
 static int word_wrap(printer_t *pr, const char *txt,
                      const char **l, const char **r)
@@ -596,8 +666,7 @@ static void print_string(printer_t *pr, const char *txt)
                        pr->prow = pr->row;
                        pr->pcol = pr->col;
                }
-               if (reg_check(&watch, i) & MATCH_START)
-                       attron(color_watch | A_BOLD);
+               watch_on(i);
                if (irc_color(txt, &i))
                        continue;
                switch (txt[i]) {
@@ -629,8 +698,7 @@ static void print_string(printer_t *pr, const char *txt)
                                pr->col += 1;
                                break;
                }
-               if (reg_check(&watch, i) & MATCH_STOP)
-                       attroff(color_watch | A_BOLD);
+               watch_off(i);
        }
        if (i <= pr->pick) {
                pr->prow = pr->row;
@@ -691,7 +759,7 @@ static void print_message(printer_t *pr, message_t *msg)
        }
 
        /* Set matches */
-       reg_match(&watch, msg->text);
+       watch_run(msg->text);
 
        /* Print message */
        pr->indent = pr->col;
@@ -699,7 +767,7 @@ static void print_message(printer_t *pr, message_t *msg)
        pr->row++;
 
        /* Clear matches */
-       watch.count = 0;
+       watch_end();
 }
 
 static void print_status(printer_t *pr)
@@ -828,6 +896,9 @@ static void send_complete(const char *text)
        else if (prefix(text, "/channel ", &arg)) {
                complete_channel(arg);
        }
+       else if (prefix(text, "/watch ", &arg)) {
+               complete_watch(arg);
+       }
        else {
                complete_args(text,
                              "/quit",     "Quit the program",
@@ -868,8 +939,8 @@ static int send_command(const char *text)
                        if (match(abbrevs[i][0], arg))
                                abbrev = i;
        }
-       else if (prefix(text, "/watch", &arg)) {
-               reg_set(&watch, arg, MATCHES);
+       else if (prefix(text, "/watch", &arg) && arg) {
+               set_watch(arg);
        }
        else if (prefix(text, "/open", &arg)) {
                win = find_window(arg ?: focus->dest->name);
@@ -1370,7 +1441,6 @@ void view_init(void)
 
        color_title = color(COLOR_WHITE, COLOR_BLUE);
        color_date  = color(COLOR_BROWN, -1);
-       color_watch = color(COLOR_RED,   -1);
        color_error = color(COLOR_RED,   -1);
 
        /* Create signal FD */
@@ -1399,6 +1469,7 @@ void view_init(void)
 void view_config(const char *group, const char *name, const char *key, const char *value)
 {
        window_t *win;
+       watch_t *watch;
 
        if (match(group, "general")) {
                if (match(key, "theme"))
@@ -1407,8 +1478,6 @@ void view_config(const char *group, const char *name, const char *key, const cha
                        abbrev = get_mapv(value, abbrevs);
                else if (match(key, "defocus"))
                        defocus = get_number(value);
-               else if (match(key, "watch"))
-                       reg_set(&watch, get_string(value), MATCHES);
        }
 
        if (match(group, "window")) {
@@ -1429,6 +1498,19 @@ void view_config(const char *group, const char *name, const char *key, const cha
                        reg_set(&win->filter, get_string(value), 0);
                }
        }
+
+       if (match(group, "watch")) {
+               watch = find_watch(name);
+               if (match(key, "")) {
+                       watch = add_watch(get_name(name));
+               }
+               else if (match(key, "regex")) {
+                       reg_set(&watch->regex, get_string(value), MATCHES);
+               }
+               else if (match(key, "color")) {
+                       watch->color = get_number(value);
+               }
+       }
 }
 
 /* View event */
@@ -1517,6 +1599,20 @@ void complete_server(const char *prefix)
                        add_item(prefix, cur->name, NULL);
 }
 
+void complete_watch(const char *prefix)
+{
+       for (watch_t *cur = watches; cur; cur = cur->next) {
+               if (starts(prefix, cur->name)) {
+                       snprintf(cur->desc, sizeof(cur->desc),
+                                       "%s %hd %s",
+                                       cur->name,
+                                       cur->color,
+                                       cur->regex.pattern);
+                       add_item(prefix, cur->desc, NULL);
+               }
+       }
+}
+
 void complete_array(const char *prefix, const char *list[][2], int n)
 {
        for (int i = 0; i < n; i++)
diff --git a/view.h b/view.h
index 7fc35c171887c83fe9f8887dc96d4671ce4c4861..d846a5e881f38496420aed86918e823da0bfd80f 100644 (file)
--- a/view.h
+++ b/view.h
@@ -27,5 +27,6 @@ void complete_item(const char *prefix, const char *value, const char *desc);
 void complete_user(const char *prefix);
 void complete_channel(const char *prefix);
 void complete_server(const char *prefix);
+void complete_watch(const char *prefix);
 void complete_array(const char *prefix, const char *list[][2], int n);
 void complete_args(const char *prefix, ...);