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 <stdlib.h>
      8 #include <inttypes.h>
      9 #include <wchar.h>
     10 #include <errno.h>
     11 
     12 #include "internal.h"
     13 #include <stdio.h>
     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