summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-10-23 17:14:08 -0400
committerJune McEnroe <june@causal.agency>2019-10-23 17:14:08 -0400
commit617f3f8b05fa4538c5ef0628196a6e473185fdc5 (patch)
tree4d03fc97bf939336c835aadad00b0ad9a7aeaa80
parentRespond to pings (diff)
downloadpounce-617f3f8b05fa4538c5ef0628196a6e473185fdc5.tar.gz
pounce-617f3f8b05fa4538c5ef0628196a6e473185fdc5.zip
Clean up state.c and factor out parsing
-rw-r--r--bounce.h24
-rw-r--r--state.c62
2 files changed, 45 insertions, 41 deletions
diff --git a/bounce.h b/bounce.h
index e81ed8f..491616b 100644
--- a/bounce.h
+++ b/bounce.h
@@ -16,6 +16,7 @@
 
 #include <stdbool.h>
 #include <stdlib.h>
+#include <string.h>
 #include <tls.h>
 
 #ifndef DEFAULT_CERT_PATH
@@ -30,6 +31,29 @@ struct Client {
 	struct tls *tls;
 };
 
+#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
+
+enum { ParamCap = 15 };
+struct Command {
+	const char *origin;
+	const char *name;
+	const char *params[ParamCap];
+};
+
+static inline struct Command parse(char *line) {
+	struct Command cmd = {0};
+	if (line[0] == ':') cmd.origin = 1 + strsep(&line, " ");
+	cmd.name = strsep(&line, " ");
+	for (size_t i = 0; line && i < ParamCap; ++i) {
+		if (line[0] == ':') {
+			cmd.params[i] = &line[1];
+			break;
+		}
+		cmd.params[i] = strsep(&line, " ");
+	}
+	return cmd;
+}
+
 bool verbose;
 
 void listenConfig(const char *cert, const char *priv);
diff --git a/state.c b/state.c
index ecbf368..c7d517e 100644
--- a/state.c
+++ b/state.c
@@ -34,11 +34,21 @@ static struct {
 	char *myInfo[4];
 } intro;
 
-enum { ISupportCap = 32 };
+enum { SupportCap = 32 };
 static struct {
-	char *values[ISupportCap];
+	char *tokens[SupportCap];
 	size_t len;
-} iSupport;
+} support;
+
+bool stateReady(void) {
+	return nick
+		&& intro.origin
+		&& intro.welcome
+		&& intro.yourHost
+		&& intro.created
+		&& intro.myInfo[0]
+		&& support.len;
+}
 
 static void set(char **field, const char *value) {
 	if (*field) free(*field);
@@ -46,30 +56,14 @@ static void set(char **field, const char *value) {
 	if (!*field) err(EX_OSERR, "strdup");
 }
 
-static void iSupportSet(const char *value) {
-	if (iSupport.len == ISupportCap) {
-		warnx("truncating ISUPPORT value %s", value);
+static void supportSet(const char *token) {
+	if (support.len == SupportCap) {
+		warnx("dropping ISUPPORT token %s", token);
 		return;
 	}
-	set(&iSupport.values[iSupport.len++], value);
+	set(&support.tokens[support.len++], token);
 }
 
-bool stateReady(void) {
-	return nick
-		&& intro.origin
-		&& intro.welcome
-		&& intro.yourHost
-		&& intro.created
-		&& intro.myInfo[0]
-		&& iSupport.len;
-}
-
-enum { ParamCap = 15 };
-struct Command {
-	const char *origin;
-	const char *name;
-	const char *params[ParamCap];
-};
 typedef void Handler(struct Command);
 
 static void handleCap(struct Command cmd) {
@@ -104,7 +98,7 @@ static void handleReplyMyInfo(struct Command cmd) {
 static void handleReplyISupport(struct Command cmd) {
 	for (size_t i = 1; i < ParamCap; ++i) {
 		if (!cmd.params[i] || strchr(cmd.params[i], ' ')) break;
-		iSupportSet(cmd.params[i]);
+		supportSet(cmd.params[i]);
 	}
 }
 
@@ -124,25 +118,11 @@ static const struct {
 	{ "CAP", handleCap },
 	{ "ERROR", handleError },
 };
-static const size_t HandlersLen = sizeof(Handlers) / sizeof(Handlers[0]);
 
 void stateParse(char *line) {
-	struct Command cmd = {0};
-	if (line[0] == ':') {
-		cmd.origin = 1 + strsep(&line, " ");
-		if (!line) errx(EX_PROTOCOL, "eof after origin");
-	}
-
-	cmd.name = strsep(&line, " ");
-	for (size_t i = 0; line && i < ParamCap; ++i) {
-		if (line[0] == ':') {
-			cmd.params[i] = &line[1];
-			break;
-		}
-		cmd.params[i] = strsep(&line, " ");
-	}
-
-	for (size_t i = 0; i < HandlersLen; ++i) {
+	struct Command cmd = parse(line);
+	if (!cmd.name) errx(EX_PROTOCOL, "no command");
+	for (size_t i = 0; i < ARRAY_LEN(Handlers); ++i) {
 		if (strcmp(cmd.name, Handlers[i].cmd)) continue;
 		Handlers[i].fn(cmd);
 		break;