This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] libstdc++/9548 and DR 231
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Cc: bkoz <bkoz at redhat dot com>
- Date: Thu, 06 Feb 2003 02:14:17 +0100
- Subject: [Patch] libstdc++/9548 and DR 231
Hi,
the below, for trunk, fixes the bug and implements the resolution of
DR 231 (Ready): both _S_format_float and its call in _M_convert_float
become cleaner.
If the patch gets accepted I would like to apply something similar
to 3_3, keeping intact _S_format_float prototype for ABI-sake.
Tested x86-linux. Ok?
Paolo.
////////////
2003-02-05 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.
diff -prN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
*** libstdc++-v3-orig/include/bits/locale_facets.h Wed Jan 22 17:51:51 2003
--- libstdc++-v3/include/bits/locale_facets.h Wed Feb 5 13:59:04 2003
*************** namespace std
*** 509,517 ****
// 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);
// Construct and return valid scanf format for integer types.
static void
--- 509,516 ----
// num_put
// Construct and return valid scanf format for floating point types.
! static void
! _S_format_float(const ios_base& __io, char* __fptr, char __mod);
// Construct and return valid scanf format for integer types.
static void
diff -prN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
*** libstdc++-v3-orig/include/bits/locale_facets.tcc Sat Feb 1 13:57:21 2003
--- libstdc++-v3/include/bits/locale_facets.tcc Thu Feb 6 01:37:58 2003
*************** namespace std
*** 635,640 ****
--- 635,644 ----
if (__prec > static_cast<streamsize>(__max_digits))
__prec = static_cast<streamsize>(__max_digits);
+ // Default precision.
+ if (__prec < static_cast<streamsize>(0))
+ __prec = static_cast<streamsize>(6);
+
// Long enough for the max format spec.
char __fbuf[16];
*************** namespace std
*** 646,669 ****
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);
// 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);
}
#else
// Consider the possibility of long ios_base::fixed outputs
--- 650,666 ----
int __cs_size = __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
! _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));
! __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
_S_c_locale, __prec);
}
#else
// Consider the possibility of long ios_base::fixed outputs
*************** namespace std
*** 678,687 ****
: __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);
#endif
return _M_widen_float(__s, __io, __fill, __cs, __len);
}
--- 675,682 ----
: __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
! _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);
}
diff -prN libstdc++-v3-orig/src/locale.cc libstdc++-v3/src/locale.cc
*** libstdc++-v3-orig/src/locale.cc Sat Feb 1 13:57:21 2003
--- libstdc++-v3/src/locale.cc Wed Feb 5 13:55:50 2003
*************** namespace std
*** 505,515 ****
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
! bool
! __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
! streamsize __prec)
{
- bool __incl_prec = false;
ios_base::fmtflags __flags = __io.flags();
*__fptr++ = '%';
// [22.2.2.2.2] Table 60
--- 505,516 ----
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
! // _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)
{
ios_base::fmtflags __flags = __io.flags();
*__fptr++ = '%';
// [22.2.2.2.2] Table 60
*************** namespace std
*** 517,529 ****
*__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;
! }
if (__mod)
*__fptr++ = __mod;
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
--- 518,529 ----
*__fptr++ = '+';
if (__flags & ios_base::showpoint)
*__fptr++ = '#';
!
! // 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;
*************** namespace std
*** 535,541 ****
else
*__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
*__fptr = '\0';
- return __incl_prec;
}
void
--- 535,540 ----
diff -prN libstdc++-v3-orig/testsuite/22_locale/num_put/put/char/6.cc libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc
*** libstdc++-v3-orig/testsuite/22_locale/num_put/put/char/6.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc Wed Feb 5 19:24:09 2003
***************
*** 0 ****
--- 1,68 ----
+ // 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
+ void test01()
+ {
+ using namespace std;
+ bool test = true;
+
+ ostringstream oss;
+ const num_put<char>& np = use_facet<num_put<char> >(oss.getloc());
+
+ oss.clear();
+ oss.precision(-1);
+ oss.setf(ios_base::fixed, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, '+', 30.5);
+ string result = oss.str();
+ VERIFY( result == "30.500000" );
+ }
+
+ // DR 231
+ void test02()
+ {
+ using namespace std;
+ bool test = true;
+
+ ostringstream oss;
+ const num_put<char>& np = use_facet<num_put<char> >(oss.getloc());
+
+ oss.clear();
+ oss.precision(0);
+ oss.setf(ios_base::scientific, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, '+', 1.0);
+ string result = oss.str();
+ VERIFY( result == "1e+00" );
+ }
+
+ int main()
+ {
+ test01();
+ test02();
+ return 0;
+ }
+
+
diff -prN libstdc++-v3-orig/testsuite/22_locale/num_put/put/wchar_t/6.cc libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc
*** libstdc++-v3-orig/testsuite/22_locale/num_put/put/wchar_t/6.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc Wed Feb 5 19:25:51 2003
***************
*** 0 ****
--- 1,68 ----
+ // 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
+ void test01()
+ {
+ using namespace std;
+ bool test = true;
+
+ wostringstream oss;
+ const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc());
+
+ oss.clear();
+ oss.precision(-1);
+ oss.setf(ios_base::fixed, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, '+', 30.5);
+ wstring result = oss.str();
+ VERIFY( result == L"30.500000" );
+ }
+
+ // DR 231
+ void test02()
+ {
+ using namespace std;
+ bool test = true;
+
+ wostringstream oss;
+ const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc());
+
+ oss.clear();
+ oss.precision(0);
+ oss.setf(ios_base::scientific, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, '+', 1.0);
+ wstring result = oss.str();
+ VERIFY( result == L"1e+00" );
+ }
+
+ int main()
+ {
+ test01();
+ test02();
+ return 0;
+ }
+
+