summaryrefslogtreecommitdiff
path: root/libc/stdio/scanf.c
diff options
context:
space:
mode:
authorDavid McCullough <davidm@snapgear.com>2001-08-09 13:44:22 +0000
committerDavid McCullough <davidm@snapgear.com>2001-08-09 13:44:22 +0000
commit71183378185d6305c2d6b5bf689be8441b1e88b3 (patch)
tree83b62e575f0569292d809339e057b6b0d46bb032 /libc/stdio/scanf.c
parente7ba98d1c71ff06b015e3acc40dd44289878a17a (diff)
Add in changes from philipc@lineo:
Fix three bugs and bring into line with glibc: 1. The first character read using getc() was being ignored if it was EOF. Normally this is okay because the next getc() returns EOF as well, but for sscanf, this was causing us to skip the null terminator and start scanning whatever happened to be next in memory. 2. %s, %c, and %[ formats now return -1 if EOF is reached before any characters are read, instead of 0. This was causing an infinite loop in diald. 3. Default to base 10 for %i fields if not prefix modifier present.
Diffstat (limited to 'libc/stdio/scanf.c')
-rw-r--r--libc/stdio/scanf.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
index dbb92392c..0b9e8007c 100644
--- a/libc/stdio/scanf.c
+++ b/libc/stdio/scanf.c
@@ -180,9 +180,6 @@ static void init_scan_cookie(struct scan_cookie *sc, FILE *fp)
sc->nread = 0;
sc->width_flag = 0;
sc->ungot_flag = 0;
- if ((sc->ungot_char = getc(fp)) > 0) { /* not EOF or EOS */
- sc->ungot_flag = 1;
- }
}
static int scan_getc_nw(struct scan_cookie *sc)
@@ -367,24 +364,27 @@ va_list ap;
} else {
b = buf;
}
- i = 0;
cc = scan_getc(&sc);
+ if (cc <= 0) {
+ scan_ungetc(&sc);
+ goto done; /* return EOF if cnt == 0 */
+ }
+ i = 0;
while ((cc>0) && (scanset[cc] != invert)) {
- i = store; /* yes, we stored something */
+ i = 1; /* yes, we stored something */
*b = cc;
b += store;
cc = scan_getc(&sc);
}
+ if (i==0) {
+ scan_ungetc(&sc);
+ goto done; /* return cnt */
+ }
if (*p != 'c') { /* nul-terminate the stored string */
*b = 0;
- cnt += i;
- goto nextfmt;
- } else if (sc.width < 0) { /* case 'c' */
- cnt += store;
- goto nextfmt;
}
- scan_ungetc(&sc);
- goto done;
+ cnt += store;
+ goto nextfmt;
}
if (p-spec < 12) { /* o,u,p,x,X,i,d - (un)signed integer */
if (*p == 'p') {
@@ -418,6 +418,9 @@ va_list ap;
}
}
}
+ if (base == 0) { /* Default to base 10 */
+ base = 10;
+ }
/* At this point, we're ready to start reading digits. */
if (cc == '0') {
*b++ = cc; /* Store first leading 0 */