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>
|
||||
|
||||
* config/io/basic_file_libio.h: Fixups.
|
||||
|
@ -546,9 +546,8 @@ namespace std
|
||||
|
||||
// num_put
|
||||
// Construct and return valid scanf format for floating point types.
|
||||
static bool
|
||||
_S_format_float(const ios_base& __io, char* __fptr, char __mod,
|
||||
streamsize __prec);
|
||||
static void
|
||||
_S_format_float(const ios_base& __io, char* __fptr, char __mod);
|
||||
|
||||
// Construct and return valid scanf format for integer types.
|
||||
static void
|
||||
|
@ -634,6 +634,9 @@ namespace std
|
||||
|
||||
if (__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.
|
||||
char __fbuf[16];
|
||||
@ -646,24 +649,17 @@ namespace std
|
||||
int __cs_size = __max_digits * 3;
|
||||
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||
|
||||
const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
|
||||
if (__fp)
|
||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||
_S_c_locale, __prec);
|
||||
else
|
||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
|
||||
_S_format_float(__io, __fbuf, __mod);
|
||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||
_S_c_locale, __prec);
|
||||
|
||||
// If the buffer was not large enough, try again with the correct size.
|
||||
if (__len >= __cs_size)
|
||||
{
|
||||
__cs_size = __len + 1;
|
||||
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||
if (__fp)
|
||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||
_S_c_locale, __prec);
|
||||
else
|
||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||
_S_c_locale);
|
||||
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
|
||||
_S_c_locale, __prec);
|
||||
}
|
||||
#else
|
||||
// Consider the possibility of long ios_base::fixed outputs
|
||||
@ -678,10 +674,8 @@ namespace std
|
||||
: __max_digits * 3;
|
||||
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||
|
||||
if (_S_format_float(__io, __fbuf, __mod, __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);
|
||||
_S_format_float(__io, __fbuf, __mod);
|
||||
__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
|
||||
#endif
|
||||
return _M_widen_float(__s, __io, __fill, __cs, __len);
|
||||
}
|
||||
|
@ -505,11 +505,12 @@ namespace std
|
||||
|
||||
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
|
||||
|
||||
bool
|
||||
__num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
|
||||
streamsize __prec)
|
||||
// _GLIBCPP_RESOLVE_LIB_DEFECTS
|
||||
// According to the resolution of DR 231, about 22.2.2.2.2, p11,
|
||||
// "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();
|
||||
*__fptr++ = '%';
|
||||
// [22.2.2.2.2] Table 60
|
||||
@ -517,13 +518,12 @@ namespace std
|
||||
*__fptr++ = '+';
|
||||
if (__flags & ios_base::showpoint)
|
||||
*__fptr++ = '#';
|
||||
// As per [22.2.2.2.2.11]
|
||||
if (__flags & ios_base::fixed || __prec > 0)
|
||||
{
|
||||
*__fptr++ = '.';
|
||||
*__fptr++ = '*';
|
||||
__incl_prec = true;
|
||||
}
|
||||
|
||||
// As per DR 231: _always_, not only when
|
||||
// __flags & ios_base::fixed || __prec > 0
|
||||
*__fptr++ = '.';
|
||||
*__fptr++ = '*';
|
||||
|
||||
if (__mod)
|
||||
*__fptr++ = __mod;
|
||||
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
|
||||
@ -535,7 +535,6 @@ namespace std
|
||||
else
|
||||
*__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
|
||||
*__fptr = '\0';
|
||||
return __incl_prec;
|
||||
}
|
||||
|
||||
void
|
||||
|
56
libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc
Normal file
56
libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc
Normal file
@ -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;
|
||||
}
|
56
libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc
Normal file
56
libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc
Normal file
@ -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
Block a user