| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 #include <wchar.h> | 8 #include <wchar.h> |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| 11 #include <stdlib.h> | 11 #include <stdlib.h> |
| 12 #include "internal.h" | 12 #include "internal.h" |
| 13 | 13 |
| 14 size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs
tate_t *restrict st) | 14 size_t mbsrtowcs(wchar_t* restrict ws, |
| 15 { | 15 const char** restrict src, |
| 16 » const unsigned char *s = (const void *)*src; | 16 size_t wn, |
| 17 » size_t wn0 = wn; | 17 mbstate_t* restrict st) { |
| 18 » unsigned c = 0; | 18 const unsigned char* s = (const void*)*src; |
| 19 size_t wn0 = wn; |
| 20 unsigned c = 0; |
| 19 | 21 |
| 20 » if (st && (c = *(unsigned *)st)) { | 22 if (st && (c = *(unsigned*)st)) { |
| 21 » » if (ws) { | 23 if (ws) { |
| 22 » » » *(unsigned *)st = 0; | 24 *(unsigned*)st = 0; |
| 23 » » » goto resume; | 25 goto resume; |
| 24 » » } else { | 26 } else { |
| 25 » » » goto resume0; | 27 goto resume0; |
| 26 » » } | 28 } |
| 27 » } | 29 } |
| 28 | 30 |
| 29 » if (MB_CUR_MAX==1) { | 31 if (MB_CUR_MAX == 1) { |
| 30 » » if (!ws) return strlen((const char *)s); | 32 if (!ws) |
| 31 » » for (;;) { | 33 return strlen((const char*)s); |
| 32 » » » if (!wn) { | 34 for (;;) { |
| 33 » » » » *src = (const void *)s; | 35 if (!wn) { |
| 34 » » » » return wn0; | 36 *src = (const void*)s; |
| 35 » » » } | 37 return wn0; |
| 36 » » » if (!*s) break; | 38 } |
| 37 » » » c = *s++; | 39 if (!*s) |
| 38 » » » *ws++ = CODEUNIT(c); | 40 break; |
| 39 » » » wn--; | 41 c = *s++; |
| 40 » » } | 42 *ws++ = CODEUNIT(c); |
| 41 » » *ws = 0; | 43 wn--; |
| 42 » » *src = 0; | 44 } |
| 43 » » return wn0-wn; | 45 *ws = 0; |
| 44 » } | 46 *src = 0; |
| 47 return wn0 - wn; |
| 48 } |
| 45 | 49 |
| 46 » if (!ws) for (;;) { | 50 if (!ws) |
| 47 » » if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { | 51 for (;;) { |
| 48 » » » while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0
x80808080)) { | 52 if (*s - 1u < 0x7f && (uintptr_t)s % 4 == 0) { |
| 49 » » » » s += 4; | 53 while (!((*(uint32_t*)s | *(uint32_t*)s - 0x01010101) & 0x80808080)) { |
| 50 » » » » wn -= 4; | 54 s += 4; |
| 51 » » » } | 55 wn -= 4; |
| 52 » » } | 56 } |
| 53 » » if (*s-1u < 0x7f) { | 57 } |
| 54 » » » s++; | 58 if (*s - 1u < 0x7f) { |
| 55 » » » wn--; | 59 s++; |
| 56 » » » continue; | 60 wn--; |
| 57 » » } | 61 continue; |
| 58 » » if (*s-SA > SB-SA) break; | 62 } |
| 59 » » c = bittab[*s++-SA]; | 63 if (*s - SA > SB - SA) |
| 60 resume0: | 64 break; |
| 61 » » if (OOB(c,*s)) { s--; break; } | 65 c = bittab[*s++ - SA]; |
| 62 » » s++; | 66 resume0: |
| 63 » » if (c&(1U<<25)) { | 67 if (OOB(c, *s)) { |
| 64 » » » if (*s-0x80u >= 0x40) { s-=2; break; } | 68 s--; |
| 65 » » » s++; | 69 break; |
| 66 » » » if (c&(1U<<19)) { | 70 } |
| 67 » » » » if (*s-0x80u >= 0x40) { s-=3; break; } | 71 s++; |
| 68 » » » » s++; | 72 if (c & (1U << 25)) { |
| 69 » » » } | 73 if (*s - 0x80u >= 0x40) { |
| 70 » » } | 74 s -= 2; |
| 71 » » wn--; | 75 break; |
| 72 » » c = 0; | 76 } |
| 73 » } else for (;;) { | 77 s++; |
| 74 » » if (!wn) { | 78 if (c & (1U << 19)) { |
| 75 » » » *src = (const void *)s; | 79 if (*s - 0x80u >= 0x40) { |
| 76 » » » return wn0; | 80 s -= 3; |
| 77 » » } | 81 break; |
| 78 » » if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { | 82 } |
| 79 » » » while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x0101
0101) & 0x80808080)) { | 83 s++; |
| 80 » » » » *ws++ = *s++; | 84 } |
| 81 » » » » *ws++ = *s++; | 85 } |
| 82 » » » » *ws++ = *s++; | 86 wn--; |
| 83 » » » » *ws++ = *s++; | 87 c = 0; |
| 84 » » » » wn -= 4; | 88 } |
| 85 » » » } | 89 else |
| 86 » » } | 90 for (;;) { |
| 87 » » if (*s-1u < 0x7f) { | 91 if (!wn) { |
| 88 » » » *ws++ = *s++; | 92 *src = (const void*)s; |
| 89 » » » wn--; | 93 return wn0; |
| 90 » » » continue; | 94 } |
| 91 » » } | 95 if (*s - 1u < 0x7f && (uintptr_t)s % 4 == 0) { |
| 92 » » if (*s-SA > SB-SA) break; | 96 while (wn >= 5 && |
| 93 » » c = bittab[*s++-SA]; | 97 !((*(uint32_t*)s | *(uint32_t*)s - 0x01010101) & 0x80808080)) { |
| 94 resume: | 98 *ws++ = *s++; |
| 95 » » if (OOB(c,*s)) { s--; break; } | 99 *ws++ = *s++; |
| 96 » » c = (c<<6) | *s++-0x80; | 100 *ws++ = *s++; |
| 97 » » if (c&(1U<<31)) { | 101 *ws++ = *s++; |
| 98 » » » if (*s-0x80u >= 0x40) { s-=2; break; } | 102 wn -= 4; |
| 99 » » » c = (c<<6) | *s++-0x80; | 103 } |
| 100 » » » if (c&(1U<<31)) { | 104 } |
| 101 » » » » if (*s-0x80u >= 0x40) { s-=3; break; } | 105 if (*s - 1u < 0x7f) { |
| 102 » » » » c = (c<<6) | *s++-0x80; | 106 *ws++ = *s++; |
| 103 » » » } | 107 wn--; |
| 104 » » } | 108 continue; |
| 105 » » *ws++ = c; | 109 } |
| 106 » » wn--; | 110 if (*s - SA > SB - SA) |
| 107 » » c = 0; | 111 break; |
| 108 » } | 112 c = bittab[*s++ - SA]; |
| 113 resume: |
| 114 if (OOB(c, *s)) { |
| 115 s--; |
| 116 break; |
| 117 } |
| 118 c = (c << 6) | *s++ - 0x80; |
| 119 if (c & (1U << 31)) { |
| 120 if (*s - 0x80u >= 0x40) { |
| 121 s -= 2; |
| 122 break; |
| 123 } |
| 124 c = (c << 6) | *s++ - 0x80; |
| 125 if (c & (1U << 31)) { |
| 126 if (*s - 0x80u >= 0x40) { |
| 127 s -= 3; |
| 128 break; |
| 129 } |
| 130 c = (c << 6) | *s++ - 0x80; |
| 131 } |
| 132 } |
| 133 *ws++ = c; |
| 134 wn--; |
| 135 c = 0; |
| 136 } |
| 109 | 137 |
| 110 » if (!c && !*s) { | 138 if (!c && !*s) { |
| 111 » » if (ws) { | 139 if (ws) { |
| 112 » » » *ws = 0; | 140 *ws = 0; |
| 113 » » » *src = 0; | 141 *src = 0; |
| 114 » » } | 142 } |
| 115 » » return wn0-wn; | 143 return wn0 - wn; |
| 116 » } | 144 } |
| 117 » errno = EILSEQ; | 145 errno = EILSEQ; |
| 118 » if (ws) *src = (const void *)s; | 146 if (ws) |
| 119 » return -1; | 147 *src = (const void*)s; |
| 148 return -1; |
| 120 } | 149 } |
| OLD | NEW |