aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-03-27 09:38:39 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-03-27 09:38:39 +0000
commit409c27f83478e2962c446be23e104a97b3f5f2e0 (patch)
tree4548f42d093397fb049fdfae40f28968d59499ab /newlib/libc
parent1ebc8da242a1e8dd7707f2bcc51c22d4e1e64990 (diff)
downloadnewlib-409c27f83478e2962c446be23e104a97b3f5f2e0.zip
newlib-409c27f83478e2962c446be23e104a97b3f5f2e0.tar.gz
newlib-409c27f83478e2962c446be23e104a97b3f5f2e0.tar.bz2
* acconfig.h (_FVWRITE_IN_STREAMIO): Undefine.
* newlib.hin (_FVWRITE_IN_STREAMIO): Undefine. * configure.in (--disable-newlib-fvwrite-in-streamio): New option. * configure: Regenerated. * libc/stdio/fputs.c (_fputs_r): Use _FVWRITE_IN_STREAMIO to control __sfvwrite_r. Add alternative implementation. * libc/stdio/fputws.c (_fputws_r): Ditto. * libc/stdio/fwrite.c (_fwrite_r): Ditto. * libc/stdio/puts.c (_puts_r): Ditto. * libc/stdio/vfprintf.c (__ssputs_r, __sfputs_r): New function. (_VFPRINTF_R): Use _FVWRITE_IN_STREAMIO to control vector buffer. (__SPRINT): Use _FVWRITE_IN_STREAMIO to control macro definition. * libc/stdio/vfwprintf.c (_VFWPRINTF_R): Use _FVWRITE_IN_STREAMIO to control vector buffer.
Diffstat (limited to 'newlib/libc')
-rw-r--r--newlib/libc/stdio/fputs.c24
-rw-r--r--newlib/libc/stdio/fputws.c30
-rw-r--r--newlib/libc/stdio/fwrite.c25
-rw-r--r--newlib/libc/stdio/puts.c28
-rw-r--r--newlib/libc/stdio/vfprintf.c147
-rw-r--r--newlib/libc/stdio/vfwprintf.c49
6 files changed, 293 insertions, 10 deletions
diff --git a/newlib/libc/stdio/fputs.c b/newlib/libc/stdio/fputs.c
index 6e623a5..de6357a 100644
--- a/newlib/libc/stdio/fputs.c
+++ b/newlib/libc/stdio/fputs.c
@@ -77,6 +77,7 @@ _DEFUN(_fputs_r, (ptr, s, fp),
char _CONST * s _AND
FILE * fp)
{
+#ifdef _FVWRITE_IN_STREAMIO
int result;
struct __suio uio;
struct __siov iov;
@@ -93,6 +94,29 @@ _DEFUN(_fputs_r, (ptr, s, fp),
result = __sfvwrite_r (ptr, fp, &uio);
_newlib_flockfile_end (fp);
return result;
+#else
+ _CONST char *p = s;
+
+ CHECK_INIT(ptr, fp);
+
+ _newlib_flockfile_start (fp);
+ ORIENT (fp, -1);
+ /* Make sure we can write. */
+ if (cantwrite (ptr, fp))
+ goto error;
+
+ while (*p)
+ {
+ if (__sputc_r (ptr, *p++, fp) == EOF)
+ goto error;
+ }
+ _newlib_flockfile_exit (fp);
+ return 0;
+
+error:
+ _newlib_flockfile_end (fp);
+ return EOF;
+#endif
}
#ifndef _REENT_ONLY
diff --git a/newlib/libc/stdio/fputws.c b/newlib/libc/stdio/fputws.c
index c88111c..0893b3c 100644
--- a/newlib/libc/stdio/fputws.c
+++ b/newlib/libc/stdio/fputws.c
@@ -84,6 +84,7 @@ _DEFUN(_fputws_r, (ptr, ws, fp),
{
size_t nbytes;
char buf[BUFSIZ];
+#ifdef _FVWRITE_IN_STREAMIO
struct __suio uio;
struct __siov iov;
@@ -108,8 +109,35 @@ _DEFUN(_fputws_r, (ptr, ws, fp),
return (0);
error:
- _newlib_flockfile_end(fp);
+ _newlib_flockfile_end (fp);
return (-1);
+#else
+ _newlib_flockfile_start (fp);
+ ORIENT (fp, 1);
+ if (cantwrite (ptr, fp) != 0)
+ goto error;
+
+ do
+ {
+ size_t i = 0;
+ nbytes = _wcsrtombs_r (ptr, buf, &ws, sizeof (buf), &fp->_mbstate);
+ if (nbytes == (size_t) -1)
+ goto error;
+ while (i < nbytes)
+ {
+ if (__sputc_r (ptr, buf[i], fp) == EOF)
+ goto error;
+ i++;
+ }
+ }
+ while (ws != NULL);
+ _newlib_flockfile_exit (fp);
+ return (0);
+
+error:
+ _newlib_flockfile_end (fp);
+ return (-1);
+#endif
}
int
diff --git a/newlib/libc/stdio/fwrite.c b/newlib/libc/stdio/fwrite.c
index dc21805..595e3ef 100644
--- a/newlib/libc/stdio/fwrite.c
+++ b/newlib/libc/stdio/fwrite.c
@@ -103,6 +103,7 @@ _DEFUN(_fwrite_r, (ptr, buf, size, count, fp),
FILE * fp)
{
size_t n;
+#ifdef _FVWRITE_IN_STREAMIO
struct __suio uio;
struct __siov iov;
@@ -128,6 +129,30 @@ _DEFUN(_fwrite_r, (ptr, buf, size, count, fp),
}
_newlib_flockfile_end (fp);
return (n - uio.uio_resid) / size;
+#else
+ size_t i = 0;
+ _CONST char *p = buf;
+ n = count * size;
+ CHECK_INIT (ptr, fp);
+
+ _newlib_flockfile_start (fp);
+ ORIENT (fp, -1);
+ /* Make sure we can write. */
+ if (cantwrite (ptr, fp))
+ goto ret;
+
+ while (i < n)
+ {
+ if (__sputc_r (ptr, p[i], fp) == EOF)
+ break;
+
+ i++;
+ }
+
+ret:
+ _newlib_flockfile_end (fp);
+ return i / size;
+#endif
}
#ifndef _REENT_ONLY
diff --git a/newlib/libc/stdio/puts.c b/newlib/libc/stdio/puts.c
index 7b8b34b..4c60aaa 100644
--- a/newlib/libc/stdio/puts.c
+++ b/newlib/libc/stdio/puts.c
@@ -78,6 +78,7 @@ _DEFUN(_puts_r, (ptr, s),
struct _reent *ptr _AND
_CONST char * s)
{
+#ifdef _FVWRITE_IN_STREAMIO
int result;
size_t c = strlen (s);
struct __suio uio;
@@ -99,6 +100,33 @@ _DEFUN(_puts_r, (ptr, s),
result = (__sfvwrite_r (ptr, fp, &uio) ? EOF : '\n');
_newlib_flockfile_end (fp);
return result;
+#else
+ int result = EOF;
+ const char *p = s;
+ FILE *fp;
+ _REENT_SMALL_CHECK_INIT (ptr);
+
+ fp = _stdout_r (ptr);
+ _newlib_flockfile_start (fp);
+ ORIENT (fp, -1);
+ /* Make sure we can write. */
+ if (cantwrite (ptr, fp))
+ goto err;
+
+ while (*p)
+ {
+ if (__sputc_r (ptr, *p++, fp) == EOF)
+ goto err;
+ }
+ if (__sputc_r (ptr, '\n', fp) == EOF)
+ goto err;
+
+ result = '\n';
+
+err:
+ _newlib_flockfile_end (fp);
+ return result;
+#endif
}
#ifndef _REENT_ONLY
diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c
index 76a445b..c6c20eb 100644
--- a/newlib/libc/stdio/vfprintf.c
+++ b/newlib/libc/stdio/vfprintf.c
@@ -178,9 +178,17 @@ static char *rcsid = "$Id$";
#endif
#ifdef STRING_ONLY
-#define __SPRINT __ssprint_r
+# ifdef _FVWRITE_IN_STREAMIO
+# define __SPRINT __ssprint_r
+# else
+# define __SPRINT __ssputs_r
+# endif
#else
-#define __SPRINT __sprint_r
+# ifdef _FVWRITE_IN_STREAMIO
+# define __SPRINT __sprint_r
+# else
+# define __SPRINT __sfputs_r
+# endif
#endif
/* The __sprint_r/__ssprint_r functions are shared between all versions of
@@ -188,6 +196,76 @@ static char *rcsid = "$Id$";
the INTEGER_ONLY versions here. */
#ifdef STRING_ONLY
#ifdef INTEGER_ONLY
+#ifndef _FVWRITE_IN_STREAMIO
+int
+_DEFUN(__ssputs_r, (ptr, fp, buf, len),
+ struct _reent *ptr _AND
+ FILE *fp _AND
+ _CONST char *buf _AND
+ size_t len)
+{
+ register int w;
+
+ 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) buf, (size_t) (w));
+ fp->_w -= w;
+ fp->_p += w;
+
+ return 0;
+
+err:
+ fp->_flags |= __SERR;
+ return EOF;
+}
+#endif
+
int
_DEFUN(__ssprint_r, (ptr, fp, uio),
struct _reent *ptr _AND
@@ -280,11 +358,42 @@ err:
return EOF;
}
#else /* !INTEGER_ONLY */
+#ifndef _FVWRITE_IN_STREAMIO
+int __ssputs_r (struct _reent *, FILE *, _CONST char *, size_t);
+#endif
int __ssprint_r (struct _reent *, FILE *, register struct __suio *);
#endif /* !INTEGER_ONLY */
#else /* !STRING_ONLY */
#ifdef INTEGER_ONLY
+
+#ifndef _FVWRITE_IN_STREAMIO
+int
+_DEFUN(__sfputs_r, (ptr, fp, buf, len),
+ struct _reent *ptr _AND
+ FILE *fp _AND
+ _CONST char *buf _AND
+ size_t len)
+{
+ register int i;
+
+ if (fp->_flags2 & __SWID) {
+ wchar_t *p;
+
+ p = (wchar_t *) buf;
+ for (i = 0; i < (len / sizeof (wchar_t)); i++) {
+ if (_fputwc_r (ptr, p[i], fp) == WEOF)
+ return -1;
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ if (_fputc_r (ptr, buf[i], fp) == EOF)
+ return -1;
+ }
+ }
+ return (0);
+}
+#endif
/*
* Flush out all the vectors defined by the given uio,
* then reset it so that it can be reused.
@@ -326,6 +435,9 @@ out:
return (err);
}
#else /* !INTEGER_ONLY */
+#ifndef _FVWRITE_IN_STREAMIO
+int __sfputs_r (struct _reent *, FILE *, _CONST char *buf, size_t);
+#endif
int __sprint_r (struct _reent *, FILE *, register struct __suio *);
#endif /* !INTEGER_ONLY */
@@ -550,7 +662,6 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
register int ch; /* character from fmt */
register int n, m; /* handy integers (short term usage) */
register char *cp; /* handy char pointer (short term usage) */
- register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */
char *fmt_anchor; /* current format spec being processed */
#ifndef _NO_POS_ARGS
@@ -597,9 +708,12 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
char *xdigs = NULL; /* digits for [xX] conversion */
+#ifdef _FVWRITE_IN_STREAMIO
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
+ register struct __siov *iovp;/* for PRINT macro */
+#endif
char buf[BUF]; /* space for %c, %S, %[diouxX], %[aA] */
char ox[2]; /* space for 0x hex-prefix */
#ifdef _MB_CAPABLE
@@ -625,6 +739,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
+#ifdef _FVWRITE_IN_STREAMIO
#define PRINT(ptr, len) { \
iovp->iov_base = (ptr); \
iovp->iov_len = (len); \
@@ -659,6 +774,30 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
uio.uio_iovcnt = 0; \
iovp = iov; \
}
+#else
+#define PRINT(ptr, len) { \
+ if (__SPRINT (data, fp, (ptr), (len)) == EOF) \
+ goto error; \
+}
+#define PAD(howmany, with) { \
+ if ((n = (howmany)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT (with, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT (with, n); \
+ } \
+}
+#define PRINTANDPAD(p, ep, len, with) { \
+ int n = (ep) - (p); \
+ if (n > (len)) \
+ n = (len); \
+ if (n > 0) \
+ PRINT((p), n); \
+ PAD((len) - (n > 0 ? n : 0), (with)); \
+}
+#define FLUSH()
+#endif
/* Macros to support positional arguments */
#ifndef _NO_POS_ARGS
@@ -741,9 +880,11 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
#endif /* STRING_ONLY */
fmt = (char *)fmt0;
+#ifdef _FVWRITE_IN_STREAMIO
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
+#endif
ret = 0;
#ifndef _NO_POS_ARGS
arg_index = 0;
diff --git a/newlib/libc/stdio/vfwprintf.c b/newlib/libc/stdio/vfwprintf.c
index dfa8fde..5860147 100644
--- a/newlib/libc/stdio/vfwprintf.c
+++ b/newlib/libc/stdio/vfwprintf.c
@@ -150,13 +150,21 @@ SEEALSO
int _EXFUN(_VFWPRINTF_R, (struct _reent *, FILE *, _CONST wchar_t *, va_list));
/* Defined in vfprintf.c. */
-#ifdef STRING_ONLY
-#define __SPRINT __ssprint_r
+#ifdef _FVWRITE_IN_STREAMIO
+# ifdef STRING_ONLY
+# define __SPRINT __ssprint_r
+# else
+# define __SPRINT __sprint_r
+# endif
+int _EXFUN(__SPRINT, (struct _reent *, FILE *, register struct __suio *));
#else
-#define __SPRINT __sprint_r
+# ifdef STRING_ONLY
+# define __SPRINT __ssputs_r
+# else
+# define __SPRINT __sfputs_r
+# endif
+int _EXFUN(__SPRINT, (struct _reent *, FILE *, _CONST char *, size_t));
#endif
-int _EXFUN(__SPRINT, (struct _reent *, FILE *, register struct __suio *));
-
#ifndef STRING_ONLY
/*
* Helper function for `fprintf to unbuffered unix file': creates a
@@ -377,7 +385,6 @@ _DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
register wint_t ch; /* character from fmt */
register int n, m; /* handy integers (short term usage) */
register wchar_t *cp; /* handy char pointer (short term usage) */
- register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */
wchar_t *fmt_anchor; /* current format spec being processed */
#ifndef _NO_POS_ARGS
@@ -426,9 +433,12 @@ _DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
int realsz; /* field size expanded by dprec */
int size = 0; /* size of converted field or string */
wchar_t *xdigs = NULL; /* digits for [xX] conversion */
+#ifdef _FVWRITE_IN_STREAMIO
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
+ register struct __siov *iovp;/* for PRINT macro */
+#endif
wchar_t buf[BUF]; /* space for %c, %ls/%S, %[diouxX], %[aA] */
wchar_t ox[2]; /* space for 0x hex-prefix */
wchar_t *malloc_buf = NULL;/* handy pointer for malloced buffers */
@@ -469,6 +479,7 @@ _DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
+#ifdef _FVWRITE_IN_STREAMIO
#define PRINT(ptr, len) { \
iovp->iov_base = (char *) (ptr); \
iovp->iov_len = (len) * sizeof (wchar_t); \
@@ -503,6 +514,30 @@ _DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
uio.uio_iovcnt = 0; \
iovp = iov; \
}
+#else
+#define PRINT(ptr, len) { \
+ if (__SPRINT (data, fp, (_CONST char *)(ptr), (len) * sizeof (wchar_t)) == EOF) \
+ goto error; \
+}
+#define PAD(howmany, with) { \
+ if ((n = (howmany)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT (with, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT (with, n); \
+ } \
+}
+#define PRINTANDPAD(p, ep, len, with) { \
+ int n = (ep) - (p); \
+ if (n > (len)) \
+ n = (len); \
+ if (n > 0) \
+ PRINT((p), n); \
+ PAD((len) - (n > 0 ? n : 0), (with)); \
+}
+#define FLUSH()
+#endif
/* Macros to support positional arguments */
#ifndef _NO_POS_ARGS
@@ -585,9 +620,11 @@ _DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
#endif /* STRING_ONLY */
fmt = (wchar_t *)fmt0;
+#ifdef _FVWRITE_IN_STREAMIO
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
+#endif
ret = 0;
#ifndef _NO_POS_ARGS
arg_index = 0;