aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-12-31 08:28:10 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-12-31 08:28:10 +0000
commit4f0c9c8a876450531bcfa8989d327efdbd0cd93c (patch)
treedc615e287c0bd2140978df6b1f24cda3d7812fb3
parentf5cb6ca2675b946792989030a5b840e25d631616 (diff)
downloadgcc-4f0c9c8a876450531bcfa8989d327efdbd0cd93c.zip
gcc-4f0c9c8a876450531bcfa8989d327efdbd0cd93c.tar.gz
gcc-4f0c9c8a876450531bcfa8989d327efdbd0cd93c.tar.bz2
locale_facets.tcc (num_get::_M_extract_int, [...]): According to 22.2.2.1.2...
2003-12-31 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 thousands_sep, then for decimal_point and finally for digits. (num_get::_M_extract_float): After the decimal_point or 'e'/'E', decimal_point and thousands_sep just break out the parsing loop. * testsuite/22_locale/num_get/get/char/11.cc: Add tests. * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise. From-SVN: r75259
-rw-r--r--libstdc++-v3/ChangeLog12
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc90
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc59
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc59
4 files changed, 159 insertions, 61 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 5add00b..4a976be 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,15 @@
+2003-12-31 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 thousands_sep, then for decimal_point and
+ finally for digits.
+ (num_get::_M_extract_float): After the decimal_point or
+ 'e'/'E', decimal_point and thousands_sep just break out the
+ parsing loop.
+ * testsuite/22_locale/num_get/get/char/11.cc: Add tests.
+ * testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
+
2003-12-30 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/13369
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 40b612c..0840ba1 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -212,39 +212,47 @@ namespace std
const char_type* __p;
while (__beg != __end)
{
- // According to 22.2.2.1.2, p8-9, first look for decimal_point
- // and thousands_sep.
+ // According to 22.2.2.1.2, p8-9, first look for thousands_sep
+ // and decimal_point.
const char_type __c = *__beg;
- if (__traits_type::eq(__c, __lc->_M_decimal_point)
- && !__found_dec && !__found_sci)
+ if (__lc->_M_use_grouping
+ && __traits_type::eq(__c, __lc->_M_thousands_sep))
{
- // 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
- && __traits_type::eq(__c, __lc->_M_thousands_sep)
- && !__found_dec && !__found_sci)
- {
- // 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;
- ++__beg;
- }
- else
+ if (!__found_dec && !__found_sci)
{
- __err |= ios_base::failbit;
- break;
+ // 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;
+ ++__beg;
+ }
+ else
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
}
+ else
+ break;
}
+ else if (__traits_type::eq(__c, __lc->_M_decimal_point))
+ {
+ if (!__found_dec && !__found_sci)
+ {
+ // If no grouping chars are seen, no grouping check
+ // is applied. Therefore __found_grouping is adjusted
+ // only if decimal_point comes after some thousands_sep.
+ if (__found_grouping.size())
+ __found_grouping += static_cast<char>(__sep_pos);
+ __xtrc += '.';
+ __found_dec = true;
+ ++__beg;
+ }
+ else
+ break;
+ }
else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
{
__xtrc += _S_atoms_in[__p - __lit];
@@ -385,13 +393,11 @@ namespace std
const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
for (; __beg != __end; ++__beg)
{
- // 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))
+ // According to 22.2.2.1.2, p8-9, first look for thousands_sep
+ // and decimal_point.
+ const char_type __c = *__beg;
+ 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.
@@ -406,6 +412,8 @@ namespace std
break;
}
}
+ else if (__traits_type::eq(__c, __lc->_M_decimal_point))
+ break;
else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
@@ -432,11 +440,9 @@ namespace std
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(__c, __lc->_M_thousands_sep))
+ const char_type __c = *__beg;
+ if (__lc->_M_use_grouping
+ && __traits_type::eq(__c, __lc->_M_thousands_sep))
{
if (__sep_pos)
{
@@ -448,7 +454,9 @@ namespace std
__err |= ios_base::failbit;
break;
}
- }
+ }
+ else if (__traits_type::eq(__c, __lc->_M_decimal_point))
+ break;
else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
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 138f10d..f9bd933 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
@@ -22,13 +22,20 @@
#include <sstream>
#include <testsuite_hooks.h>
-struct Punct: std::numpunct<char>
+struct Punct1: std::numpunct<char>
{
std::string do_grouping() const { return "\1"; }
char do_thousands_sep() const { return '2'; }
char do_decimal_point() const { return '4'; }
};
+struct Punct2: std::numpunct<char>
+{
+ std::string do_grouping() const { return "\1"; }
+ char do_thousands_sep() const { return '2'; }
+ char do_decimal_point() const { return '2'; }
+};
+
// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
void test01()
{
@@ -37,30 +44,62 @@ void test01()
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());
+ 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 = 13.0;
+ double d2 = 1.0;
+ double d3 = 30.0;
long l = 0l;
long l1 = 13l;
+ long l2 = 10l;
- iss.str("1234");
+ iss1.str("1234");
err = ios_base::goodbit;
- end = ng.get(iss.rdbuf(), 0, iss, err, d);
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
- iss.str("1234");
- iss.clear();
+ iss1.str("142");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( d == d2 );
+
+ iss1.str("3e14");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( d == d3 );
+
+ iss1.str("1234");
+ iss1.clear();
err = ios_base::goodbit;
- end = ng.get(iss.rdbuf(), 0, iss, err, l);
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
VERIFY( err == ios_base::goodbit );
VERIFY( l == l1 );
-}
+ iss2.str("123");
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss2.str("120");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( l == l2 );
+}
int main()
{
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 d478209..d056892 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
@@ -22,13 +22,20 @@
#include <sstream>
#include <testsuite_hooks.h>
-struct Punct: std::numpunct<wchar_t>
+struct Punct1: 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'; }
};
+struct Punct2: 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'2'; }
+};
+
// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
void test01()
{
@@ -37,30 +44,62 @@ void test01()
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());
+ 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 = 13.0;
+ double d2 = 1.0;
+ double d3 = 30.0;
long l = 0l;
long l1 = 13l;
+ long l2 = 10l;
- iss.str(L"1234");
+ iss1.str(L"1234");
err = ios_base::goodbit;
- end = ng.get(iss.rdbuf(), 0, iss, err, d);
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
- iss.str(L"1234");
- iss.clear();
+ iss1.str(L"142");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( d == d2 );
+
+ iss1.str(L"3e14");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( d == d3 );
+
+ iss1.str(L"1234");
+ iss1.clear();
err = ios_base::goodbit;
- end = ng.get(iss.rdbuf(), 0, iss, err, l);
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
VERIFY( err == ios_base::goodbit );
VERIFY( l == l1 );
-}
+ iss2.str(L"123");
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( d == d1 );
+
+ iss2.str(L"120");
+ iss2.clear();
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( l == l2 );
+}
int main()
{