re PR libstdc++/14220 ([3.5] num_put::do_put() undesired float/double behavior)
authorPaolo Carlini <pcarlini@suse.de>
Thu, 29 Jul 2004 22:11:04 +0000 (22:11 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 29 Jul 2004 22:11:04 +0000 (22:11 +0000)
2004-07-29  Paolo Carlini  <pcarlini@suse.de>

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
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/testsuite/22_locale/num_put/put/char/14220.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/14220.cc [new file with mode: 0644]

index e58e61d91de74c15d87933ae97a4873d3f912806..4a2381afe6969b4e31566ab5b3d6dbd5e26af368 100644 (file)
@@ -1,3 +1,12 @@
+2004-07-29  Paolo Carlini  <pcarlini@suse.de>
+
+       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  <pcarlini@suse.de>
 
        * docs/html/ext/lwg-active.html, lwg-defects.html: Import Revision 31.
index b967cee1b352c49c63f1dabb3fa7fecdf36ccfb7..94a2cb8d81d0a5a2723875a66ae1a8baf352c7b5 100644 (file)
@@ -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<streamsize>(__max_digits))
-         __prec = static_cast<streamsize>(__max_digits);
-       else if (__prec < static_cast<streamsize>(0))
+       if (__prec < static_cast<streamsize>(0))
          __prec = static_cast<streamsize>(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<char*>(__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<char*>(__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 (file)
index 0000000..ecaeec9
--- /dev/null
@@ -0,0 +1,49 @@
+// 2004-04-30  Paolo Carlini  <pcarlini@suse.de>
+
+// 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 <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/14220
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  ostringstream oss;
+  const num_put<char>& np = use_facet<num_put<char> >(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 (file)
index 0000000..1319e56
--- /dev/null
@@ -0,0 +1,49 @@
+// 2004-04-30  Paolo Carlini  <pcarlini@suse.de>
+
+// 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 <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/14220
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+  
+  wostringstream oss;
+  const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(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;
+}