about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2021-01-24 12:44:32 -0500
committerJune McEnroe <june@causal.agency>2021-01-24 13:00:20 -0500
commit9cb05451e14f02c4ebcce69a5450d02bcbb907a9 (patch)
treec4d9e2967807197c17b6ceec1db4ebac3fa371e9
parentSupport echo-message capability (diff)
downloadpounce-9cb05451e14f02c4ebcce69a5450d02bcbb907a9.tar.gz
pounce-9cb05451e14f02c4ebcce69a5450d02bcbb907a9.zip
Refactor hasTag to be usable in more places
-rw-r--r--client.c45
1 files changed, 15 insertions, 30 deletions
diff --git a/client.c b/client.c
index c4cfe14..a4ecb25 100644
--- a/client.c
+++ b/client.c
@@ -259,15 +259,16 @@ static void handleQuit(struct Client *client, struct Message *msg) {
 	client->error = true;
 }
 
-static bool hasTag(const struct Message *msg, const char *key) {
-	if (!msg->tags) return false;
-	size_t len = strlen(key);
-	for (const char *tags = msg->tags; *tags;) {
+static bool hasTag(const char *tags, const char *tag) {
+	if (!tags) return false;
+	size_t len = strlen(tag);
+	bool val = strchr(tag, '=');
+	while (*tags && *tags != ' ') {
 		if (
-			!strncmp(tags, key, len) &&
-			(!tags[len] || tags[len] == ';' || tags[len] == '=')
+			!strncmp(tags, tag, len) &&
+			(!tags[len] || strchr((val ? "; " : "=; "), tags[len]))
 		) return true;
-		tags += strcspn(tags, ";");
+		tags += strcspn(tags, "; ");
 		tags += (*tags == ';');
 	}
 	return false;
@@ -323,7 +324,7 @@ static void handlePrivmsg(struct Client *client, struct Message *msg) {
 	}
 	if (self) return;
 	reserialize(buf, sizeof(buf), NULL, msg);
-	if (stateCaps & CapEchoMessage && !hasTag(msg, "label")) {
+	if (stateCaps & CapEchoMessage && !hasTag(msg->tags, "label")) {
 		serverFormat(
 			"@%s%c%s\r\n",
 			synthLabel(client),
@@ -594,17 +595,8 @@ static Filter *Filters[] = {
 
 static const char *filterEchoMessage(struct Client *client, const char *line) {
 	if (line[0] != '@') return line;
-	const char *label = synthLabel(client);
-	size_t len = strlen(label);
-	for (const char *tags = &line[1]; *tags != ' ';) {
-		if (
-			!strncmp(tags, label, len) &&
-			(tags[len] == ' ' || tags[len] == ';')
-		) return NULL;
-		tags += strcspn(tags, "; ");
-		tags += (*tags == ';');
-	}
-	return line;
+	if (!hasTag(&line[1], synthLabel(client))) return line;
+	return NULL;
 }
 
 static const char *filterTags(const char *line) {
@@ -613,16 +605,6 @@ static const char *filterTags(const char *line) {
 	return (sp ? sp + 1 : NULL);
 }
 
-static bool hasTime(const char *line) {
-	if (!strncmp(line, "@time=", 6)) return true;
-	while (*line && *line != ' ') {
-		line += strcspn(line, "; ");
-		if (!strncmp(line, ";time=", 6)) return true;
-		if (*line == ';') line++;
-	}
-	return false;
-}
-
 void clientConsume(struct Client *client) {
 	struct timeval time;
 	const char *line = ringPeek(&time, client->consumer);
@@ -644,7 +626,10 @@ void clientConsume(struct Client *client) {
 		return;
 	}
 
-	if (client->caps & CapServerTime && !hasTime(line)) {
+	if (
+		client->caps & CapServerTime &&
+		(line[0] != '@' || !hasTag(&line[1], "time"))
+	) {
 		char ts[sizeof("YYYY-MM-DDThh:mm:ss")];
 		struct tm *tm = gmtime(&time.tv_sec);
 		strftime(ts, sizeof(ts), "%FT%T", tm);