summaryrefslogtreecommitdiff
path: root/libc/stdlib
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2002-05-23 20:33:53 +0000
committerManuel Novoa III <mjn3@codepoet.org>2002-05-23 20:33:53 +0000
commitd730fb4d646ac74ee6bbd227411329090fb3206c (patch)
tree8f843bd6aabc8a9ea20ae708a64177e0c363f37b /libc/stdlib
parent50566667587e92dcf900e2d53204d972b5650a38 (diff)
Multibyte and wide char conversion functions. Some work still to do, but
they're quite solid now and Erik needs them for the gcc port. Comments at the head of wchar.c.
Diffstat (limited to 'libc/stdlib')
-rw-r--r--libc/stdlib/Makefile6
-rw-r--r--libc/stdlib/stdlib.c133
2 files changed, 139 insertions, 0 deletions
diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile
index 64ae75d18..e69ec4ea8 100644
--- a/libc/stdlib/Makefile
+++ b/libc/stdlib/Makefile
@@ -35,6 +35,12 @@ ifeq ($(HAS_LONG_LONG),true)
MOBJ += llabs.o atoll.o strtoll.o strtoull.o _stdlib_strto_ll.o
endif
+ifeq ($(HAS_WCHAR),true)
+ MOBJ += mblen.o mbtowc.o wctomb.o mbstowcs.o wcstombs.o \
+ _stdlib_mb_cur_max.o
+endif
+
+
MSRC2=atexit.c
MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o
diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c
index 1cd350c31..4c9e8f039 100644
--- a/libc/stdlib/stdlib.c
+++ b/libc/stdlib/stdlib.c
@@ -623,3 +623,136 @@ void ssort (void *base,
#endif
/**********************************************************************/
+/* Multibyte and wchar stuff follows. */
+
+#ifdef __UCLIBC_HAS_WCHAR__
+
+#include <locale.h>
+#include <wchar.h>
+
+/* TODO: clean up the following... */
+
+#if WCHAR_MAX > 0xffffU
+#define UTF_8_MAX_LEN 6
+#else
+#define UTF_8_MAX_LEN 3
+#endif
+
+#define ENCODING (__global_locale.encoding)
+
+#endif
+
+/**********************************************************************/
+#ifdef L__stdlib_mb_cur_max
+
+size_t _stdlib_mb_cur_max(void)
+{
+ return __global_locale.mb_cur_max;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_mblen
+
+#warning implement __CTYPE_HAS_UTF_8_LOCALES!
+#define __CTYPE_HAS_UTF_8_LOCALES
+
+int mblen(register const char *s, size_t n)
+{
+ static mbstate_t state;
+ size_t r;
+
+ if (!s) {
+ state.mask = 0;
+#ifdef __CTYPE_HAS_UTF_8_LOCALES
+ return ENCODING == __ctype_encoding_utf8;
+#else
+ return 0;
+#endif
+ }
+
+ if ((r = mbrlen(s, n, &state)) == (size_t) -2) {
+ /* TODO: Should we set an error state? */
+ state.wc = 0xffffU; /* Make sure we're in an error state. */
+ return (size_t) -1; /* TODO: Change error code above? */
+ }
+ return r;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_mbtowc
+
+#warning implement __CTYPE_HAS_UTF_8_LOCALES!
+#define __CTYPE_HAS_UTF_8_LOCALES
+
+int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n)
+{
+ static mbstate_t state;
+ size_t r;
+
+ if (!s) {
+ state.mask = 0;
+#ifdef __CTYPE_HAS_UTF_8_LOCALES
+ return ENCODING == __ctype_encoding_utf8;
+#else
+ return 0;
+#endif
+ }
+
+ if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) {
+ /* TODO: Should we set an error state? */
+ state.wc = 0xffffU; /* Make sure we're in an error state. */
+ return (size_t) -1; /* TODO: Change error code above? */
+ }
+ return r;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wctomb
+
+#warning implement __CTYPE_HAS_UTF_8_LOCALES!
+#define __CTYPE_HAS_UTF_8_LOCALES
+
+/* Note: We completely ignore state in all currently supported conversions. */
+
+int wctomb(register char *__restrict s, wchar_t swc)
+{
+ return (!s)
+ ?
+#ifdef __CTYPE_HAS_UTF_8_LOCALES
+ (ENCODING == __ctype_encoding_utf8)
+#else
+ 0 /* Encoding is stateless. */
+#endif
+ : ((ssize_t) wcrtomb(s, swc, NULL));
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_mbstowcs
+
+size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
+{
+ mbstate_t state;
+
+ state.mask = 0; /* Always start in initial shift state. */
+
+ return mbsrtowcs(pwcs, &s, n, &state);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_wcstombs
+
+/* Note: We completely ignore state in all currently supported conversions. */
+
+size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
+{
+ return wcsrtombs(s, &pwcs, n, NULL);
+}
+
+#endif
+/**********************************************************************/
+