mbrtowc.c 953 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #include <stdlib.h>
  2. #include <wchar.h>
  3. #include <errno.h>
  4. #include "internal.h"
  5. size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)
  6. {
  7. static unsigned internal_state;
  8. unsigned c;
  9. const unsigned char *s = (const void *)src;
  10. const unsigned N = n;
  11. wchar_t dummy;
  12. if (!st) st = (void *)&internal_state;
  13. c = *(unsigned *)st;
  14. if (!s) {
  15. if (c) goto ilseq;
  16. return 0;
  17. } else if (!wc) wc = &dummy;
  18. if (!n) return -2;
  19. if (!c) {
  20. if (*s < 0x80) return !!(*wc = *s);
  21. if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
  22. if (*s-SA > SB-SA) goto ilseq;
  23. c = bittab[*s++-SA]; n--;
  24. }
  25. if (n) {
  26. if (OOB(c,*s)) goto ilseq;
  27. loop:
  28. c = c<<6 | *s++-0x80; n--;
  29. if (!(c&(1U<<31))) {
  30. *(unsigned *)st = 0;
  31. *wc = c;
  32. return N-n;
  33. }
  34. if (n) {
  35. if (*s-0x80u >= 0x40) goto ilseq;
  36. goto loop;
  37. }
  38. }
  39. *(unsigned *)st = c;
  40. return -2;
  41. ilseq:
  42. *(unsigned *)st = 0;
  43. errno = EILSEQ;
  44. return -1;
  45. }