• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)6 int 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