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) {
(void)sig;
input(L"/quit");
input("/quit");
uiHide();
exit(EX_OK);
}

3
chat.h
View File

@ -58,11 +58,10 @@ void uiFmt(const wchar_t *format, ...);
#endif
void handle(char *line);
void input(wchar_t *line);
void input(char *line);
void tabTouch(const char *word);
void tabRemove(const char *word);
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);

50
input.c
View File

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