summary refs log tree commit diff
path: root/bounce.h
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-11-09 12:42:39 -0500
committerJune McEnroe <june@causal.agency>2019-11-09 12:42:39 -0500
commite7e54068aa06e882bebf0750707e4b8c1af56bf5 (patch)
tree01de3e3a858b6e9e04ca3885f1c8281fe0a42be1 /bounce.h
parentAvoid the reserved _A names with BIT macro (diff)
downloadpounce-e7e54068aa06e882bebf0750707e4b8c1af56bf5.tar.gz
pounce-e7e54068aa06e882bebf0750707e4b8c1af56bf5.zip
Parse capabilities
The list that I've defined are the ones that I expect to be able to
enable probably without any clients breaking... And of course
server-time which pounce implements itself.
Diffstat (limited to '')
-rw-r--r--bounce.h55
1 files changed, 53 insertions, 2 deletions
diff --git a/bounce.h b/bounce.h
index aa7fda1..5dd2536 100644
--- a/bounce.h
+++ b/bounce.h
@@ -35,8 +35,6 @@
 
 typedef unsigned char byte;
 
-bool verbose;
-
 enum { ParamCap = 15 };
 struct Message {
 	char *origin;
@@ -58,6 +56,59 @@ static inline struct Message parse(char *line) {
 	return msg;
 }
 
+#define ENUM_CAP \
+	X("account-notify", CapAccountNotify) \
+	X("away-notify", CapAwayNotify) \
+	X("chghost", CapChghost) \
+	X("extended-join", CapExtendedJoin) \
+	X("invite-notify", CapInviteNotify) \
+	X("server-time", CapServerTime) \
+	X("", CapUnsupported)
+
+enum Cap {
+#define X(name, id) BIT(id),
+	ENUM_CAP
+#undef X
+};
+
+static const char *CapNames[] = {
+#define X(name, id) [id##Bit] = name,
+	ENUM_CAP
+#undef X
+};
+
+static inline enum Cap capParse(const char *list) {
+	enum Cap caps = 0;
+	while (*list) {
+		enum Cap cap = CapUnsupported;
+		size_t len = strcspn(list, " ");
+		for (size_t i = 0; i < ARRAY_LEN(CapNames); ++i) {
+			if (len != strlen(CapNames[i])) continue;
+			if (strncmp(list, CapNames[i], len)) continue;
+			cap = 1 << i;
+			break;
+		}
+		caps |= cap;
+		list += len;
+		if (*list) list++;
+	}
+	return caps;
+}
+
+static inline const char *capList(enum Cap caps) {
+	static char buf[1024];
+	buf[0] = '\0';
+	for (size_t i = 0; i < ARRAY_LEN(CapNames); ++i) {
+		if (caps & (1 << i)) {
+			if (buf[0]) strlcat(buf, " ", sizeof(buf));
+			strlcat(buf, CapNames[i], sizeof(buf));
+		}
+	}
+	return buf;
+}
+
+bool verbose;
+
 void ringAlloc(size_t len);
 void ringProduce(const char *line);
 size_t ringConsumer(const char *name);