1 #include <stdlib.h> 2 #include <wchar.h> 3 #include <errno.h> 4 #include "internal.h" 5 mbtowc(wchar_t * restrict wc,const char * restrict src,size_t n)6int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n) 7 { 8 unsigned c; 9 const unsigned char *s = (const void *)src; 10 wchar_t dummy; 11 12 if (!s) return 0; 13 if (!n) goto ilseq; 14 if (!wc) wc = &dummy; 15 16 if (*s < 0x80) return !!(*wc = *s); 17 if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1; 18 if (*s-SA > SB-SA) goto ilseq; 19 c = bittab[*s++-SA]; 20 21 /* Avoid excessive checks against n: If shifting the state n-1 22 * times does not clear the high bit, then the value of n is 23 * insufficient to read a character */ 24 if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq; 25 26 if (OOB(c,*s)) goto ilseq; 27 c = (c<<6) | (*s++-0x80); 28 if (!(c&(1U<<31))) { 29 *wc = c; 30 return 2; 31 } 32 33 if (*s-0x80u >= 0x40) goto ilseq; 34 c = (c<<6) | (*s++-0x80); 35 if (!(c&(1U<<31))) { 36 *wc = c; 37 return 3; 38 } 39 40 if (*s-0x80u >= 0x40) goto ilseq; 41 *wc = (c<<6) | (*s++-0x80); 42 return 4; 43 44 ilseq: 45 errno = EILSEQ; 46 return -1; 47 } 48