aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-12-22 11:00:43 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-12-22 11:00:43 +0000
commita827daa06b2335bb93c09c5a8753725f40a76ef4 (patch)
tree60a1fed9a0230867f41beb5c113006bf26cde6d8 /libstdc++-v3
parent9e62871ee9f5f2ed5ee3c4651ef2123388a82028 (diff)
downloadgcc-a827daa06b2335bb93c09c5a8753725f40a76ef4.zip
gcc-a827daa06b2335bb93c09c5a8753725f40a76ef4.tar.gz
gcc-a827daa06b2335bb93c09c5a8753725f40a76ef4.tar.bz2
locale_facets.tcc (num_get::_M_extract_int, [...]): According to 22.2.2.1.2...
2003-12-22 Paolo Carlini <pcarlini@suse.de> * include/bits/locale_facets.tcc (num_get::_M_extract_int, num_get::_M_extract_float): According to 22.2.2.1.2, p8-9, first look for decimal_point and thousands_sep, when parsing sign, leading zeros (and 0, Ox, 0X for integer types) too. * testsuite/22_locale/num_get/get/char/12.cc: New. * testsuite/22_locale/num_get/get/wchar_t/12.cc: Likewise. * testsuite/22_locale/num_get/get/char/11.cc: Add a comment. * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise. From-SVN: r74932
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog12
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc96
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc1
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/12.cc160
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc1
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/12.cc160
6 files changed, 391 insertions, 39 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4c981a5..d8ca538 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,15 @@
+2003-12-22 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/locale_facets.tcc (num_get::_M_extract_int,
+ num_get::_M_extract_float): According to 22.2.2.1.2, p8-9,
+ first look for decimal_point and thousands_sep, when parsing
+ sign, leading zeros (and 0, Ox, 0X for integer types) too.
+ * testsuite/22_locale/num_get/get/char/12.cc: New.
+ * testsuite/22_locale/num_get/get/wchar_t/12.cc: Likewise.
+
+ * testsuite/22_locale/num_get/get/char/11.cc: Add a comment.
+ * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
+
2003-12-20 Jason Merrill <jason@redhat.com>
* config/cpu/powerpc/atomicity.h: Fix oversight in previous
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index b934482..265c143 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -163,12 +163,18 @@ namespace std
const __cache_type* __lc = __uc(__loc);
const _CharT* __lit = __lc->_M_atoms_in;
+ // True if a mantissa is found.
+ bool __found_mantissa = false;
+
// First check for sign.
if (__beg != __end)
{
const char_type __c = *__beg;
const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
- if (__plus || __traits_type::eq(__c, __lit[_S_iminus]))
+ 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)))
{
__xtrc += __plus ? _S_atoms_in[_S_iplus]
: _S_atoms_in[_S_iminus];
@@ -176,16 +182,25 @@ namespace std
}
}
- // Next, look for a zero...
- bool __found_mantissa = false;
- if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
+ // Next, look for leading zeros.
+ while (__beg != __end)
{
- __xtrc += _S_atoms_in[_S_izero];
- __found_mantissa = true;
- ++__beg;
- // ... and skip the additional ones.
- for (; __beg != __end
- && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg);
+ 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)))
+ break;
+ else if (__traits_type::eq(__c, __lit[_S_izero]))
+ {
+ if (!__found_mantissa)
+ {
+ __xtrc += _S_atoms_in[_S_izero];
+ __found_mantissa = true;
+ }
+ ++__beg;
+ }
+ else
+ break;
}
// Only need acceptable digits for floating point numbers.
@@ -307,48 +322,51 @@ namespace std
// First check for sign.
bool __negative = false;
if (__beg != __end)
- {
+ {
+ const char_type __c = *__beg;
if (numeric_limits<_ValueT>::is_signed)
- __negative = __traits_type::eq(*__beg, __lit[_S_iminus]);
- if (__negative || __traits_type::eq(*__beg, __lit[_S_iplus]))
+ __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)))
++__beg;
}
// Next, look for leading zeros and check required digits
// for base formats.
- if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
+ while (__beg != __end)
{
- __found_num = true;
- ++__beg;
- if (__builtin_expect(__base == 10, true))
+ 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)))
+ break;
+ else if (__traits_type::eq(__c, __lit[_S_izero])
+ && (!__found_num || __base == 10))
{
- // Skip the additional zeros.
- for (; __beg != __end
- && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg);
-
- // Check required digits.
- if (__beg != __end && __basefield == 0)
- {
- const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
- if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
- {
- __base = 16;
- ++__beg;
- __found_num = false;
- }
- else
- __base = 8;
- }
+ __found_num = true;
+ ++__beg;
}
- else if (__base == 16 && __beg != __end)
+ else if (__found_num)
{
- const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
- if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
+ if (__traits_type::eq(__c, __lit[_S_ix])
+ || __traits_type::eq(__c, __lit[_S_iX]))
{
- ++__beg;
- __found_num = false;
+ if (__basefield == 0)
+ __base = 16;
+ if (__base == 16)
+ {
+ __found_num = false;
+ ++__beg;
+ }
}
+ else if (__basefield == 0)
+ __base = 8;
+ break;
}
+ else
+ break;
}
// At this point, base is determined. If not hex, only allow
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc
index fde63c4..138f10d 100644
--- a/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc
@@ -29,6 +29,7 @@ struct Punct: std::numpunct<char>
char do_decimal_point() const { return '4'; }
};
+// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
void test01()
{
using namespace std;
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/12.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/12.cc
new file mode 100644
index 0000000..1898867
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/12.cc
@@ -0,0 +1,160 @@
+// 2003-12-22 Paolo Carlini <pcarlini@suse.de>
+
+// 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.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 '+'; }
+ char do_decimal_point() const { return 'x'; }
+};
+
+struct Punct2: std::numpunct<char>
+{
+ std::string do_grouping() const { return "\1"; }
+ char do_thousands_sep() const { return 'X'; }
+ 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;
+ long l = 1l;
+ long l1 = 0l;
+ long l2 = 10l;
+ long l3 = 1l;
+ long l4 = 63l;
+ double d = 0.0;
+ double d1 = .4;
+ double d2 = .1;
+
+ iss1.str("+3");
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == '+' );
+
+ iss1.str("0x1");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == 'x' );
+ VERIFY( l == l1 );
+
+ iss1.str("0Xa");
+ iss1.clear();
+ iss1.unsetf(ios::basefield);
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( l == l2 );
+
+ iss1.str("0xa");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == 'x' );
+ VERIFY( l == l1 );
+
+ iss1.str("+5");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == '+' );
+
+ iss1.str("x4");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss2.str("0001-");
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == '-' );
+ VERIFY( l == l3 );
+
+ iss2.str("-2");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == '-' );
+
+ iss2.str("0X1");
+ iss2.clear();
+ iss2.unsetf(ios::basefield);
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == 'X' );
+
+ iss2.str("000778");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == '8' );
+ VERIFY( l == l4 );
+
+ iss2.str("00X");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == 'X' );
+
+ iss2.str("-1");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d2 );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc
index e438fbe..d478209 100644
--- a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc
@@ -29,6 +29,7 @@ struct Punct: std::numpunct<wchar_t>
wchar_t do_decimal_point() const { return L'4'; }
};
+// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
void test01()
{
using namespace std;
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/12.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/12.cc
new file mode 100644
index 0000000..fa9cb15
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/12.cc
@@ -0,0 +1,160 @@
+// 2003-12-22 Paolo Carlini <pcarlini@suse.de>
+
+// 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.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'+'; }
+ wchar_t do_decimal_point() const { return L'x'; }
+};
+
+struct Punct2: std::numpunct<wchar_t>
+{
+ std::string do_grouping() const { return "\1"; }
+ wchar_t do_thousands_sep() const { return L'X'; }
+ 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;
+ long l = 1l;
+ long l1 = 0l;
+ long l2 = 10l;
+ long l3 = 1l;
+ long l4 = 63l;
+ double d = 0.0;
+ double d1 = .4;
+ double d2 = .1;
+
+ iss1.str(L"+3");
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == L'+' );
+
+ iss1.str(L"0x1");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == L'x' );
+ VERIFY( l == l1 );
+
+ iss1.str(L"0Xa");
+ iss1.clear();
+ iss1.unsetf(ios::basefield);
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( l == l2 );
+
+ iss1.str(L"0xa");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == L'x' );
+ VERIFY( l == l1 );
+
+ iss1.str(L"+5");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == L'+' );
+
+ iss1.str(L"x4");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss2.str(L"0001-");
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == L'-' );
+ VERIFY( l == l3 );
+
+ iss2.str(L"-2");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == L'-' );
+
+ iss2.str(L"0X1");
+ iss2.clear();
+ iss2.unsetf(ios::basefield);
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == L'X' );
+
+ iss2.str(L"000778");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( *end == L'8' );
+ VERIFY( l == l4 );
+
+ iss2.str(L"00X");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( *end == L'X' );
+
+ iss2.str(L"-1");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d2 );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}