From: Andy Spencer Date: Sun, 17 Feb 2019 01:53:12 +0000 (-0800) Subject: Add watch groups. X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=67ae5a30a25739539a690dff771ce16634468b6b;p=~andy%2Flamechat Add watch groups. --- diff --git a/util.c b/util.c index 8381238..8294048 100644 --- 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(®->regex); + free0(®->pattern); + free0(®->start); + free0(®->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 bcae22b..3bffe78 100644 --- 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 d9d557f..b5c7052 100644 --- 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 7fc35c1..d846a5e 100644 --- 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, ...);