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 |