Hack clang into checking uiFmt format strings

master
Curtis McEnroe 2018-08-07 14:11:19 -04:00
parent 36d37bbf67
commit fa270d9287
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
5 changed files with 28 additions and 19 deletions

12
chat.h
View File

@ -45,10 +45,18 @@ void uiRead(void);
void uiTopic(const wchar_t *topic); void uiTopic(const wchar_t *topic);
void uiTopicStr(const char *topic); void uiTopicStr(const char *topic);
void uiLog(const wchar_t *line); void uiLog(const wchar_t *line);
//__attribute__((format(printf, 1, 2)))
void uiFmt(const wchar_t *format, ...); void uiFmt(const wchar_t *format, ...);
// HACK: clang won't check wchar_t *format strings.
#ifdef NDEBUG
#define uiFmt(format, ...) uiFmt(L##format, __VA_ARGS__)
#else
#define uiFmt(format, ...) do { \
snprintf(NULL, 0, format, __VA_ARGS__); \
uiFmt(L##format, __VA_ARGS__); \
} while(0)
#endif
void handle(char *line); void handle(char *line);
void input(wchar_t *line); void input(wchar_t *line);

View File

@ -59,7 +59,7 @@ static void handle432(char *prefix, char *params) {
shift(&params); shift(&params);
char *mesg = shift(&params); char *mesg = shift(&params);
uiLog(L"You can't use that name here"); uiLog(L"You can't use that name here");
uiFmt(L"Sheriff says, \"%s\"", mesg); uiFmt("Sheriff says, \"%s\"", mesg);
uiLog(L"Type /nick <name> to choose a new one"); uiLog(L"Type /nick <name> to choose a new one");
} }
@ -82,7 +82,7 @@ static void handleJoin(char *prefix, char *params) {
chat.user = strdup(user); chat.user = strdup(user);
} }
uiFmt( uiFmt(
L"\3%d%s\3 arrives in \3%d%s\3", "\3%d%s\3 arrives in \3%d%s\3",
color(user), nick, color(chan), chan color(user), nick, color(chan), chan
); );
} }
@ -94,12 +94,12 @@ static void handlePart(char *prefix, char *params) {
if (params) { if (params) {
char *mesg = shift(&params); char *mesg = shift(&params);
uiFmt( uiFmt(
L"\3%d%s\3 leaves \3%d%s\3, \"%s\"", "\3%d%s\3 leaves \3%d%s\3, \"%s\"",
color(user), nick, color(chan), chan, mesg color(user), nick, color(chan), chan, mesg
); );
} else { } else {
uiFmt( uiFmt(
L"\3%d%s\3 leaves \3%d%s\3", "\3%d%s\3 leaves \3%d%s\3",
color(user), nick, color(chan), chan color(user), nick, color(chan), chan
); );
} }
@ -112,11 +112,11 @@ static void handleQuit(char *prefix, char *params) {
char *mesg = shift(&params); char *mesg = shift(&params);
char *quot = (mesg[0] == '"') ? "" : "\""; char *quot = (mesg[0] == '"') ? "" : "\"";
uiFmt( uiFmt(
L"\3%d%s\3 leaves, %s%s%s", "\3%d%s\3 leaves, %s%s%s",
color(user), nick, quot, mesg, quot color(user), nick, quot, mesg, quot
); );
} else { } else {
uiFmt(L"\3%d%s\3 leaves", color(user), nick); uiFmt("\3%d%s\3 leaves", color(user), nick);
} }
} }
@ -127,7 +127,7 @@ static void handleKick(char *prefix, char *params) {
char *kick = shift(&params); char *kick = shift(&params);
char *mesg = shift(&params); char *mesg = shift(&params);
uiFmt( uiFmt(
L"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"", "\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"",
color(user), nick, color(kick), kick, color(chan), chan, mesg color(user), nick, color(kick), kick, color(chan), chan, mesg
); );
} }
@ -138,7 +138,7 @@ static void handle332(char *prefix, char *params) {
char *chan = shift(&params); char *chan = shift(&params);
char *topic = shift(&params); char *topic = shift(&params);
uiFmt( uiFmt(
L"The sign in \3%d%s\3 reads, \"%s\"", "The sign in \3%d%s\3 reads, \"%s\"",
color(chan), chan, topic color(chan), chan, topic
); );
uiTopicStr(topic); uiTopicStr(topic);
@ -150,7 +150,7 @@ static void handleTopic(char *prefix, char *params) {
char *chan = shift(&params); char *chan = shift(&params);
char *topic = shift(&params); char *topic = shift(&params);
uiFmt( uiFmt(
L"\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"", "\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"",
color(user), nick, color(chan), chan, topic color(user), nick, color(chan), chan, topic
); );
uiTopicStr(topic); uiTopicStr(topic);
@ -191,7 +191,7 @@ static void handle315(char *prefix, char *params) {
char *chan = shift(&params); char *chan = shift(&params);
who.len = 0; who.len = 0;
uiFmt( uiFmt(
L"In \3%d%s\3 are %s", "In \3%d%s\3 are %s",
color(chan), chan, who.buf color(chan), chan, who.buf
); );
} }
@ -205,7 +205,7 @@ static void handleNick(char *prefix, char *params) {
chat.nick = strdup(next); chat.nick = strdup(next);
} }
uiFmt( uiFmt(
L"\3%d%s\3 is now known as \3%d%s\3", "\3%d%s\3 is now known as \3%d%s\3",
color(user), prev, color(user), next color(user), prev, color(user), next
); );
} }
@ -217,9 +217,9 @@ static void handlePrivmsg(char *prefix, char *params) {
char *mesg = shift(&params); char *mesg = shift(&params);
if (mesg[0] == '\1') { if (mesg[0] == '\1') {
strsep(&mesg, " "); strsep(&mesg, " ");
uiFmt(L"* \3%d%s\3 %s", color(user), nick, strsep(&mesg, "\1")); uiFmt("* \3%d%s\3 %s", color(user), nick, strsep(&mesg, "\1"));
} else { } else {
uiFmt(L"<\3%d%s\3> %s", color(user), nick, mesg); uiFmt("<\3%d%s\3> %s", color(user), nick, mesg);
} }
} }
@ -229,7 +229,7 @@ static void handleNotice(char *prefix, char *params) {
char *chan = shift(&params); char *chan = shift(&params);
char *mesg = shift(&params); char *mesg = shift(&params);
if (strcmp(chat.chan, chan)) return; if (strcmp(chat.chan, chan)) return;
uiFmt(L"-\3%d%s\3- %s", color(user), nick, mesg); uiFmt("-\3%d%s\3- %s", color(user), nick, mesg);
} }
static const struct { static const struct {

View File

@ -98,5 +98,5 @@ void input(wchar_t *input) {
COMMANDS[i].handler(input); COMMANDS[i].handler(input);
return; return;
} }
uiFmt(L"/%ls isn't a recognized command", command); uiFmt("/%ls isn't a recognized command", command);
} }

4
irc.c
View File

@ -99,7 +99,7 @@ void ircFmt(const char *format, ...) {
int len = vasprintf(&buf, format, ap); int len = vasprintf(&buf, format, ap);
va_end(ap); va_end(ap);
if (!buf) err(EX_OSERR, "vasprintf"); if (!buf) err(EX_OSERR, "vasprintf");
if (chat.verbose) uiFmt(L"<<< %.*s", len - 2, buf); if (chat.verbose) uiFmt("<<< %.*s", len - 2, buf);
ircWrite(buf, len); ircWrite(buf, len);
free(buf); free(buf);
} }
@ -119,7 +119,7 @@ void ircRead(void) {
char *crlf, *line = buf; char *crlf, *line = buf;
while ((crlf = strnstr(line, "\r\n", &buf[len] - line))) { while ((crlf = strnstr(line, "\r\n", &buf[len] - line))) {
crlf[0] = '\0'; crlf[0] = '\0';
if (chat.verbose) uiFmt(L">>> %s", line); if (chat.verbose) uiFmt(">>> %s", line);
handle(line); handle(line);
line = &crlf[2]; line = &crlf[2];
} }

1
ui.c
View File

@ -28,6 +28,7 @@
#include <wctype.h> #include <wctype.h>
#include "chat.h" #include "chat.h"
#undef uiFmt
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))