From fac7a62f9d393eb44398ec04d2181f309028c551 Mon Sep 17 00:00:00 2001 From: paolo Date: Tue, 2 Mar 2004 22:25:51 +0000 Subject: [PATCH] 2004-03-02 Paolo Carlini * include/bits/locale_facets.tcc (money_get<>::_M_extract): Reorganize a bit the main parsing loop, thus early detecting an empty value component. * testsuite/22_locale/money_get/get/char/16.cc: New. * testsuite/22_locale/money_get/get/wchar_t/16.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@78788 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 8 +++ libstdc++-v3/include/bits/locale_facets.tcc | 44 ++++++------- .../testsuite/22_locale/money_get/get/char/16.cc | 75 ++++++++++++++++++++++ .../22_locale/money_get/get/wchar_t/16.cc | 75 ++++++++++++++++++++++ 4 files changed, 176 insertions(+), 26 deletions(-) create mode 100644 libstdc++-v3/testsuite/22_locale/money_get/get/char/16.cc create mode 100644 libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/16.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 33eb818..cbe4037 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2004-03-02 Paolo Carlini + + * include/bits/locale_facets.tcc (money_get<>::_M_extract): + Reorganize a bit the main parsing loop, thus early detecting + an empty value component. + * testsuite/22_locale/money_get/get/char/16.cc: New. + * testsuite/22_locale/money_get/get/wchar_t/16.cc: New. + 2004-03-02 Benjamin Kosnik Support automake 1.8.2 diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 712bfcc..1f36742 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -1193,12 +1193,10 @@ namespace std const __cache_type* __lc = __uc(__loc); const char_type* __lit = __lc->_M_atoms; - const money_base::pattern __p = __lc->_M_neg_format; - // Deduced sign. bool __negative = false; - // True for more than one character long sign. - bool __long_sign = false; + // Sign size. + size_type __sign_size = 0; // String of grouping info from thousands_sep plucked from __units. string __grouping_tmp; if (__lc->_M_use_grouping) @@ -1218,48 +1216,44 @@ namespace std const char_type* __lit_zero = __lit + _S_zero; const char_type* __q; - for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i) + const money_base::pattern __p = __lc->_M_neg_format; + for (int __i = 0; __i < 4 && __testvalid; ++__i) { const part __which = static_cast(__p.field[__i]); switch (__which) { case money_base::symbol: if (__io.flags() & ios_base::showbase - || __i < 2 || __long_sign + || __i < 2 || __sign_size > 1 || ((static_cast(__p.field[3]) != money_base::none) && __i == 2)) { // According to 22.2.6.1.2, p2, symbol is required - // if (__io.flags() & ios_base::showbase), - // otherwise is optional and consumed only if - // other characters are needed to complete the - // format. + // if (__io.flags() & ios_base::showbase), otherwise + // is optional and consumed only if other characters + // are needed to complete the format. const size_type __len = __lc->_M_curr_symbol_size; size_type __j = 0; for (; __beg != __end && __j < __len && *__beg == __lc->_M_curr_symbol[__j]; ++__beg, ++__j); - // When (__io.flags() & ios_base::showbase) - // symbol is required. if (__j != __len && (__io.flags() & ios_base::showbase)) __testvalid = false; } break; case money_base::sign: // Sign might not exist, or be more than one character long. - if (__lc->_M_positive_sign_size + if (__lc->_M_positive_sign_size && __beg != __end && *__beg == __lc->_M_positive_sign[0]) { - if (__lc->_M_positive_sign_size > 1) - __long_sign = true; + __sign_size = __lc->_M_positive_sign_size; ++__beg; } - else if (__lc->_M_negative_sign_size + else if (__lc->_M_negative_sign_size && __beg != __end && *__beg == __lc->_M_negative_sign[0]) { __negative = true; - if (__lc->_M_negative_sign_size > 1) - __long_sign = true; + __sign_size = __lc->_M_negative_sign_size; ++__beg; } else if (__lc->_M_positive_sign_size @@ -1307,6 +1301,8 @@ namespace std } else break; + if (__res.empty()) + __testvalid = false; break; case money_base::space: case money_base::none: @@ -1319,21 +1315,19 @@ namespace std } // Need to get the rest of the sign characters, if they exist. - if (__long_sign) + if (__sign_size > 1 && __testvalid) { const char_type* __sign = __negative ? __lc->_M_negative_sign : __lc->_M_positive_sign; - const size_type __len = __negative ? __lc->_M_negative_sign_size - : __lc->_M_positive_sign_size; size_type __i = 1; - for (; __beg != __end && __i < __len + for (; __beg != __end && __i < __sign_size && *__beg == __sign[__i]; ++__beg, ++__i); - if (__i != __len) + if (__i != __sign_size) __testvalid = false; } - if (__testvalid && __res.size()) + if (__testvalid) { // Strip leading zeros. if (__res.size() > 1) @@ -1365,8 +1359,6 @@ namespace std && __n != __lc->_M_frac_digits) __testvalid = false; } - else - __testvalid = false; // Iff no more characters are available. if (__beg == __end) diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/char/16.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/char/16.cc new file mode 100644 index 0000000..c4a2011 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/money_get/get/char/16.cc @@ -0,0 +1,75 @@ +// 2004-03-02 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 + +// Fail as soon as value digits are not present. +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"); + locale loc_hk = __gnu_test::try_named_locale("en_HK"); + VERIFY( loc_hk != loc_de ); + VERIFY( loc_c != loc_hk ); + + iterator_type end01, end02; + istringstream iss01, iss02; + iss01.imbue(loc_de); + iss02.imbue(loc_hk); + + // cache the money_get facet + const money_get& mon_get_01 = + use_facet >(iss01.getloc()); + const money_get& mon_get_02 = + use_facet >(iss02.getloc()); + + iss01.setf(ios_base::showbase); + iss01.str("EUR "); + iterator_type is_it01(iss01); + long double result1; + ios_base::iostate err01 = ios_base::goodbit; + end01 = mon_get_01.get(is_it01, end01, true, iss01, err01, result1); + VERIFY( err01 == ios_base::failbit ); + VERIFY( *end01 == 'E' ); + + iss02.str("(HKD )"); + iterator_type is_it02(iss02); + long double result2; + ios_base::iostate err02 = ios_base::goodbit; + end02 = mon_get_02.get(is_it02, end02, true, iss02, 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/16.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/16.cc new file mode 100644 index 0000000..c7d7bd2 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/16.cc @@ -0,0 +1,75 @@ +// 2004-03-02 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 + +// Fail as soon as value digits are not present. +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"); + locale loc_hk = __gnu_test::try_named_locale("en_HK"); + VERIFY( loc_hk != loc_de ); + VERIFY( loc_c != loc_hk ); + + iterator_type end01, end02; + wistringstream iss01, iss02; + iss01.imbue(loc_de); + iss02.imbue(loc_hk); + + // cache the money_get facet + const money_get& mon_get_01 = + use_facet >(iss01.getloc()); + const money_get& mon_get_02 = + use_facet >(iss02.getloc()); + + iss01.setf(ios_base::showbase); + iss01.str(L"EUR "); + iterator_type is_it01(iss01); + long double result1; + ios_base::iostate err01 = ios_base::goodbit; + end01 = mon_get_01.get(is_it01, end01, true, iss01, err01, result1); + VERIFY( err01 == ios_base::failbit ); + VERIFY( *end01 == L'E' ); + + iss02.str(L"(HKD )"); + iterator_type is_it02(iss02); + long double result2; + ios_base::iostate err02 = ios_base::goodbit; + end02 = mon_get_02.get(is_it02, end02, true, iss02, err02, result2); + VERIFY( err02 == ios_base::failbit ); + VERIFY( *end02 == L')' ); +} + +int main() +{ + test01(); + return 0; +} -- 2.7.4