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