This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

[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;
  }



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