mbtowc.c raw

   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  }
  48