diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-04-23 18:50:47 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-04-23 18:50:47 -0700 |
commit | f6fa219f1275b8a98c768d1f8593613ed85d5cfe (patch) | |
tree | 89b4848d4bd5a1fbdf9100f346c1583c657b341d /system/lib/libc/musl/src/multibyte/mbrtowc.c | |
parent | 430dcb4c1533a7c2e9486a2bcbb4e0bda3025c0c (diff) | |
parent | 029c076151fb9cb47c54af53c52870ef0b620c5c (diff) |
Merge pull request #1063 from waywardmonkeys/musl-libc1.3.7
Add wchar and multibyte libc functions
Diffstat (limited to 'system/lib/libc/musl/src/multibyte/mbrtowc.c')
-rw-r--r-- | system/lib/libc/musl/src/multibyte/mbrtowc.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/system/lib/libc/musl/src/multibyte/mbrtowc.c b/system/lib/libc/musl/src/multibyte/mbrtowc.c new file mode 100644 index 00000000..db803661 --- /dev/null +++ b/system/lib/libc/musl/src/multibyte/mbrtowc.c @@ -0,0 +1,57 @@ +/* + * This code was written by Rich Felker in 2010; no copyright is claimed. + * This code is in the public domain. Attribution is appreciated but + * unnecessary. + */ + +#include <stdlib.h> +#include <inttypes.h> +#include <wchar.h> +#include <errno.h> + +#include "internal.h" + +size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st) +{ + static unsigned internal_state; + unsigned c; + const unsigned char *s = (const void *)src; + const unsigned N = n; + + if (!st) st = (void *)&internal_state; + c = *(unsigned *)st; + + if (!s) { + if (c) goto ilseq; + return 0; + } else if (!wc) wc = (void *)&wc; + + if (!n) return -2; + if (!c) { + if (*s < 0x80) return !!(*wc = *s); + if (*s-SA > SB-SA) goto ilseq; + c = bittab[*s++-SA]; n--; + } + + if (n) { + if (OOB(c,*s)) goto ilseq; +loop: + c = c<<6 | *s++-0x80; n--; + if (!(c&(1U<<31))) { + *(unsigned *)st = 0; + *wc = c; + return N-n; + } + if (n) { + if (*s-0x80u >= 0x40) goto ilseq; + goto loop; + } + } + + *(unsigned *)st = c; + return -2; +ilseq: + *(unsigned *)st = 0; + errno = EILSEQ; + return -1; +} |