Convert input to multibyte before handling

master
Curtis McEnroe 2018-08-07 15:43:49 -04:00
parent 5d2b5cd51e
commit fe21b1410f
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
5 changed files with 37 additions and 41 deletions

2
chat.c
View File

@ -30,7 +30,7 @@
static void sigint(int sig) { static void sigint(int sig) {
(void)sig; (void)sig;
input(L"/quit"); input("/quit");
uiHide(); uiHide();
exit(EX_OK); exit(EX_OK);
} }

3
chat.h
View File

@ -58,11 +58,10 @@ void uiFmt(const wchar_t *format, ...);
#endif #endif
void handle(char *line); void handle(char *line);
void input(wchar_t *line); void input(char *line);
void tabTouch(const char *word); void tabTouch(const char *word);
void tabRemove(const char *word); void tabRemove(const char *word);
void tabReplace(const char *prev, const char *next); void tabReplace(const char *prev, const char *next);
wchar_t *wcssep(wchar_t **stringp, const wchar_t *delim);
int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap); int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap);

50
input.c
View File

@ -18,16 +18,16 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <sysexits.h> #include <sysexits.h>
#include <wchar.h>
#include "chat.h" #include "chat.h"
static void privmsg(bool action, const wchar_t *mesg) { static void privmsg(bool action, const char *mesg) {
char *line; char *line;
int send; int send;
asprintf( asprintf(
&line, ":%s!%s %nPRIVMSG %s :%s%ls%s", &line, ":%s!%s %nPRIVMSG %s :%s%s%s",
chat.nick, chat.user, &send, chat.chan, chat.nick, chat.user, &send, chat.chan,
(action ? "\1ACTION " : ""), mesg, (action ? "\1" : "") (action ? "\1ACTION " : ""), mesg, (action ? "\1" : "")
); );
@ -37,66 +37,66 @@ static void privmsg(bool action, const wchar_t *mesg) {
free(line); free(line);
} }
typedef void (*Handler)(wchar_t *params); typedef void (*Handler)(char *params);
static void inputMe(wchar_t *params) { static void inputMe(char *params) {
privmsg(true, params ? params : L""); privmsg(true, params ? params : "");
} }
static void inputNick(wchar_t *params) { static void inputNick(char *params) {
wchar_t *nick = wcssep(&params, L" "); char *nick = strsep(&params, " ");
if (nick) { if (nick) {
ircFmt("NICK %ls\r\n", nick); ircFmt("NICK %s\r\n", nick);
} else { } else {
uiLog(L"/nick requires a name"); uiLog(L"/nick requires a name");
} }
} }
static void inputWho(wchar_t *params) { static void inputWho(char *params) {
(void)params; (void)params;
ircFmt("WHO %s\r\n", chat.chan); ircFmt("WHO %s\r\n", chat.chan);
} }
static void inputTopic(wchar_t *params) { static void inputTopic(char *params) {
if (params) { if (params) {
ircFmt("TOPIC %s :%ls\r\n", chat.chan, params); ircFmt("TOPIC %s :%s\r\n", chat.chan, params);
} else { } else {
ircFmt("TOPIC %s\r\n", chat.chan); ircFmt("TOPIC %s\r\n", chat.chan);
} }
} }
static void inputQuit(wchar_t *params) { static void inputQuit(char *params) {
if (params) { if (params) {
ircFmt("QUIT :%ls\r\n", params); ircFmt("QUIT :%s\r\n", params);
} else { } else {
ircFmt("QUIT :Goodbye\r\n"); ircFmt("QUIT :Goodbye\r\n");
} }
} }
static const struct { static const struct {
const wchar_t *command; const char *command;
Handler handler; Handler handler;
} COMMANDS[] = { } COMMANDS[] = {
{ L"me", inputMe }, { "me", inputMe },
{ L"names", inputWho }, { "names", inputWho },
{ L"nick", inputNick }, { "nick", inputNick },
{ L"quit", inputQuit }, { "quit", inputQuit },
{ L"topic", inputTopic }, { "topic", inputTopic },
{ L"who", inputWho }, { "who", inputWho },
}; };
static const size_t COMMANDS_LEN = sizeof(COMMANDS) / sizeof(COMMANDS[0]); static const size_t COMMANDS_LEN = sizeof(COMMANDS) / sizeof(COMMANDS[0]);
void input(wchar_t *input) { void input(char *input) {
if (input[0] != '/') { if (input[0] != '/') {
privmsg(false, input); privmsg(false, input);
return; return;
} }
input++; input++;
wchar_t *command = wcssep(&input, L" "); char *command = strsep(&input, " ");
for (size_t i = 0; i < COMMANDS_LEN; ++i) { for (size_t i = 0; i < COMMANDS_LEN; ++i) {
if (wcscmp(command, COMMANDS[i].command)) continue; if (strcmp(command, COMMANDS[i].command)) continue;
COMMANDS[i].handler(input); COMMANDS[i].handler(input);
return; return;
} }
uiFmt("/%ls isn't a recognized command", command); uiFmt("/%s isn't a recognized command", command);
} }

12
pls.c
View File

@ -20,18 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h> #include <wchar.h>
wchar_t *wcssep(wchar_t **stringp, const wchar_t *delim) {
wchar_t *orig = *stringp;
if (!orig) return NULL;
size_t i = wcscspn(orig, delim);
*stringp = NULL;
if (orig[i]) {
orig[i] = L'\0';
*stringp = &orig[i + 1];
}
return orig;
}
// From <https://en.cppreference.com/w/c/io/fwprintf#Notes>: // From <https://en.cppreference.com/w/c/io/fwprintf#Notes>:
// //
// While narrow strings provide snprintf, which makes it possible to determine // While narrow strings provide snprintf, which makes it possible to determine

11
ui.c
View File

@ -350,7 +350,16 @@ static void delete(void) {
static void enter(void) { static void enter(void) {
if (line.end == line.buf) return; if (line.end == line.buf) return;
*line.end = L'\0'; *line.end = L'\0';
input(line.buf);
const wchar_t *src = line.buf;
size_t len = wcsrtombs(NULL, &src, 0, NULL);
if (len == (size_t)-1) err(EX_DATAERR, "wcsrtombs");
char buf[1 + len];
len = wcsrtombs(buf, &src, sizeof(buf), NULL);
if (len == (size_t)-1) err(EX_DATAERR, "wcsrtombs");
input(buf);
line.ptr = line.buf; line.ptr = line.buf;
line.end = line.buf; line.end = line.buf;
} }