From f763ad5a3646b8b88ad34474b81594e591ee3332 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Sat, 6 Sep 2003 03:37:17 +0000 Subject: Implement vsnprintf (old_vfprintf only) and vsnscanf when uClibc is configured with non-buffered stdio and non-wchar mode. Fix a couple of bugs that showed up in minimalist configurations. Update old_vfprintf to handle size qualifiers on the integer and %n conversions. It now passed the glibc printf tests with the exception of a floating point rounding difference. --- libc/stdio/Makefile | 4 +- libc/stdio/old_vfprintf.c | 232 ++++++++++++++++++++++++++++++++++++++-------- libc/stdio/printf.c | 96 +++++++++++++++---- 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 #include #include +#include #include #include #include @@ -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 #include @@ -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[] = ""; @@ -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[. */ -- cgit v1.2.3