OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * This code was written by Rich Felker in 2010; no copyright is claimed. |
| 3 * This code is in the public domain. Attribution is appreciated but |
| 4 * unnecessary. |
| 5 */ |
| 6 |
| 7 #include <stdlib.h> |
| 8 #include <wchar.h> |
| 9 #include <errno.h> |
| 10 #include "internal.h" |
| 11 |
| 12 size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate
_t *restrict st) |
| 13 { |
| 14 static unsigned internal_state; |
| 15 unsigned c; |
| 16 const unsigned char *s = (const void *)src; |
| 17 const unsigned N = n; |
| 18 wchar_t dummy; |
| 19 |
| 20 if (!st) st = (void *)&internal_state; |
| 21 c = *(unsigned *)st; |
| 22 |
| 23 if (!s) { |
| 24 if (c) goto ilseq; |
| 25 return 0; |
| 26 } else if (!wc) wc = &dummy; |
| 27 |
| 28 if (!n) return -2; |
| 29 if (!c) { |
| 30 if (*s < 0x80) return !!(*wc = *s); |
| 31 if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1; |
| 32 if (*s-SA > SB-SA) goto ilseq; |
| 33 c = bittab[*s++-SA]; n--; |
| 34 } |
| 35 |
| 36 if (n) { |
| 37 if (OOB(c,*s)) goto ilseq; |
| 38 loop: |
| 39 c = c<<6 | *s++-0x80; n--; |
| 40 if (!(c&(1U<<31))) { |
| 41 *(unsigned *)st = 0; |
| 42 *wc = c; |
| 43 return N-n; |
| 44 } |
| 45 if (n) { |
| 46 if (*s-0x80u >= 0x40) goto ilseq; |
| 47 goto loop; |
| 48 } |
| 49 } |
| 50 |
| 51 *(unsigned *)st = c; |
| 52 return -2; |
| 53 ilseq: |
| 54 *(unsigned *)st = 0; |
| 55 errno = EILSEQ; |
| 56 return -1; |
| 57 } |
OLD | NEW |