2001-01-16 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Jan 2001 07:55:26 +0000 (07:55 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Jan 2001 07:55:26 +0000 (07:55 +0000)
* docs/html/17_intro/C++STYLE (classname): Add more existing
and stylish patterns.

libstdc++/944
* include/bits/istream.tcc (istream::sentry::sentry()): Set
failbit if the state of the stream is not good.
* testsuite/27_io/istream_sentry.cc (test02): Add test.
* testsuite/27_io/istream_manip.cc (test01): Modify.

libstdc++/1019
reported by Paolo Carlini <pcarlini@unitus.it>
* include/bits/istream.tcc (operator>>(istream&, string&)): Fix.
* testsuite/21_strings/inserters_extractors.cc (test08): Add test.

libstdc++/1057
* include/bits/std_streambuf.h (setp): Set _M_buf_size correctly.
* include/bits/streambuf.tcc (xsputn): Remove outside if clause.
(xsgetn): Same. Simplify.
* testsuite/27_io/streambuf.cc (test04): Add testcases.

reported by Larry Evans <jcampbell3@prodigy.net>
* include/bits/streambuf.tcc (streambuf::xsputn): Just check for
equality with eof on returned value from overflow.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39059 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/docs/html/17_intro/C++STYLE
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/bits/std_streambuf.h
libstdc++-v3/include/bits/streambuf.tcc
libstdc++-v3/testsuite/21_strings/inserters_extractors.cc
libstdc++-v3/testsuite/27_io/istream_manip.cc
libstdc++-v3/testsuite/27_io/istream_sentry.cc
libstdc++-v3/testsuite/27_io/istream_unformatted.cc
libstdc++-v3/testsuite/27_io/streambuf.cc

index 1f7822b..dc0461f 100644 (file)
@@ -1,3 +1,29 @@
+2001-01-16  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * docs/html/17_intro/C++STYLE (classname): Add more existing
+       and stylish patterns.
+
+       libstdc++/944
+       * include/bits/istream.tcc (istream::sentry::sentry()): Set
+       failbit if the tate of the stream is not good.
+       * testsuite/27_io/istream_sentry.cc (test02): Add test.
+       * testsuite/27_io/istream_manip.cc (test01): Modify.
+
+       libstdc++/1019
+       reported by Paolo Carlini <pcarlini@unitus.it>
+       * include/bits/istream.tcc (operator>>(istream&, string&)): Fix. 
+       * testsuite/21_strings/inserters_extractors.cc (test08): Add test.
+
+       libstdc++/1057
+       * include/bits/std_streambuf.h (setp): Set _M_buf_size correctly.
+       * include/bits/streambuf.tcc (xsputn): Remove outside if clause.
+       (xsgetn): Same. Simplify.
+       * testsuite/27_io/streambuf.cc (test04): Add testcases.
+
+       reported by Larry Evans <jcampbell3@prodigy.net> 
+       * include/bits/streambuf.tcc (streambuf::xsputn): Just check for
+       equality with eof on returned value from overflow.
+
 2001-01-14  Andreas Jaeger  <aj@suse.de>
 
        * libio/libio.h: Add test for glibc 2.0.
index 6a85ac6..5c010ed 100644 (file)
@@ -1,5 +1,5 @@
 
-C++ Standard Library Style Guidelines  DRAFT 1999-02-26
+C++ Standard Library Style Guidelines  DRAFT 2001-01-15
 -------------------------------------
 
 This library is written to appropriate C++ coding standards.  As such,
@@ -99,8 +99,8 @@ Notable areas of divergence from what may be previous local practice
 07. Member initialization lists
    All one line, separate from class name.
 
-  gribble::gribble()
-  _M_private_data(0), _M_more_stuff(0), _M_helper(0);
+  gribble::gribble() :
+  _M_private_data(0), _M_more_stuff(0), _M_helper(0);
   { }
   -NOT-
   gribble::gribble() : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
@@ -148,15 +148,42 @@ Notable areas of divergence from what may be previous local practice
 
        Reason: Koenig lookup.
 
-11. constructor member intialization lists
+11. Namespaces
+  namespace std
+  {
+    blah blah blah;
+  } // namespace std
+
+  -NOT-
+
+  namespace std {
+    blah blah blah;
+  } // namespace std
+
+12. Spacing under protected and private in class declarations:
+   space above, none below
+   ie
+
+   public:
+     int foo;
+
+   -NOT-
+   public:
+   
+     int foo;
+
+13. Spacing WRT return statements.
+   no extra spacing before returns
+   ie
+
+   }
+   return __ret;
+
+   -NOT-
+   }
+
+   return __ret;
 
-  should look like this:
-  ctype<char>::ctype(const mask* __table, bool __del, size_t __refs) : 
-  __ctype_abstract_base<char>(__refs), _M_del(__table != 0 && __del), 
-  _M_toupper(__ctype_toupper), _M_tolower(__ctype_tolower),
-  _M_ctable(static_cast<const mask*>(__ctype_b), 
-  _M_table(__table == 0 ? _M_ctable : __table) 
-  { }
 
 
 The library currently has a mixture of GNU-C and modern C++ coding
@@ -264,8 +291,8 @@ namespace std
   extern long long _G_global_with_a_good_long_name;  // avoid globals!
 # endif
 
-  // avoid in-class inline definitions, define separately;
-  //   likewise for member class definitions:
+  // Avoid in-class inline definitions, define separately;
+  // likewise for member class definitions:
   inline int
   gribble::public_member() const
   { int __local = 0; return __local; }
@@ -285,8 +312,8 @@ namespace std
 #endif /* _HEADER_ */
 
 
-namespace std {
-
+namespace std 
+{
   template<typename T>  // notice: "typename", not "class", no space
     long_return_value_type<with_many, args>  
     function_name(char* pointer,               // "char *pointer" is wrong.
@@ -321,8 +348,8 @@ namespace std {
   {
     // doesn't fit in one line.
   }
+} // namespace std
 
-}
 
 
 
index e43e8a3..f1ffda2 100644 (file)
@@ -41,39 +41,44 @@ namespace std
     basic_filebuf<_CharT, _Traits>::
     _M_filebuf_init()
     {
-      _M_buf_unified = true; // Tie input to output for basic_filebuf.
-      _M_buf_size = _M_buf_size_opt;
-      try {
-       _M_file = new __file_type(&_M_lock);
-      }
-      catch(...) {
-       delete _M_file;
-       throw;
-      }
-     }
+      if (!_M_file)
+       {
+         _M_buf_unified = true; // Tie input to output for basic_filebuf.
+         try 
+           { _M_file = new __file_type(&_M_lock); }
+         catch(...) 
+           {
+             delete _M_file;
+             throw;
+           }
+       }
+    }
 
   template<typename _CharT, typename _Traits>
     void
     basic_filebuf<_CharT, _Traits>::
     _M_allocate_buffers()
     {
-      // Allocate internal buffer.
-      try {
-       _M_buf = new char_type[_M_buf_size];
-      }
-      catch(...) {
-       delete [] _M_buf;
-       throw;
-      }
-      
-      // Allocate pback buffer.
-      try {
-       _M_pback = new char_type[_M_pback_size];
-      }
-      catch(...) {
-       delete [] _M_pback;
-       throw;
-      }
+      if (!_M_buf)
+       {
+         _M_buf_size = _M_buf_size_opt;
+         // Allocate internal buffer.
+         try { _M_buf = new char_type[_M_buf_size]; }
+         catch(...) 
+           {
+             delete [] _M_buf;
+             throw;
+           }
+         
+         // Allocate pback buffer.
+         try 
+           { _M_pback = new char_type[_M_pback_size]; }
+         catch(...) 
+           {
+             delete [] _M_pback;
+             throw;
+           }
+       }
     }
 
   template<typename _CharT, typename _Traits>
@@ -86,13 +91,13 @@ namespace std
   template<typename _CharT, typename _Traits>
     basic_filebuf<_CharT, _Traits>::
     basic_filebuf(int __fd, const char* /*__name*/, ios_base::openmode __mode)
-    : __streambuf_type(), _M_state_cur(__state_type()), 
+    : __streambuf_type(),  _M_file(NULL), _M_state_cur(__state_type()), 
     _M_state_beg(__state_type()), _M_last_overflowed(false)
     {
       _M_fcvt = &use_facet<__codecvt_type>(this->getloc());
       _M_filebuf_init();
       _M_file->sys_open(__fd, __mode);
-      if (this->is_open() && _M_buf_size)
+      if (this->is_open())
        {
          _M_allocate_buffers();
          _M_mode = __mode;
@@ -116,7 +121,7 @@ namespace std
        {
          _M_filebuf_init();
          _M_file->open(__s, __mode);
-         if (this->is_open() && _M_buf_size)
+         if (this->is_open())
            {
              _M_allocate_buffers();
              _M_mode = __mode;
@@ -157,13 +162,15 @@ namespace std
 #endif
 
          _M_mode = ios_base::openmode(0);
-         if (_M_buf_size)
-           delete [] _M_buf;
-         _M_buf = NULL;
-         delete [] _M_pback;
-         _M_pback = NULL;
-         this->setg(NULL, NULL, NULL);
-         this->setp(NULL, NULL);
+         if (_M_buf)
+           {
+             delete [] _M_buf;
+             _M_buf = NULL;
+             delete [] _M_pback;
+             _M_pback = NULL;
+             this->setg(NULL, NULL, NULL);
+             this->setp(NULL, NULL);
+           }
          __ret = this;
        }
 
index 0e32781..c257907 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -66,7 +66,14 @@ namespace std {
 #endif
            }
        }
-      _M_ok = __in.good();
+
+      if (__in.good())
+       _M_ok = true;
+      else
+       {
+         _M_ok = false;
+         __in.setstate(ios_base::failbit);
+       }
     }
 
   template<typename _CharT, typename _Traits>
@@ -1123,7 +1130,7 @@ namespace std {
          bool __testsp = __ctype->is(ctype_base::space, __c);
          bool __testeof =  __c == __eof;
 
-         while (__extracted <= __n && !__testeof && !__testsp)
+         while (__extracted < __n && !__testeof && !__testsp)
            {
              __str += _Traits::to_char_type(__c);
              ++__extracted;
index f4d65ae..5cf7b02 100644 (file)
@@ -1,6 +1,6 @@
 // Stream buffer classes -*- C++ -*-
 
-// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -44,7 +44,7 @@ namespace std {
 
   template<typename _CharT, typename _Traits>
     static streamsize
-    _S_copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
+    _S_copy_streambufs(basic_ios<_CharT, _Traits>& _ios,
                       basic_streambuf<_CharT, _Traits>* __sbin,
                       basic_streambuf<_CharT, _Traits>* __sbout);
   
@@ -83,7 +83,7 @@ namespace std {
       // leave it NULL.
       char_type*               _M_buf;         
 
-      // Actual size of internal buffer, in bytes.
+      // Actual size of allocated internal buffer, in bytes.
       int_type                 _M_buf_size;
 
       // Optimal or preferred size of internal buffer, in bytes.
@@ -172,6 +172,17 @@ namespace std {
          }
       }
 
+      // Correctly sets the _M_in_cur pointer, and bumps the
+      // _M_out_cur pointer as well if necessary.
+      void 
+      _M_in_cur_move(off_type __n) // argument needs to be +-
+      {
+       bool __testout = _M_out_cur;
+       _M_in_cur += __n;
+       if (__testout && _M_buf_unified)
+         _M_out_cur += __n;
+      }
+
       // Correctly sets the _M_out_cur pointer, and bumps the
       // appropriate _M_*_end pointers as well. Necessary for the
       // un-tied stringbufs, in in|out mode.
@@ -183,7 +194,7 @@ namespace std {
       void 
       _M_out_cur_move(off_type __n) // argument needs to be +-
       {
-       bool __testin = _M_mode & ios_base::in;
+       bool __testin = _M_in_cur;
 
        _M_out_cur += __n;
        if (__testin && _M_buf_unified)
@@ -197,6 +208,25 @@ namespace std {
          }
       }
 
+      // Return the size of the output buffer.  This depends on the
+      // buffer in use: allocated buffers have a stored size in
+      // _M_buf_size and setbuf() buffers don't.
+      off_type
+      _M_out_buf_size()
+      {
+       off_type __ret = 0;
+       if (_M_out_cur)
+         {
+           // Using allocated buffer.
+           if (_M_out_beg == _M_buf)
+             __ret = _M_out_beg + _M_buf_size - _M_out_cur;
+           // Using non-allocated buffer.
+           else
+             __ret = _M_out_end - _M_out_cur;
+         }
+       return __ret;
+      }
+
       // These three functions are used to clarify internal buffer
       // maintenance. After an overflow, or after a seekoff call that
       // started at beg or end, or possibly when the stream becomes
@@ -219,11 +249,7 @@ namespace std {
        bool __testin = _M_mode & ios_base::in;
        bool __testout = _M_mode & ios_base::out;
        if (__testin)
-         {
-           this->setg(_M_buf, _M_buf, _M_buf + __off);
-           if (!__testout)
-             _M_buf_size = static_cast<int_type>(__off);
-         }
+         this->setg(_M_buf, _M_buf, _M_buf + __off);
        if (__testout)
          this->setp(_M_buf, _M_buf + __off);
 
@@ -404,12 +430,6 @@ namespace std {
        _M_out_end = __pend; 
        if (!(_M_mode & ios_base::out) && __pbeg && __pend)
          _M_mode = _M_mode | ios_base::out;
-       // The output sequence is highly tied to _M_buf and
-       // _M_buf_size in addition to the actual pointers into the
-       // buffer. Because of this, (re)set _M_buf_size here, as
-       // sputc/xsputn need _M_buf_size to be accurate. (The
-       // corresponding input functions rely instead on _M_in_end.)
-       _M_buf_size = max(_M_buf_size, static_cast<int_type>(__pend - __pbeg));
       }
 
       // Virtual functions:
@@ -460,7 +480,6 @@ namespace std {
        int_type __ret = traits_type::eof();
        bool __testeof = this->underflow() == __ret;
        bool __testpending = _M_in_cur && _M_in_cur < _M_in_end;
-       
        if (!__testeof && __testpending)
          {
            __ret = traits_type::to_int_type(*_M_in_cur);
index d03b7bc..8424e46 100644 (file)
@@ -1,6 +1,6 @@
 // Stream buffer classes -*- C++ -*-
 
-// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -45,9 +45,7 @@ namespace std {
       if (_M_in_cur && _M_in_cur < _M_in_end)
        {
          char_type __c = *gptr();
-         ++_M_in_cur;
-         if (_M_buf_unified &&  _M_mode & ios_base::out)
-           ++_M_out_cur;
+         _M_in_cur_move(1);
          __ret = traits_type::to_int_type(__c);
        }
       else 
@@ -67,9 +65,7 @@ namespace std {
        __ret = pbackfail(traits_type::to_int_type(__c));
       else 
        {
-         --_M_in_cur;
-         if (_M_buf_unified && _M_mode & ios_base::out)
-           --_M_out_cur;
+         _M_in_cur_move(-1);
          __ret = traits_type::to_int_type(*this->gptr());
        }
       return __ret;
@@ -83,9 +79,7 @@ namespace std {
       int_type __ret;
       if (_M_in_cur && _M_in_beg < _M_in_cur)
        {
-         --_M_in_cur;
-         if (_M_buf_unified && _M_mode & ios_base::out)
-           --_M_out_cur;
+         _M_in_cur_move(-1);
          __ret = traits_type::to_int_type(*_M_in_cur);
        }
       else 
@@ -104,8 +98,7 @@ namespace std {
     sputc(char_type __c)
     {
       int_type __ret;
-
-      if (_M_out_cur && _M_out_cur < _M_out_beg + _M_buf_size)
+      if (_M_out_buf_size())
        {
          *_M_out_cur = __c;
          _M_out_cur_move(1);
@@ -121,37 +114,27 @@ namespace std {
     basic_streambuf<_CharT, _Traits>::
     xsgetn(char_type* __s, streamsize __n)
     {
-      bool __testout = _M_mode & ios_base::out;
       streamsize __ret = 0;
-
-      if (__n)
+      while (__ret < __n)
        {
-         while (__ret < __n)
+         size_t __buf_len = _M_in_end - _M_in_cur;
+         if (__buf_len > 0)
            {
-             if (_M_in_cur < _M_in_end)
-               {
-                 size_t __len;
-                 if (_M_in_cur + __n - __ret <= _M_in_end)
-                   __len = __n - __ret;
-                 else
-                   __len = _M_in_end - _M_in_cur;
-                 traits_type::copy(__s, _M_in_cur, __len);
-                 __ret += __len;
-                 __s += __len;
-                 _M_in_cur += __len;
-                 if (_M_buf_unified && __testout)
-                   _M_out_cur += __len;
-               }
-             
-             if (__ret != __n)
-               {
-                 int_type __c = this->uflow();  
-                 if (traits_type::eq_int_type(__c, traits_type::eof()))
-                    break;
-
-                 traits_type::assign(*__s++, traits_type::to_char_type(__c));
-                  ++__ret;
-               }
+             size_t __remaining = __n - __ret;
+             size_t __len = min(__buf_len, __remaining);
+             traits_type::copy(__s, _M_in_cur, __len);
+             __ret += __len;
+             __s += __len;
+             _M_in_cur_move(__len);
+           }
+         
+         if (__ret < __n)
+           {
+             int_type __c = this->uflow();  
+             if (traits_type::eq_int_type(__c, traits_type::eof()))
+               break;
+             traits_type::assign(*__s++, traits_type::to_char_type(__c));
+             ++__ret;
            }
        }
       return __ret;
@@ -168,44 +151,32 @@ namespace std {
     xsputn(const char_type* __s, streamsize __n)
     {
       streamsize __ret = 0;
-
-      if (__n)
+      while (__ret < __n)
        {
-         while (__ret < __n)
+         off_type __buf_len = _M_out_buf_size();
+         if (__buf_len > 0)
            {
-             bool __testput = _M_out_cur < _M_out_beg + _M_buf_size;
-             bool __testout = _M_mode & ios_base::out;
-             if (!(__testput && __testout))
-               {
-                 int_type __c = traits_type::to_int_type(*__s);
-                 int_type __overfc = this->overflow(__c);
-                 if (traits_type::eq_int_type(__c, __overfc))
-                   {
-                     ++__ret;
-                     ++__s;
-                   }
-                 else
-                   break;
-               }
-             
-             if (__ret != __n)
-               {
-                 size_t __len;
-                 if (_M_out_cur + __n - __ret <= _M_out_beg + _M_buf_size)
-                   __len = __n - __ret;
-                 else
-                   __len = _M_out_beg + _M_buf_size - _M_out_cur;
-                 traits_type::copy(_M_out_cur, __s, __len);
-                 __ret += __len;
-                 __s += __len;
-                 _M_out_cur_move(__len);
-               }
+             off_type __remaining = __n - __ret;
+             off_type __len = min(__buf_len, __remaining);
+             traits_type::copy(_M_out_cur, __s, __len);
+             __ret += __len;
+             __s += __len;
+             _M_out_cur_move(__len);
+           }
+
+         if (__ret < __n)
+           {
+             int_type __c = traits_type::to_int_type(*__s);
+             int_type __overfc = this->overflow(__c);
+             if (traits_type::eq_int_type(__overfc, traits_type::eof()))
+               break;
+             ++__ret;
+             ++__s;
            }
        }
       return __ret;
     }
 
-
   // Conceivably, this could be used to implement buffer-to-buffer
   // copies, if this was ever desired in an un-ambiguous way by the
   // standard. If so, then checks for __ios being zero would be
@@ -221,16 +192,13 @@ namespace std {
       streamsize __ret = 0;
       streamsize __bufsize = __sbin->in_avail();
       streamsize __xtrct;
-      bool __testout = __sbin->_M_mode & ios_base::out;
       bool __testput = __sbout->_M_mode & ios_base::out;
       try {
        while (__testput && __bufsize != -1)
          {
            __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
            __ret += __xtrct;
-           __sbin->_M_in_cur += __xtrct;
-           if (__testout && __sbin->_M_buf_unified)
-             __sbin->_M_out_cur += __xtrct;
+           __sbin->_M_in_cur_move(__xtrct);
            if (__xtrct == __bufsize)
              {
                int_type __c = __sbin->sgetc();
@@ -251,7 +219,6 @@ namespace std {
       }
       return __ret;
     }
-
 } // namespace std
 
 #endif // _CPP_BITS_STREAMBUF_TCC
@@ -259,3 +226,4 @@ namespace std {
 
 
 
+
index 6ba5bda..7332782 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-07-01 bkoz
 
-// Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -29,6 +29,7 @@
 #include <sstream>
 #include <fstream>
 #include <iostream>
+#include <iomanip>
 #include <debug_assert.h>
 
 bool test01(void)
@@ -287,6 +288,23 @@ void test07(void)
 #endif
 }
 
+// libstdc++/1019
+void test08()
+{
+  using namespace std;
+
+  bool                 test = true;
+  istringstream istrm("enero:2001");
+  int          year;
+  char                 sep;
+  string       month;
+  
+  istrm >> setw(5) >> month >> sep >> year;
+  VERIFY( month.size() == 5 );
+  VERIFY( sep == ':' );
+  VERIFY( year == 2001 );
+}
+
 int main()
 { 
   test01();
@@ -302,6 +320,7 @@ int main()
   test06();
   test07();
 
+  test08();
   return 0;
 }
 
index 57d376c..ba3826c 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-07-22 bkoz
 
-// Copyright (C) 1994, 1999 Free Software Foundation, Inc.
+// Copyright (C) 1994, 1999, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -70,7 +70,7 @@ bool test01(void)
   VERIFY( !iss02.eof() );
 
   iss01 >> std::ws;
-  VERIFY( !iss01.fail() );
+  VERIFY( iss01.fail() );
   VERIFY( iss01.eof() );
 
 #ifdef DEBUG_ASSERT
index 5baca93..cf4a1bb 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-10-14 bkoz
 
-// Copyright (C) 1999 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -57,16 +57,30 @@ void test01()
 
   std::istream::sentry sentry04(istr02, true);
   VERIFY( bool(sentry04) == true ); 
-
-#ifdef DEBUG_ASSERT
-  assert(test);
-#endif
 }
 
-
-int main() {
-  
+// libstdc++/944
+void 
+test02()
+{
+  using namespace std;
+  istringstream in("80.21 56.89 12.3");
+  bool  test = true;
+  int i = 0;
+  double x;
+
+  // ios_base::eof == 2
+  while(in >> x)
+    {
+      ++i;
+    }
+  VERIFY( i == 3 );
+}    
+
+int main() 
+{
   test01();
+  test02();
   return 0;
 }
 
index 3e479f2..76464d7 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-08-11 bkoz
 
-// Copyright (C) 1999, 2000 Free Software Foundation
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -103,7 +103,7 @@ test01()
   VERIFY( is_04.peek() == traits_type::eof() );
   VERIFY( is_04.gcount() == 0 );
   state2 = is_04.rdstate();
-  VERIFY( state1 == state2 );
+  VERIFY( state1 != state2 );
 
 
   // istream& putback(char c)
index 8b28988..4aaa895 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-10-11 bkoz
 
-// Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -31,6 +31,7 @@
 
 #include <cstring> // for memset, memcmp
 #include <streambuf>
+#include <string>
 #include <ostream>
 #include <debug_assert.h>
 
@@ -232,6 +233,98 @@ void test03()
 #endif
 }
 
+class setpbuf : public std::streambuf
+{
+  char                 buffer[4];
+  std::string  result;
+
+public:
+
+  std::string&
+  get_result()
+  { return result; }
+
+  setpbuf()
+  {
+    char foo [32];
+    setp(foo, foo + 32);
+    setp(buffer, buffer + 4);
+  }
+
+  ~setpbuf()
+  { sync(); }
+
+  virtual int_type 
+  overflow(int_type n)
+  {
+    if (sync() != 0)
+      return traits_type::eof();
+    
+    result += traits_type::to_char_type(n);
+    
+    return n;
+  }
+  
+  virtual int 
+  sync()
+  {
+    result.append(pbase(), pptr());
+    setp(buffer, buffer + 4);
+    return 0;
+  }
+};
+
+// libstdc++/1057
+void test04()
+{
+  bool test = true;
+  std::string text = "abcdefghijklmn";
+  
+  // 01
+  setpbuf sp1;
+  // Here xsputn writes over sp1.result
+  sp1.sputn(text.c_str(), text.length());
+
+  // This crashes when result is accessed
+  sp1.pubsync();
+  VERIFY( sp1.get_result() == text );
+  
+
+  // 02
+  setpbuf sp2;
+  for (std::string::size_type i = 0; i < text.length(); ++i)
+    {
+      // sputc also writes over result
+      sp2.sputc(text[i]);
+    }
+  
+  // Crash here
+  sp2.pubsync();
+  VERIFY( sp2.get_result() == text );
+}
+
+class nullsetpbuf : public std::streambuf
+{
+  char foo[64];
+public:
+  nullsetpbuf()
+  {
+    setp(foo, foo + 64);
+    setp(NULL, NULL);
+  }
+};
+
+// libstdc++/1057
+void test05()
+{
+    std::string text1 = "abcdefghijklmn";
+
+    nullsetpbuf nsp;
+    // Immediate crash as xsputn writes to null pointer
+    nsp.sputn(text1.c_str(), text1.length());
+    // ditto
+    nsp.sputc('a');
+}
 
 int main() 
 {
@@ -239,6 +332,8 @@ int main()
   test02();
   test03();
 
+  test04();
+  test05();
   return 0;
 }