fgetwc.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include "stdio_impl.h"
  2. #include "locale_impl.h"
  3. #include <wchar.h>
  4. #include <errno.h>
  5. static wint_t __fgetwc_unlocked_internal(FILE *f)
  6. {
  7. wchar_t wc;
  8. int c;
  9. size_t l;
  10. /* Convert character from buffer if possible */
  11. if (f->rpos != f->rend) {
  12. l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos);
  13. if (l+1 >= 1) {
  14. f->rpos += l + !l; /* l==0 means 1 byte, null */
  15. return wc;
  16. }
  17. }
  18. /* Convert character byte-by-byte */
  19. mbstate_t st = { 0 };
  20. unsigned char b;
  21. int first = 1;
  22. do {
  23. b = c = getc_unlocked(f);
  24. if (c < 0) {
  25. if (!first) {
  26. f->flags |= F_ERR;
  27. errno = EILSEQ;
  28. }
  29. return WEOF;
  30. }
  31. l = mbrtowc(&wc, (void *)&b, 1, &st);
  32. if (l == -1) {
  33. if (!first) {
  34. f->flags |= F_ERR;
  35. ungetc(b, f);
  36. }
  37. return WEOF;
  38. }
  39. first = 0;
  40. } while (l == -2);
  41. return wc;
  42. }
  43. wint_t __fgetwc_unlocked(FILE *f)
  44. {
  45. locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
  46. if (f->mode <= 0) fwide(f, 1);
  47. *ploc = f->locale;
  48. wchar_t wc = __fgetwc_unlocked_internal(f);
  49. *ploc = loc;
  50. return wc;
  51. }
  52. wint_t fgetwc(FILE *f)
  53. {
  54. wint_t c;
  55. FLOCK(f);
  56. c = __fgetwc_unlocked(f);
  57. FUNLOCK(f);
  58. return c;
  59. }
  60. weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
  61. weak_alias(__fgetwc_unlocked, getwc_unlocked);