Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2008-04-15 01:14:55 +0400
committerJeff Johnston <jjohnstn@redhat.com>2008-04-15 01:14:55 +0400
commiteabd7de028075f106e1434bf9efd91a5fd32129f (patch)
tree0f40f0f7c842dbbdab04f15c7dcdcce5d964f290 /newlib/libc
parenta7b6c156deb51bc349193bafbf4e3d0a439e53f0 (diff)
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.am18
-rw-r--r--newlib/libc/stdio/Makefile.in25
-rw-r--r--newlib/libc/stdio/asprintf.c4
-rw-r--r--newlib/libc/stdio/local.h8
-rw-r--r--newlib/libc/stdio/siprintf.c4
-rw-r--r--newlib/libc/stdio/siscanf.c4
-rw-r--r--newlib/libc/stdio/sniprintf.c4
-rw-r--r--newlib/libc/stdio/snprintf.c4
-rw-r--r--newlib/libc/stdio/sprintf.c4
-rw-r--r--newlib/libc/stdio/sscanf.c4
-rw-r--r--newlib/libc/stdio/vasiprintf.c2
-rw-r--r--newlib/libc/stdio/vasnprintf.c2
-rw-r--r--newlib/libc/stdio/vasprintf.c2
-rw-r--r--newlib/libc/stdio/vfprintf.c114
-rw-r--r--newlib/libc/stdio/vfscanf.c154
-rw-r--r--newlib/libc/stdio/vsiprintf.c2
-rw-r--r--newlib/libc/stdio/vsiscanf.c2
-rw-r--r--newlib/libc/stdio/vsniprintf.c2
-rw-r--r--newlib/libc/stdio/vsprintf.c2
-rw-r--r--newlib/libc/stdio/vsscanf.c2
20 files changed, 334 insertions, 29 deletions
diff --git a/newlib/libc/stdio/Makefile.am b/newlib/libc/stdio/Makefile.am
index 4d3daaefb..b50b87188 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 3b80e35bc..be8cd4554 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 d72a4a7e9..59a08c808 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 f02f91d57..5dc2e6223 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 296a16ee0..d6a0e1983 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 15b25c196..a64e2a891 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 8cd06ce86..98a2c2509 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 52db2dd2c..13414e3d1 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 bdff0797d..48d811cf6 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 c0921e1e1..b09390380 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 b16efe794..671bbdb08 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 740aa0700..2dda30a7a 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 90539d1d8..525c6963a 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 e9c7c9e1a..cfe1e3f4e 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 68b55f426..f56681eaa 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 967c178e4..05d009d72 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 ffbf22e97..c26171acf 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 d1c318576..f7c60e280 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 5c2600411..fd052cd95 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 9bb7c0c3e..566823add 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);
}