From 7c9b102edeb552a4bb8de08c2287e86130259dc8 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 29 Jul 2004 22:11:04 +0000 Subject: [PATCH] re PR libstdc++/14220 ([3.5] num_put::do_put() undesired float/double behavior) 2004-07-29 Paolo Carlini PR libstdc++/14220 * include/bits/locale_facets.tcc (num_put<>::_M_insert_float): Don't clip the precision passed down to __convert_from_v: 22.2.2.2.2 nowhere says so. * testsuite/22_locale/num_put/put/char/14220.cc: New. * testsuite/22_locale/num_put/put/wchar_t/14220.c: Likewise. From-SVN: r85315 --- libstdc++-v3/ChangeLog | 9 ++++ libstdc++-v3/include/bits/locale_facets.tcc | 31 +++++--------- .../testsuite/22_locale/num_put/put/char/14220.cc | 49 ++++++++++++++++++++++ .../22_locale/num_put/put/wchar_t/14220.cc | 49 ++++++++++++++++++++++ 4 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 libstdc++-v3/testsuite/22_locale/num_put/put/char/14220.cc create mode 100644 libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/14220.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e58e61d..4a2381a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2004-07-29 Paolo Carlini + PR libstdc++/14220 + * include/bits/locale_facets.tcc (num_put<>::_M_insert_float): + Don't clip the precision passed down to __convert_from_v: + 22.2.2.2.2 nowhere says so. + * testsuite/22_locale/num_put/put/char/14220.cc: New. + * testsuite/22_locale/num_put/put/wchar_t/14220.c: Likewise. + +2004-07-29 Paolo Carlini + * docs/html/ext/lwg-active.html, lwg-defects.html: Import Revision 31. 2004-07-29 Paolo Carlini diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index b967cee..94a2cb8 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -1052,29 +1052,20 @@ namespace std const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); - // Note: digits10 is rounded down: add 1 to ensure the maximum - // available precision. Then, in general, one more 1 needs to - // be added since, when the %{g,G} conversion specifiers are - // chosen inside _S_format_float, the precision field is "the - // maximum number of significant digits", *not* the "number of - // digits to appear after the decimal point", as happens for - // %{e,E,f,F} (C99, 7.19.6.1,4). - const int __max_digits = numeric_limits<_ValueT>::digits10 + 2; - // Use default precision if out of range. streamsize __prec = __io.precision(); - if (__prec > static_cast(__max_digits)) - __prec = static_cast(__max_digits); - else if (__prec < static_cast(0)) + if (__prec < static_cast(0)) __prec = static_cast(6); + const int __max_digits = numeric_limits<_ValueT>::digits10; + // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; // Long enough for the max format spec. char __fbuf[16]; #ifdef _GLIBCXX_USE_C99 - // First try a buffer perhaps big enough (for sure sufficient + // First try a buffer perhaps big enough (most probably sufficient // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast(__builtin_alloca(__cs_size)); @@ -1097,13 +1088,13 @@ namespace std const int __max_exp = numeric_limits<_ValueT>::max_exponent10; // The size of the output string is computed as follows. - // ios_base::fixed outputs may need up to __max_exp+1 chars - // for the integer part + up to __max_digits chars for the - // fractional part + 3 chars for sign, decimal point, '\0'. On - // the other hand, for non-fixed outputs __max_digits*3 chars - // are largely sufficient. - const int __cs_size = __fixed ? __max_exp + __max_digits + 4 - : __max_digits * 3; + // ios_base::fixed outputs may need up to __max_exp + 1 chars + // for the integer part + __prec chars for the fractional part + // + 3 chars for sign, decimal point, '\0'. On the other hand, + // for non-fixed outputs __max_digits * 2 + __prec chars are + // largely sufficient. + const int __cs_size = __fixed ? __max_exp + __prec + 4 + : __max_digits * 2 + __prec; char* __cs = static_cast(__builtin_alloca(__cs_size)); __num_base::_S_format_float(__io, __fbuf, __mod); diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/14220.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/14220.cc new file mode 100644 index 0000000..ecaeec9 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/14220.cc @@ -0,0 +1,49 @@ +// 2004-04-30 Paolo Carlini + +// Copyright (C) 2004 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 +#include +#include + +// libstdc++/14220 +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + ostringstream oss; + const num_put& np = use_facet >(oss.getloc()); + + const int precision = 1000; + + oss.precision(precision); + oss.setf(ios_base::fixed); + np.put(oss.rdbuf(), oss, '+', 1.0); + const string result = oss.str(); + VERIFY( result.size() == precision + 2 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/14220.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/14220.cc new file mode 100644 index 0000000..1319e56 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/14220.cc @@ -0,0 +1,49 @@ +// 2004-04-30 Paolo Carlini + +// Copyright (C) 2004 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 +#include +#include + +// libstdc++/14220 +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + wostringstream oss; + const num_put& np = use_facet >(oss.getloc()); + + const int precision = 1000; + + oss.precision(precision); + oss.setf(ios_base::fixed); + np.put(oss.rdbuf(), oss, L'+', 1.0); + const wstring result = oss.str(); + VERIFY( result.size() == precision + 2 ); +} + +int main() +{ + test01(); + return 0; +} -- 2.7.4