This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH] Money_get::do_get: first create, then destroy
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: libstdc++ at gcc dot gnu dot org
- Cc: bkoz at redhat dot com
- Date: Mon, 04 Feb 2002 22:36:35 +0100
- Subject: [PATCH] Money_get::do_get: first create, then destroy
Hi,
so I have implemented the fix suggested by Nathan and Benjamin for the problem
presented here:
http://gcc.gnu.org/ml/libstdc++/2002-02/msg00009.html
Tested i686-pc-linux-gnu, as usual. Ok?
Cheers,
Paolo.
P.S. I'm afraid we are still not doing always the right thing when the sign is
longer than 1 char. I will tackle this next.
////////////////
2002-02-04 Paolo Carlini <pcarlini@unitus.it>
* include/bits/locale_facets.tcc (money_get::do_get(string)):
First build a tentative returned string, then, only if the
parsing succeeds, copy it into the string passed by reference.
* testsuite/22_locale/money_get_members_char.cc: Add test06.
* testsuite/22_locale/money_get_members_wchar_t.cc: Add test06.
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 Sun Feb 3 19:03:59 2002
--- libstdc++-v3/include/bits/locale_facets.tcc Mon Feb 4 22:25:13 2002
*************** namespace std
*** 930,935 ****
--- 930,938 ----
// Flag marking when a decimal point is found.
bool __testdecfound = false;
+ // The tentative returned string is stored here.
+ string_type __temp_units;
+
char_type __c = *__beg;
char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
*************** namespace std
*** 1019,1025 ****
}
else
{
! __units += __c;
++__sep_pos;
}
__c = *(++__beg);
--- 1022,1028 ----
}
else
{
! __temp_units += __c;
++__sep_pos;
}
__c = *(++__beg);
*************** namespace std
*** 1050,1060 ****
}
// Strip leading zeros.
! while (__units[0] == __ctype.widen('0'))
! __units.erase(__units.begin());
if (__sign.size() && __sign == __neg_sign)
! __units.insert(__units.begin(), __ctype.widen('-'));
// Test for grouping fidelity.
if (__grouping.size() && __grouping_tmp.size())
--- 1053,1063 ----
}
// Strip leading zeros.
! while (__temp_units[0] == __ctype.widen('0'))
! __temp_units.erase(__temp_units.begin());
if (__sign.size() && __sign == __neg_sign)
! __temp_units.insert(__temp_units.begin(), __ctype.widen('-'));
// Test for grouping fidelity.
if (__grouping.size() && __grouping_tmp.size())
*************** namespace std
*** 1068,1075 ****
__err |= ios_base::eofbit;
// Iff valid sequence is not recognized.
! if (!__testvalid || !__units.size())
__err |= ios_base::failbit;
return __beg;
}
--- 1071,1082 ----
__err |= ios_base::eofbit;
// Iff valid sequence is not recognized.
! if (!__testvalid || !__temp_units.size())
__err |= ios_base::failbit;
+ else
+ // Use the "swap trick" to copy __temp_units into __units.
+ __temp_units.swap(__units);
+
return __beg;
}
diff -prN libstdc++-v3-orig/testsuite/22_locale/money_get_members_char.cc
libstdc++-v3/testsuite/22_locale/money_get_members_char.cc
*** libstdc++-v3-orig/testsuite/22_locale/money_get_members_char.cc Sun Feb
3 18:32:20 2002
--- libstdc++-v3/testsuite/22_locale/money_get_members_char.cc Mon Feb 4
22:16:01 2002
*************** void test05()
*** 383,388 ****
--- 383,424 ----
VERIFY( valn_ns == "-123456" );
}
+ void test06()
+ {
+ using namespace std;
+
+ typedef istreambuf_iterator<char> InIt;
+ InIt iend1, iend2, iend3;
+
+ locale loc;
+ string buffer1("123");
+ string buffer2("456");
+ string buffer3("Golgafrincham"); // From Nathan's original idea.
+
+ string val;
+
+ ios_base::iostate err;
+
+ const money_get<char,InIt>& mg =
+ use_facet<money_get<char, InIt> >(loc);
+
+ istringstream fmt1(buffer1);
+ InIt ibeg1(fmt1);
+ mg.get(ibeg1,iend1,false,fmt1,err,val);
+ VERIFY( val == buffer1 );
+
+ istringstream fmt2(buffer2);
+ InIt ibeg2(fmt2);
+ mg.get(ibeg2,iend2,false,fmt2,err,val);
+ VERIFY( val == buffer2 );
+
+ val = buffer3;
+ istringstream fmt3(buffer3);
+ InIt ibeg3(fmt3);
+ mg.get(ibeg3,iend3,false,fmt3,err,val);
+ VERIFY( val == buffer3 );
+ }
+
int main()
{
test01();
*************** int main()
*** 390,394 ****
--- 426,431 ----
test03();
test04();
test05();
+ test06();
return 0;
}
diff -prN libstdc++-v3-orig/testsuite/22_locale/money_get_members_wchar_t.cc
libstdc++-v3/testsuite/22_locale/money_get_members_wchar_t.cc
*** libstdc++-v3-orig/testsuite/22_locale/money_get_members_wchar_t.cc Sun Feb
3 18:35:32 2002
--- libstdc++-v3/testsuite/22_locale/money_get_members_wchar_t.cc Mon Feb
4 22:16:33 2002
*************** void test05()
*** 384,389 ****
--- 384,425 ----
mg.get(ibegn_ns,iendn_ns,intl,fmtn_ns,err,valn_ns);
VERIFY( valn_ns == L"-123456" );
}
+
+ void test06()
+ {
+ using namespace std;
+
+ typedef istreambuf_iterator<wchar_t> InIt;
+ InIt iend1, iend2, iend3;
+
+ locale loc;
+ wstring buffer1(L"123");
+ wstring buffer2(L"456");
+ wstring buffer3(L"Golgafrincham");
+
+ wstring val;
+
+ ios_base::iostate err;
+
+ const money_get<wchar_t,InIt>& mg =
+ use_facet<money_get<wchar_t, InIt> >(loc);
+
+ wistringstream fmt1(buffer1);
+ InIt ibeg1(fmt1);
+ mg.get(ibeg1,iend1,false,fmt1,err,val);
+ VERIFY( val == buffer1 );
+
+ wistringstream fmt2(buffer2);
+ InIt ibeg2(fmt2);
+ mg.get(ibeg2,iend2,false,fmt2,err,val);
+ VERIFY( val == buffer2 );
+
+ val = buffer3;
+ wistringstream fmt3(buffer3);
+ InIt ibeg3(fmt3);
+ mg.get(ibeg3,iend3,false,fmt3,err,val);
+ VERIFY( val == buffer3 );
+ }
#endif
int main()
*************** int main()
*** 394,399 ****
--- 430,436 ----
test03();
test04();
test05();
+ test06();
#endif
return 0;
}