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