commit 1908a6ea5f748db20b6b2e9f2eda55ae40d0bd75
parent 1a210c4013e2c6f78fafacc3655b54640541e4a2
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Wed, 9 Nov 2022 21:04:49 +0100
libc/wchar: Add wcsrtombs()
Diffstat:
3 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/src/libc/objs/common-objs.mk b/src/libc/objs/common-objs.mk
@@ -124,6 +124,7 @@ COMMON_OBJS =\
wchar/mbsrtowcs.$O\
wchar/wcrtomb.$O\
wchar/wcslen.$O\
+ wchar/wcsrtombs.$O\
wchar/wcwidth.$O\
wchar/putwc.$O\
wchar/_validutf8.$O\
diff --git a/src/libc/wchar/Makefile b/src/libc/wchar/Makefile
@@ -10,6 +10,7 @@ OBJS =\
mbsrtowcs.$O\
wcrtomb.$O\
wcslen.$O\
+ wcsrtombs.$O\
wcwidth.$O\
putwc.$O\
_validutf8.$O\
diff --git a/src/libc/wchar/wcsrtombs.c b/src/libc/wchar/wcsrtombs.c
@@ -0,0 +1,38 @@
+#include <string.h>
+#include <limits.h>
+#include <wchar.h>
+
+#undef wcsrtombs
+
+size_t
+wcsrtombs(char *restrict dest, const wchar_t **restrict src,
+ size_t len, mbstate_t *restrict ps)
+{
+ size_t cnt, n;
+ wchar_t wc;
+ char buf[MB_LEN_MAX];
+ static mbstate_t p;
+
+ if (!ps)
+ ps = &p;
+
+ for (n = 0; ; n += cnt) {
+ wc = **src;
+ cnt = wcrtomb(buf, wc, ps);
+ if (cnt == (size_t) -1)
+ return -1;
+
+ if (dest) {
+ if (n+cnt > len)
+ return n;
+ memcpy(dest+n, buf, cnt);
+ }
+ *src += 1;
+
+ if (wc == L'\0')
+ break;
+ }
+ *src = NULL;
+
+ return n;
+}