]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/9371 (Bad exception handling in i/ostream::operator>>/<<(streambuf*))
authorBenjamin Kosnik <bkoz@redhat.com>
Thu, 4 Dec 2003 03:10:53 +0000 (03:10 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 4 Dec 2003 03:10:53 +0000 (03:10 +0000)
2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>

* include/bits/basic_ios.h (basic_ios::setstate): Revert.
* include/bits/istream.tcc: Only call setstate if __err != goodbit.
* include/bits/ostream.tcc: Same.
* testsuite/27_io/basic_ios/exceptions/char/2.cc: New.

2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>

PR libstdc++/9371
PR libstdc++/9546
PR libstdc++/10093
PR libstdc++/10095
* include/bits/basic_ios.h (basic_ios::setstate): Elide if goodbit.
(basic_ios::_M_setstate): Consolidate common error handling code.
* include/bits/basic_ios.tcc: Tweak.
* include/bits/fstream.tcc: Tweak.
* include/bits/istream.tcc: Use _M_setstate for common exception
handling. Move setstate calls after catch.
(basic_istream::tellg): Check for exceptions thrown by streambuf
virtual functions.
(basic_istream::seekg): Same.
* include/bits/ostream.tcc: Same, but for ostream.
(basic_ostream::flush): Check for exceptions thrown by streambuf
virtual functions.
(basic_istream::tellp): Same.
(basic_istream::seekp): Same.
* include/bits/locale_facets.tcc: Tweak.
* include/bits/streambuf.tcc: Tweak.
(__copy_streambufs): Propagate exceptions.

From-SVN: r74265

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_ios.h
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/bits/ostream.tcc
libstdc++-v3/include/bits/streambuf.tcc

index a16784e8b7b7f8e5b46d94bd2cf8223b9c28d8c5..71b75b70389c532cb190b97a8ac8ef237e06c7f0 100644 (file)
@@ -1,3 +1,34 @@
+2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * include/bits/basic_ios.h (basic_ios::setstate): Revert.
+       * include/bits/istream.tcc: Only call setstate if __err != goodbit.
+       * include/bits/ostream.tcc: Same.
+       * testsuite/27_io/basic_ios/exceptions/char/2.cc: New.
+
+2003-12-03  Benjamin Kosnik  <bkoz@redhat.com>
+
+       PR libstdc++/9371
+       PR libstdc++/9546
+       PR libstdc++/10093
+       PR libstdc++/10095
+       * include/bits/basic_ios.h (basic_ios::setstate): Elide if goodbit.
+       (basic_ios::_M_setstate): Consolidate common error handling code.
+       * include/bits/basic_ios.tcc: Tweak.
+       * include/bits/fstream.tcc: Tweak.
+       * include/bits/istream.tcc: Use _M_setstate for common exception
+       handling. Move setstate calls after catch. 
+       (basic_istream::tellg): Check for exceptions thrown by streambuf
+       virtual functions.
+       (basic_istream::seekg): Same.
+       * include/bits/ostream.tcc: Same, but for ostream.
+       (basic_ostream::flush): Check for exceptions thrown by streambuf
+       virtual functions.
+       (basic_istream::tellp): Same.   
+       (basic_istream::seekp): Same.
+       * include/bits/locale_facets.tcc: Tweak.
+       * include/bits/streambuf.tcc: Tweak.
+       (__copy_streambufs): Propagate exceptions.
+
 2003-11-26  Benjamin Kosnik  <bkoz@redhat.com>
 
        PR libstdc++/12297
index 70d8e8404280be74aad4f21541a59ad669846f9b..e98ea50ecb300e28d0f74388cd04888e0afc1ac6 100644 (file)
@@ -145,6 +145,19 @@ namespace std
       setstate(iostate __state) 
       { this->clear(this->rdstate() | __state); }
 
+      // Flip the internal state on for the proper state bits, then re
+      // throws the propagated exception if bit also set in
+      // exceptions().
+      void
+      _M_setstate(iostate __state) 
+      { 
+       // 27.6.1.2.1 Common requirements.
+       // Turn this on without causing an ios::failure to be thrown.
+       _M_streambuf_state |= __state; 
+       if (this->exceptions() & __state)
+         __throw_exception_again;
+      }
+
       /**
        *  @brief  Fast error checking.
        *  @return  True if no error flags are set.
@@ -444,11 +457,6 @@ namespace std
       void
       _M_cache_facets(const locale& __loc);
 #endif
-       // Internal state setter that won't throw, only set the state bits.
-       // Used to guarantee we don't throw when setting badbit.
-       void
-       _M_setstate(iostate __state) { _M_streambuf_state |= __state; }
     };
 } // namespace std
 
index c69ac9c7226688313c38e74ef4c0a40234114983..1efeaab470e69c4cae7acafd49f69ed39dbf438c 100644 (file)
@@ -136,9 +136,7 @@ namespace std
 #endif
            }
          catch(...)
-           {
-             __testfail = true;
-           }
+           { __testfail = true; }
 
          // NB: Do this here so that re-opened filebufs will be cool...
          this->_M_mode = ios_base::openmode(0);
index 09aa5e0e38fc5ee716fdcdc439df72fe0525c70e..e7346dcdb55f5466a9e08194de32aeb7a311ce8f 100644 (file)
@@ -54,17 +54,18 @@ namespace std
              __streambuf_type* __sb = __in.rdbuf();
              __int_type __c = __sb->sgetc();
 
-             if (__in._M_check_facet(__in._M_fctype))
-               while (!traits_type::eq_int_type(__c, __eof)
-                      && __in._M_fctype->is(ctype_base::space, 
-                                            traits_type::to_char_type(__c)))
-                 __c = __sb->snextc();
+             __in._M_check_facet(__in._M_fctype);
+             const __ctype_type& __ct = *__in._M_fctype;
+             while (!traits_type::eq_int_type(__c, __eof)
+                    && __ct.is(ctype_base::space, 
+                               traits_type::to_char_type(__c)))
+               __c = __sb->snextc();
 
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-//195.  Should basic_istream::sentry's constructor ever set eofbit? 
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 195. Should basic_istream::sentry's constructor ever
+             // set eofbit?
              if (traits_type::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
-#endif
            }
        }
 
@@ -74,18 +75,15 @@ namespace std
        {
          _M_ok = false;
          __err |= ios_base::failbit;
+         __in.setstate(__err);
        }
-      __in.setstate(__err);
     }
 
   template<typename _CharT, typename _Traits>
     basic_istream<_CharT, _Traits>& 
     basic_istream<_CharT, _Traits>::
     operator>>(__istream_type& (*__pf)(__istream_type&))
-    {
-      __pf(*this);
-      return *this;
-    }
+    { return __pf(*this); }
 
   template<typename _CharT, typename _Traits>
     basic_istream<_CharT, _Traits>& 
@@ -113,21 +111,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -140,13 +134,14 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
              long __l;
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __l);
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __l);
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
              // 118. basic_istream uses nonexistent num_get member functions.
              if (!(__err & ios_base::failbit)
                  && (numeric_limits<short>::min() <= __l 
@@ -154,17 +149,11 @@ namespace std
                __n = __l;
              else
                 __err |= ios_base::failbit;
-#endif
-             this->setstate(__err);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -177,21 +166,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -204,13 +189,14 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
              long __l;
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __l);
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __l);
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
              // 118. basic_istream uses nonexistent num_get member functions.
              if (!(__err & ios_base::failbit)
                  && (numeric_limits<int>::min() <= __l 
@@ -218,17 +204,11 @@ namespace std
                __n = __l;
              else
                 __err |= ios_base::failbit;
-#endif
-             this->setstate(__err);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -241,21 +221,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -268,21 +244,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -295,21 +267,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -323,21 +291,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-             __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -350,21 +314,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -378,21 +338,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -405,21 +361,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -432,21 +384,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -459,21 +407,17 @@ namespace std
       sentry __cerb(*this, false);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-             if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
-             this->setstate(__err);
+             _M_check_facet(this->_M_fnumget);
+             const __numget_type& __ng = *this->_M_fnumget;
+             __ng.get(*this, 0, *this, __err, __n);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -483,30 +427,23 @@ namespace std
     basic_istream<_CharT, _Traits>::
     operator>>(__streambuf_type* __sbout)
     {
-       sentry __cerb(*this, false);
-       if (__cerb)
-        {
-          try
-            {
-              streamsize __xtrct = 0;
-              if (__sbout)
-                {
-                  __streambuf_type* __sbin = this->rdbuf();
-                  __xtrct = __copy_streambufs(*this, __sbin, __sbout);
-                }
-              if (!__sbout || !__xtrct)
-                this->setstate(ios_base::failbit);
-            }
-          catch(...)
-            {
-              // 27.6.2.5.1 Common requirements.
-              // Turn this on without causing an ios::failure to be thrown.
-              this->_M_setstate(ios_base::badbit);
-              if ((this->exceptions() & ios_base::badbit) != 0)
-                __throw_exception_again;
-            }
-        }
-       return *this;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      sentry __cerb(*this, false);
+      if (__cerb && __sbout)
+       {
+         try
+           {
+             if (!__copy_streambufs(*this, this->rdbuf(), __sbout))
+               __err |= ios_base::failbit;
+           }
+         catch(...)
+           { this->_M_setstate(ios_base::failbit); }
+       }
+      else if (!__sbout)
+       __err |= ios_base::failbit;
+      if (__err)
+       this->setstate(__err);
+      return *this;
     }
 
   template<typename _CharT, typename _Traits>
@@ -517,6 +454,7 @@ namespace std
       const int_type __eof = traits_type::eof();
       int_type __c = __eof;
       _M_gcount = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       sentry __cerb(*this, true);
       if (__cerb) 
        {
@@ -527,17 +465,15 @@ namespace std
              if (!traits_type::eq_int_type(__c, __eof))
                _M_gcount = 1;
              else
-               this->setstate(ios_base::eofbit | ios_base::failbit);
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
        }
+      if (!_M_gcount)
+       __err |= ios_base::failbit;
+      if (__err)
+       this->setstate(__err);
       return __c;
     }
 
@@ -547,31 +483,29 @@ namespace std
     get(char_type& __c)
     {
       _M_gcount = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       sentry __cerb(*this, true);
       if (__cerb) 
        {
          try 
            {
-             const int_type __eof = traits_type::eof();
-             int_type __bufval = this->rdbuf()->sbumpc();
+             int_type __cb = this->rdbuf()->sbumpc();
              // 27.6.1.1 paragraph 3
-             if (!traits_type::eq_int_type(__bufval, __eof))
+             if (!traits_type::eq_int_type(__cb, traits_type::eof()))
                {
                  _M_gcount = 1;
-                 __c = traits_type::to_char_type(__bufval);
+                 __c = traits_type::to_char_type(__cb);
                }
              else
-               this->setstate(ios_base::eofbit | ios_base::failbit);
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
        }
+      if (!_M_gcount)
+       __err |= ios_base::failbit;
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -581,6 +515,7 @@ namespace std
     get(char_type* __s, streamsize __n, char_type __delim)
     {
       _M_gcount = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       sentry __cerb(*this, true);
       if (__cerb) 
        {
@@ -600,20 +535,16 @@ namespace std
                  ++_M_gcount;
                }
              if (traits_type::eq_int_type(__c, __eof))
-               this->setstate(ios_base::eofbit);
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
        }
       *__s = char_type();
       if (!_M_gcount)
-       this->setstate(ios_base::failbit);
+       __err |= ios_base::failbit;
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -623,6 +554,7 @@ namespace std
     get(__streambuf_type& __sb, char_type __delim)
     {
       _M_gcount = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       sentry __cerb(*this, true);
       if (__cerb) 
        {
@@ -643,19 +575,15 @@ namespace std
                  __c2 = traits_type::to_char_type(__c);
                }
              if (traits_type::eq_int_type(__c, __eof))
-               this->setstate(ios_base::eofbit);
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
        }
       if (!_M_gcount)
-       this->setstate(ios_base::failbit);
+       __err |= ios_base::failbit;
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -665,6 +593,7 @@ namespace std
     getline(char_type* __s, streamsize __n, char_type __delim)
     {
       _M_gcount = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       sentry __cerb(*this, true);
       if (__cerb) 
        {
@@ -684,7 +613,7 @@ namespace std
                  ++_M_gcount;
                }
              if (traits_type::eq_int_type(__c, __eof))
-               this->setstate(ios_base::eofbit);
+               __err |= ios_base::eofbit;
              else
                {
                  if (traits_type::eq_int_type(__c, __idelim))
@@ -693,21 +622,17 @@ namespace std
                      ++_M_gcount;
                    }
                  else
-                   this->setstate(ios_base::failbit);
+                   __err |= ios_base::failbit;
                }
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
        }
       *__s = char_type();
       if (!_M_gcount)
-       this->setstate(ios_base::failbit);
+       __err |= ios_base::failbit;
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
   
@@ -720,6 +645,7 @@ namespace std
       sentry __cerb(*this, true);
       if (__cerb && __n > 0) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
              const int_type __eof = traits_type::eof();
@@ -735,16 +661,12 @@ namespace std
                    break;
                }
              if (traits_type::eq_int_type(__c, __eof))
-               this->setstate(ios_base::eofbit);
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -759,22 +681,19 @@ namespace std
       sentry __cerb(*this, true);
       if (__cerb)
        {
-         try
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+         try 
            {
              __c = this->rdbuf()->sgetc();
              if (traits_type::eq_int_type(__c, traits_type::eof()))
-               this->setstate(ios_base::eofbit);
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        } 
-      return __c;
+       return __c;
     }
 
   template<typename _CharT, typename _Traits>
@@ -786,23 +705,18 @@ namespace std
       sentry __cerb(*this, true);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
              _M_gcount = this->rdbuf()->sgetn(__s, __n);
              if (_M_gcount != __n)
-               this->setstate(ios_base::eofbit | ios_base::failbit);
+               __err |= (ios_base::eofbit | ios_base::failbit);
            }       
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
-      else
-       this->setstate(ios_base::failbit);
       return *this;
     }
   
@@ -815,6 +729,7 @@ namespace std
       sentry __cerb(*this, true);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
              // Cannot compare int_type with streamsize generically.
@@ -826,19 +741,13 @@ namespace std
                    _M_gcount = this->rdbuf()->sgetn(__s, __num);
                }
              else
-               this->setstate(ios_base::eofbit);                   
+               __err |= ios_base::eofbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
-      else
-       this->setstate(ios_base::failbit);
       return _M_gcount;
     }
       
@@ -854,25 +763,20 @@ namespace std
       sentry __cerb(*this, true);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
              const int_type __eof = traits_type::eof();
              __streambuf_type* __sb = this->rdbuf();
              if (!__sb 
                  || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
-               this->setstate(ios_base::badbit);                   
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
-      else
-       this->setstate(ios_base::failbit);
       return *this;
     }
   
@@ -888,25 +792,20 @@ namespace std
       sentry __cerb(*this, true);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
              const int_type __eof = traits_type::eof();
              __streambuf_type* __sb = this->rdbuf();
              if (!__sb 
                  || traits_type::eq_int_type(__sb->sungetc(), __eof))
-               this->setstate(ios_base::badbit);                   
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
-      else
-       this->setstate(ios_base::failbit);
       return *this;
     }
   
@@ -915,30 +814,28 @@ namespace std
     basic_istream<_CharT, _Traits>::
     sync(void)
     {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR60.  Do not change _M_gcount.
       int __ret = -1;
       sentry __cerb(*this, true);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
              __streambuf_type* __sb = this->rdbuf();
              if (__sb)
                {
                  if (__sb->pubsync() == -1)
-                   this->setstate(ios_base::badbit);               
+                   __err |= ios_base::badbit;
                  else 
                    __ret = 0;
                }
            }
          catch(...)
-           {
-             // 27.6.1.3 paragraph 1
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return __ret;
     }
@@ -948,10 +845,16 @@ namespace std
     basic_istream<_CharT, _Traits>::
     tellg(void)
     {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR60.  Do not change _M_gcount.
       pos_type __ret = pos_type(-1);
-      if (!this->fail())
-       __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
+      try
+       {
+         if (!this->fail())
+           __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
+       }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
       return __ret;
     }
 
@@ -961,18 +864,25 @@ namespace std
     basic_istream<_CharT, _Traits>::
     seekg(pos_type __pos)
     {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR60.  Do not change _M_gcount.
-      if (!this->fail())
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      try
        {
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-// 136.  seekp, seekg setting wrong streams?
-         pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::in);
+         if (!this->fail())
+           {
+             // 136.  seekp, seekg setting wrong streams?
+             pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::in);
 
-// 129. Need error indication from seekp() and seekg()
-         if (__err == pos_type(off_type(-1)))
-           this->setstate(ios_base::failbit);
-#endif
+             // 129. Need error indication from seekp() and seekg()
+             if (__p == pos_type(off_type(-1)))
+               __err |= ios_base::failbit;
+           }
        }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -981,19 +891,26 @@ namespace std
     basic_istream<_CharT, _Traits>::
     seekg(off_type __off, ios_base::seekdir __dir)
     {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR60.  Do not change _M_gcount.
-      if (!this->fail())
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      try
        {
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-// 136.  seekp, seekg setting wrong streams?
-         pos_type __err = this->rdbuf()->pubseekoff(__off, __dir, 
-                                                    ios_base::in);
-
-// 129. Need error indication from seekp() and seekg()
-         if (__err == pos_type(off_type(-1)))
-           this->setstate(ios_base::failbit);
-#endif
+         if (!this->fail())
+           {
+             // 136.  seekp, seekg setting wrong streams?
+             pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, 
+                                                      ios_base::in);
+             
+             // 129. Need error indication from seekp() and seekg()
+             if (__p == pos_type(off_type(-1)))
+               __err |= ios_base::failbit;
+           }
        }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -1006,19 +923,20 @@ namespace std
       typename __istream_type::sentry __cerb(__in, false);
       if (__cerb)
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
-           { __in.get(__c); }
-         catch(...)
            {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __in._M_setstate(ios_base::badbit);
-             if ((__in.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
+             typename __istream_type::int_type __cb = __in.rdbuf()->sbumpc();
+             if (!_Traits::eq_int_type(__cb, _Traits::eof()))
+               __c = _Traits::to_char_type(__cb);
+             else
+               __err |= (ios_base::eofbit | ios_base::failbit);
            }
+         catch(...)
+           { __in._M_setstate(ios_base::badbit); }
+         if (__err)
+           __in.setstate(__err);
        }
-      else
-       __in.setstate(ios_base::failbit);
       return __in;
     }
 
@@ -1031,8 +949,9 @@ namespace std
       typedef typename _Traits::int_type               int_type;
       typedef _CharT                                   char_type;
       typedef ctype<_CharT>                            __ctype_type;
-      streamsize __extracted = 0;
 
+      streamsize __extracted = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       typename __istream_type::sentry __cerb(__in, false);
       if (__cerb)
        {
@@ -1057,7 +976,7 @@ namespace std
                  __c = __sb->snextc();
                }
              if (_Traits::eq_int_type(__c, __eof))
-               __in.setstate(ios_base::eofbit);
+               __err |= ios_base::eofbit;
 
 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
 //68.  Extractors for char* should store null at end
@@ -1066,16 +985,12 @@ namespace std
              __in.width(0);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __in._M_setstate(ios_base::badbit);
-             if ((__in.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { __in._M_setstate(ios_base::badbit); }
        }
       if (!__extracted)
-       __in.setstate(ios_base::failbit);
+       __err |= ios_base::failbit;
+      if (__err)
+       __in.setstate(__err);
       return __in;
     }
 
@@ -1099,8 +1014,7 @@ namespace std
        __c = __sb->snextc();
 
        if (_Traits::eq_int_type(__c, __eof))
-       __in.setstate(ios_base::eofbit);
-
+        __in.setstate(ios_base::eofbit);
       return __in;
     }
 
@@ -1116,38 +1030,49 @@ namespace std
       typedef typename __istream_type::__ctype_type    __ctype_type;
       typedef basic_string<_CharT, _Traits, _Alloc>    __string_type;
       typedef typename __string_type::size_type                __size_type;
-      __size_type __extracted = 0;
 
+      __size_type __extracted = 0;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       typename __istream_type::sentry __cerb(__in, false);
       if (__cerb) 
        {
-         __str.erase();
-         streamsize __w = __in.width();
-         __size_type __n;
-         __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
-
-         const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc());
-         const __int_type __eof = _Traits::eof();
-         __streambuf_type* __sb = __in.rdbuf();
-         __int_type __c = __sb->sgetc();
-         
-         while (__extracted < __n 
-                && !_Traits::eq_int_type(__c, __eof)
-                && !__ctype.is(ctype_base::space, _Traits::to_char_type(__c)))
+         try
            {
-             __str += _Traits::to_char_type(__c);
-             ++__extracted;
-             __c = __sb->snextc();
+             __str.erase();
+             streamsize __w = __in.width();
+             __size_type __n;
+             __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
+             
+             const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
+             const __int_type __eof = _Traits::eof();
+             __streambuf_type* __sb = __in.rdbuf();
+             __int_type __c = __sb->sgetc();
+             
+             while (__extracted < __n 
+                    && !_Traits::eq_int_type(__c, __eof)
+                    && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
+               {
+                 __str += _Traits::to_char_type(__c);
+                 ++__extracted;
+                 __c = __sb->snextc();
+               }
+             if (_Traits::eq_int_type(__c, __eof))
+               __err |= ios_base::eofbit;
+             __in.width(0);
+           }
+         catch(...)
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 91. Description of operator>> and getline() for string<>
+             // might cause endless loop
+             __in._M_setstate(ios_base::badbit);
            }
-         if (_Traits::eq_int_type(__c, __eof))
-           __in.setstate(ios_base::eofbit);
-         __in.width(0);
        }
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-//211.  operator>>(istream&, string&) doesn't set failbit
+      // 211.  operator>>(istream&, string&) doesn't set failbit
       if (!__extracted)
-       __in.setstate (ios_base::failbit);
-#endif
+       __err |= ios_base::failbit;
+      if (__err)
+       __in.setstate(__err);
       return __in;
     }
 
@@ -1164,33 +1089,44 @@ namespace std
       typedef typename __string_type::size_type                __size_type;
 
       __size_type __extracted = 0;
+      const __size_type __n = __str.max_size();
       bool __testdelim = false;
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
       typename __istream_type::sentry __cerb(__in, true);
       if (__cerb) 
        {
-         __str.erase();
-         __size_type __n = __str.max_size();
-
-         __int_type __idelim = _Traits::to_int_type(__delim);
-         __streambuf_type* __sb = __in.rdbuf();
-         __int_type __c = __sb->sbumpc();
-         const __int_type __eof = _Traits::eof();
-         __testdelim = _Traits::eq_int_type(__c, __idelim);
-
-         while (__extracted <= __n 
-                && !_Traits::eq_int_type(__c, __eof)
-                && !__testdelim)
+         try
            {
-             __str += _Traits::to_char_type(__c);
-             ++__extracted;
-             __c = __sb->sbumpc();
+             __str.erase();
+             __int_type __idelim = _Traits::to_int_type(__delim);
+             __streambuf_type* __sb = __in.rdbuf();
+             __int_type __c = __sb->sbumpc();
+             const __int_type __eof = _Traits::eof();
              __testdelim = _Traits::eq_int_type(__c, __idelim);
+             
+             while (!_Traits::eq_int_type(__c, __eof) && !__testdelim
+                    && __extracted < __n)
+               {
+                 __str += _Traits::to_char_type(__c);
+                 ++__extracted;
+                 __c = __sb->sbumpc();
+                 __testdelim = _Traits::eq_int_type(__c, __idelim);
+               }
+             if (_Traits::eq_int_type(__c, __eof))
+               __err |= ios_base::eofbit;
+           }
+         catch(...)
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 91. Description of operator>> and getline() for string<>
+             // might cause endless loop
+             __in._M_setstate(ios_base::badbit);
            }
-         if (_Traits::eq_int_type(__c, __eof))
-           __in.setstate(ios_base::eofbit);
        }
-      if (!__extracted && !__testdelim)
-       __in.setstate(ios_base::failbit);
+      if ((!__extracted && !__testdelim) || __extracted == __n)
+       __err |= ios_base::failbit;
+      if (__err)
+       __in.setstate(__err);
       return __in;
     }
 
index 1c4dfa25daa0734efce07ac9e18b31db330886bd..11e9bc006e55f54a1e4a42395bda7c7c3ca2e2ad 100644 (file)
@@ -40,7 +40,7 @@ namespace std
 {
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>::sentry::
-    sentry(basic_ostream<_CharT,_Traits>& __os)
+    sentry(basic_ostream<_CharT, _Traits>& __os)
     : _M_os(__os)
     {
       // XXX MT
@@ -93,113 +93,82 @@ namespace std
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin)
-    {
-      sentry __cerb(*this);
-      if (__cerb && __sbin)
-       {
-         try
-           {
-             if (!__copy_streambufs(*this, __sbin, this->rdbuf()))
-               this->setstate(ios_base::failbit);
-           }
-         catch(...)
-           {
-             // 27.6.2.5.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
-       }
-      else if (!__sbin)
-       this->setstate(ios_base::badbit);
-      return *this;
-    }
-
-  template<typename _CharT, typename _Traits>
-    basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(bool __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(bool __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             if (_M_check_facet(_M_fnumput))
-               if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
-                 this->setstate(ios_base::badbit);
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if (__np.put(*this, *this, this->fill(), __n).failed())
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(long __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(long __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
+             bool __b = false;
              char_type __c = this->fill();
              ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
-             if (_M_check_facet(_M_fnumput))
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
                {
-                 bool __b = false;
-                 if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
-                   {
-                     unsigned long __l = static_cast<unsigned long>(__n);
-                     __b = _M_fnumput->put(*this, *this, __c, __l).failed();
-                   }
-                 else
-                   __b = _M_fnumput->put(*this, *this, __c, __n).failed();
-                 if (__b)  
-                   this->setstate(ios_base::badbit);
+                 unsigned long __l = static_cast<unsigned long>(__n);
+                 __b = __np.put(*this, *this, __c, __l).failed();
                }
+             else
+               __b = __np.put(*this, *this, __c, __n).failed();
+             if (__b)  
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(unsigned long __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             if (_M_check_facet(_M_fnumput))
-               if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
-                 this->setstate(ios_base::badbit);
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if (__np.put(*this, *this, this->fill(), __n).failed())
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -207,63 +176,59 @@ namespace std
 #ifdef _GLIBCPP_USE_LONG_LONG
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(long long __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(long long __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
+             bool __b = false;
              char_type __c = this->fill();
              ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
-             if (_M_check_facet(_M_fnumput))
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
                {
-                 bool __b = false;
-                 if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
-                   {
-                     unsigned long long __l;
-                     __l = static_cast<unsigned long long>(__n);
-                     __b = _M_fnumput->put(*this, *this, __c, __l).failed();
-                   }
-                 else
-                   __b = _M_fnumput->put(*this, *this, __c, __n).failed();
-                 if (__b)  
-                   this->setstate(ios_base::badbit);
+                 unsigned long long __l;
+                 __l = static_cast<unsigned long long>(__n);
+                 __b = __np.put(*this, *this, __c, __l).failed();
                }
+             else
+               __b = __np.put(*this, *this, __c, __n).failed();
+             if (__b)  
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(unsigned long long __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             if (_M_check_facet(_M_fnumput))
-               if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
-                 this->setstate(ios_base::badbit);
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if (__np.put(*this, *this, this->fill(), __n).failed())
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -271,76 +236,97 @@ namespace std
   
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(double __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(double __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             if (_M_check_facet(_M_fnumput))
-               if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
-                 this->setstate(ios_base::badbit);
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if (__np.put(*this, *this, this->fill(), __n).failed())
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
   
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(long double __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(long double __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             if (_M_check_facet(_M_fnumput))
-               if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
-                 this->setstate(ios_base::badbit);
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if (__np.put(*this, *this, this->fill(), __n).failed())
+               __err |= ios_base::badbit;
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>& 
-    basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
+    basic_ostream<_CharT, _Traits>::
+    operator<<(const void* __n)
     {
       sentry __cerb(*this);
       if (__cerb) 
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try 
            {
-             if (_M_check_facet(_M_fnumput))
-               if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
-                 this->setstate(ios_base::badbit);
+             _M_check_facet(this->_M_fnumput);
+             const __numput_type& __np = *this->_M_fnumput;
+             if (__np.put(*this, *this, this->fill(), __n).failed())
+               __err |= ios_base::badbit;
            }
          catch(...)
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
+       }
+      return *this;
+    }
+
+  template<typename _CharT, typename _Traits>
+    basic_ostream<_CharT, _Traits>& 
+    basic_ostream<_CharT, _Traits>::
+    operator<<(__streambuf_type* __sbin)
+    {
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      sentry __cerb(*this);
+      if (__cerb && __sbin)
+       {
+         try
            {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
+             if (!__copy_streambufs(*this, __sbin, this->rdbuf()))
+               __err |= ios_base::failbit;
            }
+         catch(...)
+           { this->_M_setstate(ios_base::failbit); }
        }
+      else if (!__sbin)
+       __err |= ios_base::badbit;
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -348,33 +334,28 @@ namespace std
     basic_ostream<_CharT, _Traits>&
     basic_ostream<_CharT, _Traits>::put(char_type __c)
     { 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 60. What is a formatted input function?
+      // basic_ostream::put(char_type) is an unformatted output function.
+      // DR 63. Exception-handling policy for unformatted output.
+      // Unformatted output functions should catch exceptions thrown
+      // from streambuf members.
       sentry __cerb(*this);
       if (__cerb) 
        {
-         // _GLIBCXX_RESOLVE_LIB_DEFECTS
-         // DR 60. What is a formatted input function?
-         // basic_ostream::put(char_type) is an unformatted output function.
-         // DR 63. Exception-handling policy for unformatted output.
-         // Unformatted output functions should catch exceptions thrown
-         // from streambuf members.
-         sentry __cerb(*this);
-         if (__cerb) 
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+         try
            {
-             try
-               {
-                 int_type __put = this->rdbuf()->sputc(__c); 
-                 if (traits_type::eq_int_type(__put, traits_type::eof()))
-                   this->setstate(ios_base::badbit);
-               }
-             catch (...)
-               {
-                 this->_M_setstate(ios_base::badbit);
-                 if ((this->exceptions() & ios_base::badbit) != 0)
-                   __throw_exception_again;
-               }
+             int_type __put = this->rdbuf()->sputc(__c); 
+             if (traits_type::eq_int_type(__put, traits_type::eof()))
+               __err |= ios_base::badbit;
            }
+         catch (...)
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
-      return *this;
+      return *this;     
     }   
       
   template<typename _CharT, typename _Traits>
@@ -391,18 +372,17 @@ namespace std
       sentry __cerb(*this);
       if (__cerb)
        {
+         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
          try
            {
              streamsize __put = this->rdbuf()->sputn(__s, __n);
              if (__put != __n)
-               this->setstate(ios_base::badbit);
+               __err |= ios_base::badbit;
            }
          catch (...)
-           {
-             this->_M_setstate(ios_base::badbit);
-             if ((this->exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { this->_M_setstate(ios_base::badbit); }
+         if (__err)
+           this->setstate(__err);
        }
       return *this;
     }
@@ -414,8 +394,16 @@ namespace std
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 60. What is a formatted input function?
       // basic_ostream::flush() is *not* an unformatted output function.
-      if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
-       this->setstate(ios_base::badbit);
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      try
+       {
+         if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
+           __err |= ios_base::badbit;
+       }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
   
@@ -424,8 +412,13 @@ namespace std
     basic_ostream<_CharT, _Traits>::tellp()
     {
       pos_type __ret = pos_type(-1);
-      if (!this->fail())
-       __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
+      try
+       {
+         if (!this->fail())
+           __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
+       }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
       return __ret;
     }
 
@@ -434,37 +427,51 @@ namespace std
     basic_ostream<_CharT, _Traits>&
     basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
     {
-      if (!this->fail())
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      try
        {
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-// 136.  seekp, seekg setting wrong streams?
-         pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::out);
-
-// 129. Need error indication from seekp() and seekg()
-         if (__err == pos_type(off_type(-1)))
-           this->setstate(ios_base::failbit);
-#endif
+         if (!this->fail())
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 136.  seekp, seekg setting wrong streams?
+             pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
+             
+             // 129. Need error indication from seekp() and seekg()
+             if (__p == pos_type(off_type(-1)))
+               __err |= ios_base::failbit;
+           }
        }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>&
     basic_ostream<_CharT, _Traits>::
-    seekp(off_type __off, ios_base::seekdir __d)
+    seekp(off_type __off, ios_base::seekdir __dir)
     {
-      if (!this->fail())
+      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      try
        {
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-// 136.  seekp, seekg setting wrong streams?
-         pos_type __err = this->rdbuf()->pubseekoff(__off, __d, 
-                                                    ios_base::out);
-
-// 129. Need error indication from seekp() and seekg()
-         if (__err == pos_type(off_type(-1)))
-           this->setstate(ios_base::failbit);
-#endif
+         if (!this->fail())
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 136.  seekp, seekg setting wrong streams?
+             pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, 
+                                                      ios_base::out);
+             
+             // 129. Need error indication from seekp() and seekg()
+             if (__p == pos_type(off_type(-1)))
+               __err |= ios_base::failbit;
+           }
        }
+      catch(...)
+       { this->_M_setstate(ios_base::badbit); }
+      if (__err)
+       this->setstate(__err);
       return *this;
     }
 
@@ -493,13 +500,7 @@ namespace std
              __out.width(0);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __out._M_setstate(ios_base::badbit);
-             if ((__out.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { __out._M_setstate(ios_base::badbit); }
        }
       return __out;
     }
@@ -529,13 +530,7 @@ namespace std
              __out.width(0);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __out._M_setstate(ios_base::badbit);
-             if ((__out.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { __out._M_setstate(ios_base::badbit); }
        }
       return __out;
      }
@@ -564,13 +559,7 @@ namespace std
              __out.width(0);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __out._M_setstate(ios_base::badbit);
-             if ((__out.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { __out._M_setstate(ios_base::badbit); }
        }
       else if (!__s)
        __out.setstate(ios_base::badbit);
@@ -613,13 +602,7 @@ namespace std
              __out.width(0);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __out._M_setstate(ios_base::badbit);
-             if ((__out.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { __out._M_setstate(ios_base::badbit); }
        }
       else if (!__s)
        __out.setstate(ios_base::badbit);
@@ -652,13 +635,7 @@ namespace std
              __out.width(0);
            }
          catch(...)
-           {
-             // 27.6.1.2.1 Common requirements.
-             // Turn this on without causing an ios::failure to be thrown.
-             __out._M_setstate(ios_base::badbit);
-             if ((__out.exceptions() & ios_base::badbit) != 0)
-               __throw_exception_again;
-           }
+           { __out._M_setstate(ios_base::badbit); }
        }
       else if (!__s)
        __out.setstate(ios_base::badbit);
index be858621b85b4923aa2dfba261227c165e070b07..9b65f4e7073801daab29da50fe9466837b6a0b5f 100644 (file)
@@ -194,42 +194,32 @@ namespace std
   // necessary.
   template<typename _CharT, typename _Traits>
     streamsize
-    __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
+    __copy_streambufs(basic_ios<_CharT, _Traits>&,
                      basic_streambuf<_CharT, _Traits>* __sbin,
                      basic_streambuf<_CharT, _Traits>* __sbout) 
   {
     streamsize __ret = 0;
-    try 
+    typename _Traits::int_type __c = __sbin->sgetc();
+    while (!_Traits::eq_int_type(__c, _Traits::eof()))
       {
-       typename _Traits::int_type __c = __sbin->sgetc();
-       while (!_Traits::eq_int_type(__c, _Traits::eof()))
+       const size_t __n = __sbin->_M_in_end - __sbin->_M_in_cur;
+       if (__n > 1)
          {
-           const size_t __n = __sbin->_M_in_end - __sbin->_M_in_cur;
-           if (__n > 1)
-             {
-               const size_t __wrote = __sbout->sputn(__sbin->_M_in_cur,
-                                                     __n);
-               __sbin->_M_in_cur_move(__wrote);
-               __ret += __wrote;
-               if (__wrote < __n)
-                 break;
-               __c = __sbin->underflow();
-             }
-           else 
-             {
-               __c = __sbout->sputc(_Traits::to_char_type(__c));
-               if (_Traits::eq_int_type(__c, _Traits::eof()))
-                 break;
-               ++__ret;
-               __c = __sbin->snextc();
-             }
+           const size_t __wrote = __sbout->sputn(__sbin->_M_in_cur, __n);
+           __sbin->_M_in_cur_move(__wrote);
+           __ret += __wrote;
+           if (__wrote < __n)
+             break;
+           __c = __sbin->underflow();
+         }
+       else 
+         {
+           __c = __sbout->sputc(_Traits::to_char_type(__c));
+           if (_Traits::eq_int_type(__c, _Traits::eof()))
+             break;
+           ++__ret;
+           __c = __sbin->snextc();
          }
-      }
-    catch(exception& __fail) 
-      {
-       __ios.setstate(ios_base::failbit);
-       if ((__ios.exceptions() & ios_base::failbit) != 0)
-         __throw_exception_again;
       }
     return __ret;
   }