From 4c1b1fc6a32061e86dedd6f34ed352cfda380feb Mon Sep 17 00:00:00 2001 From: C. McEnroe Date: Thu, 30 Jul 2020 14:37:46 -0400 Subject: Replace catf with something that tracks len Also the old catf would be broken with -DNDEBUG oops! --- chat.h | 15 +++++++++++---- handle.c | 35 ++++++++++++++++------------------- ui.c | 30 ++++++++++++------------------ 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/chat.h b/chat.h index fd8f81a..023baf6 100644 --- a/chat.h +++ b/chat.h @@ -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 { diff --git a/handle.c b/handle.c index 5f29db2..cf9b296 100644 --- a/handle.c +++ b/handle.c @@ -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; } diff --git a/ui.c b/ui.c index c92fb01..b6aaafc 100644 --- a/ui.c +++ b/ui.c @@ -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); -- cgit 1.4.1-2-gfad0