This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] More money_get work


Hi,

I have just committed to mainline the below, tested x86-linux.

Paolo.

//////////////////
2004-03-02  Paolo Carlini  <pcarlini@suse.de>

	* 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.
diff -prN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
*** libstdc++-v3-orig/include/bits/locale_facets.tcc	Mon Mar  1 18:22:17 2004
--- libstdc++-v3/include/bits/locale_facets.tcc	Tue Mar  2 16:07:12 2004
*************** namespace std
*** 1193,1204 ****
  	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;
  	// String of grouping info from thousands_sep plucked from __units.
  	string __grouping_tmp;
  	if (__lc->_M_use_grouping)
--- 1193,1202 ----
  	const __cache_type* __lc = __uc(__loc);
  	const char_type* __lit = __lc->_M_atoms;
  
  	// Deduced sign.
  	bool __negative = 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)
*************** namespace std
*** 1218,1265 ****
  
  	const char_type* __lit_zero = __lit + _S_zero;
  	const char_type* __q;
! 	for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
  	  {
  	    const part __which = static_cast<part>(__p.field[__i]);
  	    switch (__which)
  	      {
  	      case money_base::symbol:
  		if (__io.flags() & ios_base::showbase
! 		    || __i < 2 || __long_sign
  		    || ((static_cast<part>(__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.
  		    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
  		    && *__beg == __lc->_M_positive_sign[0])
  		  {
! 		    if (__lc->_M_positive_sign_size > 1)
! 		      __long_sign = true;
  		    ++__beg;
  		  }
! 		else if (__lc->_M_negative_sign_size
  			 && *__beg == __lc->_M_negative_sign[0])
  		  {
  		    __negative = true;
! 		    if (__lc->_M_negative_sign_size > 1)
! 		      __long_sign = true;		    
  		    ++__beg;
  		  }
  		else if (__lc->_M_positive_sign_size
--- 1216,1259 ----
  
  	const char_type* __lit_zero = __lit + _S_zero;
  	const char_type* __q;
! 	const money_base::pattern __p = __lc->_M_neg_format;	
! 	for (int __i = 0; __i < 4 && __testvalid; ++__i)
  	  {
  	    const part __which = static_cast<part>(__p.field[__i]);
  	    switch (__which)
  	      {
  	      case money_base::symbol:
  		if (__io.flags() & ios_base::showbase
! 		    || __i < 2 || __sign_size > 1
  		    || ((static_cast<part>(__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.
  		    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);
  		    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 && __beg != __end
  		    && *__beg == __lc->_M_positive_sign[0])
  		  {
! 		    __sign_size = __lc->_M_positive_sign_size;
  		    ++__beg;
  		  }
! 		else if (__lc->_M_negative_sign_size && __beg != __end
  			 && *__beg == __lc->_M_negative_sign[0])
  		  {
  		    __negative = true;
! 		    __sign_size = __lc->_M_negative_sign_size;
  		    ++__beg;
  		  }
  		else if (__lc->_M_positive_sign_size
*************** namespace std
*** 1307,1312 ****
--- 1301,1308 ----
  		    }
  		  else
  		    break;
+ 		if (__res.empty())
+ 		  __testvalid = false;
  		break;
  	      case money_base::space:
  	      case money_base::none:
*************** namespace std
*** 1319,1339 ****
  	  }
  
  	// Need to get the rest of the sign characters, if they exist.
! 	if (__long_sign)
  	  {
  	    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
  		   && *__beg == __sign[__i]; ++__beg, ++__i);
  	    
! 	    if (__i != __len)
  	      __testvalid = false;
  	  }
  
! 	if (__testvalid && __res.size())
  	  {
  	    // Strip leading zeros.
  	    if (__res.size() > 1)
--- 1315,1333 ----
  	  }
  
  	// Need to get the rest of the sign characters, if they exist.
! 	if (__sign_size > 1 && __testvalid)
  	  {
  	    const char_type* __sign = __negative ? __lc->_M_negative_sign
  	                                         : __lc->_M_positive_sign;
  	    size_type __i = 1;
! 	    for (; __beg != __end && __i < __sign_size
  		   && *__beg == __sign[__i]; ++__beg, ++__i);
  	    
! 	    if (__i != __sign_size)
  	      __testvalid = false;
  	  }
  
! 	if (__testvalid)
  	  {
  	    // Strip leading zeros.
  	    if (__res.size() > 1)
*************** namespace std
*** 1365,1372 ****
  		&& __n != __lc->_M_frac_digits)
  	      __testvalid = false;
  	  }
- 	else
- 	  __testvalid = false;
  	
  	// Iff no more characters are available.
  	if (__beg == __end)
--- 1359,1364 ----
diff -prN libstdc++-v3-orig/testsuite/22_locale/money_get/get/char/16.cc libstdc++-v3/testsuite/22_locale/money_get/get/char/16.cc
*** libstdc++-v3-orig/testsuite/22_locale/money_get/get/char/16.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/money_get/get/char/16.cc	Tue Mar  2 16:48:12 2004
***************
*** 0 ****
--- 1,75 ----
+ // 2004-03-02  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // 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 <locale>
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ 
+ // Fail as soon as value digits are not present.
+ void test01()
+ {
+   using namespace std;
+   bool test __attribute__((unused)) = true;
+ 
+   typedef istreambuf_iterator<char> 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<char>& mon_get_01 =
+     use_facet<money_get<char> >(iss01.getloc());
+   const money_get<char>& mon_get_02 =
+     use_facet<money_get<char> >(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 -prN libstdc++-v3-orig/testsuite/22_locale/money_get/get/wchar_t/16.cc libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/16.cc
*** libstdc++-v3-orig/testsuite/22_locale/money_get/get/wchar_t/16.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/16.cc	Tue Mar  2 16:49:48 2004
***************
*** 0 ****
--- 1,75 ----
+ // 2004-03-02  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // 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 <locale>
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ 
+ // Fail as soon as value digits are not present.
+ void test01()
+ {
+   using namespace std;
+   bool test __attribute__((unused)) = true;
+ 
+   typedef istreambuf_iterator<wchar_t> 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<wchar_t>& mon_get_01 =
+     use_facet<money_get<wchar_t> >(iss01.getloc());
+   const money_get<wchar_t>& mon_get_02 =
+     use_facet<money_get<wchar_t> >(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;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]