OSDN Git Service

2003-02-06 Paolo Carlini <pcarlini@unitus.it>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 Feb 2003 18:08:51 +0000 (18:08 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 Feb 2003 18:08:51 +0000 (18:08 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62492 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/src/locale.cc
libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc [new file with mode: 0644]

index 0dc7487..716943f 100644 (file)
@@ -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.
index a2a043c..59f9d5b 100644 (file)
@@ -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
index e6e9fbe..a30404c 100644 (file)
@@ -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);
       }
index 42972e9..4e90f37 100644 (file)
@@ -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
diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/6.cc
new file mode 100644 (file)
index 0000000..3cc5507
--- /dev/null
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/6.cc
new file mode 100644 (file)
index 0000000..0173360
--- /dev/null
@@ -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;
+}