author | Rich Felker <dalias@aerifal.cx> | 2017年11月20日 16:25:54 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2017年11月20日 16:25:54 -0500 |
commit | 4000b0107ddd7fe733fa31d4f078c6fcd35851d6 (patch) | |
tree | ed33813b0dbc943915c1a6f0458075e1742b6fd3 /src/stdio/fgetwc.c | |
parent | a90d9da1d1b14d81c4f93e1a6d1a686c3312e4ba (diff) | |
download | musl-4000b0107ddd7fe733fa31d4f078c6fcd35851d6.tar.gz |
-rw-r--r-- | src/stdio/fgetwc.c | 28 |
diff --git a/src/stdio/fgetwc.c b/src/stdio/fgetwc.c index a00c1a86..07fb6d7c 100644 --- a/src/stdio/fgetwc.c +++ b/src/stdio/fgetwc.c @@ -5,36 +5,36 @@ static wint_t __fgetwc_unlocked_internal(FILE *f) { - mbstate_t st = { 0 }; wchar_t wc; int c; - unsigned char b; size_t l; /* Convert character from buffer if possible */ if (f->rpos < f->rend) { - l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st); - if (l+2 >= 2) { + 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; - } - f->rpos = f->rend; - } else l = -2; + } /* Convert character byte-by-byte */ - while (l == -2) { + 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) errno = EILSEQ; return WEOF; } l = mbrtowc(&wc, (void *)&b, 1, &st); - if (l == -1) return WEOF; - } + if (l == -1) { + if (!first) ungetc(b, f); + return WEOF; + } + first = 0; + } while (l == -2); return wc; } |