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.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index 22ed5a0..54cf776 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -35,7 +35,11 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
+#endif
+static const char rcsid[] =
+ "$Id: vfscanf.c,v 1.7 1997/02/22 15:02:41 peter Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -46,6 +50,9 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
#else
#include <varargs.h>
#endif
+#include <string.h>
+
+#include "collate.h"
#include "local.h"
#define FLOATING_POINT
@@ -89,11 +96,12 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
#define u_char unsigned char
#define u_long unsigned long
-static u_char *__sccl();
+static u_char *__sccl(char *, u_char *);
/*
* vfscanf
*/
+int
__svfscanf(fp, fmt0, ap)
register FILE *fp;
char const *fmt0;
@@ -107,6 +115,7 @@ __svfscanf(fp, fmt0, ap)
register int flags; /* flags as defined above */
register char *p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
+ int nconversions; /* number of conversions */
int nread; /* number of characters consumed from fp */
int base; /* base argument to strtol/strtoul */
u_long (*ccfn)(); /* conversion function (strtol/strtoul) */
@@ -118,6 +127,7 @@ __svfscanf(fp, fmt0, ap)
{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
nassigned = 0;
+ nconversions = 0;
nread = 0;
base = 0; /* XXX just to keep gcc happy */
ccfn = NULL; /* XXX just to keep gcc happy */
@@ -128,7 +138,7 @@ __svfscanf(fp, fmt0, ap)
if (isspace(c)) {
for (;;) {
if (fp->_r <= 0 && __srefill(fp))
- return (nassigned);
+ goto input_failure;
if (!isspace(*fp->_p))
break;
nread++, fp->_r--, fp->_p++;
@@ -253,6 +263,7 @@ literal:
break;
case 'n':
+ nconversions++;
if (flags & SUPPRESS) /* ??? */
continue;
if (flags & SHORT)
@@ -341,12 +352,13 @@ literal:
nread += r;
nassigned++;
}
+ nconversions++;
break;
case CT_CCL:
/* scan a (nonempty) character class (sets NOSKIP) */
if (width == 0)
- width = ~0; /* `infinity' */
+ width = (size_t)~0; /* `infinity' */
/* take only those things in the class */
if (flags & SUPPRESS) {
n = 0;
@@ -382,12 +394,13 @@ literal:
nassigned++;
}
nread += n;
+ nconversions++;
break;
case CT_STRING:
/* like CCL, but zero-length string OK, & no NOSKIP */
if (width == 0)
- width = ~0;
+ width = (size_t)~0;
if (flags & SUPPRESS) {
n = 0;
while (!isspace(*fp->_p)) {
@@ -412,6 +425,7 @@ literal:
nread += p - p0;
nassigned++;
}
+ nconversions++;
continue;
case CT_INT:
@@ -548,6 +562,7 @@ literal:
nassigned++;
}
nread += p - buf;
+ nconversions++;
break;
#ifdef FLOATING_POINT
@@ -639,12 +654,13 @@ literal:
nassigned++;
}
nread += p - buf;
+ nconversions++;
break;
#endif /* FLOATING_POINT */
}
}
input_failure:
- return (nassigned ? nassigned : -1);
+ return (nconversions != 0 ? nassigned : EOF);
match_failure:
return (nassigned);
}
@@ -660,7 +676,7 @@ __sccl(tab, fmt)
register char *tab;
register u_char *fmt;
{
- register int c, n, v;
+ register int c, n, v, i;
/* first `clear' the whole table */
c = *fmt++; /* first char hat => negated scanset */
@@ -669,9 +685,10 @@ __sccl(tab, fmt)
c = *fmt++; /* get new first char */
} else
v = 0; /* default => reject */
- /* should probably use memset here */
- for (n = 0; n < 256; n++)
- tab[n] = v;
+
+ /* XXX: Will not work if sizeof(tab*) > sizeof(char) */
+ (void) memset(tab, v, 256);
+
if (c == 0)
return (fmt - 1);/* format ended before closing ] */
@@ -712,15 +729,19 @@ doswitch:
* we just stored in the table (c).
*/
n = *fmt;
- if (n == ']' || n < c) {
+ if (n == ']' || __collate_range_cmp (n, c) < 0) {
c = '-';
break; /* resume the for(;;) */
}
fmt++;
- do { /* fill in the range */
- tab[++c] = v;
- } while (c < n);
+ /* fill in the range */
+ for (i = 0; i < 256; i ++)
+ if ( __collate_range_cmp (c, i) < 0
+ && __collate_range_cmp (i, n) <= 0
+ )
+ tab[i] = v;
#if 1 /* XXX another disgusting compatibility hack */
+ c = n;
/*
* Alas, the V7 Unix scanf also treats formats
* such as [a-c-e] as `the letters a through e'.
OpenPOWER on IntegriCloud