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