mirror of git://gcc.gnu.org/git/gcc.git
re PR libstdc++/9548 (Incorrect results from setf(ios::fixed) and precision(-1) [DR231])
2003-02-06 Paolo Carlini <pcarlini@unitus.it> PR libstdc++/9548 Implement resolution of DR 231 (Ready) * include/bits/locale_facets.h (__num_base::_S_format_float): Change declaration: return void, remove __prec parameter. * src/locale.cc (__num_base::_S_format_float): Implement resolution of DR 231. * include/bits/locale_facets.tcc (num_put::_M_convert_float): Tweak uses. Check for negative precision. * testsuite/22_locale/num_put/put/char/6.cc: Add * testsuite/22_locale/num_put/put/wchar_t/6.cc: Likewise. From-SVN: r62492
This commit is contained in:
parent
a1ba6e15ea
commit
5dc911525c
|
|
@ -1,3 +1,16 @@
|
||||||
|
2003-02-06 Paolo Carlini <pcarlini@unitus.it>
|
||||||
|
|
||||||
|
PR libstdc++/9548
|
||||||
|
Implement resolution of DR 231 (Ready)
|
||||||
|
* include/bits/locale_facets.h (__num_base::_S_format_float):
|
||||||
|
Change declaration: return void, remove __prec parameter.
|
||||||
|
* src/locale.cc (__num_base::_S_format_float): Implement
|
||||||
|
resolution of DR 231.
|
||||||
|
* include/bits/locale_facets.tcc (num_put::_M_convert_float):
|
||||||
|
Tweak uses. Check for negative precision.
|
||||||
|
* testsuite/22_locale/num_put/put/char/6.cc: Add
|
||||||
|
* testsuite/22_locale/num_put/put/wchar_t/6.cc: Likewise.
|
||||||
|
|
||||||
2003-02-06 Peter Soetens <peter.soetens@mech.kuleuven.ac.be>
|
2003-02-06 Peter Soetens <peter.soetens@mech.kuleuven.ac.be>
|
||||||
|
|
||||||
* config/io/basic_file_libio.h: Fixups.
|
* config/io/basic_file_libio.h: Fixups.
|
||||||
|
|
|
||||||
|
|
@ -546,9 +546,8 @@ namespace std
|
||||||
|
|
||||||
// num_put
|
// num_put
|
||||||
// Construct and return valid scanf format for floating point types.
|
// Construct and return valid scanf format for floating point types.
|
||||||
static bool
|
static void
|
||||||
_S_format_float(const ios_base& __io, char* __fptr, char __mod,
|
_S_format_float(const ios_base& __io, char* __fptr, char __mod);
|
||||||
streamsize __prec);
|
|
||||||
|
|
||||||
// Construct and return valid scanf format for integer types.
|
// Construct and return valid scanf format for integer types.
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -634,6 +634,9 @@ namespace std
|
||||||
|
|
||||||
if (__prec > static_cast<streamsize>(__max_digits))
|
if (__prec > static_cast<streamsize>(__max_digits))
|
||||||
__prec = static_cast<streamsize>(__max_digits);
|
__prec = static_cast<streamsize>(__max_digits);
|
||||||
|
else if (__prec < static_cast<streamsize>(0))
|
||||||
|
// Default precision.
|
||||||
|
__prec = static_cast<streamsize>(6);
|
||||||
|
|
||||||
// Long enough for the max format spec.
|
// Long enough for the max format spec.
|
||||||
char __fbuf[16];
|
char __fbuf[16];
|
||||||
|
|
@ -646,24 +649,17 @@ namespace std
|
||||||
int __cs_size = __max_digits * 3;
|
int __cs_size = __max_digits * 3;
|
||||||
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||||
|
|
||||||
const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
|
_S_format_float(__io, __fbuf, __mod);
|
||||||
if (__fp)
|
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
_S_c_locale, __prec);
|
||||||
_S_c_locale, __prec);
|
|
||||||
else
|
|
||||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
|
|
||||||
|
|
||||||
// If the buffer was not large enough, try again with the correct size.
|
// If the buffer was not large enough, try again with the correct size.
|
||||||
if (__len >= __cs_size)
|
if (__len >= __cs_size)
|
||||||
{
|
{
|
||||||
__cs_size = __len + 1;
|
__cs_size = __len + 1;
|
||||||
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||||
if (__fp)
|
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
_S_c_locale, __prec);
|
||||||
_S_c_locale, __prec);
|
|
||||||
else
|
|
||||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
|
||||||
_S_c_locale);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Consider the possibility of long ios_base::fixed outputs
|
// Consider the possibility of long ios_base::fixed outputs
|
||||||
|
|
@ -678,10 +674,8 @@ namespace std
|
||||||
: __max_digits * 3;
|
: __max_digits * 3;
|
||||||
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||||
|
|
||||||
if (_S_format_float(__io, __fbuf, __mod, __prec))
|
_S_format_float(__io, __fbuf, __mod);
|
||||||
__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
|
__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
|
||||||
else
|
|
||||||
__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
|
|
||||||
#endif
|
#endif
|
||||||
return _M_widen_float(__s, __io, __fill, __cs, __len);
|
return _M_widen_float(__s, __io, __fill, __cs, __len);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -505,11 +505,12 @@ namespace std
|
||||||
|
|
||||||
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
|
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
|
||||||
|
|
||||||
bool
|
// _GLIBCPP_RESOLVE_LIB_DEFECTS
|
||||||
__num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
|
// According to the resolution of DR 231, about 22.2.2.2.2, p11,
|
||||||
streamsize __prec)
|
// "str.precision() is specified in the conversion specification".
|
||||||
|
void
|
||||||
|
__num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod)
|
||||||
{
|
{
|
||||||
bool __incl_prec = false;
|
|
||||||
ios_base::fmtflags __flags = __io.flags();
|
ios_base::fmtflags __flags = __io.flags();
|
||||||
*__fptr++ = '%';
|
*__fptr++ = '%';
|
||||||
// [22.2.2.2.2] Table 60
|
// [22.2.2.2.2] Table 60
|
||||||
|
|
@ -517,13 +518,12 @@ namespace std
|
||||||
*__fptr++ = '+';
|
*__fptr++ = '+';
|
||||||
if (__flags & ios_base::showpoint)
|
if (__flags & ios_base::showpoint)
|
||||||
*__fptr++ = '#';
|
*__fptr++ = '#';
|
||||||
// As per [22.2.2.2.2.11]
|
|
||||||
if (__flags & ios_base::fixed || __prec > 0)
|
// As per DR 231: _always_, not only when
|
||||||
{
|
// __flags & ios_base::fixed || __prec > 0
|
||||||
*__fptr++ = '.';
|
*__fptr++ = '.';
|
||||||
*__fptr++ = '*';
|
*__fptr++ = '*';
|
||||||
__incl_prec = true;
|
|
||||||
}
|
|
||||||
if (__mod)
|
if (__mod)
|
||||||
*__fptr++ = __mod;
|
*__fptr++ = __mod;
|
||||||
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
|
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
|
||||||
|
|
@ -535,7 +535,6 @@ namespace std
|
||||||
else
|
else
|
||||||
*__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
|
*__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
|
||||||
*__fptr = '\0';
|
*__fptr = '\0';
|
||||||
return __incl_prec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
// 2003-02-05 Paolo Carlini <pcarlini@unitus.it>
|
||||||
|
|
||||||
|
// Copyright (C) 2003 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING. If not, write to the Free
|
||||||
|
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||||
|
// USA.
|
||||||
|
|
||||||
|
// 22.2.2.2.1 num_put members
|
||||||
|
|
||||||
|
#include <locale>
|
||||||
|
#include <sstream>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
// libstdc++/9548 and DR 231
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
bool test = true;
|
||||||
|
|
||||||
|
ostringstream oss1, oss2;
|
||||||
|
const num_put<char>& np1 = use_facet<num_put<char> >(oss1.getloc());
|
||||||
|
const num_put<char>& np2 = use_facet<num_put<char> >(oss2.getloc());
|
||||||
|
|
||||||
|
string result1, result2;
|
||||||
|
|
||||||
|
oss1.precision(-1);
|
||||||
|
oss1.setf(ios_base::fixed, ios_base::floatfield);
|
||||||
|
np1.put(oss1.rdbuf(), oss1, '+', 30.5);
|
||||||
|
result1 = oss1.str();
|
||||||
|
VERIFY( result1 == "30.500000" );
|
||||||
|
|
||||||
|
oss2.precision(0);
|
||||||
|
oss2.setf(ios_base::scientific, ios_base::floatfield);
|
||||||
|
np2.put(oss2.rdbuf(), oss2, '+', 1.0);
|
||||||
|
result2 = oss2.str();
|
||||||
|
VERIFY( result2 == "1e+00" );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
// 2003-02-05 Paolo Carlini <pcarlini@unitus.it>
|
||||||
|
|
||||||
|
// Copyright (C) 2003 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING. If not, write to the Free
|
||||||
|
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||||
|
// USA.
|
||||||
|
|
||||||
|
// 22.2.2.2.1 num_put members
|
||||||
|
|
||||||
|
#include <locale>
|
||||||
|
#include <sstream>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
// libstdc++/9548 and DR 231
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
bool test = true;
|
||||||
|
|
||||||
|
wostringstream woss1, woss2;
|
||||||
|
const num_put<wchar_t>& np1 = use_facet<num_put<wchar_t> >(woss1.getloc());
|
||||||
|
const num_put<wchar_t>& np2 = use_facet<num_put<wchar_t> >(woss2.getloc());
|
||||||
|
|
||||||
|
wstring result1, result2;
|
||||||
|
|
||||||
|
woss1.precision(-1);
|
||||||
|
woss1.setf(ios_base::fixed, ios_base::floatfield);
|
||||||
|
np1.put(woss1.rdbuf(), woss1, '+', 30.5);
|
||||||
|
result1 = woss1.str();
|
||||||
|
VERIFY( result1 == L"30.500000" );
|
||||||
|
|
||||||
|
woss2.precision(0);
|
||||||
|
woss2.setf(ios_base::scientific, ios_base::floatfield);
|
||||||
|
np2.put(woss2.rdbuf(), woss2, '+', 1.0);
|
||||||
|
result2 = woss2.str();
|
||||||
|
VERIFY( result2 == L"1e+00" );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue