summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/vfscanf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdio/vfscanf.c')
-rw-r--r--lib/libc/stdio/vfscanf.c200
1 files changed, 60 insertions, 140 deletions
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index 6a6b19c..4fe40e3 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -127,9 +127,8 @@ static const mbstate_t initial_mbs;
static __inline int
convert_char(FILE *fp, char * __restrict p, int width)
{
- int n, nread;
+ int n;
- nread = 0;
if (p == SUPPRESS_PTR) {
size_t sum = 0;
for (;;) {
@@ -149,59 +148,34 @@ convert_char(FILE *fp, char * __restrict p, int width)
break;
}
}
- nread += sum;
+ return (sum);
} else {
size_t r = __fread(p, 1, width, fp);
if (r == 0)
return (-1);
- nread += r;
+ return (r);
}
- return (nread);
}
static __inline int
-convert_wchar(FILE *fp, wchar_t *wcp, int width)
+convert_wchar(FILE *fp, wchar_t *wcp, int width, locale_t locale)
{
mbstate_t mbs;
- size_t nconv;
int n, nread;
- char buf[MB_CUR_MAX];
+ wint_t wi;
- nread = 0;
+ mbs = initial_mbs;
n = 0;
- while (width != 0) {
- if (n == MB_CUR_MAX) {
- fp->_flags |= __SERR;
- return (-1);
- }
- buf[n++] = *fp->_p;
- fp->_p++;
- fp->_r--;
- mbs = initial_mbs;
- nconv = mbrtowc(wcp, buf, n, &mbs);
- if (nconv == (size_t)-1) {
- fp->_flags |= __SERR;
- return (-1);
- }
- if (nconv == 0 && wcp != SUPPRESS_PTR)
- *wcp = L'\0';
- if (nconv != (size_t)-2) {
- nread += n;
- width--;
- if (wcp != SUPPRESS_PTR)
- wcp++;
- n = 0;
- }
- if (fp->_r <= 0 && __srefill(fp)) {
- if (n != 0) {
- fp->_flags |= __SERR;
- return (-1);
- }
- break;
- }
+ while (width-- != 0 &&
+ (wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF) {
+ if (wcp != SUPPRESS_PTR)
+ *wcp++ = (wchar_t)wi;
+ n += nread;
}
- return (nread);
+ if (n == 0)
+ return (-1);
+ return (n);
}
static __inline int
@@ -244,63 +218,34 @@ convert_ccl(FILE *fp, char * __restrict p, int width, const char *ccltab)
}
static __inline int
-convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab)
+convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab,
+ locale_t locale)
{
mbstate_t mbs;
- wchar_t twc;
- int n, nchars, nconv;
- char buf[MB_CUR_MAX];
+ wint_t wi;
+ int n, nread;
- if (wcp == SUPPRESS_PTR)
- wcp = &twc;
+ mbs = initial_mbs;
n = 0;
- nchars = 0;
- while (width != 0) {
- if (n == MB_CUR_MAX) {
- fp->_flags |= __SERR;
- return (-1);
- }
- buf[n++] = *fp->_p;
- fp->_p++;
- fp->_r--;
- mbs = initial_mbs;
- nconv = mbrtowc(wcp, buf, n, &mbs);
- if (nconv == (size_t)-1) {
- fp->_flags |= __SERR;
- return (-1);
- }
- if (nconv == 0)
- *wcp = L'\0';
- if (nconv != (size_t)-2) {
- if (wctob(*wcp) != EOF && !ccltab[wctob(*wcp)]) {
- while (n != 0) {
- n--;
- __ungetc(buf[n], fp);
- }
- break;
- }
- width--;
- if (wcp != &twc)
- wcp++;
- nchars++;
- n = 0;
- }
- if (fp->_r <= 0 && __srefill(fp)) {
- if (n != 0) {
- fp->_flags |= __SERR;
- return (-1);
- }
- break;
+ if (wcp == SUPPRESS_PTR) {
+ while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF &&
+ width-- != 0 && ccltab[wctob(wi)])
+ n += nread;
+ if (wi != WEOF)
+ __ungetwc(wi, fp, __get_locale());
+ } else {
+ while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF &&
+ width-- != 0 && ccltab[wctob(wi)]) {
+ *wcp++ = (wchar_t)wi;
+ n += nread;
}
+ if (wi != WEOF)
+ __ungetwc(wi, fp, __get_locale());
+ if (n == 0)
+ return (0);
+ *wcp = 0;
}
- if (n != 0) {
- fp->_flags |= __SERR;
- return (-1);
- }
- if (nchars == 0)
- return (0);
- *wcp = L'\0';
- return (nchars);
+ return (n);
}
static __inline int
@@ -335,56 +280,31 @@ convert_string(FILE *fp, char * __restrict p, int width)
}
static __inline int
-convert_wstring(FILE *fp, wchar_t *wcp, int width)
+convert_wstring(FILE *fp, wchar_t *wcp, int width, locale_t locale)
{
mbstate_t mbs;
- wchar_t twc;
- int n, nconv, nread;
- char buf[MB_CUR_MAX];
-
- if (wcp == SUPPRESS_PTR)
- wcp = &twc;
- n = nread = 0;
- while (!isspace(*fp->_p) && width != 0) {
- if (n == MB_CUR_MAX) {
- fp->_flags |= __SERR;
- return (-1);
- }
- buf[n++] = *fp->_p;
- fp->_p++;
- fp->_r--;
- mbs = initial_mbs;
- nconv = mbrtowc(wcp, buf, n, &mbs);
- if (nconv == (size_t)-1) {
- fp->_flags |= __SERR;
- return (-1);
- }
- if (nconv == 0)
- *wcp = L'\0';
- if (nconv != (size_t)-2) {
- if (iswspace(*wcp)) {
- while (n != 0) {
- n--;
- __ungetc(buf[n], fp);
- }
- break;
- }
- nread += n;
- width--;
- if (wcp != &twc)
- wcp++;
- n = 0;
- }
- if (fp->_r <= 0 && __srefill(fp)) {
- if (n != 0) {
- fp->_flags |= __SERR;
- return (-1);
- }
- break;
+ wint_t wi;
+ int n, nread;
+
+ mbs = initial_mbs;
+ n = 0;
+ if (wcp == SUPPRESS_PTR) {
+ while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF &&
+ width-- != 0 && !iswspace(wi))
+ n += nread;
+ if (wi != WEOF)
+ __ungetwc(wi, fp, __get_locale());
+ } else {
+ while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF &&
+ width-- != 0 && !iswspace(wi)) {
+ *wcp++ = (wchar_t)wi;
+ n += nread;
}
+ if (wi != WEOF)
+ __ungetwc(wi, fp, __get_locale());
+ *wcp = '\0';
}
- *wcp = L'\0';
- return (nread);
+ return (n);
}
/*
@@ -766,7 +686,7 @@ literal:
width = 1;
if (flags & LONG) {
nr = convert_wchar(fp, GETARG(wchar_t *),
- width);
+ width, locale);
} else {
nr = convert_char(fp, GETARG(char *), width);
}
@@ -780,7 +700,7 @@ literal:
width = (size_t)~0; /* `infinity' */
if (flags & LONG) {
nr = convert_wccl(fp, GETARG(wchar_t *), width,
- ccltab);
+ ccltab, locale);
} else {
nr = convert_ccl(fp, GETARG(char *), width,
ccltab);
@@ -799,7 +719,7 @@ literal:
width = (size_t)~0;
if (flags & LONG) {
nr = convert_wstring(fp, GETARG(wchar_t *),
- width);
+ width, locale);
} else {
nr = convert_string(fp, GETARG(char *), width);
}
OpenPOWER on IntegriCloud