summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/vfscanf.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2002-10-16 14:07:08 +0000
committertjr <tjr@FreeBSD.org>2002-10-16 14:07:08 +0000
commit0d7bae16975de150978751d3ebe3eda458364592 (patch)
treee8ad528cf5b36f65939b1619b0d58b367c1bfa15 /lib/libc/stdio/vfscanf.c
parent9bd570eeceb0fc4aedc55b199a91399644941f9b (diff)
downloadFreeBSD-src-0d7bae16975de150978751d3ebe3eda458364592.zip
FreeBSD-src-0d7bae16975de150978751d3ebe3eda458364592.tar.gz
Count field width correctly for suppressed multibyte fields (%*lc,
%*ls, %*l[).
Diffstat (limited to 'lib/libc/stdio/vfscanf.c')
-rw-r--r--lib/libc/stdio/vfscanf.c144
1 files changed, 84 insertions, 60 deletions
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index d825034..977bfc9 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -359,28 +359,11 @@ literal:
/* scan arbitrary characters (sets NOSKIP) */
if (width == 0)
width = 1;
- if (flags & SUPPRESS) {
- size_t sum = 0;
- for (;;) {
- if ((n = fp->_r) < width) {
- sum += n;
- width -= n;
- fp->_p += n;
- if (__srefill(fp)) {
- if (sum == 0)
- goto input_failure;
- break;
- }
- } else {
- sum += width;
- fp->_r -= width;
- fp->_p += width;
- break;
- }
- }
- nread += sum;
- } else if (flags & LONG) {
- wcp = va_arg(ap, wchar_t *);
+ if (flags & LONG) {
+ if ((flags & SUPPRESS) == 0)
+ wcp = va_arg(ap, wchar_t *);
+ else
+ wcp = NULL;
n = 0;
while (width != 0) {
if (n == MB_CUR_MAX) {
@@ -396,12 +379,13 @@ literal:
fp->_flags |= __SERR;
goto input_failure;
}
- if (nconv == 0)
+ if (nconv == 0 && wcp != NULL)
*wcp = L'\0';
if (nconv != (size_t)-2) {
nread += n;
width--;
- wcp++;
+ if (wcp != NULL)
+ wcp++;
n = 0;
}
if (fp->_r <= 0 && __srefill(fp)) {
@@ -412,7 +396,28 @@ literal:
break;
}
}
- nassigned++;
+ if (wcp != NULL)
+ nassigned++;
+ } else if (flags & SUPPRESS) {
+ size_t sum = 0;
+ for (;;) {
+ if ((n = fp->_r) < width) {
+ sum += n;
+ width -= n;
+ fp->_p += n;
+ if (__srefill(fp)) {
+ if (sum == 0)
+ goto input_failure;
+ break;
+ }
+ } else {
+ sum += width;
+ fp->_r -= width;
+ fp->_p += width;
+ break;
+ }
+ }
+ nread += sum;
} else {
size_t r = fread((void *)va_arg(ap, char *), 1,
width, fp);
@@ -430,23 +435,16 @@ literal:
if (width == 0)
width = (size_t)~0; /* `infinity' */
/* take only those things in the class */
- if (flags & SUPPRESS) {
- n = 0;
- while (ccltab[*fp->_p]) {
- n++, fp->_r--, fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp)) {
- if (n == 0)
- goto input_failure;
- break;
- }
- }
- if (n == 0)
- goto match_failure;
- } else if (flags & LONG) {
- wcp = wcp0 = va_arg(ap, wchar_t *);
+ if (flags & LONG) {
+ wchar_t twc;
+ int nchars;
+
+ if ((flags & SUPPRESS) == 0)
+ wcp = wcp0 = va_arg(ap, wchar_t *);
+ else
+ wcp = wcp0 = &twc;
n = 0;
+ nchars = 0;
while (width != 0) {
if (n == MB_CUR_MAX) {
fp->_flags |= __SERR;
@@ -473,7 +471,9 @@ literal:
}
nread += n;
width--;
- wcp++;
+ if (wcp != &twc)
+ wcp++;
+ nchars++;
n = 0;
}
if (fp->_r <= 0 && __srefill(fp)) {
@@ -488,11 +488,27 @@ literal:
fp->_flags |= __SERR;
goto input_failure;
}
- n = wcp - wcp0;
+ n = nchars;
+ if (n == 0)
+ goto match_failure;
+ if (wcp != &twc) {
+ *wcp = L'\0';
+ nassigned++;
+ }
+ } else if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[*fp->_p]) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n == 0)
+ goto input_failure;
+ break;
+ }
+ }
if (n == 0)
goto match_failure;
- *wcp = L'\0';
- nassigned++;
} else {
p0 = p = va_arg(ap, char *);
while (ccltab[*fp->_p]) {
@@ -520,18 +536,13 @@ literal:
/* like CCL, but zero-length string OK, & no NOSKIP */
if (width == 0)
width = (size_t)~0;
- if (flags & SUPPRESS) {
- n = 0;
- while (!isspace(*fp->_p)) {
- n++, fp->_r--, fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp))
- break;
- }
- nread += n;
- } else if (flags & LONG) {
- wcp = va_arg(ap, wchar_t *);
+ if (flags & LONG) {
+ wchar_t twc;
+
+ if ((flags & SUPPRESS) == 0)
+ wcp = va_arg(ap, wchar_t *);
+ else
+ wcp = &twc;
n = 0;
while (!isspace(*fp->_p) && width != 0) {
if (n == MB_CUR_MAX) {
@@ -558,7 +569,8 @@ literal:
}
nread += n;
width--;
- wcp++;
+ if (wcp != &twc)
+ wcp++;
n = 0;
}
if (fp->_r <= 0 && __srefill(fp)) {
@@ -569,8 +581,20 @@ literal:
break;
}
}
- *wcp = L'\0';
- nassigned++;
+ if (wcp != &twc) {
+ *wcp = L'\0';
+ nassigned++;
+ }
+ } else if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace(*fp->_p)) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ nread += n;
} else {
p0 = p = va_arg(ap, char *);
while (!isspace(*fp->_p)) {
OpenPOWER on IntegriCloud