diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2008-04-14 21:14:55 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2008-04-14 21:14:55 +0000 |
commit | eabd7de028075f106e1434bf9efd91a5fd32129f (patch) | |
tree | 0f40f0f7c842dbbdab04f15c7dcdcce5d964f290 /newlib/libc | |
parent | a7b6c156deb51bc349193bafbf4e3d0a439e53f0 (diff) | |
download | newlib-eabd7de028075f106e1434bf9efd91a5fd32129f.zip newlib-eabd7de028075f106e1434bf9efd91a5fd32129f.tar.gz newlib-eabd7de028075f106e1434bf9efd91a5fd32129f.tar.bz2 |
2008-04-14 Jeff Johnston <jjohnstn@redhat.com>
* libc/stdio/Makefile.am: Build vfprintf.c and vfscanf.c with
-DSTRING_ONLY defined with and without -DINTEGER_ONLY defined
to build special versions for sprintf/sscanf family functions.
* libc/stdio/Makefile.in: Regenerated.
* libc/stdio/vfprintf.c[STRING_ONLY][INTEGER_ONLY](_VFPRINTF_R):
Redefine to be _svfiprintf_r which is optimized to work with siprintf
family of functions (i.e. no I/O) and does not support floating-point.
[STRING_ONLY][!INTEGER_ONLY](_VFPRINTF_R): Redefine to be
_svfprintf_r which is optimized to work with sprintf family of
functions and not use I/O.
[STRING_ONLY](__sprint_r): New string only version of static function.
designed to work with sprintf family of functions.
* libc/stdio/vfscanf.c[STRING_ONLY][INTEGER_ONLY](_SVFSCANF_R):
Redefine to be _ssvfiscanf_r which is optimized to work with siscanf
family of functions (i.e. no I/O) and no float-point support.
[STRING_ONLY][!INTEGER_ONLY](_SVFSCANF_R): Redefine to be
__ssvfscanf_r which is optimized to work with sscanf family of
functions and does not require I/O functions.
* libc/stdio/asprintf.c: Call _svfprintf_r instead of _vfprintf_r.
* libc/stdio/snprintf.c: Ditto.
* libc/stdio/sprintf.c: Ditto.
* libc/stdio/vasnprintf.c: Ditto.
* libc/stdio/vasprintf.c: Ditto.
* libc/stdio/siprintf.c: Call _svfiprintf_r instead of _vfiprintf_r.
* libc/stdio/sniprintf.c: Ditto.
* libc/stdio/vasiprintf.c: Ditto.
* libc/stdio/vsiprintf.c: Ditto.
* libc/stdio/vsniprintf.c: Ditto.
* libc/stdio/vsprintf.c: Ditto.
* libc/stdio/local.h: Add prototypes for _svfprintf_r, _svfiprintf_r,
_ssvfscanf_r, and _ssvfiscanf_r.
* libc/stdio/sscanf.c: Call _ssvfscanf_r instead of _svfscanf_r.
* libc/stdio/vsscanf.c: Ditto.
* libc/stdio/siscanf.c: Call _ssvfiscanf_r instead of _svfiscanf_r.
* libc/stdio/vsiscanf.c: Ditto.
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/stdio/Makefile.am | 18 | ||||
-rw-r--r-- | newlib/libc/stdio/Makefile.in | 25 | ||||
-rw-r--r-- | newlib/libc/stdio/asprintf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/local.h | 8 | ||||
-rw-r--r-- | newlib/libc/stdio/siprintf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/siscanf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/sniprintf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/snprintf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/sprintf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/sscanf.c | 4 | ||||
-rw-r--r-- | newlib/libc/stdio/vasiprintf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vasnprintf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vasprintf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vfprintf.c | 114 | ||||
-rw-r--r-- | newlib/libc/stdio/vfscanf.c | 154 | ||||
-rw-r--r-- | newlib/libc/stdio/vsiprintf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vsiscanf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vsniprintf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vsprintf.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdio/vsscanf.c | 2 |
20 files changed, 334 insertions, 29 deletions
diff --git a/newlib/libc/stdio/Makefile.am b/newlib/libc/stdio/Makefile.am index 4d3daae..b50b871 100644 --- a/newlib/libc/stdio/Makefile.am +++ b/newlib/libc/stdio/Makefile.am @@ -128,6 +128,8 @@ endif !ELIX_LEVEL_2 endif !ELIX_LEVEL_1 LIBADD_OBJS = \ + $(lpfx)svfiprintf.$(oext) $(lpfx)svfprintf.$(oext) \ + $(lpfx)svfiscanf.$(oext) $(lpfx)svfscanf.$(oext) \ $(lpfx)vfiprintf.$(oext) $(lpfx)vfprintf.$(oext) \ $(lpfx)vfscanf.$(oext) $(lpfx)vfiscanf.$(oext) @@ -161,12 +163,24 @@ $(lpfx)vfprintf.$(oext): vfprintf.c $(lpfx)vfiprintf.$(oext): vfprintf.c $(LIB_COMPILE) -fshort-enums -DINTEGER_ONLY -c $(srcdir)/vfprintf.c -o $@ +$(lpfx)svfprintf.$(oext): vfprintf.c + $(LIB_COMPILE) -fshort-enums -DSTRING_ONLY -c $(srcdir)/vfprintf.c -o $@ + +$(lpfx)svfiprintf.$(oext): vfprintf.c + $(LIB_COMPILE) -fshort-enums -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfprintf.c -o $@ + $(lpfx)vfscanf.$(oext): vfscanf.c $(LIB_COMPILE) -c $(srcdir)/vfscanf.c -o $@ $(lpfx)vfiscanf.$(oext): vfscanf.c $(LIB_COMPILE) -DINTEGER_ONLY -c $(srcdir)/vfscanf.c -o $@ +$(lpfx)svfscanf.$(oext): vfscanf.c + $(LIB_COMPILE) -DSTRING_ONLY -c $(srcdir)/vfscanf.c -o $@ + +$(lpfx)svfiscanf.$(oext): vfscanf.c + $(LIB_COMPILE) -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfscanf.c -o $@ + CHEWOUT_FILES = \ clearerr.def \ diprintf.def \ @@ -274,6 +288,10 @@ $(lpfx)sprintf.$(oext): local.h $(lpfx)siscanf.$(oext): local.h $(lpfx)sscanf.$(oext): local.h $(lpfx)stdio.$(oext): local.h +$(lpfx)svfiprintf.$(oext): local.h +$(lpfx)svfiscanf.$(oext): local.h floatio.h +$(lpfx)svfprintf.$(oext): local.h +$(lpfx)svfscanf.$(oext): local.h floatio.h $(lpfx)ungetc.$(oext): local.h $(lpfx)vfiprintf.$(oext): local.h $(lpfx)vfprintf.$(oext): local.h diff --git a/newlib/libc/stdio/Makefile.in b/newlib/libc/stdio/Makefile.in index 3b80e35..be8cd45 100644 --- a/newlib/libc/stdio/Makefile.in +++ b/newlib/libc/stdio/Makefile.in @@ -54,8 +54,11 @@ CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru lib_a_AR = $(AR) $(ARFLAGS) -am__DEPENDENCIES_1 = $(lpfx)vfiprintf.$(oext) $(lpfx)vfprintf.$(oext) \ - $(lpfx)vfscanf.$(oext) $(lpfx)vfiscanf.$(oext) +am__DEPENDENCIES_1 = $(lpfx)svfiprintf.$(oext) \ + $(lpfx)svfprintf.$(oext) $(lpfx)svfiscanf.$(oext) \ + $(lpfx)svfscanf.$(oext) $(lpfx)vfiprintf.$(oext) \ + $(lpfx)vfprintf.$(oext) $(lpfx)vfscanf.$(oext) \ + $(lpfx)vfiscanf.$(oext) am__objects_1 = lib_a-clearerr.$(OBJEXT) lib_a-fclose.$(OBJEXT) \ lib_a-fdopen.$(OBJEXT) lib_a-feof.$(OBJEXT) \ lib_a-ferror.$(OBJEXT) lib_a-fflush.$(OBJEXT) \ @@ -438,6 +441,8 @@ GENERAL_SOURCES = \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@ELIX_4_SOURCES = @ELIX_LEVEL_1_TRUE@ELIX_4_SOURCES = LIBADD_OBJS = \ + $(lpfx)svfiprintf.$(oext) $(lpfx)svfprintf.$(oext) \ + $(lpfx)svfiscanf.$(oext) $(lpfx)svfscanf.$(oext) \ $(lpfx)vfiprintf.$(oext) $(lpfx)vfprintf.$(oext) \ $(lpfx)vfscanf.$(oext) $(lpfx)vfiscanf.$(oext) @@ -1345,12 +1350,24 @@ $(lpfx)vfprintf.$(oext): vfprintf.c $(lpfx)vfiprintf.$(oext): vfprintf.c $(LIB_COMPILE) -fshort-enums -DINTEGER_ONLY -c $(srcdir)/vfprintf.c -o $@ +$(lpfx)svfprintf.$(oext): vfprintf.c + $(LIB_COMPILE) -fshort-enums -DSTRING_ONLY -c $(srcdir)/vfprintf.c -o $@ + +$(lpfx)svfiprintf.$(oext): vfprintf.c + $(LIB_COMPILE) -fshort-enums -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfprintf.c -o $@ + $(lpfx)vfscanf.$(oext): vfscanf.c $(LIB_COMPILE) -c $(srcdir)/vfscanf.c -o $@ $(lpfx)vfiscanf.$(oext): vfscanf.c $(LIB_COMPILE) -DINTEGER_ONLY -c $(srcdir)/vfscanf.c -o $@ +$(lpfx)svfscanf.$(oext): vfscanf.c + $(LIB_COMPILE) -DSTRING_ONLY -c $(srcdir)/vfscanf.c -o $@ + +$(lpfx)svfiscanf.$(oext): vfscanf.c + $(LIB_COMPILE) -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfscanf.c -o $@ + .c.def: $(CHEW) < $< > $*.def 2> $*.ref touch stmp-def @@ -1388,6 +1405,10 @@ $(lpfx)sprintf.$(oext): local.h $(lpfx)siscanf.$(oext): local.h $(lpfx)sscanf.$(oext): local.h $(lpfx)stdio.$(oext): local.h +$(lpfx)svfiprintf.$(oext): local.h +$(lpfx)svfiscanf.$(oext): local.h floatio.h +$(lpfx)svfprintf.$(oext): local.h +$(lpfx)svfscanf.$(oext): local.h floatio.h $(lpfx)ungetc.$(oext): local.h $(lpfx)vfiprintf.$(oext): local.h $(lpfx)vfprintf.$(oext): local.h diff --git a/newlib/libc/stdio/asprintf.c b/newlib/libc/stdio/asprintf.c index d72a4a7..59a08c8 100644 --- a/newlib/libc/stdio/asprintf.c +++ b/newlib/libc/stdio/asprintf.c @@ -40,7 +40,7 @@ _DEFUN(_asprintf_r, (ptr, strp, fmt), f._bf._size = f._w = 0; f._file = -1; /* No file. */ va_start (ap, fmt); - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); va_end (ap); if (ret >= 0) { @@ -67,7 +67,7 @@ _DEFUN(asprintf, (strp, fmt), f._bf._size = f._w = 0; f._file = -1; /* No file. */ va_start (ap, fmt); - ret = _vfprintf_r (_REENT, &f, fmt, ap); + ret = _svfprintf_r (_REENT, &f, fmt, ap); va_end (ap); if (ret >= 0) { diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index f02f91d..5dc2e62 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -34,7 +34,15 @@ extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); +extern int _EXFUN(__ssvfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); extern int _EXFUN(__svfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); +extern int _EXFUN(__ssvfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); +int _EXFUN(_svfprintf_r,(struct _reent *, FILE *, const char *, + va_list) + _ATTRIBUTE ((__format__ (__printf__, 3, 0)))); +int _EXFUN(_svfiprintf_r,(struct _reent *, FILE *, const char *, + va_list) + _ATTRIBUTE ((__format__ (__printf__, 3, 0)))); extern FILE *_EXFUN(__sfp,(struct _reent *)); extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); extern int _EXFUN(__srefill_r,(struct _reent *,FILE *)); diff --git a/newlib/libc/stdio/siprintf.c b/newlib/libc/stdio/siprintf.c index 296a16e..d6a0e19 100644 --- a/newlib/libc/stdio/siprintf.c +++ b/newlib/libc/stdio/siprintf.c @@ -119,7 +119,7 @@ _siprintf_r(ptr, str, fmt, va_alist) #else va_start (ap); #endif - ret = _vfiprintf_r (ptr, &f, fmt, ap); + ret = _svfiprintf_r (ptr, &f, fmt, ap); va_end (ap); *f._p = 0; return (ret); @@ -152,7 +152,7 @@ siprintf(str, fmt, va_alist) #else va_start (ap); #endif - ret = _vfiprintf_r (_REENT, &f, fmt, ap); + ret = _svfiprintf_r (_REENT, &f, fmt, ap); va_end (ap); *f._p = 0; return (ret); diff --git a/newlib/libc/stdio/siscanf.c b/newlib/libc/stdio/siscanf.c index 15b25c1..a64e2a8 100644 --- a/newlib/libc/stdio/siscanf.c +++ b/newlib/libc/stdio/siscanf.c @@ -152,7 +152,7 @@ siscanf(str, fmt, va_alist) #else va_start (ap); #endif - ret = __svfiscanf_r (_REENT, &f, fmt, ap); + ret = __ssvfiscanf_r (_REENT, &f, fmt, ap); va_end (ap); return ret; } @@ -190,7 +190,7 @@ _siscanf_r(ptr, str, fmt, va_alist) #else va_start (ap); #endif - ret = __svfiscanf_r (ptr, &f, fmt, ap); + ret = __ssvfiscanf_r (ptr, &f, fmt, ap); va_end (ap); return ret; } diff --git a/newlib/libc/stdio/sniprintf.c b/newlib/libc/stdio/sniprintf.c index 8cd06ce..98a2c25 100644 --- a/newlib/libc/stdio/sniprintf.c +++ b/newlib/libc/stdio/sniprintf.c @@ -64,7 +64,7 @@ _sniprintf_r (ptr, str, size, fmt, va_alist) #else va_start (ap); #endif - ret = _vfiprintf_r (ptr, &f, fmt, ap); + ret = _svfiprintf_r (ptr, &f, fmt, ap); va_end (ap); if (ret < EOF) ptr->_errno = EOVERFLOW; @@ -108,7 +108,7 @@ sniprintf (str, size, fmt, va_alist) #else va_start (ap); #endif - ret = _vfiprintf_r (ptr, &f, fmt, ap); + ret = _svfiprintf_r (ptr, &f, fmt, ap); va_end (ap); if (ret < EOF) ptr->_errno = EOVERFLOW; diff --git a/newlib/libc/stdio/snprintf.c b/newlib/libc/stdio/snprintf.c index 52db2dd..13414e3 100644 --- a/newlib/libc/stdio/snprintf.c +++ b/newlib/libc/stdio/snprintf.c @@ -63,7 +63,7 @@ _snprintf_r(ptr, str, size, fmt, va_alist) #else va_start (ap); #endif - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); va_end (ap); if (ret < EOF) ptr->_errno = EOVERFLOW; @@ -107,7 +107,7 @@ snprintf(str, size, fmt, va_alist) #else va_start (ap); #endif - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); va_end (ap); if (ret < EOF) ptr->_errno = EOVERFLOW; diff --git a/newlib/libc/stdio/sprintf.c b/newlib/libc/stdio/sprintf.c index bdff079..48d811c 100644 --- a/newlib/libc/stdio/sprintf.c +++ b/newlib/libc/stdio/sprintf.c @@ -583,7 +583,7 @@ _sprintf_r(ptr, str, fmt, va_alist) #else va_start (ap); #endif - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); va_end (ap); *f._p = 0; return (ret); @@ -616,7 +616,7 @@ sprintf(str, fmt, va_alist) #else va_start (ap); #endif - ret = _vfprintf_r (_REENT, &f, fmt, ap); + ret = _svfprintf_r (_REENT, &f, fmt, ap); va_end (ap); *f._p = 0; return (ret); diff --git a/newlib/libc/stdio/sscanf.c b/newlib/libc/stdio/sscanf.c index c0921e1..b093903 100644 --- a/newlib/libc/stdio/sscanf.c +++ b/newlib/libc/stdio/sscanf.c @@ -433,7 +433,7 @@ sscanf(str, fmt, va_alist) #else va_start (ap); #endif - ret = __svfscanf_r (_REENT, &f, fmt, ap); + ret = __ssvfscanf_r (_REENT, &f, fmt, ap); va_end (ap); return ret; } @@ -471,7 +471,7 @@ _sscanf_r(ptr, str, fmt, va_alist) #else va_start (ap); #endif - ret = __svfscanf_r (ptr, &f, fmt, ap); + ret = __ssvfscanf_r (ptr, &f, fmt, ap); va_end (ap); return ret; } diff --git a/newlib/libc/stdio/vasiprintf.c b/newlib/libc/stdio/vasiprintf.c index b16efe7..671bbdb 100644 --- a/newlib/libc/stdio/vasiprintf.c +++ b/newlib/libc/stdio/vasiprintf.c @@ -53,7 +53,7 @@ _DEFUN(_vasiprintf_r, (ptr, strp, fmt, ap), f._bf._base = f._p = NULL; f._bf._size = f._w = 0; f._file = -1; /* No file. */ - ret = _vfiprintf_r (ptr, &f, fmt, ap); + ret = _svfiprintf_r (ptr, &f, fmt, ap); if (ret >= 0) { *f._p = 0; diff --git a/newlib/libc/stdio/vasnprintf.c b/newlib/libc/stdio/vasnprintf.c index 740aa07..2dda30a 100644 --- a/newlib/libc/stdio/vasnprintf.c +++ b/newlib/libc/stdio/vasnprintf.c @@ -47,7 +47,7 @@ _DEFUN(_vasnprintf_r, (ptr, buf, lenp, fmt, ap), } f._bf._size = f._w = len; f._file = -1; /* No file. */ - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); if (ret < 0) return NULL; *lenp = ret; diff --git a/newlib/libc/stdio/vasprintf.c b/newlib/libc/stdio/vasprintf.c index 90539d1..525c696 100644 --- a/newlib/libc/stdio/vasprintf.c +++ b/newlib/libc/stdio/vasprintf.c @@ -53,7 +53,7 @@ _DEFUN(_vasprintf_r, (ptr, strp, fmt, ap), f._bf._base = f._p = NULL; f._bf._size = f._w = 0; f._file = -1; /* No file. */ - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); if (ret >= 0) { *f._p = 0; diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c index e9c7c9e..cfe1e3f 100644 --- a/newlib/libc/stdio/vfprintf.c +++ b/newlib/libc/stdio/vfprintf.c @@ -116,10 +116,18 @@ static char *rcsid = "$Id$"; #ifdef INTEGER_ONLY # define VFPRINTF vfiprintf -# define _VFPRINTF_R _vfiprintf_r +# ifdef STRING_ONLY +# define _VFPRINTF_R _svfiprintf_r +# else +# define _VFPRINTF_R _vfiprintf_r +# endif #else # define VFPRINTF vfprintf -# define _VFPRINTF_R _vfprintf_r +# ifdef STRING_ONLY +# define _VFPRINTF_R _svfprintf_r +# else +# define _VFPRINTF_R _vfprintf_r +# endif # ifndef NO_FLOATING_POINT # define FLOATING_POINT # endif @@ -158,6 +166,100 @@ static char *rcsid = "$Id$"; # undef _NO_LONGLONG #endif +#ifdef STRING_ONLY +static int +_DEFUN(__sprint_r, (ptr, fp, uio), + struct _reent *ptr _AND + FILE *fp _AND + register struct __suio *uio) +{ + register size_t len; + register int w; + register struct __siov *iov; + register _CONST char *p = NULL; + + iov = uio->uio_iov; + len = 0; + + if (uio->uio_resid == 0) { + uio->uio_iovcnt = 0; + return (0); + } + + do { + while (len == 0) { + p = iov->iov_base; + len = iov->iov_len; + iov++; + } + w = fp->_w; + if (len >= w && fp->_flags & (__SMBF | __SOPT)) { + /* must be asprintf family */ + unsigned char *str; + int curpos = (fp->_p - fp->_bf._base); + /* Choose a geometric growth factor to avoid + * quadratic realloc behavior, but use a rate less + * than (1+sqrt(5))/2 to accomodate malloc + * overhead. asprintf EXPECTS us to overallocate, so + * that it can add a trailing \0 without + * reallocating. The new allocation should thus be + * max(prev_size*1.5, curpos+len+1). */ + int newsize = fp->_bf._size * 3 / 2; + if (newsize < curpos + len + 1) + newsize = curpos + len + 1; + if (fp->_flags & __SOPT) + { + /* asnprintf leaves original buffer alone. */ + str = (unsigned char *)_malloc_r (ptr, newsize); + if (!str) + { + ptr->_errno = ENOMEM; + goto err; + } + memcpy (str, fp->_bf._base, curpos); + fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; + } + else + { + str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, + newsize); + if (!str) { + /* Free unneeded buffer. */ + _free_r (ptr, fp->_bf._base); + /* Ensure correct errno, even if free + * changed it. */ + ptr->_errno = ENOMEM; + goto err; + } + } + fp->_bf._base = str; + fp->_p = str + curpos; + fp->_bf._size = newsize; + w = len; + fp->_w = newsize - curpos; + } + if (len < w) + w = len; + (void)memmove ((_PTR) fp->_p, (_PTR) p, (size_t) (w)); + fp->_w -= w; + fp->_p += w; + w = len; /* pretend we copied all */ + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return 0; + +err: + fp->_flags |= __SERR; + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return EOF; +} + +#else /* !STRING_ONLY */ /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. @@ -222,6 +324,7 @@ _DEFUN(__sbprintf, (rptr, fp, fmt, ap), #endif return (ret); } +#endif /* !STRING_ONLY */ #ifdef FLOATING_POINT @@ -360,6 +463,7 @@ _EXFUN(get_arg, (struct _reent *data, int n, char *fmt, int _EXFUN(_VFPRINTF_R, (struct _reent *, FILE *, _CONST char *, va_list)); +#ifndef STRING_ONLY int _DEFUN(VFPRINTF, (fp, fmt0, ap), FILE * fp _AND @@ -370,6 +474,7 @@ _DEFUN(VFPRINTF, (fp, fmt0, ap), result = _VFPRINTF_R (_REENT, fp, fmt0, ap); return result; } +#endif /* STRING_ONLY */ int _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), @@ -517,6 +622,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), (u_long)GET_ARG (N, ap, u_int)) #endif +#ifndef STRING_ONLY + /* Initialize std streams if not dealing with sprintf family. */ CHECK_INIT (data, fp); _flockfile (fp); @@ -532,6 +639,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), _funlockfile (fp); return (__sbprintf (data, fp, fmt0, ap)); } +#endif /* STRING_ONLY */ fmt = (char *)fmt0; uio.uio_iov = iovp = iov; @@ -1330,7 +1438,9 @@ done: error: if (malloc_buf != NULL) _free_r (data, malloc_buf); +#ifndef STRING_ONLY _funlockfile (fp); +#endif return (__sferror (fp) ? EOF : ret); /* NOTREACHED */ } diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c index 68b55f4..f56681e 100644 --- a/newlib/libc/stdio/vfscanf.c +++ b/newlib/libc/stdio/vfscanf.c @@ -121,17 +121,35 @@ Supporting OS subroutines required: #define VFSCANF vfiscanf #define _VFSCANF_R _vfiscanf_r #define __SVFSCANF __svfiscanf -#define __SVFSCANF_R __svfiscanf_r +#ifdef STRING_ONLY +# define __SVFSCANF_R __ssvfiscanf_r +#else +# define __SVFSCANF_R __svfiscanf_r +#endif #else #define VFSCANF vfscanf #define _VFSCANF_R _vfscanf_r #define __SVFSCANF __svfscanf -#define __SVFSCANF_R __svfscanf_r +#ifdef STRING_ONLY +# define __SVFSCANF_R __ssvfscanf_r +#else +# define __SVFSCANF_R __svfscanf_r +#endif #ifndef NO_FLOATING_POINT #define FLOATING_POINT #endif #endif +#ifdef STRING_ONLY +#undef _flockfile +#undef _funlockfile +#define _flockfile(x) {} +#define _funlockfile(x) {} +#define _ungetc_r _sungetc_r +#define __srefill_r __ssrefill_r +#define _fread_r _sfread_r +#endif + #ifdef FLOATING_POINT #include <math.h> #include <float.h> @@ -234,6 +252,8 @@ typedef unsigned long long u_long_long; #define BufferEmpty (fp->_r <= 0 && __srefill_r(rptr, fp)) +#ifndef STRING_ONLY + #ifndef _REENT_ONLY int @@ -267,7 +287,135 @@ _DEFUN(_VFSCANF_R, (data, fp, fmt, ap), CHECK_INIT(data, fp); return __SVFSCANF_R (data, fp, fmt, ap); } +#endif /* !STRING_ONLY */ + +#ifdef STRING_ONLY +/* When dealing with the sscanf family, we don't want to use the + * regular ungetc which will drag in file I/O items we don't need. + * So, we create our own trimmed-down version. */ +static int +_DEFUN(_sungetc_r, (data, fp, ch), + struct _reent *data _AND + int c _AND + register FILE *fp) +{ + if (c == EOF) + return (EOF); + /* After ungetc, we won't be at eof anymore */ + fp->_flags &= ~__SEOF; + c = (unsigned char) c; + + /* + * If we are in the middle of ungetc'ing, just continue. + * This may require expanding the current ungetc buffer. + */ + + if (HASUB (fp)) + { + if (fp->_r >= fp->_ub._size && __submore (data, fp)) + { + return EOF; + } + *--fp->_p = c; + fp->_r++; + return c; + } + + /* + * If we can handle this by simply backing up, do so, + * but never replace the original character. + * (This makes sscanf() work when scanning `const' data.) + */ + + if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c) + { + fp->_p--; + fp->_r++; + return c; + } + + /* + * Create an ungetc buffer. + * Initially, we will use the `reserve' buffer. + */ + + fp->_ur = fp->_r; + fp->_up = fp->_p; + fp->_ub._base = fp->_ubuf; + fp->_ub._size = sizeof (fp->_ubuf); + fp->_ubuf[sizeof (fp->_ubuf) - 1] = c; + fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1]; + fp->_r = 1; + return c; +} + +/* String only version of __srefill_r for sscanf family. */ +static int +_DEFUN(__ssrefill_r, (ptr, fp), + struct _reent * ptr _AND + register FILE * fp) +{ + /* + * Our only hope of further input is the ungetc buffer. + * If there is anything in that buffer to read, return. + */ + if (HASUB (fp)) + { + FREEUB (ptr, fp); + if ((fp->_r = fp->_ur) != 0) + { + fp->_p = fp->_up; + return 0; + } + } + + /* Otherwise we are out of character input. */ + fp->_p = fp->_bf._base; + fp->_r = 0; + fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ + fp->_flags |= __SEOF; + return EOF; +} + +static size_t +_DEFUN(_sfread_r, (ptr, buf, size, count, fp), + struct _reent * ptr _AND + _PTR buf _AND + size_t size _AND + size_t count _AND + FILE * fp) +{ + register size_t resid; + register char *p; + register int r; + size_t total; + + if ((resid = count * size) == 0) + return 0; + + total = resid; + p = buf; + + while (resid > (r = fp->_r)) + { + _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r); + fp->_p += r; + fp->_r = 0; + p += r; + resid -= r; + if (__ssrefill_r (ptr, fp)) + { + /* no more input: return partial result */ + return (total - resid) / size; + } + } + _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid); + fp->_r -= resid; + fp->_p += resid; + return count; +} +#endif /* STRING_ONLY */ int _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), @@ -741,7 +889,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), } else { - size_t r = fread ((_PTR) GET_ARG (N, ap, char *), 1, width, fp); + size_t r = _fread_r (rptr, (_PTR) GET_ARG (N, ap, char *), 1, width, fp); if (r == 0) goto input_failure; diff --git a/newlib/libc/stdio/vsiprintf.c b/newlib/libc/stdio/vsiprintf.c index 967c178..05d009d 100644 --- a/newlib/libc/stdio/vsiprintf.c +++ b/newlib/libc/stdio/vsiprintf.c @@ -53,7 +53,7 @@ _DEFUN(_vsiprintf_r, (ptr, str, fmt, ap), f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._w = INT_MAX; f._file = -1; /* No file. */ - ret = _vfiprintf_r (ptr, &f, fmt, ap); + ret = _svfiprintf_r (ptr, &f, fmt, ap); *f._p = 0; return ret; } diff --git a/newlib/libc/stdio/vsiscanf.c b/newlib/libc/stdio/vsiscanf.c index ffbf22e..c26171a 100644 --- a/newlib/libc/stdio/vsiscanf.c +++ b/newlib/libc/stdio/vsiscanf.c @@ -71,5 +71,5 @@ _DEFUN(_vsiscanf_r, (ptr, str, fmt, ap), f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ - return __svfiscanf_r (ptr, &f, fmt, ap); + return __ssvfiscanf_r (ptr, &f, fmt, ap); } diff --git a/newlib/libc/stdio/vsniprintf.c b/newlib/libc/stdio/vsniprintf.c index d1c3185..f7c60e2 100644 --- a/newlib/libc/stdio/vsniprintf.c +++ b/newlib/libc/stdio/vsniprintf.c @@ -61,7 +61,7 @@ _DEFUN(_vsniprintf_r, (ptr, str, size, fmt, ap), f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._w = (size > 0 ? size - 1 : 0); f._file = -1; /* No file. */ - ret = _vfiprintf_r (ptr, &f, fmt, ap); + ret = _svfiprintf_r (ptr, &f, fmt, ap); if (ret < EOF) ptr->_errno = EOVERFLOW; if (size > 0) diff --git a/newlib/libc/stdio/vsprintf.c b/newlib/libc/stdio/vsprintf.c index 5c26004..fd052cd 100644 --- a/newlib/libc/stdio/vsprintf.c +++ b/newlib/libc/stdio/vsprintf.c @@ -53,7 +53,7 @@ _DEFUN(_vsprintf_r, (ptr, str, fmt, ap), f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._w = INT_MAX; f._file = -1; /* No file. */ - ret = _vfprintf_r (ptr, &f, fmt, ap); + ret = _svfprintf_r (ptr, &f, fmt, ap); *f._p = 0; return ret; } diff --git a/newlib/libc/stdio/vsscanf.c b/newlib/libc/stdio/vsscanf.c index 9bb7c0c..566823a 100644 --- a/newlib/libc/stdio/vsscanf.c +++ b/newlib/libc/stdio/vsscanf.c @@ -71,5 +71,5 @@ _DEFUN(_vsscanf_r, (ptr, str, fmt, ap), f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ - return __svfscanf_r (ptr, &f, fmt, ap); + return __ssvfscanf_r (ptr, &f, fmt, ap); } |