This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Fix a bug in basic_stringbuf


Hi,

tested x86/x86_64-linux, committed to mainline.

Paolo.

/////////////
2004-09-29  Paolo Carlini  <pcarlini@suse.de>

	* include/std/std_sstream.h (basic_stringbuf(ios_base::openmode)):
	Don't use _M_stringbuf_init, keep the pointers null, per 27.7.1.1.
	(str()): Slightly tweak, protect from pptr() == 0.
	(_M_update_egptr()): Likewise.
	* include/bits/sstream.tcc (ssekoff, seekpos): In order to check
	for an empty buffer use __beg instead of _M_string.capacity().
	* testsuite/27_io/basic_stringbuf/cons/char/1.cc: New.
	* testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc: Likewise.

	* testsuite/27_io/basic_filebuf/cons/char/1.cc: New.
	* testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc: Likewise.
	* testsuite/27_io/basic_streambuf/cons/char/1.cc: Update.
	* testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc: Likewise.

2004-09-29  Paolo Carlini  <pcarlini@suse.de>
	    Benjamin Kosnik  <bkoz@redhat.com>
	
	* testsuite/testsuite_io.h (class constraint_buf): New, extended
	and templatized version of constraint_filebuf; add typedefs for
	streambuf/stringbuf/filebuf and wchar_t counterparts.
diff -prN libstdc++-v3-orig/include/bits/sstream.tcc libstdc++-v3/include/bits/sstream.tcc
*** libstdc++-v3-orig/include/bits/sstream.tcc	Fri Aug 13 00:26:31 2004
--- libstdc++-v3/include/bits/sstream.tcc	Wed Sep 29 14:38:24 2004
*************** namespace std
*** 123,128 ****
--- 123,129 ----
  	{
  	  // Update egptr() to match the actual string end.
  	  _M_update_egptr();
+ 
  	  if (this->gptr() < this->egptr())
  	    __ret = traits_type::to_int_type(*this->gptr());
  	}
*************** namespace std
*** 141,150 ****
        __testin &= !(__mode & ios_base::out);
        __testout &= !(__mode & ios_base::in);
  
!       if (_M_string.capacity() && (__testin || __testout || __testboth))
  	{
- 	  char_type* __beg = __testin ? this->eback() : this->pbase();
- 
  	  _M_update_egptr();
  
  	  off_type __newoffi = __off;
--- 142,150 ----
        __testin &= !(__mode & ios_base::out);
        __testout &= !(__mode & ios_base::in);
  
!       const char_type* __beg = __testin ? this->eback() : this->pbase();
!       if (__beg && (__testin || __testout || __testboth))
  	{
  	  _M_update_egptr();
  
  	  off_type __newoffi = __off;
*************** namespace std
*** 181,195 ****
      seekpos(pos_type __sp, ios_base::openmode __mode)
      {
        pos_type __ret =  pos_type(off_type(-1));
!       if (_M_string.capacity())
! 	{
! 	  off_type __pos (__sp);
! 	  const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
! 	  const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
! 	  char_type* __beg = __testin ? this->eback() : this->pbase();
  
  	  _M_update_egptr();
  
  	  const bool __testpos = 0 <= __pos
  	                         && __pos <=  this->egptr() - __beg;
  	  if ((__testin || __testout) && __testpos)
--- 181,195 ----
      seekpos(pos_type __sp, ios_base::openmode __mode)
      {
        pos_type __ret =  pos_type(off_type(-1));
!       const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
!       const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
  
+       const char_type* __beg = __testin ? this->eback() : this->pbase();
+       if (__beg)
+ 	{
  	  _M_update_egptr();
  
+ 	  off_type __pos(__sp);
  	  const bool __testpos = 0 <= __pos
  	                         && __pos <=  this->egptr() - __beg;
  	  if ((__testin || __testout) && __testpos)
diff -prN libstdc++-v3-orig/include/std/std_sstream.h libstdc++-v3/include/std/std_sstream.h
*** libstdc++-v3-orig/include/std/std_sstream.h	Sun May 23 01:46:33 2004
--- libstdc++-v3/include/std/std_sstream.h	Wed Sep 29 14:19:46 2004
*************** namespace std
*** 111,118 ****
        */
        explicit
        basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
!       : __streambuf_type(), _M_mode(), _M_string()
!       { _M_stringbuf_init(__mode); }
  
        /**
         *  @brief  Starts with an existing string buffer.
--- 111,118 ----
        */
        explicit
        basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
!       : __streambuf_type(), _M_mode(__mode), _M_string()
!       { }
  
        /**
         *  @brief  Starts with an existing string buffer.
*************** namespace std
*** 140,147 ****
        __string_type
        str() const
        {
! 	const bool __testout = this->_M_mode & ios_base::out;
! 	if (__testout)
  	  {
  	    // The current egptr() may not be the actual string end.
  	    if (this->pptr() > this->egptr())
--- 140,146 ----
        __string_type
        str() const
        {
! 	if (this->pptr())
  	  {
  	    // The current egptr() may not be the actual string end.
  	    if (this->pptr() > this->egptr())
*************** namespace std
*** 169,175 ****
        }
  
      protected:
!       // Common initialization code for both ctors goes here.
        /**
         *  @if maint
         *  @doctodo
--- 168,174 ----
        }
  
      protected:
!       // Common initialization code goes here.
        /**
         *  @if maint
         *  @doctodo
*************** namespace std
*** 277,285 ****
        _M_update_egptr()
        {
  	const bool __testin = this->_M_mode & ios_base::in;
- 	const bool __testout = this->_M_mode & ios_base::out;
  
! 	if (__testout && this->pptr() > this->egptr())
  	  if (__testin)
  	    this->setg(this->eback(), this->gptr(), this->pptr());
  	  else
--- 276,283 ----
        _M_update_egptr()
        {
  	const bool __testin = this->_M_mode & ios_base::in;
  
! 	if (this->pptr() && this->pptr() > this->egptr())
  	  if (__testin)
  	    this->setg(this->eback(), this->gptr(), this->pptr());
  	  else
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_filebuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/char/1.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/cons/char/1.cc	Wed Sep 29 20:01:11 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // Copyright (C) 2004 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
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // 27.8.1.2  basic_filebuf constructors  [lib.filebuf.cons]
+ 
+ #include <fstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+ 
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   __gnu_test::constraint_filebuf fbuf;
+   VERIFY( fbuf.check_pointers() );
+ }
+ 
+ int main() 
+ {
+   test01();
+   return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc	Wed Sep 29 20:01:24 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // Copyright (C) 2004 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
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // 27.8.1.2  basic_filebuf constructors  [lib.filebuf.cons]
+ 
+ #include <fstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+ 
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   __gnu_test::constraint_wfilebuf fbuf;
+   VERIFY( fbuf.check_pointers() );
+ }
+ 
+ int main() 
+ {
+   test01();
+   return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_streambuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/char/1.cc	Tue Sep 23 22:03:17 2003
--- libstdc++-v3/testsuite/27_io/basic_streambuf/cons/char/1.cc	Wed Sep 29 20:00:11 2004
***************
*** 31,99 ****
  
  #include <streambuf>
  #include <testsuite_hooks.h>
! 
! class testbuf : public std::streambuf
! {
! public:
! 
!   // Typedefs:
!   typedef std::streambuf::traits_type traits_type;
!   typedef std::streambuf::char_type char_type;
! 
!   testbuf(): std::streambuf() 
!   { }
! 
!   bool
!   check_pointers()
!   { 
!     bool test __attribute__((unused)) = true;
!     VERIFY( this->eback() == NULL );
!     VERIFY( this->gptr() == NULL );
!     VERIFY( this->egptr() == NULL );
!     VERIFY( this->pbase() == NULL );
!     VERIFY( this->pptr() == NULL );
!     VERIFY( this->epptr() == NULL );
!     return test;
!   }
! 
!   int_type 
!   pub_uflow() 
!   { return (this->uflow()); }
! 
!   int_type 
!   pub_overflow(int_type __c = traits_type::eof()) 
!   { return (this->overflow(__c)); }
! 
!   int_type 
!   pub_pbackfail(int_type __c) 
!   { return (this->pbackfail(__c)); }
! 
!   void 
!   pub_setg(char* beg, char* cur, char *end) 
!   { this->setg(beg, cur, end); }
! 
!   void 
!   pub_setp(char* beg, char* end) 
!   { this->setp(beg, end); }
! 
! protected:
!   int_type 
!   underflow() 
!   { 
!     int_type __retval = traits_type::eof();
!     if (this->gptr() < this->egptr())
!       __retval = traits_type::not_eof(0); 
!     return __retval;
!   }
! };
  
  void test01()
  {
-   typedef testbuf::traits_type traits_type;
-   typedef testbuf::int_type int_type;
- 
    bool test __attribute__((unused)) = true;
!   testbuf buf01;
  
    // 27.5.2.1 basic_streambuf ctors
    // default ctor initializes 
--- 31,42 ----
  
  #include <streambuf>
  #include <testsuite_hooks.h>
! #include <testsuite_io.h>
  
  void test01()
  {
    bool test __attribute__((unused)) = true;
!   __gnu_test::constraint_streambuf buf01;
  
    // 27.5.2.1 basic_streambuf ctors
    // default ctor initializes 
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc	Sun Jul 11 21:13:56 2004
--- libstdc++-v3/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc	Wed Sep 29 20:18:26 2004
***************
*** 32,100 ****
  
  #include <streambuf>
  #include <testsuite_hooks.h>
! 
! class testbuf : public std::wstreambuf
! {
! public:
! 
!   // Typedefs:
!   typedef std::wstreambuf::traits_type traits_type;
!   typedef std::wstreambuf::char_type char_type;
! 
!   testbuf(): std::wstreambuf() 
!   { }
! 
!   bool
!   check_pointers()
!   { 
!     bool test __attribute__((unused)) = true;
!     VERIFY( this->eback() == NULL );
!     VERIFY( this->gptr() == NULL );
!     VERIFY( this->egptr() == NULL );
!     VERIFY( this->pbase() == NULL );
!     VERIFY( this->pptr() == NULL );
!     VERIFY( this->epptr() == NULL );
!     return test;
!   }
! 
!   int_type 
!   pub_uflow() 
!   { return (this->uflow()); }
! 
!   int_type 
!   pub_overflow(int_type __c = traits_type::eof()) 
!   { return (this->overflow(__c)); }
! 
!   int_type 
!   pub_pbackfail(int_type __c) 
!   { return (this->pbackfail(__c)); }
! 
!   void 
!   pub_setg(wchar_t* beg, wchar_t* cur, wchar_t* end) 
!   { this->setg(beg, cur, end); }
! 
!   void 
!   pub_setp(wchar_t* beg, wchar_t* end) 
!   { this->setp(beg, end); }
! 
! protected:
!   int_type 
!   underflow() 
!   { 
!     int_type __retval = traits_type::eof();
!     if (this->gptr() < this->egptr())
!       __retval = traits_type::not_eof(0); 
!     return __retval;
!   }
! };
  
  void test01()
  {
-   typedef testbuf::traits_type traits_type;
-   typedef testbuf::int_type int_type;
- 
    bool test __attribute__((unused)) = true;
!   testbuf buf01;
  
    // 27.5.2.1 basic_streambuf ctors
    // default ctor initializes 
--- 32,43 ----
  
  #include <streambuf>
  #include <testsuite_hooks.h>
! #include <testsuite_io.h>
  
  void test01()
  {
    bool test __attribute__((unused)) = true;
!   __gnu_test::constraint_wstreambuf buf01;
  
    // 27.5.2.1 basic_streambuf ctors
    // default ctor initializes 
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/char/1.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/1.cc	Wed Sep 29 20:00:30 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // Copyright (C) 2004 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
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // 27.7.1.1  basic_stringbuf constructors  [lib.stringbuf.cons]
+ 
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+ 
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   __gnu_test::constraint_stringbuf sbuf;
+   VERIFY( sbuf.check_pointers() );
+ }
+ 
+ int main() 
+ {
+   test01();
+   return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc	Wed Sep 29 20:00:47 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // Copyright (C) 2004 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
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // 27.7.1.1  basic_stringbuf constructors  [lib.stringbuf.cons]
+ 
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+ 
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   __gnu_test::constraint_wstringbuf sbuf;
+   VERIFY( sbuf.check_pointers() );
+ }
+ 
+ int main() 
+ {
+   test01();
+   return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/testsuite_io.h libstdc++-v3/testsuite/testsuite_io.h
*** libstdc++-v3-orig/testsuite/testsuite_io.h	Tue Dec  2 03:48:50 2003
--- libstdc++-v3/testsuite/testsuite_io.h	Wed Sep 29 20:01:43 2004
***************
*** 1,7 ****
  // -*- C++ -*-
! // Testing filebuf for the C++ library testsuite.
  //
! // Copyright (C) 2003 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
--- 1,7 ----
  // -*- C++ -*-
! // Testing streambuf/filebuf/stringbuf for the C++ library testsuite.
  //
! // Copyright (C) 2003, 2004 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
***************
*** 32,37 ****
--- 32,38 ----
  #define _GLIBCXX_TESTSUITE_IO_H
  
  #include <fstream>
+ #include <sstream>
  
  namespace __gnu_test
  {  
*************** namespace __gnu_test
*** 44,77 ****
    //   Joint file position
    // 27.8.1.4 - Overridden virtual functions p9
    //   If unbuffered, pbase == pptr == NULL
!   class constraint_filebuf: public std::filebuf
!   {
!   public:
!     bool
!     write_position() 
!     { 
!       bool two = this->pptr() != NULL; 
!       bool one = this->pptr() < this->epptr();
!       return one && two;
!     }
! 
!     bool
!     read_position()
!     { 
!       bool one = this->gptr() != NULL; 
!       bool two = this->gptr() < this->egptr();
! 
!       return one && two;
!     }
! 
!     bool
!     unbuffered() 
!     { 
!       bool one = this->pbase() == NULL; 
!       bool two = this->pptr() == NULL; 
!       return one && two;
!     }    
!   };
  
    // Used to check if basic_streambuf::pubsync() has been called.
    // This is useful for checking if a function creates [io]stream::sentry
--- 45,104 ----
    //   Joint file position
    // 27.8.1.4 - Overridden virtual functions p9
    //   If unbuffered, pbase == pptr == NULL
!   // 27.7.1.1 - Basic_stringbuf constructors p 1
!   // 27.8.1.2 - Basic_filebuf constructors p 1
!   //   ... , initializing the base class with basic_streambuf() 27.5.2.1
!   template<typename T>
!     class constraint_buf
!     : public T
!     {
!     public:
!       bool
!       write_position() 
!       { 
! 	bool one = this->pptr() != NULL; 
! 	bool two = this->pptr() < this->epptr();
! 	return one && two;
!       }
!       
!       bool
!       read_position()
!       { 
! 	bool one = this->gptr() != NULL; 
! 	bool two = this->gptr() < this->egptr();
! 	return one && two;
!       }
!       
!       bool
!       unbuffered() 
!       { 
! 	bool one = this->pbase() == NULL; 
! 	bool two = this->pptr() == NULL; 
! 	return one && two;
!       }
!   
!       bool
!       check_pointers()
!       {
! 	bool one   = this->eback() == NULL;
! 	bool two   = this->gptr() == NULL;
! 	bool three = this->egptr() == NULL;
! 	
! 	bool four  = this->pbase() == NULL;
! 	bool five  = this->pptr() == NULL;
! 	bool six   = this->epptr() == NULL;
! 	return one && two && three && four && five && six;
!       }
!     };
! 
!   typedef  constraint_buf<std::streambuf>   constraint_streambuf;
!   typedef  constraint_buf<std::filebuf>     constraint_filebuf;
!   typedef  constraint_buf<std::stringbuf>   constraint_stringbuf;
! #ifdef _GLIBCXX_USE_WCHAR_T
!   typedef  constraint_buf<std::wstreambuf>  constraint_wstreambuf;
!   typedef  constraint_buf<std::wfilebuf>    constraint_wfilebuf;
!   typedef  constraint_buf<std::wstringbuf>  constraint_wstringbuf;
! #endif
  
    // Used to check if basic_streambuf::pubsync() has been called.
    // This is useful for checking if a function creates [io]stream::sentry

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