1#include <stdlib.h>
2#include <wchar.h>
3#include <errno.h>
4#include "internal.h"
5
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
44ilseq:
45	errno = EILSEQ;
46	return -1;
47}
48