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