2004-03-01 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Mar 2004 10:31:33 +0000 (10:31 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Mar 2004 10:31:33 +0000 (10:31 +0000)
* include/bits/locale_facets.tcc (num_get<>::_M_extract_float):
Also when parsing exponent sign, first look for thousands_sep
and decimal_point; tweak a bit.
* testsuite/22_locale/num_get/get/char/15.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/15.cc: New.

* include/bits/locale_facets.tcc (num_get<>::_M_extract_float,
num_get<>::_M_extract_int): Reorder some conditionals.

2004-03-01  Paolo Carlini  <pcarlini@suse.de>

* include/bits/locale_facets.tcc (money_get<>::_M_extract):
Consistently with numpunct, enforce the requirements in
22.2.6.3, p3 for the thousands separators; tweak a bit.
* testsuite/22_locale/money_get/get/char/15.cc: New.
* testsuite/22_locale/money_get/get/wchar_t/15.cc: New.

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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/testsuite/22_locale/money_get/get/char/15.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/15.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get/get/char/15.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/15.cc [new file with mode: 0644]

index 4525565..251c5e0 100644 (file)
@@ -1,3 +1,22 @@
+2004-03-01  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/locale_facets.tcc (num_get<>::_M_extract_float):
+       Also when parsing exponent sign, first look for thousands_sep
+       and decimal_point; tweak a bit.
+       * testsuite/22_locale/num_get/get/char/15.cc: New.
+       * testsuite/22_locale/num_get/get/wchar_t/15.cc: New.
+       
+       * include/bits/locale_facets.tcc (num_get<>::_M_extract_float,
+       num_get<>::_M_extract_int): Reorder some conditionals.
+
+2004-03-01  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/locale_facets.tcc (money_get<>::_M_extract):
+       Consistently with numpunct, enforce the requirements in
+       22.2.6.3, p3 for the thousands separators; tweak a bit.
+       * testsuite/22_locale/money_get/get/char/15.cc: New.
+       * testsuite/22_locale/money_get/get/wchar_t/15.cc: New.
+       
 2004-03-01  David Billinghurst <David.Billinghurst@riotinto.com>
 
        * testsuite/lib/libstdc++.exp (v3-list-tests): Use 
index ae824b5..9fb234b 100644 (file)
@@ -184,9 +184,9 @@ namespace std
          const char_type __c = *__beg;
          const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
          if ((__plus || __traits_type::eq(__c, __lit[_S_iminus]))
-             && !__traits_type::eq(__c, __lc->_M_decimal_point)
              && (!__lc->_M_use_grouping
-                 || !__traits_type::eq(__c, __lc->_M_thousands_sep)))
+                 || !__traits_type::eq(__c, __lc->_M_thousands_sep))
+             && !__traits_type::eq(__c, __lc->_M_decimal_point))
            {
              __xtrc += __plus ? '+' : '-';
              ++__beg;
@@ -197,9 +197,9 @@ namespace std
       while (__beg != __end)
        {
          const char_type __c = *__beg;
-         if (__traits_type::eq(__c, __lc->_M_decimal_point)
-             || (__lc->_M_use_grouping
-                 && __traits_type::eq(__c, __lc->_M_thousands_sep)))
+         if (__lc->_M_use_grouping
+             && __traits_type::eq(__c, __lc->_M_thousands_sep)
+             || __traits_type::eq(__c, __lc->_M_decimal_point))
            break;
          else if (__traits_type::eq(__c, __lit[_S_izero]))
            {
@@ -221,7 +221,6 @@ namespace std
       if (__lc->_M_use_grouping)
        __found_grouping.reserve(32);
       int __sep_pos = 0;
-      bool __e;
       const char_type* __lit_zero = __lit + _S_izero;
       const char_type* __q;
       while (__beg != __end)
@@ -274,14 +273,14 @@ namespace std
              ++__sep_pos;
              ++__beg;
            }
-         else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
+         else if ((__traits_type::eq(__c, __lit[_S_ie])
                    || __traits_type::eq(__c, __lit[_S_iE]))
                   && __found_mantissa && !__found_sci)
            {
              // Scientific notation.
              if (__found_grouping.size() && !__found_dec)
                __found_grouping += static_cast<char>(__sep_pos);
-             __xtrc += __e ? 'e' : 'E';
+             __xtrc += 'e';
              __found_sci = true;
 
              // Remove optional plus or minus sign, if they exist.
@@ -289,7 +288,10 @@ namespace std
                {
                  const bool __plus = __traits_type::eq(*__beg,
                                                        __lit[_S_iplus]);
-                 if (__plus || __traits_type::eq(*__beg, __lit[_S_iminus]))
+                 if ((__plus || __traits_type::eq(*__beg, __lit[_S_iminus]))
+                     && (!__lc->_M_use_grouping
+                         || !__traits_type::eq(*__beg, __lc->_M_thousands_sep))
+                     && !__traits_type::eq(*__beg, __lc->_M_decimal_point))
                    {
                      __xtrc += __plus ? '+' : '-';
                      ++__beg;
@@ -351,9 +353,9 @@ namespace std
            if (numeric_limits<_ValueT>::is_signed)
              __negative = __traits_type::eq(__c, __lit[_S_iminus]);
            if ((__negative || __traits_type::eq(__c, __lit[_S_iplus]))
-               && !__traits_type::eq(__c, __lc->_M_decimal_point)
                && (!__lc->_M_use_grouping
-                   || !__traits_type::eq(__c, __lc->_M_thousands_sep)))
+                   || !__traits_type::eq(__c, __lc->_M_thousands_sep))
+               && !__traits_type::eq(__c, __lc->_M_decimal_point))
              ++__beg;
          }
 
@@ -362,9 +364,9 @@ namespace std
        while (__beg != __end)
          {
            const char_type __c = *__beg;
-           if (__traits_type::eq(__c, __lc->_M_decimal_point)
-               || (__lc->_M_use_grouping
-                   && __traits_type::eq(__c, __lc->_M_thousands_sep)))
+           if (__lc->_M_use_grouping
+               && __traits_type::eq(__c, __lc->_M_thousands_sep)
+               || __traits_type::eq(__c, __lc->_M_decimal_point))
              break;
            else if (__traits_type::eq(__c, __lit[_S_izero])
                     && (!__found_num || __base == 10))
@@ -1201,8 +1203,10 @@ namespace std
        string __grouping_tmp;
        if (__lc->_M_use_grouping)
          __grouping_tmp.reserve(32);
-       // Marker for thousands_sep position.
-       int __sep_pos = 0;
+       // Last position before the decimal point.
+       int __last_pos = 0;
+       // Separator positions, then, possibly, fractional digits.
+       int __n = 0;
        // If input iterator is in a valid state.
        bool __testvalid = true;
        // Flag marking when a decimal point is found.
@@ -1277,26 +1281,23 @@ namespace std
                  if (__q = __traits_type::find(__lit_zero, 10, *__beg))
                    {
                      __res += _S_atoms[__q - __lit];
-                     ++__sep_pos;
+                     ++__n;
                    }
                  else if (*__beg == __lc->_M_decimal_point && !__testdecfound)
                    {
-                     // If no grouping chars are seen, no grouping check
-                     // is applied. Therefore __grouping_tmp is adjusted
-                     // only if decimal_point comes after some thousands_sep.
-                     if (__grouping_tmp.size())
-                       __grouping_tmp += static_cast<char>(__sep_pos);
-                     __sep_pos = 0;
+                     __last_pos = __n;
+                     __n = 0;
                      __testdecfound = true;
                    }
                  else if (__lc->_M_use_grouping
-                          && *__beg == __lc->_M_thousands_sep)
+                          && *__beg == __lc->_M_thousands_sep
+                          && !__testdecfound)
                    {
-                     if (!__testdecfound)
+                     if (__n)
                        {
                          // Mark position for later analysis.
-                         __grouping_tmp += static_cast<char>(__sep_pos);
-                         __sep_pos = 0;
+                         __grouping_tmp += static_cast<char>(__n);
+                         __n = 0;
                        }
                      else
                        {
@@ -1350,10 +1351,9 @@ namespace std
            // Test for grouping fidelity.
            if (__grouping_tmp.size())
              {
-               // Add the ending grouping if a decimal wasn't found.
-               if (!__testdecfound)
-                 __grouping_tmp += static_cast<char>(__sep_pos);
-               
+               // Add the ending grouping.
+               __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
+                                                                  : __n);
                if (!std::__verify_grouping(__lc->_M_grouping,
                                            __lc->_M_grouping_size,
                                            __grouping_tmp))
@@ -1362,7 +1362,7 @@ namespace std
            
            // Iff not enough digits were supplied after the decimal-point.
            if (__testdecfound && __lc->_M_frac_digits > 0
-               && __sep_pos != __lc->_M_frac_digits)
+               && __n != __lc->_M_frac_digits)
              __testvalid = false;
          }
        else
diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/char/15.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/char/15.cc
new file mode 100644 (file)
index 0000000..a5e766e
--- /dev/null
@@ -0,0 +1,68 @@
+// 2004-03-01  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.6.1.1 money_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// The grammar doesn't allow thousands separator at the beginning of a
+// string, neither two consecutive thousands separators. 
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  typedef istreambuf_iterator<char> iterator_type;
+
+  // basic construction
+  locale loc_c = locale::classic();
+  locale loc_de = __gnu_test::try_named_locale("de_DE@euro");
+  VERIFY( loc_c != loc_de );
+
+  iterator_type end01, end02;
+  istringstream iss;
+  iss.imbue(loc_de);
+  // cache the money_get facet
+  const money_get<char>& mon_get = use_facet<money_get<char> >(iss.getloc()); 
+
+  iss.str(".100");
+  iterator_type is_it01(iss);
+  long double result1;
+  ios_base::iostate err01 = ios_base::goodbit;
+  end01 = mon_get.get(is_it01, end01, true, iss, err01, result1);
+  VERIFY( err01 == ios_base::failbit );
+  VERIFY( *end01 == '.' );
+
+  iss.str("30..0");
+  iterator_type is_it02(iss);
+  long double result2;
+  ios_base::iostate err02 = ios_base::goodbit;
+  end02 = mon_get.get(is_it02, end02, false, iss, err02, result2);
+  VERIFY( err02 == ios_base::failbit );
+  VERIFY( *end02 == '.' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/15.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/15.cc
new file mode 100644 (file)
index 0000000..52a4589
--- /dev/null
@@ -0,0 +1,69 @@
+// 2004-03-01  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.6.1.1 money_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// The grammar doesn't allow thousands separator at the beginning of a
+// string, neither two consecutive thousands separators. 
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  typedef istreambuf_iterator<wchar_t> iterator_type;
+
+  // basic construction
+  locale loc_c = locale::classic();
+  locale loc_de = __gnu_test::try_named_locale("de_DE@euro");
+  VERIFY( loc_c != loc_de );
+
+  iterator_type end01, end02;
+  wistringstream iss;
+  iss.imbue(loc_de);
+  // cache the money_get facet
+  const money_get<wchar_t>& mon_get =
+    use_facet<money_get<wchar_t> >(iss.getloc()); 
+
+  iss.str(L".100");
+  iterator_type is_it01(iss);
+  long double result1;
+  ios_base::iostate err01 = ios_base::goodbit;
+  end01 = mon_get.get(is_it01, end01, true, iss, err01, result1);
+  VERIFY( err01 == ios_base::failbit );
+  VERIFY( *end01 == L'.' );
+
+  iss.str(L"30..0");
+  iterator_type is_it02(iss);
+  long double result2;
+  ios_base::iostate err02 = ios_base::goodbit;
+  end02 = mon_get.get(is_it02, end02, false, iss, err02, result2);
+  VERIFY( err02 == ios_base::failbit );
+  VERIFY( *end02 == L'.' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/15.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/15.cc
new file mode 100644 (file)
index 0000000..c550181
--- /dev/null
@@ -0,0 +1,75 @@
+// 2004-03-01  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.1.1  num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct Punct1: std::numpunct<char>
+{
+  std::string do_grouping() const { return "\1"; }
+  char do_thousands_sep() const { return '+'; }
+};
+
+struct Punct2: std::numpunct<char>
+{
+  char do_decimal_point() const { return '-'; }
+};
+
+// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
+void test01()
+{
+  using namespace std;
+  typedef istreambuf_iterator<char> iterator_type;
+  
+  bool test __attribute__((unused)) = true;
+
+  istringstream iss1, iss2;
+  iss1.imbue(locale(iss1.getloc(), static_cast<numpunct<char>*>(new Punct1)));
+  iss2.imbue(locale(iss2.getloc(), static_cast<numpunct<char>*>(new Punct2)));
+  const num_get<char>& ng1 = use_facet<num_get<char> >(iss1.getloc()); 
+  const num_get<char>& ng2 = use_facet<num_get<char> >(iss2.getloc()); 
+
+  ios_base::iostate err = ios_base::goodbit;
+  iterator_type end;
+  double d = 0.0;
+  double d1 = 1.0;
+  double d2 = 3.0;
+  
+  iss1.str("1e+2");
+  err = ios_base::goodbit;
+  end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( d == d1 );
+
+  iss2.str("3e-1");
+  err = ios_base::goodbit;
+  end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( d == d2 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/15.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/15.cc
new file mode 100644 (file)
index 0000000..ef4d7b7
--- /dev/null
@@ -0,0 +1,75 @@
+// 2004-03-01  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.1.1  num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct Punct1: std::numpunct<wchar_t>
+{
+  std::string do_grouping() const { return "\1"; }
+  wchar_t do_thousands_sep() const { return L'+'; }
+};
+
+struct Punct2: std::numpunct<wchar_t>
+{
+  wchar_t do_decimal_point() const { return L'-'; }
+};
+
+// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
+void test01()
+{
+  using namespace std;
+  typedef istreambuf_iterator<wchar_t> iterator_type;
+  
+  bool test __attribute__((unused)) = true;
+
+  wistringstream iss1, iss2;
+  iss1.imbue(locale(iss1.getloc(), static_cast<numpunct<wchar_t>*>(new Punct1)));
+  iss2.imbue(locale(iss2.getloc(), static_cast<numpunct<wchar_t>*>(new Punct2)));
+  const num_get<wchar_t>& ng1 = use_facet<num_get<wchar_t> >(iss1.getloc()); 
+  const num_get<wchar_t>& ng2 = use_facet<num_get<wchar_t> >(iss2.getloc()); 
+
+  ios_base::iostate err = ios_base::goodbit;
+  iterator_type end;
+  double d = 0.0;
+  double d1 = 1.0;
+  double d2 = 3.0;
+  
+  iss1.str(L"1e+2");
+  err = ios_base::goodbit;
+  end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( d == d1 );
+
+  iss2.str(L"3e-1");
+  err = ios_base::goodbit;
+  end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( d == d2 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}