fgetwc.c 930 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include "stdio_impl.h"
  2. #include <wchar.h>
  3. #include <errno.h>
  4. wint_t __fgetwc_unlocked(FILE *f)
  5. {
  6. mbstate_t st = { 0 };
  7. wchar_t wc;
  8. int c;
  9. unsigned char b;
  10. size_t l;
  11. f->mode |= f->mode+1;
  12. /* Convert character from buffer if possible */
  13. if (f->rpos < f->rend) {
  14. l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st);
  15. if (l+2 >= 2) {
  16. f->rpos += l + !l; /* l==0 means 1 byte, null */
  17. return wc;
  18. }
  19. if (l == -1) {
  20. f->rpos++;
  21. return WEOF;
  22. }
  23. } else l = -2;
  24. /* Convert character byte-by-byte */
  25. while (l == -2) {
  26. b = c = getc_unlocked(f);
  27. if (c < 0) {
  28. if (!mbsinit(&st)) errno = EILSEQ;
  29. return WEOF;
  30. }
  31. l = mbrtowc(&wc, (void *)&b, 1, &st);
  32. if (l == -1) return WEOF;
  33. }
  34. return wc;
  35. }
  36. wint_t fgetwc(FILE *f)
  37. {
  38. wint_t c;
  39. FLOCK(f);
  40. c = __fgetwc_unlocked(f);
  41. FUNLOCK(f);
  42. return c;
  43. }
  44. weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
  45. weak_alias(__fgetwc_unlocked, getwc_unlocked);