summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--client.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/client.c b/client.c
index 0e94ad4..324c6f0 100644
--- a/client.c
+++ b/client.c
@@ -16,6 +16,7 @@
 
 #include <assert.h>
 #include <err.h>
+#include <regex.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -275,15 +276,18 @@ size_t clientDiff(const struct Client *client) {
 	return ringDiff(client->consumer);
 }
 
-typedef const char *Filter(const char *line);
-
-static int strncmpn(const char *a, size_t alen, const char *b, size_t blen) {
-	return alen == blen
-		? memcmp(a, b, alen)
-		: alen - blen;
+static int wordcmp(const char *line, size_t i, const char *word) {
+	while (i--) {
+		line += strcspn(line, " ");
+		if (*line) line++;
+	}
+	size_t len = strcspn(line, " ");
+	return len == strlen(word)
+		? strncmp(line, word, len)
+		: len - strlen(word);
 }
 
-static size_t strlcpyn(char *dst, size_t cap, const char *src, size_t len) {
+static size_t strlcpyn(char *dst, const char *src, size_t cap, size_t len) {
 	if (len < cap) {
 		memcpy(dst, src, len);
 		dst[len] = '\0';
@@ -294,24 +298,37 @@ static size_t strlcpyn(char *dst, size_t cap, const char *src, size_t len) {
 	return len;
 }
 
-static int wordcmp(const char *line, size_t i, const char *word) {
-	while (i--) {
-		line += strcspn(line, " ");
-		if (*line) line++;
+// s/..(..)../\1/g
+static char *snip(char *dst, size_t cap, const char *src, const regex_t *regex) {
+	size_t len = 0;
+	regmatch_t match[2];
+	for (; *src; src += match[0].rm_eo) {
+		if (regexec(regex, src, 2, match, 0)) break;
+		len += strlcpyn(&dst[len], src, cap - len, match[0].rm_so);
+		if (len >= cap) return NULL;
+		len += strlcpyn(
+			&dst[len], &src[match[1].rm_so],
+			cap - len, match[1].rm_eo - match[1].rm_so
+		);
+		if (len >= cap) return NULL;
 	}
-	size_t len = strcspn(line, " ");
-	return strncmpn(line, len, word, strlen(word));
+	len += strlcpy(&dst[len], src, cap - len);
+	return (len < cap ? dst : NULL);
 }
 
-static size_t wordcpy(char *dst, size_t cap, const char *src, size_t count) {
-	size_t len = 0;
-	while (count--) {
-		if (src[len] == ' ') len++;
-		len += strcspn(&src[len], " ");
+static regex_t *compile(regex_t *regex, const char *pattern) {
+	if (regex->re_nsub) return regex;
+	int error = regcomp(regex, pattern, REG_EXTENDED);
+	if (error) {
+		char buf[256];
+		regerror(error, regex, buf, sizeof(buf));
+		errx(EX_SOFTWARE, "regcomp: %s: %s", buf, pattern);
 	}
-	return strlcpyn(dst, cap, src, len);
+	return regex;
 }
 
+typedef const char *Filter(const char *line);
+
 static const char *filterAccountNotify(const char *line) {
 	return (wordcmp(line, 1, "ACCOUNT") ? line : NULL);
 }
@@ -326,9 +343,9 @@ static const char *filterChghost(const char *line) {
 
 static const char *filterExtendedJoin(const char *line) {
 	if (wordcmp(line, 1, "JOIN")) return line;
+	static regex_t regex;
 	static char buf[512];
-	wordcpy(buf, sizeof(buf), line, 3);
-	return buf;
+	return snip(buf, sizeof(buf), line, compile(&regex, "(JOIN [^ ]+).+"));
 }
 
 static const char *filterInviteNotify(const char *line) {
@@ -338,18 +355,12 @@ static const char *filterInviteNotify(const char *line) {
 
 static const char *filterUserhostInNames(const char *line) {
 	if (wordcmp(line, 1, "353")) return line;
+	static regex_t regex;
 	static char buf[512];
-	size_t len = wordcpy(buf, sizeof(buf), line, 5);
-	if (len >= sizeof(buf)) return NULL;
-	line += len;
-	while (*line) {
-		size_t nick = strcspn(line, "!");
-		len += strlcpyn(&buf[len], sizeof(buf) - len, line, nick);
-		if (len >= sizeof(buf)) return NULL;
-		line += nick;
-		line += strcspn(line, " ");
-	}
-	return buf;
+	return snip(
+		buf, sizeof(buf), line,
+		compile(&regex, "([ :][^!]+)![^ ]+")
+	);
 }
 
 static Filter *Filters[] = {
td colspan='3' class='logmsg'> 2021-02-08Tweak trackpad scaling, mouse accelerationJune McEnroe This feels more comfortable. 2021-02-08Use xsel in up and add it do install.shJune McEnroe 2021-02-07Swap root window coloursJune McEnroe 2021-02-07Add -X flag to install X stuff on OpenBSDJune McEnroe 2021-02-07Adjust brightness by smaller incrementsJune McEnroe 2021-02-07Fix cwm window cycling, move big by defaultJune McEnroe 2021-02-07Use class names for Foreground, Background, BorderColorJune McEnroe I'm not really sure what difference this makes, but it seems like the right thing to do to be generic? 2021-02-07Add simple battery status and clock to xsessionJune McEnroe I love how simple this is. 2021-02-07Set cursor theme and sizeJune McEnroe 2021-02-07Use scrot for up -s if no screencaptureJune McEnroe Still missing putting the URL in an X selection. 2021-02-07Enable mouse acceleration in XJune McEnroe 2021-02-07Set colours for Xt and cwmJune McEnroe And increase XTerm internalBorder. 2021-02-07Set urgency on bell in xtermJune McEnroe 2021-02-07Add bindings for brightness controlJune McEnroe Weirdly the Fn key doesn't change how the F row registers... I wonder if I can do something about that. 2021-02-07Set X key repeat rateJune McEnroe 2021-02-07Bump font size to 12June McEnroe 11 is what I use on macOS, but I feel like my eyes are working harder here. 2021-02-07Fully configure and rebind cwmJune McEnroe This is sort of a mix of trying to emulate macOS somewhat for my muscle memory and just rebinding some of the cwm defaults to use 4- rather than M-. 2021-02-07Add BintiJune McEnroe 2021-02-07Finish configuring xtermJune McEnroe 2021-02-06Enable tapping, reverse scroll, set scaling in wsconsctlJune McEnroe 2021-02-06Set root window to black on purple snowJune McEnroe 2021-02-06Add xmodmap configurationJune McEnroe 2021-02-06Add initial OpenBSD X configurationJune McEnroe cwm still needs a lot more rebinding, and I need to actually look at its other options. xterm definitely still needs some configuration, but I at least managed to get it to use a decent looking font. Very happy that OpenBSD includes Luxi Mono, which is what my usual font, Go Mono, is based on anyway. Still missing is xmodmap and such. 2021-02-06Add xterm output to schemeJune McEnroe