X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fstdio%2Ffgetwc.c;h=aa10b818566a8f1d19af680a9d00458d101572fa;hb=0847902ab99065a48f9bd3729b6e676288dfd69e;hp=c990545f85b73690544b8e6d061833e23493e9b6;hpb=0b44a0315b47dd8eced9f3b7f31580cf14bbfc01;p=musl diff --git a/src/stdio/fgetwc.c b/src/stdio/fgetwc.c index c990545f..aa10b818 100644 --- a/src/stdio/fgetwc.c +++ b/src/stdio/fgetwc.c @@ -1,40 +1,57 @@ #include "stdio_impl.h" +#include "locale_impl.h" +#include +#include -wint_t __fgetwc_unlocked(FILE *f) +static wint_t __fgetwc_unlocked_internal(FILE *f) { - mbstate_t st = { 0 }; wchar_t wc; int c; - unsigned char b; size_t l; - f->mode |= f->mode+1; - /* Convert character from buffer if possible */ - if (f->rpos < f->rend) { - l = mbrtowc(&wc, f->rpos, f->rend - f->rpos, &st); - if (l+2 >= 2) { + if (f->rpos != f->rend) { + l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos); + if (l+1 >= 1) { f->rpos += l + !l; /* l==0 means 1 byte, null */ return wc; } - if (l == -1) { - f->rpos++; - return WEOF; - } - } else l = -2; + } - /* Convert character byte-by-byte from __uflow */ - while (l == -2) { - b = c = __uflow(f); + /* Convert character byte-by-byte */ + mbstate_t st = { 0 }; + unsigned char b; + int first = 1; + do { + b = c = getc_unlocked(f); if (c < 0) { - if (!mbsinit(&st)) errno = EILSEQ; + if (!first) { + f->flags |= F_ERR; + errno = EILSEQ; + } return WEOF; } - l = mbrtowc(&wc, &b, 1, &st); - if (l == -1) return WEOF; - } + l = mbrtowc(&wc, (void *)&b, 1, &st); + if (l == -1) { + if (!first) { + f->flags |= F_ERR; + ungetc(b, f); + } + return WEOF; + } + first = 0; + } while (l == -2); - FUNLOCK(f); + return wc; +} + +wint_t __fgetwc_unlocked(FILE *f) +{ + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; + if (f->mode <= 0) fwide(f, 1); + *ploc = f->locale; + wchar_t wc = __fgetwc_unlocked_internal(f); + *ploc = loc; return wc; }