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