about summary refs log tree commit diff
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;
 }