This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bug (?) in sprintf family?


Please try the attached patch. It disconnects the sprintf and sscanf family of functions from bringing in all the I/O stuff. This is especially useful since tzset drags in sscanf.

If I missed something, let me know.

-- Jeff J.

Jeff Johnston wrote:
I'm looking at this. I have one patch for vfprintf.c, but there may be other patches required.

-- Jeff J.

Jonathan S. Shapiro wrote:
I am not sure whether or not this is a bug; my goal is to find out.

I have a call to vsnprintf. This is failing because isatty() is not yet
defined by our libc port.  The call to isatty() is being made from
within __smakebuf_r. There are also references to the reentrant versions
of close, read, write, sbrk, fstat, and lseek.

Now I do understand that all of these are required to do anything
significant with stdio, but it is somewhat surprising that they are
required for sprintf, which really doesn't need to touch the
file-oriented logic at all.

Is the implementation of sprintf deficient, or does the libc standard
not require any independence between sprintf and the file system?

I can either stub out the missing routines or supply a replacement for
vsnprintf in our coyotos-specific library, but before I do I would like
to understand whether this should be viewed as a newlib bug.

Heck, vsnprintf doesn't have a FILE* to work with, so there isn't any
fd, so I'm not entirely sure what these routines could possibly be
getting called *on* in this case. The program makes no other use of
stdio.


shap




Index: Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/Makefile.am,v
retrieving revision 1.27
diff -u -p -r1.27 Makefile.am
--- Makefile.am	2 Aug 2007 20:23:06 -0000	1.27
+++ Makefile.am	9 Apr 2008 19:28:05 -0000
@@ -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
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/Makefile.in,v
retrieving revision 1.40
diff -u -p -r1.40 Makefile.in
--- Makefile.in	19 Dec 2007 22:36:38 -0000	1.40
+++ Makefile.in	9 Apr 2008 19:28:05 -0000
@@ -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
Index: asprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/asprintf.c,v
retrieving revision 1.8
diff -u -p -r1.8 asprintf.c
--- asprintf.c	4 May 2007 02:55:16 -0000	1.8
+++ asprintf.c	9 Apr 2008 19:28:05 -0000
@@ -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)
     {
Index: local.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/local.h,v
retrieving revision 1.22
diff -u -p -r1.22 local.h
--- local.h	4 Jun 2007 18:10:17 -0000	1.22
+++ local.h	9 Apr 2008 19:28:05 -0000
@@ -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 *));
Index: siprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/siprintf.c,v
retrieving revision 1.9
diff -u -p -r1.9 siprintf.c
--- siprintf.c	19 Jul 2007 03:42:21 -0000	1.9
+++ siprintf.c	9 Apr 2008 19:28:05 -0000
@@ -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);
Index: siscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/siscanf.c,v
retrieving revision 1.4
diff -u -p -r1.4 siscanf.c
--- siscanf.c	19 Jul 2007 03:42:21 -0000	1.4
+++ siscanf.c	9 Apr 2008 19:28:05 -0000
@@ -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;
 }
Index: sniprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/sniprintf.c,v
retrieving revision 1.4
diff -u -p -r1.4 sniprintf.c
--- sniprintf.c	4 May 2007 02:55:16 -0000	1.4
+++ sniprintf.c	9 Apr 2008 19:28:05 -0000
@@ -64,7 +64,7 @@ _sniprintf_r (ptr, str, size, fmt, va_al
 #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;
Index: snprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/snprintf.c,v
retrieving revision 1.6
diff -u -p -r1.6 snprintf.c
--- snprintf.c	15 Mar 2007 18:40:48 -0000	1.6
+++ snprintf.c	9 Apr 2008 19:28:05 -0000
@@ -63,7 +63,7 @@ _snprintf_r(ptr, str, size, fmt, va_alis
 #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;
Index: sprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/sprintf.c,v
retrieving revision 1.11
diff -u -p -r1.11 sprintf.c
--- sprintf.c	19 Jul 2007 03:42:21 -0000	1.11
+++ sprintf.c	9 Apr 2008 19:28:06 -0000
@@ -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);
Index: sscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/sscanf.c,v
retrieving revision 1.12
diff -u -p -r1.12 sscanf.c
--- sscanf.c	19 Jul 2007 03:42:21 -0000	1.12
+++ sscanf.c	9 Apr 2008 19:28:06 -0000
@@ -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;
 }
Index: vasiprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vasiprintf.c,v
retrieving revision 1.3
diff -u -p -r1.3 vasiprintf.c
--- vasiprintf.c	4 Apr 2007 18:32:49 -0000	1.3
+++ vasiprintf.c	9 Apr 2008 19:28:06 -0000
@@ -53,7 +53,7 @@ _DEFUN(_vasiprintf_r, (ptr, strp, fmt, a
   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;
Index: vasnprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vasnprintf.c,v
retrieving revision 1.2
diff -u -p -r1.2 vasnprintf.c
--- vasnprintf.c	9 May 2007 19:27:30 -0000	1.2
+++ vasnprintf.c	9 Apr 2008 19:28:06 -0000
@@ -47,7 +47,7 @@ _DEFUN(_vasnprintf_r, (ptr, buf, lenp, f
     }
   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;
Index: vasprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vasprintf.c,v
retrieving revision 1.6
diff -u -p -r1.6 vasprintf.c
--- vasprintf.c	4 Apr 2007 18:32:49 -0000	1.6
+++ vasprintf.c	9 Apr 2008 19:28:06 -0000
@@ -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;
Index: vfprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
retrieving revision 1.68
diff -u -p -r1.68 vfprintf.c
--- vfprintf.c	19 Dec 2007 17:06:19 -0000	1.68
+++ vfprintf.c	9 Apr 2008 19:28:06 -0000
@@ -116,10 +116,18 @@ static char *rcsid = "$Id: vfprintf.c,v 
 
 #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: vfprintf.c,v 
 # 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, in
 
 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 */
 }
Index: vfscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfscanf.c,v
retrieving revision 1.39
diff -u -p -r1.39 vfscanf.c
--- vfscanf.c	19 Jul 2007 03:42:21 -0000	1.39
+++ vfscanf.c	9 Apr 2008 19:28:06 -0000
@@ -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;
Index: vsiprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsiprintf.c,v
retrieving revision 1.3
diff -u -p -r1.3 vsiprintf.c
--- vsiprintf.c	4 May 2007 02:55:16 -0000	1.3
+++ vsiprintf.c	9 Apr 2008 19:28:06 -0000
@@ -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;
 }
Index: vsiscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsiscanf.c,v
retrieving revision 1.2
diff -u -p -r1.2 vsiscanf.c
--- vsiscanf.c	4 Jun 2007 18:10:17 -0000	1.2
+++ vsiscanf.c	9 Apr 2008 19:28:06 -0000
@@ -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);
 }
Index: vsniprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsniprintf.c,v
retrieving revision 1.4
diff -u -p -r1.4 vsniprintf.c
--- vsniprintf.c	4 May 2007 02:55:16 -0000	1.4
+++ vsniprintf.c	9 Apr 2008 19:28:06 -0000
@@ -61,7 +61,7 @@ _DEFUN(_vsniprintf_r, (ptr, str, size, f
   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)
Index: vsprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsprintf.c,v
retrieving revision 1.6
diff -u -p -r1.6 vsprintf.c
--- vsprintf.c	4 Apr 2007 18:32:49 -0000	1.6
+++ vsprintf.c	9 Apr 2008 19:28:06 -0000
@@ -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;
 }
Index: vsscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsscanf.c,v
retrieving revision 1.5
diff -u -p -r1.5 vsscanf.c
--- vsscanf.c	4 Jun 2007 18:10:17 -0000	1.5
+++ vsscanf.c	9 Apr 2008 19:28:06 -0000
@@ -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);
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]