diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/stdio/Makefile | 4 | ||||
| -rw-r--r-- | libc/stdio/old_vfprintf.c | 232 | ||||
| -rw-r--r-- | libc/stdio/printf.c | 96 | ||||
| -rw-r--r-- | libc/stdio/scanf.c | 96 | 
4 files changed, 358 insertions, 70 deletions
diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 44ce51848..b92eed2a1 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -50,7 +50,7 @@ MOBJ = fclose.o fflush.o fopen.o freopen.o perror.o remove.o \  MSRC2= printf.c  MOBJ2=  vsnprintf.o vdprintf.o vasprintf.o vprintf.o vsprintf.o \  	fprintf.o  snprintf.o  dprintf.o  asprintf.o  printf.o  sprintf.o \ -	_store_inttype.o +	_store_inttype.o _load_inttype.o  MSRC3=scanf.c  MOBJ3=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o \ @@ -65,7 +65,7 @@ endif  ifneq ($(USE_OLD_VFPRINTF),y)  	MOBJ2 += _ppfs_init.o _ppfs_prepargs.o _ppfs_setargs.o \ -		 _ppfs_parsespec.o vfprintf.o _load_inttype.o \ +		 _ppfs_parsespec.o vfprintf.o \  		 register_printf_function.o parse_printf_format.o  endif diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c index ecec63c9f..5afbefb07 100644 --- a/libc/stdio/old_vfprintf.c +++ b/libc/stdio/old_vfprintf.c @@ -85,6 +85,8 @@   *   * Sep 5, 2003   *    Convert to new floating point conversion routine. + *    Fix qualifier handling on integer and %n conversions. + *    Add support for vsnprintf when in non-buffered/no-wchar configuration.   *   */ @@ -125,11 +127,13 @@  /**************************************************************************/ +#define _ISOC99_SOURCE			/* for ULLONG primarily... */  #define _GNU_SOURCE				/* for strnlen */  #define _STDIO_UTILITY  #include <stdio.h>  #include <stdarg.h>  #include <limits.h> +#include <stdint.h>  #include <string.h>  #include <errno.h>  #include <ctype.h> @@ -153,7 +157,60 @@  #define WANT_GNU_ERRNO         0  #endif -#if defined(__UCLIBC_HAS_FLOATS__) +#undef PUTC +#undef OUTNSTR +#undef _outnstr + +#ifdef __STDIO_BUFFERS + +#define PUTC(C,F)      putc_unlocked((C),(F)) +#define OUTNSTR        _outnstr +#define _outnstr(stream, string, len)	_stdio_fwrite(string, len, stream) + +#else  /* __STDIO_BUFFERS */ + +typedef struct { +	FILE f; +	unsigned char *bufend;		/* pointer to 1 past end of buffer */ +	unsigned char *bufpos; +} __FILE_vsnprintf; + +#ifdef __UCLIBC_HAS_FLOATS__ +static void _outnstr(FILE *stream, const unsigned char *s, size_t n) +{ +	__FILE_vsnprintf *f = (__FILE_vsnprintf *) stream; + +	if (f->f.filedes != -2) { +		_stdio_fwrite(s, n, &f->f); +	} else { +		if (f->bufend > f->bufpos) { +			size_t r = f->bufend - f->bufpos; +			if (r > n) { +				r = n; +			} +			memcpy(f->bufpos, s, r); +			f->bufpos += r; +		} +	} +} +#endif + +static void putc_unlocked_sprintf(int c, __FILE_vsnprintf *f) +{ +	if (f->f.filedes != -2) { +		putc_unlocked(c, &f->f); +	} else if (f->bufpos < f->bufend) { +		*f->bufpos++ = c; +	} +} + + +#define PUTC(C,F)      putc_unlocked_sprintf((C),(__FILE_vsnprintf *)(F)) +#define OUTNSTR        _outnstr + +#endif /* __STDIO_BUFFERS */ + +#ifdef __UCLIBC_HAS_FLOATS__  #include <float.h>  #include <bits/uClibc_fpmax.h> @@ -163,14 +220,10 @@ typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,  extern size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,  						  __fp_outfunc_t fp_outfunc); -#define FMT_TYPE char -#define OUTNSTR _outnstr -#define _outnstr(stream, string, len)	_stdio_fwrite(string, len, stream) -  static void _charpad(FILE * __restrict stream, int padchar, size_t numpad)  {  	/* TODO -- Use a buffer to cut down on function calls... */ -	FMT_TYPE pad[1]; +	char pad[1];  	*pad = padchar;  	while (numpad) { @@ -191,8 +244,6 @@ static void _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)  	OUTNSTR(fp, (const char *) buf, len);  } - -  #endif @@ -207,7 +258,69 @@ enum {  /* layout                   01234  */  static const char spec[] = "+-#0 "; -static const char qual[] = "hlLq"; +/**********************************************************************/ + +extern void _store_inttype(void *dest, int desttype, uintmax_t val); +extern uintmax_t _load_inttype(int desttype, const void *src, int uflag); + +/* + * In order to ease translation to what arginfo and _print_info._flags expect, + * we map:  0:int  1:char  2:longlong 4:long  8:short + * and then _flags |= (((q << 7) + q) & 0x701) and argtype |= (_flags & 0x701) + */ + +#ifdef PDS +#error PDS already defined! +#endif +#ifdef SS +#error SS already defined! +#endif +#ifdef IMS +#error IMS already defined! +#endif + +#if PTRDIFF_MAX == INT_MAX +#define PDS		0 +#elif PTRDIFF_MAX == LONG_MAX +#define PDS		4 +#elif defined(LLONG_MAX) && (PTRDIFF_MAX == LLONG_MAX) +#define PDS		8 +#else +#error fix QUAL_CHARS ptrdiff_t entry 't'! +#endif + +#if SIZE_MAX == UINT_MAX +#define SS		0 +#elif SIZE_MAX == ULONG_MAX +#define SS		4 +#elif defined(LLONG_MAX) && (SIZE_MAX == ULLONG_MAX) +#define SS		8 +#else +#error fix QUAL_CHARS size_t entries 'z', 'Z'! +#endif + +#if INTMAX_MAX == INT_MAX +#define IMS		0 +#elif INTMAX_MAX == LONG_MAX +#define IMS		4 +#elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX) +#define IMS		8 +#else +#error fix QUAL_CHARS intmax_t entry 'j'! +#endif + +#define QUAL_CHARS		{ \ +	/* j:(u)intmax_t z:(s)size_t  t:ptrdiff_t  \0:int */ \ +	/* q:long_long  Z:(s)size_t */ \ +	'h',   'l',  'L',  'j',  'z',  't',  'q', 'Z',  0, \ +	 2,     4,    8,  IMS,   SS,  PDS,    8,  SS,   0, /* TODO -- fix!!! */\ +     1,     8 \ +} + +static const char qual_chars[] = QUAL_CHARS; + +/* static const char qual[] = "hlLq"; */ +/**********************************************************************/  #if !defined(__UCLIBC_HAS_FLOATS__) && WANT_FLOAT_ERROR  static const char dbl_err[] = "<DOUBLE>"; @@ -228,7 +341,17 @@ static const char u_radix[] = "\x02\x08\x10\x10\x10\x0a";  int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  			 va_list ap)  { -	int i, cnt, lval, len; +	union { +#ifdef LLONG_MAX +		long long ll; +#endif +#if LONG_MAX != INT_MAX +		long l; +#endif +		int i; +	} intarg; +	int i, cnt, dataargtype, len; +	const void *argptr;			/* This does not need to be initialized. */  	register char *p;  	const char *fmt0;  	int preci, width; @@ -249,11 +372,6 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  			preci = -5;			/* max string width or mininum digits */  			radix = 10;			/* number base */  			dpoint = 0;			/* found decimal point */ -#if INT_MAX != LONG_MAX -			lval = 0;			/* sizeof(int) != sizeof(long) */ -#else -			lval = 1;			/* sizeof(int) == sizeof(long) */ -#endif  			/* init flags */  			for (p =(char *) spec ; *p ; p++) { @@ -305,16 +423,18 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  			} while ((*fmt == '.') && !dpoint );  			/* process optional qualifier */ -			for (p = (char *) qual ; *p ; p++) { -				if (*p == *fmt) { -					lval = p - qual; -					++fmt;		/* TODO - hh */ -					if ((*p == 'l') && (*fmt == *p)) { -						++lval; -						++fmt; -					} +			p = (char *) qual_chars; +			do { +				if (*fmt == *p) { +					++fmt; +					break;  				} +			} while (*++p); +			if ((p - qual_chars < 2) && (*fmt == *p)) { +				p += ((sizeof(qual_chars)-2) / 2); +				++fmt;  			} +			dataargtype = ((int)(p[(sizeof(qual_chars)-2) / 2])) << 8;  #if WANT_GNU_ERRNO  			if (*fmt == 'm') { @@ -332,23 +452,51 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  					goto charout;  				}  				if (p-u_spec < 2) {	/* store output count in int ptr */ -					*(va_arg(ap, int *)) = cnt; +					_store_inttype(va_arg(ap, void *), +								   dataargtype, +								   (intmax_t) (cnt));  					goto nextfmt;  				} + +				if (p-u_spec < 10) { +					if (*p == 'p') { +#if INTPTR_MAX == INT_MAX +						dataargtype = 0; +#else +#error Fix dataargtype for pointers! +#endif +					} + +					switch(dataargtype) { +						case (PA_INT|PA_FLAG_LONG_LONG): +#ifdef LLONG_MAX +							intarg.ll = va_arg(ap, long long); +							argptr = &intarg.ll; +							break; +#endif +						case (PA_INT|PA_FLAG_LONG): +#if LONG_MAX != INT_MAX +							intarg.l = va_arg(ap, long); +							argptr = &intarg.l; +							break; +#endif +						default: +							intarg.i = va_arg(ap, int); +							argptr = &intarg.i; +							break; +					} +				} +  				if (p-u_spec < 8) { /* unsigned conversion */  					radix = u_radix[p-u_spec-2];  					upcase = ((*p == 'x') ? __UIM_LOWER : __UIM_UPPER);  					if (*p == 'p') { -						lval = (sizeof(char *) == sizeof(long));  						upcase = __UIM_LOWER;  						flag[FLAG_HASH] = 'p';  					} - -					p = _uintmaxtostr((tmp + sizeof(tmp) - 1), -									  ((lval>1) /* TODO -- longlong/long/int/short/char */ -									   ? va_arg(ap, uintmax_t) -									   : (uintmax_t) -									   va_arg(ap, unsigned long)), +					p = _uintmaxtostr(tmp + sizeof(tmp) - 1, +									  (uintmax_t) +									  _load_inttype(dataargtype, argptr, radix),  									  radix, upcase);  					flag[FLAG_PLUS] = '\0';	/* meaningless for unsigned */ @@ -371,12 +519,9 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  						p = "(nil)";  					}  				} else if (p-u_spec < 10) { /* signed conversion */ - - 					p = _uintmaxtostr((tmp + sizeof(tmp) - 1), -									  ((lval>1) /* TODO -- longlong/long/int/short/char */ -									   ? va_arg(ap, uintmax_t) -									   : (uintmax_t) ((intmax_t) /* sign-extend! */ -													va_arg(ap, long))), +					p = _uintmaxtostr(tmp + sizeof(tmp) - 1, +									  (uintmax_t) +									  _load_inttype(dataargtype, argptr, -radix),  									  -radix, upcase);  				} else if (p-u_spec < 12) {	/* character or string */ @@ -425,12 +570,21 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  					if (flag[FLAG_MINUS_LJUSTIFY]) {  						PRINT_INFO_SET_FLAG(&info,left);  					} +#if 1 +					cnt += _fpmaxtostr(op,  +									   (__fpmax_t) +									   ((dataargtype == (8 << 8)) +										? va_arg(ap, long double) +										: (long double) va_arg(ap, double)), +									   &info, _fp_out_narrow); +#else  					cnt += _fpmaxtostr(op,   									   (__fpmax_t)  									   ((lval > 1)  										? va_arg(ap, long double)  										: (long double) va_arg(ap, double)),  									   &info, _fp_out_narrow); +#endif  					goto nextfmt;  #elif WANT_FLOAT_ERROR  					(void) ((lval > 1) ? va_arg(ap, long double) @@ -520,7 +674,7 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  							--len;  						}  						++cnt; -						putc(ch, op); +						PUTC(ch, op);  					}  				}  				goto nextfmt; @@ -531,7 +685,7 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,  	charout:  		++cnt; -		putc(*fmt, op);	/* normal char out */ +		PUTC(*fmt, op); /* normal char out */  	nextfmt:  		++fmt; diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index d7d23ddc0..1cc121212 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -72,6 +72,9 @@   *   * Aug 31, 2003   * Fix precision bug for %g conversion specifier when using %f style. + * + * Sep 5, 2003 + * Implement *s*scanf for the non-buffered stdio case with old_vfprintf.   */  /* TODO: @@ -145,6 +148,12 @@  #undef L__fpmaxtostr  #endif /* __STDIO_PRINTF_FLOAT */ + +#undef __STDIO_HAS_VSNPRINTF +#if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__STDIO_GLIBC_CUSTOM_STREAMS) +#define __STDIO_HAS_VSNPRINTF 1 +#endif +  /**********************************************************************/  /* Now controlled by uClibc_stdio.h. */ @@ -1190,6 +1199,7 @@ int register_printf_function(int spec, printf_function handler,  #endif /* __UCLIBC_MJN3_ONLY__ */  #ifdef __STDIO_BUFFERS +  int vsnprintf(char *__restrict buf, size_t size,  			  const char * __restrict format, va_list arg)  { @@ -1238,8 +1248,59 @@ int vsnprintf(char *__restrict buf, size_t size,  	}  	return rv;  } -#else  /* __STDIO_BUFFERS */ -#ifdef __STDIO_GLIBC_CUSTOM_STREAMS + +#elif defined(__USE_OLD_VFPRINTF__) + +typedef struct { +	FILE f; +	unsigned char *bufend;		/* pointer to 1 past end of buffer */ +	unsigned char *bufpos; +} __FILE_vsnprintf; + +int vsnprintf(char *__restrict buf, size_t size, +			  const char * __restrict format, va_list arg) +{ +	__FILE_vsnprintf f; +	int rv; + +	f.bufpos = buf; + +	if (size > SIZE_MAX - (size_t) buf) { +		size = SIZE_MAX - (size_t) buf; +	} +	f.bufend = buf + size; + +#if 0							/* shouldn't be necessary */ +/*  #ifdef __STDIO_GLIBC_CUSTOM_STREAMS */ +	f.f.cookie = &(f.f.filedes); +	f.f.gcs.read = 0; +	f.f.gcs.write = 0; +	f.f.gcs.seek = 0; +	f.f.gcs.close = 0; +#endif +	f.f.filedes = -2;				/* for debugging */ +	f.f.modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); + +#ifdef __STDIO_MBSTATE +	__INIT_MBSTATE(&(f.f.state)); +#endif /* __STDIO_MBSTATE */ + +#ifdef __STDIO_THREADSAFE +	f.f.user_locking = 0; +	__stdio_init_mutex(&f.f.lock); +#endif + +	rv = vfprintf((FILE *) &f, format, arg); +	if (size) { +		if (f.bufpos == f.bufend) { +			--f.bufpos; +		} +		*f.bufpos = 0; +	} +	return rv; +} + +#elif defined(__STDIO_GLIBC_CUSTOM_STREAMS)  typedef struct {  	size_t pos; @@ -1314,10 +1375,13 @@ int vsnprintf(char *__restrict buf, size_t size,  	return rv;  } -#else  /* __STDIO_GLIBC_CUSTOM_STREAMS */ -#warning Skipping vsnprintf since no buffering and no custom streams! -#endif /* __STDIO_GLIBC_CUSTOM_STREAMS */ -#endif /* __STDIO_BUFFERS */ +#else +#warning Skipping vsnprintf since no buffering, no custom streams, and not old vfprintf! +#ifdef __STDIO_HAS_VSNPRINTF +#error WHOA! __STDIO_HAS_VSNPRINTF is defined! +#endif +#endif +  #endif  /**********************************************************************/  #ifdef L_vdprintf @@ -1366,8 +1430,8 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)  /**********************************************************************/  #ifdef L_vasprintf -#if !defined(__STDIO_BUFFERS) && !defined(__STDIO_GLIBC_CUSTOM_STREAMS) -#warning Skipping vasprintf since no buffering and no custom streams! +#ifndef __STDIO_HAS_VSNPRINTF +#warning Skipping vasprintf since no vsnprintf!  #else  int vasprintf(char **__restrict buf, const char * __restrict format, @@ -1420,8 +1484,8 @@ int vprintf(const char * __restrict format, va_list arg)  /**********************************************************************/  #ifdef L_vsprintf -#if !defined(__STDIO_BUFFERS) && !defined(__STDIO_GLIBC_CUSTOM_STREAMS) -#warning Skipping vsprintf since no buffering and no custom streams! +#ifndef __STDIO_HAS_VSNPRINTF +#warning Skipping vsprintf since no vsnprintf!  #else  int vsprintf(char *__restrict buf, const char * __restrict format, @@ -1451,8 +1515,8 @@ int fprintf(FILE * __restrict stream, const char * __restrict format, ...)  /**********************************************************************/  #ifdef L_snprintf -#if !defined(__STDIO_BUFFERS) && !defined(__STDIO_GLIBC_CUSTOM_STREAMS) -#warning Skipping snprintf since no buffering and no custom streams! +#ifndef __STDIO_HAS_VSNPRINTF +#warning Skipping snprintf since no vsnprintf!  #else  int snprintf(char *__restrict buf, size_t size, @@ -1488,8 +1552,8 @@ int dprintf(int filedes, const char * __restrict format, ...)  /**********************************************************************/  #ifdef L_asprintf -#if !defined(__STDIO_BUFFERS) && !defined(__STDIO_GLIBC_CUSTOM_STREAMS) -#warning Skipping asprintf and __asprintf since no buffering and no custom streams! +#ifndef __STDIO_HAS_VSNPRINTF +#warning Skipping asprintf and __asprintf since no vsnprintf!  #else  weak_alias(__asprintf,asprintf) @@ -1525,8 +1589,8 @@ int printf(const char * __restrict format, ...)  /**********************************************************************/  #ifdef L_sprintf -#if !defined(__STDIO_BUFFERS) && !defined(__STDIO_GLIBC_CUSTOM_STREAMS) -#warning Skipping sprintf since no buffering and no custom streams! +#ifndef __STDIO_HAS_VSNPRINTF +#warning Skipping sprintf since no vsnprintf!  #else  int sprintf(char *__restrict buf, const char * __restrict format, ...) diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c index 11deea38c..9f811968a 100644 --- a/libc/stdio/scanf.c +++ b/libc/stdio/scanf.c @@ -25,6 +25,10 @@   * 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. + * + * Sep 5, 2003 + * Bug fix: store flag wasn't respected if no positional args. + * Implement vs{n}scanf for the non-buffered stdio no-wchar case.   */ @@ -72,6 +76,20 @@  #undef __UCLIBC_HAS_SCANF_GLIBC_A_FLAG__  #endif +#undef __STDIO_HAS_VSSCANF +#if defined(__STDIO_BUFFERS) || !defined(__UCLIBC_HAS_WCHAR__) || defined(__STDIO_GLIBC_CUSTOM_STREAMS) +#define __STDIO_HAS_VSSCANF 1 + +#if !defined(__STDIO_BUFFERS) && !defined(__UCLIBC_HAS_WCHAR__) +typedef struct { +	FILE f; +	unsigned char *bufread;		/* pointer to 1 past end of buffer */ +	unsigned char *bufpos; +} __FILE_vsscanf; +#endif + +#endif +  extern void _store_inttype(void *dest, int desttype, uintmax_t val);  #ifdef LLONG_MAX @@ -143,7 +161,7 @@ int scanf(const char * __restrict format, ...)  /**********************************************************************/  #ifdef L_sscanf -#if defined(__STDIO_BUFFERS) || defined(__STDIO_GLIBC_CUSTOM_STREAMS) +#ifdef __STDIO_HAS_VSSCANF  int sscanf(const char * __restrict str, const char * __restrict format, ...)  { @@ -157,9 +175,9 @@ int sscanf(const char * __restrict str, const char * __restrict format, ...)  	return rv;  } -#else  /* defined(__STDIO_BUFFERS) || defined(__STDIO_GLIBC_CUSTOM_STREAMS) */ -#warning Skipping sscanf since no buffering and no custom streams! -#endif /* defined(__STDIO_BUFFERS) || defined(__STDIO_GLIBC_CUSTOM_STREAMS) */ +#else  /* __STDIO_HAS_VSSCANF */ +#warning Skipping sscanf since no vsscanf! +#endif /* __STDIO_HAS_VSSCANF */  #endif  /**********************************************************************/ @@ -179,6 +197,7 @@ int vscanf(const char * __restrict format, va_list arg)  #endif /* __UCLIBC_MJN3_ONLY__ */  #ifdef __STDIO_BUFFERS +  int vsscanf(__const char *sp, __const char *fmt, va_list ap)  {  	FILE string[1]; @@ -202,8 +221,32 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)  	return vfscanf(string, fmt, ap);  } -#else  /* __STDIO_BUFFERS */ -#ifdef __STDIO_GLIBC_CUSTOM_STREAMS + +#elif !defined(__UCLIBC_HAS_WCHAR__) + +int vsscanf(__const char *sp, __const char *fmt, va_list ap) +{ +	__FILE_vsscanf string[1]; + +	string->f.filedes = -2; +	string->f.modeflags = (__FLAG_NARROW|__FLAG_READONLY); +	string->bufpos = (unsigned char *) ((void *) sp); +	string->bufread = string->bufpos + strlen(sp); + +#ifdef __STDIO_MBSTATE +#error __STDIO_MBSTATE is defined! +#endif /* __STDIO_MBSTATE */ + +#ifdef __STDIO_THREADSAFE +	string->user_locking = 0; +	__stdio_init_mutex(&string->f.lock); +#endif + +	return vfscanf(&string->f, fmt, ap); +} + +#elif defined(__STDIO_GLIBC_CUSTOM_STREAMS) +  int vsscanf(__const char *sp, __const char *fmt, va_list ap)  {  	FILE *f; @@ -217,10 +260,13 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)  	return rv;  } -#else  /* __STDIO_GLIBC_CUSTOM_STREAMS */ -#warning Skipping vsscanf since no buffering and no custom streams! -#endif /* __STDIO_GLIBC_CUSTOM_STREAMS */ -#endif /* __STDIO_BUFFERS */ + +#else +#warning Skipping vsscanf since no buffering, no custom streams, and wchar enabled! +#ifdef __STDIO_HAS_VSSCANF +#error WHOA! __STDIO_HAS_VSSCANF is defined! +#endif +#endif  #endif  /**********************************************************************/ @@ -617,10 +663,28 @@ int __scan_getc(register struct scan_cookie *sc)  	}  	if (sc->ungot_flag == 0) { +#if !defined(__STDIO_BUFFERS) && !defined(__UCLIBC_HAS_WCHAR__) +		if (sc->fp->filedes != -2) { +			c = GETC(sc); +		} else { +			__FILE_vsscanf *fv = (__FILE_vsscanf *)(sc->fp); +			if (fv->bufpos < fv->bufread) { +				c = *fv->bufpos++; +			} else { +				c = EOF; +				sc->fp->modeflags |= __FLAG_EOF; +			} +		} +		if (c == EOF) { +			sc->ungot_flag |= 2; +			return -1; +		} +#else  		if ((c = GETC(sc)) == EOF) {  			sc->ungot_flag |= 2;  			return -1;  		} +#endif  		sc->ungot_char = c;  	} else {  		assert(sc->ungot_flag == 1); @@ -962,7 +1026,13 @@ static __inline void kill_scan_cookie(register struct scan_cookie *sc)  #ifdef L_vfscanf  	if (sc->ungot_flag & 1) { +#if !defined(__STDIO_BUFFERS) && !defined(__UCLIBC_HAS_WCHAR__) +		if (sc->fp->filedes != -2) { +			ungetc(sc->ungot_char, sc->fp); +		} +#else  		ungetc(sc->ungot_char, sc->fp); +#endif  		/* Deal with distiction between user and scanf ungots. */  		if (sc->nread == 0) {	/* Only one char was read... app ungot? */  			sc->fp->ungot[1] = sc->app_ungot; /* restore ungot state. */ @@ -1146,8 +1216,8 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)  			}  			fmt += i; -#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)  			if (psfs.store) { +#if defined(NL_ARGMAX) && (NL_ARGMAX > 0)  				if (psfs.num_pos_args == -2) {  					psfs.cur_ptr = va_arg(arg, void *);  				} else { @@ -1156,10 +1226,10 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)  					}  					psfs.cur_ptr = psfs.pos_args[psfs.cur_pos_arg];  				} -			}  #else  /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */ -			psfs.cur_ptr = va_arg(arg, void *); +				psfs.cur_ptr = va_arg(arg, void *);  #endif /* defined(NL_ARGMAX) && (NL_ARGMAX > 0) */ +			}  		DO_CONVERSION:  			/* First, consume white-space if not n, c, [, C, or l[. */  | 
