Home | History | Annotate | Download | only in musl-multibyte
      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 }
     51