aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-12-19 18:14:22 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-12-19 18:14:22 +0000
commitcc16f8b948be00bdbac8af00a388a25a53da901f (patch)
treeff1b04fd3a6e2c553c61890d46904a37bdbad8c7
parent9175d628d00f9f3a5a98a19aba733f6e66452f8f (diff)
downloadgcc-cc16f8b948be00bdbac8af00a388a25a53da901f.zip
gcc-cc16f8b948be00bdbac8af00a388a25a53da901f.tar.gz
gcc-cc16f8b948be00bdbac8af00a388a25a53da901f.tar.bz2
locale_facets.tcc (num_get::_M_extract_int, [...]): According to 22.2.2.1.2, p8-9, first look for decimal_point and thousands_sep.
2003-12-19 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. * testsuite/22_locale/num_get/get/char/11.cc: New. * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise. From-SVN: r74841
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc104
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc68
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc68
4 files changed, 198 insertions, 50 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 441ed54..34bf9d6 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,13 @@
2003-12-19 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.
+ * testsuite/22_locale/num_get/get/char/11.cc: New.
+ * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
+
+2003-12-19 Paolo Carlini <pcarlini@suse.de>
+
* include/bits/locale_facets.tcc (num_get::_M_extract_float):
When __found_sci becomes true stop eating thousands separators
and the decimal radix separator.
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 8f79d9e..4dd3be1 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -169,18 +169,22 @@ namespace std
string __found_grouping;
int __sep_pos = 0;
bool __e;
+ const char_type* __p;
while (__beg != __end)
{
- // Only look in digits.
+ // According to 22.2.2.1.2, p8-9, first look for decimal_point
+ // and thousands_sep.
const char_type __c = *__beg;
- const char_type* __p = __traits_type::find(__lit + _S_izero, 10,
- __c);
- if (__p)
+ if (__traits_type::eq(__c, __lc->_M_decimal_point)
+ && !__found_dec && !__found_sci)
{
- // Try first for acceptable digit; record it if found.
- __xtrc += _S_atoms_in[__p - __lit];
- __found_mantissa = true;
- ++__sep_pos;
+ // According to the standard, if no grouping chars are seen,
+ // no grouping check is applied. Therefore __found_grouping
+ // must be adjusted only if __dec comes after some __sep.
+ if (__found_grouping.size())
+ __found_grouping += static_cast<char>(__sep_pos);
+ __xtrc += '.';
+ __found_dec = true;
++__beg;
}
else if (__lc->_M_use_grouping
@@ -201,16 +205,11 @@ namespace std
break;
}
}
- else if (__traits_type::eq(__c, __lc->_M_decimal_point)
- && !__found_dec && !__found_sci)
+ else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
{
- // According to the standard, if no grouping chars are seen,
- // no grouping check is applied. Therefore __found_grouping
- // must be adjusted only if __dec comes after some __sep.
- if (__found_grouping.size())
- __found_grouping += static_cast<char>(__sep_pos);
- __xtrc += '.';
- __found_dec = true;
+ __xtrc += _S_atoms_in[__p - __lit];
+ __found_mantissa = true;
+ ++__sep_pos;
++__beg;
}
else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
@@ -337,14 +336,34 @@ namespace std
bool __overflow = false;
_ValueT __result = 0;
const char_type* __lit_zero = __lit + _S_izero;
+ const char_type* __p;
if (__negative)
{
const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
for (; __beg != __end; ++__beg)
{
- const char_type* __p = __traits_type::find(__lit_zero,
- __len, *__beg);
- if (__p)
+ // According to 22.2.2.1.2, p8-9, first look for decimal_point
+ // and thousands_sep.
+ const char_type __c = *__beg;
+ if (__traits_type::eq(__c, __lc->_M_decimal_point))
+ break;
+ else if (__lc->_M_use_grouping
+ && __traits_type::eq(__c, __lc->_M_thousands_sep))
+ {
+ // NB: Thousands separator at the beginning of a string
+ // is a no-no, as is two consecutive thousands separators.
+ if (__sep_pos)
+ {
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ }
+ else
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
+ }
+ else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
if (__digit > 15)
@@ -360,11 +379,22 @@ namespace std
__found_num = true;
}
}
+ else
+ // Not a valid input item.
+ break;
+ }
+ }
+ else
+ {
+ const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
+ for (; __beg != __end; ++__beg)
+ {
+ const char_type __c = *__beg;
+ if (__traits_type::eq(__c, __lc->_M_decimal_point))
+ break;
else if (__lc->_M_use_grouping
- && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
+ && __traits_type::eq(__c, __lc->_M_thousands_sep))
{
- // NB: Thousands separator at the beginning of a string
- // is a no-no, as is two consecutive thousands separators.
if (__sep_pos)
{
__found_grouping += static_cast<char>(__sep_pos);
@@ -376,19 +406,7 @@ namespace std
break;
}
}
- else
- // Not a valid input item.
- break;
- }
- }
- else
- {
- const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
- for (; __beg != __end; ++__beg)
- {
- const char_type* __p = __traits_type::find(__lit_zero,
- __len, *__beg);
- if (__p)
+ else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
if (__digit > 15)
@@ -404,20 +422,6 @@ namespace std
__found_num = true;
}
}
- else if (__lc->_M_use_grouping
- && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
- {
- if (__sep_pos)
- {
- __found_grouping += static_cast<char>(__sep_pos);
- __sep_pos = 0;
- }
- else
- {
- __err |= ios_base::failbit;
- break;
- }
- }
else
break;
}
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
new file mode 100644
index 0000000..fde63c4
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc
@@ -0,0 +1,68 @@
+// 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 Punct: std::numpunct<char>
+{
+ std::string do_grouping() const { return "\1"; }
+ char do_thousands_sep() const { return '2'; }
+ char do_decimal_point() const { return '4'; }
+};
+
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ istringstream iss;
+ iss.imbue(locale(iss.getloc(), static_cast<numpunct<char>*>(new Punct)));
+ const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ double d = 0.0;
+ double d1 = 13.0;
+ long l = 0l;
+ long l1 = 13l;
+
+ iss.str("1234");
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss.str("1234");
+ iss.clear();
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( l == l1 );
+}
+
+
+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
new file mode 100644
index 0000000..e438fbe
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc
@@ -0,0 +1,68 @@
+// 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 Punct: std::numpunct<wchar_t>
+{
+ std::string do_grouping() const { return "\1"; }
+ wchar_t do_thousands_sep() const { return L'2'; }
+ wchar_t do_decimal_point() const { return L'4'; }
+};
+
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ wistringstream iss;
+ iss.imbue(locale(iss.getloc(), static_cast<numpunct<wchar_t>*>(new Punct)));
+ const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ double d = 0.0;
+ double d1 = 13.0;
+ long l = 0l;
+ long l1 = 13l;
+
+ iss.str(L"1234");
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss.str(L"1234");
+ iss.clear();
+ err = ios_base::goodbit;
+ end = ng.get(iss.rdbuf(), 0, iss, err, l);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( l == l1 );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}