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] Implement resolution of DR 91 [WP]


Hi,

a straightforward implementation, basically wrapping the code in try/catch.
Also took the occasion to fix some minor issues with the exit conditions
(ordering prescribed by 21.3.7.9, p7; off-by-one in the check for
str.max_size() and std::failbit not set in this case)

Tested x86-linux, committed.

Paolo.

////////////
2003-11-22  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/12593
	* include/bits/istream.tcc (operator>>(basic_string<>&),
	getline(basic_string<>&)): Implement resolution of DR 91 [WP];
	fix some minor issues with the exit conditions.
	* docs/html/ext/howto.html: Add an entry for DR 91.
diff -prN libstdc++-v3-orig/docs/html/ext/howto.html libstdc++-v3/docs/html/ext/howto.html
*** libstdc++-v3-orig/docs/html/ext/howto.html	Wed Nov 19 12:37:24 2003
--- libstdc++-v3/docs/html/ext/howto.html	Sat Nov 22 10:38:05 2003
***************
*** 526,531 ****
--- 526,540 ----
          replaced by <code>isspace(c,is.getloc())</code>.
      </dd>
  
+     <dt><a href="lwg-defects.html#91">91</a>:
+         <em>Description of operator&gt;&gt; and getline() for string&lt;&gt;
+ 	    might cause endless loop</em>
+     </dt>
+     <dd>They behave as a formatted input function and as an unformatted
+         input function, respectively (except that <code>getline</code> is
+ 	not required to set <code>gcount</code>).
+     </dd>
+ 
      <dt><a href="lwg-defects.html#109">109</a>:
          <em>Missing binders for non-const sequence elements</em>
      </dt>
diff -prN libstdc++-v3-orig/include/bits/istream.tcc libstdc++-v3/include/bits/istream.tcc
*** libstdc++-v3-orig/include/bits/istream.tcc	Tue Nov  4 03:14:05 2003
--- libstdc++-v3/include/bits/istream.tcc	Sat Nov 22 10:26:56 2003
*************** namespace std 
*** 1102,1133 ****
        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;
  
        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& __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))
- 	    __in.setstate(ios_base::eofbit);
- 	  __in.width(0);
  	}
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 211.  operator>>(istream&, string&) doesn't set failbit
--- 1102,1147 ----
        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;
        typename __istream_type::sentry __cerb(__in, false);
        if (__cerb) 
  	{
! 	  try
! 	    {
! 	      __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))
! 		__in.setstate(ios_base::eofbit);
! 	      __in.width(0);
! 	    }
! 	  catch(...)
  	    {
! 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
! 	      // 91. Description of operator>> and getline() for string<>
! 	      // might cause endless loop
! 	      // 27.6.1.2.1 Common requirements.
! 	      // Turn this on without causing an ios::failure to be thrown.
! 	      __in.setstate(ios_base::badbit);
! 	      if ((__in.exceptions() & ios_base::badbit) != 0)
! 		__throw_exception_again;
  	    }
  	}
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 211.  operator>>(istream&, string&) doesn't set failbit
*************** namespace std 
*** 1149,1179 ****
        typedef typename __string_type::size_type		__size_type;
  
        __size_type __extracted = 0;
        bool __testdelim = false;
        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)
  	    {
! 	      __str += _Traits::to_char_type(__c);
! 	      ++__extracted;
! 	      __c = __sb->sbumpc();
  	      __testdelim = _Traits::eq_int_type(__c, __idelim);
  	    }
- 	  if (_Traits::eq_int_type(__c, __eof))
- 	    __in.setstate(ios_base::eofbit);
  	}
!       if (!__extracted && !__testdelim)
  	__in.setstate(ios_base::failbit);
        return __in;
      }
--- 1163,1206 ----
        typedef typename __string_type::size_type		__size_type;
  
        __size_type __extracted = 0;
+       const __size_type __n = __str.max_size();
        bool __testdelim = false;
        typename __istream_type::sentry __cerb(__in, true);
        if (__cerb) 
  	{
! 	  try
  	    {
! 	      __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))
+ 		__in.setstate(ios_base::eofbit);
+ 	    }
+ 	  catch(...)
+ 	    {
+ 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ 	      // 91. Description of operator>> and getline() for string<>
+ 	      // might cause endless loop
+ 	      // 27.6.1.2.1 Common requirements.
+ 	      // Turn this on without causing an ios::failure to be thrown.
+ 	      __in.setstate(ios_base::badbit);
+ 	      if ((__in.exceptions() & ios_base::badbit) != 0)
+ 		__throw_exception_again;
  	    }
  	}
!       if ((!__extracted && !__testdelim) || __extracted == __n)
  	__in.setstate(ios_base::failbit);
        return __in;
      }

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