diff options
| -rw-r--r-- | chat.h | 15 | ||||
| -rw-r--r-- | handle.c | 35 | ||||
| -rw-r--r-- | ui.c | 30 | 
3 files changed, 39 insertions, 41 deletions
| @@ -43,13 +43,20 @@  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); +struct Cat { +	char *buf; +	size_t cap; +	size_t len; +}; +static inline void __attribute__((format(printf, 2, 3))) +catf(struct Cat *cat, const char *format, ...) {  	va_list ap;  	va_start(ap, format); -	assert(0 <= vsnprintf(&buf[len], cap - len, format, ap)); +	int len = vsnprintf(&cat->buf[cat->len], cat->cap - cat->len, format, ap); +	assert(len >= 0);  	va_end(ap); +	cat->len += len; +	if (cat->len >= cat->cap) cat->len = cat->cap - 1;  }  enum Color { @@ -65,9 +65,10 @@ static enum Cap capParse(const char *list) {  static const char *capList(enum Cap caps) {  	static char buf[1024];  	buf[0] = '\0'; +	struct Cat cat = { buf, sizeof(buf), 0 };  	for (size_t i = 0; i < ARRAY_LEN(CapNames); ++i) {  		if (caps & (1 << i)) { -			catf(buf, sizeof(buf), "%s%s", (buf[0] ? " " : ""), CapNames[i]); +			catf(&cat, "%s%s", (buf[0] ? " " : ""), CapNames[i]);  		}  	}  	return buf; @@ -490,6 +491,7 @@ static void handleReplyNames(struct Message *msg) {  	require(msg, false, 4);  	uint id = idFor(msg->params[2]);  	char buf[1024] = ""; +	struct Cat cat = { buf, sizeof(buf), 0 };  	while (msg->params[3]) {  		char *name = strsep(&msg->params[3], " ");  		char *prefixes = strsep(&name, "!"); @@ -498,10 +500,7 @@ static void handleReplyNames(struct Message *msg) {  		enum Color color = (user ? hash(user) : Default);  		completeAdd(id, nick, color);  		if (!replies.names) continue; -		catf( -			buf, sizeof(buf), "%s\3%02d%s\3", -			(buf[0] ? ", " : ""), color, prefixes -		); +		catf(&cat, "%s\3%02d%s\3", (buf[0] ? ", " : ""), color, prefixes);  	}  	if (!replies.names) return;  	uiFormat( @@ -602,13 +601,11 @@ static void handleReplyUserModeIs(struct Message *msg) {  	replies.mode--;  	char buf[1024] = ""; +	struct Cat cat = { buf, sizeof(buf), 0 };  	for (char *ch = msg->params[1]; *ch; ++ch) {  		if (*ch == '+') continue;  		const char *name = UserModes[(byte)*ch]; -		catf( -			buf, sizeof(buf), ", +%c%s%s", -			*ch, (name ? " " : ""), (name ?: "") -		); +		catf(&cat, ", +%c%s%s", *ch, (name ? " " : ""), (name ?: ""));  	}  	uiFormat(  		Network, Warm, tagTime(msg), @@ -639,6 +636,7 @@ static void handleReplyChannelModeIs(struct Message *msg) {  	uint param = 3;  	char buf[1024] = ""; +	struct Cat cat = { buf, sizeof(buf), 0 };  	for (char *ch = msg->params[2]; *ch; ++ch) {  		if (*ch == '+') continue;  		const char *name = ChanModes[(byte)*ch]; @@ -648,13 +646,13 @@ static void handleReplyChannelModeIs(struct Message *msg) {  		) {  			assert(param < ParamCap);  			catf( -				buf, sizeof(buf), ", +%c%s%s %s", +				&cat, ", +%c%s%s %s",  				*ch, (name ? " " : ""), (name ?: ""),  				msg->params[param++]  			);  		} else {  			catf( -				buf, sizeof(buf), ", +%c%s%s", +				&cat, ", +%c%s%s",  				*ch, (name ? " " : ""), (name ?: "")  			);  		} @@ -987,13 +985,11 @@ static void handleReplyWhoisChannels(struct Message *msg) {  	require(msg, false, 3);  	if (!replies.whois) return;  	char buf[1024] = ""; +	struct Cat cat = { buf, sizeof(buf), 0 };  	while (msg->params[2]) {  		char *channel = strsep(&msg->params[2], " ");  		char *name = &channel[strspn(channel, network.prefixes)]; -		catf( -			buf, sizeof(buf), "%s\3%02d%s\3", -			(buf[0] ? ", " : ""), hash(name), channel -		); +		catf(&cat, "%s\3%02d%s\3", (buf[0] ? ", " : ""), hash(name), channel);  	}  	uiFormat(  		Network, Warm, tagTime(msg), @@ -1093,9 +1089,10 @@ static const char *colorMentions(uint id, struct Message *msg) {  	static char buf[1024];  	buf[0] = '\0'; +	struct Cat cat = { buf, sizeof(buf), 0 };  	while (*mention) {  		size_t skip = strspn(mention, ",<> "); -		catf(buf, sizeof(buf), "%.*s", (int)skip, mention); +		catf(&cat, "%.*s", (int)skip, mention);  		mention += skip;  		size_t len = strcspn(mention, ",<> "); @@ -1103,14 +1100,14 @@ static const char *colorMentions(uint id, struct Message *msg) {  		mention[len] = '\0';  		enum Color color = completeColor(id, mention);  		if (color != Default) { -			catf(buf, sizeof(buf), "\3%02d%s\3", color, mention); +			catf(&cat, "\3%02d%s\3", color, mention);  		} else { -			catf(buf, sizeof(buf), "%s", mention); +			catf(&cat, "%s", mention);  		}  		mention[len] = punct;  		mention += len;  	} -	catf(buf, sizeof(buf), "%c", delimit); +	catf(&cat, "%c", delimit);  	return buf;  } @@ -465,45 +465,38 @@ static void statusUpdate(void) {  			if (window->heat > others.heat) others.heat = window->heat;  		}  		char buf[256] = ""; +		struct Cat cat = { buf, sizeof(buf), 0 };  		catf( -			buf, sizeof(buf), "\3%d%s %u ", +			&cat, "\3%d%s %u ",  			idColors[window->id], (num == windows.show ? "\26" : ""), num  		);  		if (!window->ignore || window->mute) { -			catf( -				buf, sizeof(buf), "%s%s ", -				&"-"[window->ignore], &"="[!window->mute] -			); +			catf(&cat, "%s%s ", &"-"[window->ignore], &"="[!window->mute]);  		} -		catf(buf, sizeof(buf), "%s ", idNames[window->id]); +		catf(&cat, "%s ", idNames[window->id]);  		if (window->mark && window->unreadWarm) {  			catf( -				buf, sizeof(buf), "\3%d+%d\3%d%s", +				&cat, "\3%d+%d\3%d%s",  				(window->heat > Warm ? White : idColors[window->id]),  				window->unreadWarm, idColors[window->id],  				(window->scroll ? "" : " ")  			);  		}  		if (window->scroll) { -			catf(buf, sizeof(buf), "~%d ", window->scroll); +			catf(&cat, "~%d ", window->scroll);  		}  		statusAdd(buf);  	}  	wclrtoeol(status); +	struct Cat cat = { title, sizeof(title), 0 };  	const struct Window *window = windows.ptrs[windows.show]; -	snprintf(title, sizeof(title), "%s %s", network.name, idNames[window->id]); +	catf(&cat, "%s %s", network.name, idNames[window->id]);  	if (window->mark && window->unreadWarm) { -		catf( -			title, sizeof(title), " +%d%s", -			window->unreadWarm, &"!"[window->heat < Hot] -		); +		catf(&cat, " +%d%s", window->unreadWarm, &"!"[window->heat < Hot]);  	}  	if (others.unread) { -		catf( -			title, sizeof(title), " (+%d%s)", -			others.unread, &"!"[others.heat < Hot] -		); +		catf(&cat, " (+%d%s)", others.unread, &"!"[others.heat < Hot]);  	}  } @@ -638,10 +631,11 @@ static void notify(uint id, const char *str) {  	struct Util util = uiNotifyUtil;  	utilPush(&util, idNames[id]);  	char buf[1024] = ""; +	struct Cat cat = { buf, sizeof(buf), 0 };  	while (*str) {  		struct Style style = Reset;  		size_t len = styleParse(&style, &str); -		catf(buf, sizeof(buf), "%.*s", (int)len, str); +		catf(&cat, "%.*s", (int)len, str);  		str += len;  	}  	utilPush(&util, buf); | 
