commit 30c000db05198ff90a368031b0b96c1d8caf390f
parent f2b5424d6820bbc9e3a7d54b84aa7fae5d5d8502
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 16 Mar 2022 12:10:43 +0100
libc: Add mbtowc()
Diffstat:
3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/include/stdlib.h b/include/stdlib.h
@@ -11,7 +11,7 @@
 
 #define _ATEXIT_MAX 32
 
-#define MB_CUR_MAX 1
+#define MB_CUR_MAX 6
 #define RAND_MAX 32767
 
 typedef struct {
diff --git a/src/libc/stdlib/Makefile b/src/libc/stdlib/Makefile
@@ -18,6 +18,7 @@ OBJS =\
 	labs.$O\
 	llabs.$O\
 	malloc.$O\
+	mbtowc.$O\
 	qsort.$O\
 	rand.$O\
 	realloc.$O\
diff --git a/src/libc/stdlib/mbtowc.c b/src/libc/stdlib/mbtowc.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+
+#undef mbtowc
+
+int
+mbtowc(wchar_t *restrict pwc, const char *restrict s, size_t n)
+{
+	const char *t = s;
+	unsigned long wc;
+	unsigned c;
+	size_t len;
+
+	if (s == NULL)
+		return 0;
+
+	wc = c = *t++;
+	for (len = 0; n > 0 && c & 0x80; --n, ++len)
+		c <<= 1;
+	if (n == 0 || len == 1 || len == 8)
+		return -1;
+	if (len == 0)
+		goto return_code;
+
+	for (wc = (c & 0xFF) >> len; len--; wc |= c & 0x3F) {
+		if ((c = *t++) & 0xC0 != 0x80)
+			return -1;
+		wc <<= 6;
+	}
+
+return_code:
+	if (pwc)
+		*pwc = wc;
+	return (*s) ? t - s : 0;
+}