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