github.com/afumu/libc@v0.0.6/musl/src/multibyte/mbtowc.c (about)

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