diff options
author | Manuel Novoa III <mjn3@codepoet.org> | 2002-05-23 20:33:53 +0000 |
---|---|---|
committer | Manuel Novoa III <mjn3@codepoet.org> | 2002-05-23 20:33:53 +0000 |
commit | d730fb4d646ac74ee6bbd227411329090fb3206c (patch) | |
tree | 8f843bd6aabc8a9ea20ae708a64177e0c363f37b /libc/stdlib | |
parent | 50566667587e92dcf900e2d53204d972b5650a38 (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/Makefile | 6 | ||||
-rw-r--r-- | libc/stdlib/stdlib.c | 133 |
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 +/**********************************************************************/ + |