diff options
| author | Manuel Novoa III <mjn3@codepoet.org> | 2003-08-18 21:15:55 +0000 | 
|---|---|---|
| committer | Manuel Novoa III <mjn3@codepoet.org> | 2003-08-18 21:15:55 +0000 | 
| commit | e38addad3ed68c47c486f7e38c09369b685b9ce1 (patch) | |
| tree | 61132f68b03e127f99f80a5797a51a791df7638c | |
| parent | 30792221a919ccbdf3e214496451761ae20ec199 (diff) | |
scanf %lc,%ls,%l[ would always set mb_fail on eof or error,
  even when just starting a new mb char.
wscanf would incorrectly unget in certain situations.
| -rw-r--r-- | libc/stdio/scanf.c | 30 | 
1 files changed, 22 insertions, 8 deletions
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c index 48e9344c0..11deea38c 100644 --- a/libc/stdio/scanf.c +++ b/libc/stdio/scanf.c @@ -20,6 +20,11 @@   * Also now optionally supports hexadecimal float notation, positional   * args, and glibc locale-specific digit grouping.  Should now be   * standards compliant. + * + * Aug 18, 2003 + * Bug fix: scanf %lc,%ls,%l[ would always set mb_fail on eof or error, + *   even when just starting a new mb char. + * Bug fix: wscanf would incorrectly unget in certain situations.   */ @@ -829,7 +834,9 @@ static int scan_getwc(register struct scan_cookie *sc)  	width = sc->width;			/* Preserve width. */  	sc->width = INT_MAX;		/* MB_CUR_MAX can invoke a function. */ -	r = (size_t)(-1); +	assert(!sc->mb_fail); + +	r = (size_t)(-3);  	while (__scan_getc(sc) >= 0) {  		*b = sc->cc; @@ -844,12 +851,17 @@ static int scan_getwc(register struct scan_cookie *sc)  		break;  	} -	/* If we reach here, either r == ((size_t)-1) and -	 * mbrtowc set errno to EILSEQ, or r == ((size_t)-2) -	 * and stream is in an error state or at EOF with a -	 * partially complete wchar. */ -	__set_errno(EILSEQ);		/* In case of incomplete conversion. */ -	sc->mb_fail = 1; +	if (r == ((size_t)(-3))) {	/* EOF or ERROR on first read */ +		sc->wc = WEOF; +		r = (size_t)(-1); +	} else { +		/* If we reach here, either r == ((size_t)-1) and +		 * mbrtowc set errno to EILSEQ, or r == ((size_t)-2) +		 * and stream is in an error state or at EOF with a +		 * partially complete wchar. */ +		__set_errno(EILSEQ);		/* In case of incomplete conversion. */ +		sc->mb_fail = 1; +	}   SUCCESS:  	sc->width = width;			/* Restore width. */ @@ -961,7 +973,9 @@ static __inline void kill_scan_cookie(register struct scan_cookie *sc)  #else -	if ((sc->ungot_wflag & 1) && (sc->fp->filedes != -3) && (sc->fp->state.mask == 0)) { +	if ((sc->ungot_flag & 1) && (sc->ungot_wflag & 1) +		&& (sc->fp->filedes != -3) && (sc->fp->state.mask == 0) +		) {  		ungetwc(sc->ungot_char, sc->fp);  		/* Deal with distiction between user and scanf ungots. */  		if (sc->nread == 0) {	/* Only one char was read... app ungot? */  | 
