From: paolo Date: Mon, 1 Mar 2004 10:31:33 +0000 (+0000) Subject: 2004-03-01 Paolo Carlini X-Git-Tag: upstream/4.9.2~72631 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=148a2759586536e759d5d77db9a8e706502620fa;p=platform%2Fupstream%2Flinaro-gcc.git 2004-03-01 Paolo Carlini * 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 * 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 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4525565..251c5e0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2004-03-01 Paolo Carlini + + * 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 + + * 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 * testsuite/lib/libstdc++.exp (v3-list-tests): Use diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index ae824b5..9fb234b 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -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(__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(__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(__sep_pos); - __sep_pos = 0; + __grouping_tmp += static_cast(__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(__sep_pos); - + // Add the ending grouping. + __grouping_tmp += static_cast(__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 index 0000000..a5e766e --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/money_get/get/char/15.cc @@ -0,0 +1,68 @@ +// 2004-03-01 Paolo Carlini + +// 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 +#include +#include + +// 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 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& mon_get = use_facet >(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 index 0000000..52a4589 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/15.cc @@ -0,0 +1,69 @@ +// 2004-03-01 Paolo Carlini + +// 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 +#include +#include + +// 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 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& mon_get = + use_facet >(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 index 0000000..c550181 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/15.cc @@ -0,0 +1,75 @@ +// 2004-03-01 Paolo Carlini + +// 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 +#include +#include + +struct Punct1: std::numpunct +{ + std::string do_grouping() const { return "\1"; } + char do_thousands_sep() const { return '+'; } +}; + +struct Punct2: std::numpunct +{ + char do_decimal_point() const { return '-'; } +}; + +// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html +void test01() +{ + using namespace std; + typedef istreambuf_iterator iterator_type; + + bool test __attribute__((unused)) = true; + + istringstream iss1, iss2; + iss1.imbue(locale(iss1.getloc(), static_cast*>(new Punct1))); + iss2.imbue(locale(iss2.getloc(), static_cast*>(new Punct2))); + const num_get& ng1 = use_facet >(iss1.getloc()); + const num_get& ng2 = use_facet >(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 index 0000000..ef4d7b7 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/15.cc @@ -0,0 +1,75 @@ +// 2004-03-01 Paolo Carlini + +// 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 +#include +#include + +struct Punct1: std::numpunct +{ + std::string do_grouping() const { return "\1"; } + wchar_t do_thousands_sep() const { return L'+'; } +}; + +struct Punct2: std::numpunct +{ + 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 iterator_type; + + bool test __attribute__((unused)) = true; + + wistringstream iss1, iss2; + iss1.imbue(locale(iss1.getloc(), static_cast*>(new Punct1))); + iss2.imbue(locale(iss2.getloc(), static_cast*>(new Punct2))); + const num_get& ng1 = use_facet >(iss1.getloc()); + const num_get& ng2 = use_facet >(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; +}