diff options
author | Paolo Carlini <pcarlini@suse.de> | 2003-12-31 08:28:10 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2003-12-31 08:28:10 +0000 |
commit | 4f0c9c8a876450531bcfa8989d327efdbd0cd93c (patch) | |
tree | dc615e287c0bd2140978df6b1f24cda3d7812fb3 | |
parent | f5cb6ca2675b946792989030a5b840e25d631616 (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.tcc | 90 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/22_locale/num_get/get/char/11.cc | 59 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/11.cc | 59 |
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() { |