This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH] Better fix for libstdc++/5579
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: libstdc++ at gcc dot gnu dot org
- Cc: bkoz at redhat dot com, ncm at cantrip dot org
- Date: Sun, 03 Feb 2002 19:38:27 +0100
- Subject: [PATCH] Better fix for libstdc++/5579
Hi again,
I have managed (just one additional &&) to improve the previous attempt to *not*
fail when !(__io.flags() & ios_base::showbase) and symbol is *not* present in
the input stream. This is very close to my best interpretation of the standard!
Tested i686-pc-linux-gnu. Ok?
Cheers,
Paolo.
/////////////
2002-02-03 Paolo Carlini <pcarlini@unitus.it>
libstdc++/5579
* include/bits/locale_facets.tcc (money_get::do_get(string)):
Deal correctly with !(__io.flags() & ios_base::showbase)
for case money_base::symbol.
* testsuite/22_locale/money_get_members_char.cc: Add test05.
* testsuite/22_locale/money_get_members_wchar_t.cc: Add test05.
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 Thu Jan 24 00:35:18 2002
--- libstdc++-v3/include/bits/locale_facets.tcc Sun Feb 3 19:03:59 2002
*************** namespace std
*** 938,957 ****
switch (__which)
{
case money_base::symbol:
! if (__io.flags() & ios_base::showbase)
{
! // Symbol is required.
const string_type __symbol = __intl ? __mpt.curr_symbol()
: __mpf.curr_symbol();
size_type __len = __symbol.size();
! size_type __i = 0;
while (__beg != __end
! && __i < __len && __symbol[__i] == __c)
{
__c = *(++__beg);
! ++__i;
}
! if (__i != __len)
__testvalid = false;
}
break;
--- 938,962 ----
switch (__which)
{
case money_base::symbol:
! if (__io.flags() & ios_base::showbase || __i < 2 ||
! __i == 2 && static_cast<part>(__p.field[3]) != money_base::none)
{
! // According to 22.2.6.1.2.2, 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 string_type __symbol = __intl ? __mpt.curr_symbol()
: __mpf.curr_symbol();
size_type __len = __symbol.size();
! size_type __j = 0;
while (__beg != __end
! && __j < __len && __symbol[__j] == __c)
{
__c = *(++__beg);
! ++__j;
}
! // When (__io.flags() & ios_base::showbase) symbol is required.
! if (__j != __len && (__io.flags() & ios_base::showbase))
__testvalid = false;
}
break;
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 Fri Feb 1
18:34:21 2002
--- libstdc++-v3/testsuite/22_locale/money_get_members_char.cc Sun Feb 3
18:32:20 2002
*************** void test04()
*** 309,319 ****
--- 309,394 ----
#endif
}
+ class My_money_io : public std::moneypunct<char,false>
+ {
+ public:
+ explicit My_money_io(size_t r = 0): std::moneypunct<char,false>(r) { }
+ char_type do_decimal_point() const { return '.'; }
+ char_type do_thousands_sep() const { return ','; }
+ std::string do_grouping() const { return "\004"; }
+
+ std::string do_curr_symbol() const { return "$"; }
+ std::string do_positive_sign() const { return ""; }
+ std::string do_negative_sign() const { return "-"; }
+
+ int do_frac_digits() const { return 2; }
+
+ pattern do_pos_format() const
+ {
+ static pattern pat = { { symbol, none, sign, value } };
+ return pat;
+ }
+
+ pattern do_neg_format() const
+ {
+ static pattern pat = { { symbol, none, sign, value } };
+ return pat;
+ }
+ };
+
+ // libstdc++/5579
+ void test05()
+ {
+ using namespace std;
+ typedef istreambuf_iterator<char> InIt;
+
+ locale loc(locale::classic(), new My_money_io);
+
+ string bufferp("$1234.56");
+ string buffern("$-1234.56");
+ string bufferp_ns("1234.56");
+ string buffern_ns("-1234.56");
+
+ bool intl = false;
+
+ InIt iendp, iendn, iendp_ns, iendn_ns;
+ ios_base::iostate err;
+ string valp, valn, valp_ns, valn_ns;
+
+ const money_get<char,InIt>& mg =
+ use_facet<money_get<char, InIt> >(loc);
+
+ istringstream fmtp(bufferp);
+ fmtp.imbue(loc);
+ InIt ibegp(fmtp);
+ mg.get(ibegp,iendp,intl,fmtp,err,valp);
+ VERIFY( valp == "123456" );
+
+ istringstream fmtn(buffern);
+ fmtn.imbue(loc);
+ InIt ibegn(fmtn);
+ mg.get(ibegn,iendn,intl,fmtn,err,valn);
+ VERIFY( valn == "-123456" );
+
+ istringstream fmtp_ns(bufferp_ns);
+ fmtp_ns.imbue(loc);
+ InIt ibegp_ns(fmtp_ns);
+ mg.get(ibegp_ns,iendp_ns,intl,fmtp_ns,err,valp_ns);
+ VERIFY( valp_ns == "123456" );
+
+ istringstream fmtn_ns(buffern_ns);
+ fmtn_ns.imbue(loc);
+ InIt ibegn_ns(fmtn_ns);
+ mg.get(ibegn_ns,iendn_ns,intl,fmtn_ns,err,valn_ns);
+ VERIFY( valn_ns == "-123456" );
+ }
+
int main()
{
test01();
test02();
test03();
test04();
+ test05();
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 Fri Feb
1 18:34:21 2002
--- libstdc++-v3/testsuite/22_locale/money_get_members_wchar_t.cc Sun Feb 3
18:35:32 2002
*************** void test04()
*** 310,317 ****
}
#endif
}
- #endif
int main()
{
--- 310,390 ----
}
#endif
}
+ class My_money_io : public std::moneypunct<wchar_t,false>
+ {
+ public:
+ explicit My_money_io(size_t r = 0): std::moneypunct<wchar_t,false>(r) { }
+ char_type do_decimal_point() const { return L'.'; }
+ char_type do_thousands_sep() const { return L','; }
+ std::string do_grouping() const { return "\004"; }
+
+ std::wstring do_curr_symbol() const { return L"$"; }
+ std::wstring do_positive_sign() const { return L""; }
+ std::wstring do_negative_sign() const { return L"-"; }
+
+ int do_frac_digits() const { return 2; }
+
+ pattern do_pos_format() const
+ {
+ static pattern pat = { { symbol, none, sign, value } };
+ return pat;
+ }
+
+ pattern do_neg_format() const
+ {
+ static pattern pat = { { symbol, none, sign, value } };
+ return pat;
+ }
+ };
+
+ // libstdc++/5579
+ void test05()
+ {
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> InIt;
+
+ locale loc(locale::classic(), new My_money_io);
+
+ wstring bufferp(L"$1234.56");
+ wstring buffern(L"$-1234.56");
+ wstring bufferp_ns(L"1234.56");
+ wstring buffern_ns(L"-1234.56");
+
+ bool intl = false;
+
+ InIt iendp, iendn, iendp_ns, iendn_ns;
+ ios_base::iostate err;
+ wstring valp, valn, valp_ns, valn_ns;
+
+ const money_get<wchar_t,InIt>& mg =
+ use_facet<money_get<wchar_t, InIt> >(loc);
+
+ wistringstream fmtp(bufferp);
+ fmtp.imbue(loc);
+ InIt ibegp(fmtp);
+ mg.get(ibegp,iendp,intl,fmtp,err,valp);
+ VERIFY( valp == L"123456" );
+
+ wistringstream fmtn(buffern);
+ fmtn.imbue(loc);
+ InIt ibegn(fmtn);
+ mg.get(ibegn,iendn,intl,fmtn,err,valn);
+ VERIFY( valn == L"-123456" );
+
+ wistringstream fmtp_ns(bufferp_ns);
+ fmtp_ns.imbue(loc);
+ InIt ibegp_ns(fmtp_ns);
+ mg.get(ibegp_ns,iendp_ns,intl,fmtp_ns,err,valp_ns);
+ VERIFY( valp_ns == L"123456" );
+
+ wistringstream fmtn_ns(buffern_ns);
+ fmtn_ns.imbue(loc);
+ InIt ibegn_ns(fmtn_ns);
+ mg.get(ibegn_ns,iendn_ns,intl,fmtn_ns,err,valn_ns);
+ VERIFY( valn_ns == L"-123456" );
+ }
+ #endif
int main()
{
*************** int main()
*** 320,325 ****
--- 393,399 ----
test02();
test03();
test04();
+ test05();
#endif
return 0;
}