1 #include <stdlib.h> 2 #include <wchar.h> 3 #include <errno.h> 4 #include "internal.h" 5 mbrtowc(wchar_t * restrict wc,const char * restrict src,size_t n,mbstate_t * restrict st)6size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st) 7 { 8 static unsigned internal_state; 9 unsigned c; 10 const unsigned char *s = (const void *)src; 11 const unsigned N = n; 12 wchar_t dummy; 13 14 if (!st) st = (void *)&internal_state; 15 c = *(unsigned *)st; 16 17 if (!s) { 18 if (c) goto ilseq; 19 return 0; 20 } else if (!wc) wc = &dummy; 21 22 if (!n) return -2; 23 if (!c) { 24 if (*s < 0x80) return !!(*wc = *s); 25 if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1; 26 if (*s-SA > SB-SA) goto ilseq; 27 c = bittab[*s++-SA]; n--; 28 } 29 30 if (n) { 31 if (OOB(c,*s)) goto ilseq; 32 loop: 33 c = c<<6 | *s++-0x80; n--; 34 if (!(c&(1U<<31))) { 35 *(unsigned *)st = 0; 36 *wc = c; 37 return N-n; 38 } 39 if (n) { 40 if (*s-0x80u >= 0x40) goto ilseq; 41 goto loop; 42 } 43 } 44 45 *(unsigned *)st = c; 46 return -2; 47 ilseq: 48 *(unsigned *)st = 0; 49 errno = EILSEQ; 50 return -1; 51 } 52