summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chat.h2
-rw-r--r--pls.c32
-rw-r--r--ui.c21
3 files changed, 41 insertions, 14 deletions
diff --git a/chat.h b/chat.h
index 8af6e8a..1c7ae5a 100644
--- a/chat.h
+++ b/chat.h
@@ -64,4 +64,6 @@ void tabTouch(const char *word);
void tabRemove(const char *word);
void tabReplace(const char *prev, const char *next);
+wchar_t *ambstowcs(const char *src);
+char *awcstombs(const wchar_t *src);
int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap);
diff --git a/pls.c b/pls.c
index 0667036..27ede4c 100644
--- a/pls.c
+++ b/pls.c
@@ -20,6 +20,38 @@
#include <stdlib.h>
#include <wchar.h>
+wchar_t *ambstowcs(const char *src) {
+ size_t len = mbsrtowcs(NULL, &src, 0, NULL);
+ if (len == (size_t)-1) return NULL;
+
+ wchar_t *dst = malloc(sizeof(*dst) * (1 + len));
+ if (!dst) return NULL;
+
+ len = mbsrtowcs(dst, &src, 1 + len, NULL);
+ if (len == (size_t)-1) {
+ free(dst);
+ return NULL;
+ }
+
+ return dst;
+}
+
+char *awcstombs(const wchar_t *src) {
+ size_t len = wcsrtombs(NULL, &src, 0, NULL);
+ if (len == (size_t)-1) return NULL;
+
+ char *dst = malloc(sizeof(*dst) * (1 + len));
+ if (!dst) return NULL;
+
+ len = wcsrtombs(dst, &src, 1 + len, NULL);
+ if (len == (size_t)-1) {
+ free(dst);
+ return NULL;
+ }
+
+ return dst;
+}
+
// From <https://en.cppreference.com/w/c/io/fwprintf#Notes>:
//
// While narrow strings provide snprintf, which makes it possible to determine
diff --git a/ui.c b/ui.c
index 2e028ff..62c3b3c 100644
--- a/ui.c
+++ b/ui.c
@@ -267,11 +267,10 @@ void uiTopic(const wchar_t *topic) {
}
void uiTopicStr(const char *topic) {
- size_t len = strlen(topic);
- wchar_t wcs[1 + len];
- len = mbstowcs(wcs, topic, 1 + len);
- if (len == (size_t)-1) err(EX_DATAERR, "mbstowcs");
+ wchar_t *wcs = ambstowcs(topic);
+ if (!wcs) err(EX_DATAERR, "ambstowcs");
uiTopic(wcs);
+ free(wcs);
}
void uiLog(const wchar_t *line) {
@@ -350,16 +349,10 @@ static void delete(void) {
static void enter(void) {
if (line.end == line.buf) return;
*line.end = L'\0';
-
- 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);
+ char *str = awcstombs(line.buf);
+ if (!str) err(EX_DATAERR, "awcstombs");
+ input(str);
+ free(str);
line.ptr = line.buf;
line.end = line.buf;
}