about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--chat.h12
-rw-r--r--handle.c37
-rw-r--r--ui.c23
3 files changed, 36 insertions, 36 deletions
diff --git a/chat.h b/chat.h
index adde642..1f4274f 100644
--- a/chat.h
+++ b/chat.h
@@ -14,10 +14,13 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+#include <assert.h>
 #include <err.h>
 #include <getopt.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <string.h>
 #include <sysexits.h>
 #include <time.h>
@@ -29,6 +32,15 @@
 typedef unsigned uint;
 typedef unsigned char byte;
 
+static inline void __attribute__((format(printf, 3, 4)))
+catf(char *buf, size_t cap, const char *format, ...) {
+	size_t len = strnlen(buf, cap);
+	va_list ap;
+	va_start(ap, format);
+	assert(0 <= vsnprintf(&buf[len], cap - len, format, ap));
+	va_end(ap);
+}
+
 enum Color {
 	White, Black, Blue, Green, Red, Brown, Magenta, Orange,
 	Yellow, LightGreen, Cyan, LightCyan, LightBlue, Pink, Gray, LightGray,
diff --git a/handle.c b/handle.c
index 629b138..cec823a 100644
--- a/handle.c
+++ b/handle.c
@@ -353,8 +353,7 @@ static void handleQuit(struct Message *msg) {
 static void handleReplyNames(struct Message *msg) {
 	require(msg, false, 4);
 	uint id = idFor(msg->params[2]);
-	char buf[1024];
-	size_t len = 0;
+	char buf[1024] = "";
 	while (msg->params[3]) {
 		char *name = strsep(&msg->params[3], " ");
 		char *prefixes = strsep(&name, "!");
@@ -363,12 +362,10 @@ static void handleReplyNames(struct Message *msg) {
 		enum Color color = (user ? hash(user) : Default);
 		completeAdd(id, nick, color);
 		if (!replies.names) continue;
-		int n = snprintf(
-			&buf[len], sizeof(buf) - len,
-			"%s\3%02d%s\3", (len ? ", " : ""), color, prefixes
+		catf(
+			buf, sizeof(buf), "%s\3%02d%s\3",
+			(buf[0] ? ", " : ""), color, prefixes
 		);
-		assert(n > 0 && len + n < sizeof(buf));
-		len += n;
 	}
 	if (!replies.names) return;
 	uiFormat(
@@ -515,17 +512,14 @@ static void handleReplyWhoisIdle(struct Message *msg) {
 static void handleReplyWhoisChannels(struct Message *msg) {
 	require(msg, false, 3);
 	if (!replies.whois) return;
-	char buf[1024];
-	size_t len = 0;
+	char buf[1024] = "";
 	while (msg->params[2]) {
 		char *channel = strsep(&msg->params[2], " ");
 		char *name = &channel[strspn(channel, network.prefixes)];
-		int n = snprintf(
-			&buf[len], sizeof(buf) - len,
-			"%s\3%02d%s\3", (len ? ", " : ""), hash(name), channel
+		catf(
+			buf, sizeof(buf), "%s\3%02d%s\3",
+			(buf[0] ? ", " : ""), hash(name), channel
 		);
-		assert(n > 0 && len + n < sizeof(buf));
-		len += n;
 	}
 	uiFormat(
 		Network, Warm, tagTime(msg),
@@ -622,12 +616,10 @@ static const char *colorMentions(uint id, struct Message *msg) {
 	*split = '\0';
 
 	static char buf[1024];
-	FILE *str = fmemopen(buf, sizeof(buf), "w");
-	if (!str) err(EX_OSERR, "fmemopen");
-
+	buf[0] = '\0';
 	while (*mention) {
 		size_t skip = strspn(mention, ",<> ");
-		fwrite(mention, skip, 1, str);
+		catf(buf, sizeof(buf), "%.*s", (int)skip, mention);
 		mention += skip;
 
 		size_t len = strcspn(mention, ",<> ");
@@ -635,17 +627,14 @@ static const char *colorMentions(uint id, struct Message *msg) {
 		mention[len] = '\0';
 		enum Color color = completeColor(id, mention);
 		if (color != Default) {
-			fprintf(str, "\3%02d%s\3", color, mention);
+			catf(buf, sizeof(buf), "\3%02d%s\3", color, mention);
 		} else {
-			fprintf(str, "%s", mention);
+			catf(buf, sizeof(buf), "%s", mention);
 		}
 		mention[len] = punct;
 		mention += len;
 	}
-	fputc(delimit, str);
-
-	fclose(str);
-	buf[sizeof(buf) - 1] = '\0';
+	catf(buf, sizeof(buf), "%c", delimit);
 	return buf;
 }
 
diff --git a/ui.c b/ui.c
index c39e6c3..aaa7b49 100644
--- a/ui.c
+++ b/ui.c
@@ -428,15 +428,15 @@ static void statusUpdate(void) {
 	const struct Window *window = windows.ptrs[windows.show];
 	snprintf(title, sizeof(title), "%s %s", network.name, idNames[window->id]);
 	if (window->mark && window->unreadWarm) {
-		snprintf(
-			&title[strlen(title)], sizeof(title) - strlen(title),
-			" (%d%s)", window->unreadWarm, (window->heat > Warm ? "!" : "")
+		catf(
+			title, sizeof(title), " (%d%s)",
+			window->unreadWarm, (window->heat > Warm ? "!" : "")
 		);
 	}
 	if (otherUnread) {
-		snprintf(
-			&title[strlen(title)], sizeof(title) - strlen(title),
-			" (+%d%s)", otherUnread, (otherHeat > Warm ? "!" : "")
+		catf(
+			title, sizeof(title), " (+%d%s)",
+			otherUnread, (otherHeat > Warm ? "!" : "")
 		);
 	}
 }
@@ -560,14 +560,13 @@ static void notify(uint id, const char *str) {
 
 	struct Util util = uiNotifyUtil;
 	utilPush(&util, idNames[id]);
-	size_t len = 0;
 	char buf[1024] = "";
-	while (*str && len < sizeof(buf)) {
-		size_t run;
+	while (*str) {
+		size_t len;
 		struct Style style = Reset;
-		styleParse(&style, &str, &run);
-		len += snprintf(&buf[len], sizeof(buf) - len, "%.*s", (int)run, str);
-		str += run;
+		styleParse(&style, &str, &len);
+		catf(buf, sizeof(buf), "%.*s", (int)len, str);
+		str += len;
 	}
 	utilPush(&util, buf);