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 . */ +#include #include #include +#include #include #include +#include #include #include #include @@ -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);