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] libstdc++/5280, take two



Ouch. std::istreambuf_iterators weren't invalidating on eof().

tested x86/linux
tested alpha/linux

gcc
gcc-3_1-branch

2002-04-29  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/5280
	* include/bits/fstream.tcc (basic_filebuf::_M_underflow_common):
	Check for eof.
	* include/bits/streambuf_iterator.h: Match stream_iterator.h.
	(istreambuf_iterator::operator++): Invalidate on eof.
	(istreambuf_iterator::operator++(int)): Same.
	(istreambuf_iterator::operator*): Same.
	
Index: include/bits/fstream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/fstream.tcc,v
retrieving revision 1.34
diff -c -p -r1.34 fstream.tcc
*** include/bits/fstream.tcc	29 Apr 2002 07:00:46 -0000	1.34
--- include/bits/fstream.tcc	30 Apr 2002 06:48:26 -0000
*************** namespace std
*** 227,237 ****
  	  // Check for unbuffered stream.
  	  if (_M_buf_size == 1)
  	    {
! 	      __ret = _M_file.sys_getc();
! 	      *_M_in_cur = traits_type::to_char_type(__ret);
! 	      _M_set_determinate(1);
! 	      if (__testout)
! 		_M_out_cur = _M_in_cur;
  	      return __ret;
  	    }
  
--- 227,241 ----
  	  // Check for unbuffered stream.
  	  if (_M_buf_size == 1)
  	    {
! 	      int_type __c = _M_file.sys_getc();
! 	      if (__c != __ret)
! 		{
! 		  __ret = __c;
! 		  *_M_in_cur = traits_type::to_char_type(__c);
! 		  _M_set_determinate(1);
! 		  if (__testout)
! 		    _M_out_cur = _M_in_cur;
! 		}
  	      return __ret;
  	    }
  Index: include/bits/streambuf_iterator.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/streambuf_iterator.h,v
retrieving revision 1.5
diff -c -p -r1.5 streambuf_iterator.h
*** include/bits/streambuf_iterator.h	16 Jan 2002 19:57:31 -0000	1.5
--- include/bits/streambuf_iterator.h	30 Apr 2002 06:48:26 -0000
***************
*** 1,6 ****
  // Streambuf iterators
  
! // 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
--- 1,7 ----
  // Streambuf iterators
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
! // 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
***************
*** 41,100 ****
  
  namespace std
  {
-   template<typename _CharT, typename _Traits>
-     class ostreambuf_iterator
-     : public iterator<output_iterator_tag, void, void, void, void>
-     {
-     public:
-       // Types:
-       typedef _CharT                           char_type;
-       typedef _Traits                          traits_type;
-       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
-       typedef basic_ostream<_CharT, _Traits>   ostream_type;
- 
-     private:
-       streambuf_type* 	_M_sbuf;
-       bool 		_M_failed;
- 
-     public:
-       inline 
-       ostreambuf_iterator(ostream_type& __s) throw ()
-       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
-       
-       ostreambuf_iterator(streambuf_type* __s) throw ()
-       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
- 
-       ostreambuf_iterator& 
-       operator=(_CharT __c);
- 
-       ostreambuf_iterator& 
-       operator*() throw()
-       { return *this; }
- 
-       ostreambuf_iterator& 
-       operator++(int) throw()
-       { return *this; }
- 
-       ostreambuf_iterator& 
-       operator++() throw()
-       { return *this; }
- 
-       bool 
-       failed() const throw()
-       { return _M_failed; }
-     };
- 
-   template<typename _CharT, typename _Traits>
-     inline ostreambuf_iterator<_CharT, _Traits>&
-     ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
-     {
-       if (!_M_failed && 
-           _Traits::eq_int_type(_M_sbuf->sputc(__c),_Traits::eof()))
-       _M_failed = true;
-       return *this;
-     }
- 
- 
    // 24.5.3 Template class istreambuf_iterator
    template<typename _CharT, typename _Traits>
      class istreambuf_iterator
--- 42,47 ----
*************** namespace std
*** 117,128 ****
        // the "end of stream" iterator value.
        // NB: This implementation assumes the "end of stream" value
        // is EOF, or -1.
!       streambuf_type* 		_M_sbuf;  
        int_type 			_M_c;
  
      public:
        istreambuf_iterator() throw() 
!       : _M_sbuf(NULL), _M_c(-2) { }
        
        istreambuf_iterator(istream_type& __s) throw()
        : _M_sbuf(__s.rdbuf()), _M_c(-2) { }
--- 64,75 ----
        // the "end of stream" iterator value.
        // NB: This implementation assumes the "end of stream" value
        // is EOF, or -1.
!       mutable streambuf_type* 	_M_sbuf;  
        int_type 			_M_c;
  
      public:
        istreambuf_iterator() throw() 
!       : _M_sbuf(0), _M_c(-2) { }
        
        istreambuf_iterator(istream_type& __s) throw()
        : _M_sbuf(__s.rdbuf()), _M_c(-2) { }
*************** namespace std
*** 137,158 ****
        operator*() const
        { 
  	// The result of operator*() on an end of stream is undefined.
! 	char_type __ret;
! 	if (_M_sbuf && _M_c != static_cast<int_type>(-2))
! 	  __ret = _M_c;
! 	else if (_M_sbuf)
! 	  __ret = traits_type::to_char_type(_M_sbuf->sgetc()); 
! 	else
! 	  __ret = static_cast<char_type>(traits_type::eof());
! 	return __ret;
        }
  	
        istreambuf_iterator& 
        operator++()
        { 
! 	if (_M_sbuf)
! 	  _M_sbuf->sbumpc();
! 	_M_c = -2;
  	return *this; 
        }
  
--- 84,108 ----
        operator*() const
        { 
  	// The result of operator*() on an end of stream is undefined.
! 	int_type __ret = traits_type::eof();
! 	if (_M_sbuf)
! 	  { 
! 	    if (_M_c != static_cast<int_type>(-2))
! 	      __ret = _M_c;
! 	    else 
! 	      if ((__ret = _M_sbuf->sgetc()) == traits_type::eof())
! 		_M_sbuf = 0;
! 	  }
! 	return traits_type::to_char_type(__ret);
        }
  	
        istreambuf_iterator& 
        operator++()
        { 
! 	if (_M_sbuf && _M_sbuf->sbumpc() == traits_type::eof())
! 	  _M_sbuf = 0;
! 	else
! 	  _M_c = -2;
  	return *this; 
        }
  
*************** namespace std
*** 160,189 ****
        operator++(int)
        {
  	istreambuf_iterator __old = *this;
! 	if (_M_sbuf)
! 	  __old._M_c = _M_sbuf->sbumpc();
! 	_M_c = -2;
  	return __old; 
        }
  
-       bool 
-       equal(const istreambuf_iterator& __b)
-       { 
- 	int_type __eof = traits_type::eof();
- 	bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
- 	bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
- 	return (__thiseof && __beof || (!__thiseof && !__beof));
-       }
- 
  #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
        // 110 istreambuf_iterator::equal not const
        // NB: there is also number 111 (NAD, Future) pending on this function.
        bool 
        equal(const istreambuf_iterator& __b) const
        {
! 	int_type __eof = traits_type::eof();
! 	bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
! 	bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
  	return (__thiseof && __beof || (!__thiseof && !__beof));
        }
  #endif
--- 110,131 ----
        operator++(int)
        {
  	istreambuf_iterator __old = *this;
! 	if (_M_sbuf && (__old._M_c = _M_sbuf->sbumpc()) == traits_type::eof())
! 	  _M_sbuf = 0;
! 	else
! 	  _M_c = -2;
  	return __old; 
        }
  
  #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
        // 110 istreambuf_iterator::equal not const
        // NB: there is also number 111 (NAD, Future) pending on this function.
        bool 
        equal(const istreambuf_iterator& __b) const
        {
! 	const int_type __eof = traits_type::eof();
! 	bool __thiseof = traits_type::eq_int_type(this->operator*(), __eof);
! 	bool __beof = traits_type::eq_int_type(__b.operator*(), __eof);
  	return (__thiseof && __beof || (!__thiseof && !__beof));
        }
  #endif
*************** namespace std
*** 200,204 ****
--- 142,199 ----
      operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
  	       const istreambuf_iterator<_CharT, _Traits>& __b)
      { return !__a.equal(__b); }
+ 
+   template<typename _CharT, typename _Traits>
+     class ostreambuf_iterator
+     : public iterator<output_iterator_tag, void, void, void, void>
+     {
+     public:
+       // Types:
+       typedef _CharT                           char_type;
+       typedef _Traits                          traits_type;
+       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
+       typedef basic_ostream<_CharT, _Traits>   ostream_type;
+ 
+     private:
+       streambuf_type* 	_M_sbuf;
+       bool 		_M_failed;
+ 
+     public:
+       inline 
+       ostreambuf_iterator(ostream_type& __s) throw ()
+       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
+       
+       ostreambuf_iterator(streambuf_type* __s) throw ()
+       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
+ 
+       ostreambuf_iterator& 
+       operator=(_CharT __c);
+ 
+       ostreambuf_iterator& 
+       operator*() throw()
+       { return *this; }
+ 
+       ostreambuf_iterator& 
+       operator++(int) throw()
+       { return *this; }
+ 
+       ostreambuf_iterator& 
+       operator++() throw()
+       { return *this; }
+ 
+       bool 
+       failed() const throw()
+       { return _M_failed; }
+     };
+ 
+   template<typename _CharT, typename _Traits>
+     inline ostreambuf_iterator<_CharT, _Traits>&
+     ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
+     {
+       if (!_M_failed && 
+           _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
+ 	_M_failed = true;
+       return *this;
+     }
  } // namespace std
  #endif


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