* 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.
This commit is contained in:
Corinna Vinschen 2013-03-27 09:38:39 +00:00
parent 1ebc8da242
commit 409c27f834
11 changed files with 354 additions and 11 deletions

View File

@ -1,3 +1,20 @@
2013-03-27 Bin Cheng <bin.cheng@arm.com>
* 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.
2013-03-26 Sebastian Huber <sebastian.huber@embedded-brains.de>
* libc/stdio/local.h (_STDIO_WITH_THREAD_CANCELLATION_SUPPORT):

View File

@ -54,6 +54,9 @@
/* Define if the platform long double type is equal to double. */
#undef _LDBL_EQ_DBL
/* Define if ivo supported in streamio. */
#undef _FVWRITE_IN_STREAMIO
@BOTTOM@
/*

22
newlib/configure vendored
View File

@ -789,6 +789,7 @@ enable_newlib_iconv_to_encodings
enable_newlib_iconv_external_ccs
enable_newlib_atexit_dynamic_alloc
enable_newlib_reent_small
enable_newlib_fvwrite_in_streamio
enable_multilib
enable_target_optspace
enable_malloc_debugging
@ -1452,6 +1453,7 @@ Optional Features:
--enable-newlib-iconv-external-ccs enable capabilities to load external CCS files for iconv
--disable-newlib-atexit-alloc disable dynamic allocation of atexit entries
--enable-newlib-reent-small enable small reentrant struct support
--disable-newlib-fvwrite-in-streamio disable iov in streamio
--enable-multilib build many library versions (default)
--enable-target-optspace optimize for space
--enable-malloc-debugging indicate malloc debugging requested
@ -2351,6 +2353,19 @@ else
newlib_reent_small=
fi
# Check whether --enable-newlib-fvwrite-in-streamio was given.
if test "${enable_newlib_fvwrite_in_streamio+set}" = set; then :
enableval=$enable_newlib_fvwrite_in_streamio; if test "${newlib_fvwrite_in_streamio+set}" != set; then
case "${enableval}" in
yes) newlib_fvwrite_in_streamio=yes ;;
no) newlib_fvwrite_in_streamio=no ;;
*) as_fn_error $? "bad value ${enableval} for newlib-fvwrite-in-streamio option" "$LINENO" 5 ;;
esac
fi
else
newlib_fvwrite_in_streamio=yes
fi
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@ -12232,6 +12247,13 @@ _ACEOF
fi
if test "${newlib_fvwrite_in_streamio}" = "yes"; then
cat >>confdefs.h <<_ACEOF
#define _FVWRITE_IN_STREAMIO 1
_ACEOF
fi
if test "x${iconv_encodings}" != "x" \
|| test "x${iconv_to_encodings}" != "x" \

View File

@ -123,6 +123,17 @@ AC_ARG_ENABLE(newlib-reent-small,
no) newlib_reent_small=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for newlib-reent-small option) ;;
esac], [newlib_reent_small=])dnl
dnl Support --disable-newlib-fvwrite-in-streamio
AC_ARG_ENABLE(newlib-fvwrite-in-streamio,
[ --disable-newlib-fvwrite-in-streamio disable iov in streamio],
[if test "${newlib_fvwrite_in_streamio+set}" != set; then
case "${enableval}" in
yes) newlib_fvwrite_in_streamio=yes ;;
no) newlib_fvwrite_in_streamio=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for newlib-fvwrite-in-streamio option) ;;
esac
fi], [newlib_fvwrite_in_streamio=yes])dnl
NEWLIB_CONFIGURE(.)
@ -312,6 +323,10 @@ fi
if test "${newlib_atexit_dynamic_alloc}" = "yes"; then
AC_DEFINE_UNQUOTED(_ATEXIT_DYNAMIC_ALLOC)
fi
if test "${newlib_fvwrite_in_streamio}" = "yes"; then
AC_DEFINE_UNQUOTED(_FVWRITE_IN_STREAMIO)
fi
dnl
dnl Parse --enable-newlib-iconv-encodings option argument

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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
#else
#define __SPRINT __sprint_r
#endif
#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
# ifdef STRING_ONLY
# define __SPRINT __ssputs_r
# else
# define __SPRINT __sfputs_r
# endif
int _EXFUN(__SPRINT, (struct _reent *, FILE *, _CONST char *, size_t));
#endif
#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;

View File

@ -57,6 +57,9 @@
/* True if long double supported and it is equal to double. */
#undef _LDBL_EQ_DBL
/* Define if ivo supported in streamio. */
#undef _FVWRITE_IN_STREAMIO
/*
* Iconv encodings enabled ("to" direction)