2011-07-15 Yufeng Zhang <yufeng.zhang@arm.com>
* libc/stdio/vfwprintf.c (wcvt): Add a new parameter len of type int. *length is set to the value of (rev - digits) regardless of whether _MB_CAPABLE is defined or not. Replace BUF with len in calling _mbsnrtowcs_r and also in the loop where _MB_CAPABLE is not defined. (_VFWPRINTF_R): Call wcvt with an extra argument. Call wcvt again with allocated new buffer if buf is not large enough for the conversion. * testsuite/newlib.stdio/stdio.exp: New. * testsuite/newlib.stdio/swprintf.c: Likewise.
This commit is contained in:
parent
c842ff73e7
commit
7890be6e7d
|
@ -1,3 +1,16 @@
|
||||||
|
2011-07-15 Yufeng Zhang <yufeng.zhang@arm.com>
|
||||||
|
|
||||||
|
* libc/stdio/vfwprintf.c (wcvt): Add a new parameter len of type
|
||||||
|
int. *length is set to the value of (rev - digits) regardless
|
||||||
|
of whether _MB_CAPABLE is defined or not. Replace BUF with len
|
||||||
|
in calling _mbsnrtowcs_r and also in the loop where _MB_CAPABLE
|
||||||
|
is not defined.
|
||||||
|
(_VFWPRINTF_R): Call wcvt with an extra argument. Call wcvt
|
||||||
|
again with allocated new buffer if buf is not large enough for
|
||||||
|
the conversion.
|
||||||
|
* testsuite/newlib.stdio/stdio.exp: New.
|
||||||
|
* testsuite/newlib.stdio/swprintf.c: Likewise.
|
||||||
|
|
||||||
2011-07-15 Matt Johnson <johnso87@crhc.illinois.edu>
|
2011-07-15 Matt Johnson <johnso87@crhc.illinois.edu>
|
||||||
|
|
||||||
* libc/stdio/fscanf.c (fscanf): Call _vfscanf_r instead of __svfscanf_r
|
* libc/stdio/fscanf.c (fscanf): Call _vfscanf_r instead of __svfscanf_r
|
||||||
|
|
|
@ -240,7 +240,7 @@ extern int _EXFUN(_ldcheck,(_LONG_DOUBLE *));
|
||||||
# endif /* !_NO_LONGDBL */
|
# endif /* !_NO_LONGDBL */
|
||||||
|
|
||||||
static wchar_t *wcvt(struct _reent *, _PRINTF_FLOAT_TYPE, int, int, wchar_t *,
|
static wchar_t *wcvt(struct _reent *, _PRINTF_FLOAT_TYPE, int, int, wchar_t *,
|
||||||
int *, int, int *, wchar_t *);
|
int *, int, int *, wchar_t *, int);
|
||||||
|
|
||||||
static int wexponent(wchar_t *, int, int);
|
static int wexponent(wchar_t *, int, int);
|
||||||
|
|
||||||
|
@ -996,7 +996,23 @@ reswitch: switch (ch) {
|
||||||
flags |= FPT;
|
flags |= FPT;
|
||||||
|
|
||||||
cp = wcvt (data, _fpvalue, prec, flags, &softsign,
|
cp = wcvt (data, _fpvalue, prec, flags, &softsign,
|
||||||
&expt, ch, &ndig, cp);
|
&expt, ch, &ndig, cp, BUF);
|
||||||
|
|
||||||
|
/* If buf is not large enough for the converted wchar_t
|
||||||
|
sequence, call wcvt again with a malloced new buffer.
|
||||||
|
This should happen fairly rarely.
|
||||||
|
*/
|
||||||
|
if (cp == buf && ndig > BUF && malloc_buf == NULL) {
|
||||||
|
if ((malloc_buf =
|
||||||
|
(wchar_t *)_malloc_r (data, ndig * sizeof (wchar_t)))
|
||||||
|
== NULL)
|
||||||
|
{
|
||||||
|
fp->_flags |= __SERR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
cp = wcvt (data, _fpvalue, prec, flags, &softsign,
|
||||||
|
&expt, ch, &ndig, malloc_buf, ndig);
|
||||||
|
}
|
||||||
|
|
||||||
if (ch == L'g' || ch == L'G') {
|
if (ch == L'g' || ch == L'G') {
|
||||||
if (expt <= -4 || expt > prec)
|
if (expt <= -4 || expt > prec)
|
||||||
|
@ -1450,11 +1466,15 @@ error:
|
||||||
to whether trailing zeros must be included. Set *SIGN to nonzero
|
to whether trailing zeros must be included. Set *SIGN to nonzero
|
||||||
if VALUE was negative. Set *DECPT to the exponent plus one. Set
|
if VALUE was negative. Set *DECPT to the exponent plus one. Set
|
||||||
*LENGTH to the length of the returned string. CH must be one of
|
*LENGTH to the length of the returned string. CH must be one of
|
||||||
[aAeEfFgG]; if it is [aA], then the return string lives in BUF,
|
[aAeEfFgG]; different from vfprintf.c:cvt(), the return string
|
||||||
otherwise the return value shares the mprec reentrant storage. */
|
lives in BUF regardless of CH. LEN is the length of BUF, except
|
||||||
|
when CH is [aA], in which case LEN is not in use. If BUF is not
|
||||||
|
large enough for the converted string, only the first LEN number
|
||||||
|
of characters will be returned in BUF, but *LENGTH will be set to
|
||||||
|
the full length of the string before the truncation. */
|
||||||
static wchar_t *
|
static wchar_t *
|
||||||
wcvt(struct _reent *data, _PRINTF_FLOAT_TYPE value, int ndigits, int flags,
|
wcvt(struct _reent *data, _PRINTF_FLOAT_TYPE value, int ndigits, int flags,
|
||||||
wchar_t *sign, int *decpt, int ch, int *length, wchar_t *buf)
|
wchar_t *sign, int *decpt, int ch, int *length, wchar_t *buf, int len)
|
||||||
{
|
{
|
||||||
int mode, dsgn;
|
int mode, dsgn;
|
||||||
# ifdef _NO_LONGDBL
|
# ifdef _NO_LONGDBL
|
||||||
|
@ -1548,12 +1568,13 @@ wcvt(struct _reent *data, _PRINTF_FLOAT_TYPE value, int ndigits, int flags,
|
||||||
while (rve < bp)
|
while (rve < bp)
|
||||||
*rve++ = '0';
|
*rve++ = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*length = rve - digits; /* full length of the string */
|
||||||
#ifdef _MB_CAPABLE
|
#ifdef _MB_CAPABLE
|
||||||
*length = _mbsnrtowcs_r (data, buf, (const char **) &digits,
|
_mbsnrtowcs_r (data, buf, (const char **) &digits, *length,
|
||||||
rve - digits, BUF, NULL);
|
len, NULL);
|
||||||
#else
|
#else
|
||||||
*length = rve - digits;
|
for (i = 0; i < *length && i < len; ++i)
|
||||||
for (i = 0; i < *length && i < BUF; ++i)
|
|
||||||
buf[i] = (wchar_t) digits[i];
|
buf[i] = (wchar_t) digits[i];
|
||||||
#endif
|
#endif
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (C) 2011 by ARM Ltd. All rights reserved.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software
|
||||||
|
# is freely granted, provided that this notice is preserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
load_lib passfail.exp
|
||||||
|
|
||||||
|
set exclude_list {
|
||||||
|
}
|
||||||
|
|
||||||
|
newlib_pass_fail_all -x $exclude_list
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 by ARM Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software
|
||||||
|
* is freely granted, provided that this notice is preserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <newlib.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "check.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#if defined(INTEGER_ONLY) || defined(NO_FLOATING_POINT)
|
||||||
|
|
||||||
|
#else
|
||||||
|
char cbuf[512];
|
||||||
|
wchar_t wcbuf[512], wcbuf2[512];
|
||||||
|
double val = 1E+308;
|
||||||
|
snprintf(cbuf, 512, "%.*f", 3, val);
|
||||||
|
swprintf(wcbuf, 512, L"%.*f", 3, val);
|
||||||
|
mbstowcs(wcbuf2, cbuf, 512);
|
||||||
|
|
||||||
|
CHECK (wcscmp(wcbuf, wcbuf2) == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit (0);
|
||||||
|
}
|
Loading…
Reference in New Issue