Additional patch for __copy_streambufs

Jonathan Lennox lennox@cs.columbia.edu
Sun Oct 20 21:08:00 GMT 2002


It occured to me, on further reflection, that there was a case not caught by
my earlier patch to copy_streambufs
(<http://gcc.gnu.org/ml/gcc-patches/2002-10/msg00377.html>).

This is the case in which a streambuf sometimes fills its buffer, but
doesn't always do so.  (In practice, it might only create a buffer for
put-backs, or some such.)

This patch fixes this case, and adds a test for it.  It also deletes some
useless unused variables that crept into my earlier testcase.

The testcase fails with the current mainline.  (It's not a regression,
however, as far as I can tell -- I don't think the gcc2 libstdc++ ever got
this case right.)

2002-10-20  Jonathan Lennox  <lennox@cs.columbia.edu>

	* include/bits/streambuf.tcc (__copy_streambufs): verify
	__sbin->gptr() + __bufsize < __sbin->egptr() before using.
	* testsuite/27_io/ostream_inserter_other.cc (test_buffer_4): Add.
	(test05): Use test_buffer_4.  Delete unused ostringstream
	variables.

Index: libstdc++-v3/include/bits/streambuf.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/streambuf.tcc,v
retrieving revision 1.16
diff -c -r1.16 streambuf.tcc
*** libstdc++-v3/include/bits/streambuf.tcc	9 Oct 2002 06:32:11 -0000	1.16
--- libstdc++-v3/include/bits/streambuf.tcc	21 Oct 2002 04:06:10 -0000
***************
*** 209,215 ****
  	{
  	  while (__testput && __bufsize != -1)
    	    {
!  	      if (__bufsize != 0 && __sbin->gptr() != NULL) 
  		{
  		  __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
  		  __ret += __xtrct;
--- 209,216 ----
  	{
  	  while (__testput && __bufsize != -1)
    	    {
!  	      if (__bufsize != 0 && __sbin->gptr() != NULL
!                   && __sbin->gptr() + __bufsize <= __sbin->egptr()) 
  		{
  		  __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
  		  __ret += __xtrct;
Index: libstdc++-v3/testsuite/27_io/ostream_inserter_other.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/testsuite/27_io/ostream_inserter_other.cc,v
retrieving revision 1.12
diff -c -r1.12 ostream_inserter_other.cc
*** libstdc++-v3/testsuite/27_io/ostream_inserter_other.cc	9 Oct 2002 06:32:11 -0000	1.12
--- libstdc++-v3/testsuite/27_io/ostream_inserter_other.cc	21 Oct 2002 04:06:10 -0000
***************
*** 199,204 ****
--- 199,228 ----
  };
  
  
+ class test_buffer_4 : public std::streambuf {
+ public:
+   test_buffer_4(const std::string& s) : str(s), it(str.begin())
+   {
+     if (it != str.end()) {
+       buf[0] = *it++;
+       setg(buf, buf, buf+1);
+     }
+   }
+ 
+ protected:
+   virtual int underflow() { return (it != str.end() ? *it : EOF); }
+   virtual int uflow() { return (it != str.end() ? *it++ : EOF); }
+   virtual std::streamsize showmanyc() {
+     std::streamsize ret = std::distance(it, str.end());
+     return ret > 0 ? ret : -1;
+   }
+ private:
+   const std::string str;
+   std::string::const_iterator it;
+   char buf[1];
+ };
+ 
+ 
  void test(const std::string& str, std::streambuf& buf)
  {
    bool test = true;
***************
*** 218,225 ****
  // Jonathan Lennox  <lennox@cs.columbia.edu>
  void test05()
  {
-   std::ostringstream out_1, out_2, out_3, out_4;
- 
    std::string string_a("Hello, world!");
    std::string string_b("");
  
--- 242,247 ----
***************
*** 232,237 ****
--- 254,262 ----
    test_buffer_3 buf3a(string_a);
    test_buffer_3 buf3b(string_b);
  
+   test_buffer_4 buf4a(string_a);
+   test_buffer_4 buf4b(string_b);
+ 
    test(string_a, buf1a);
    test(string_b, buf1b);
  
***************
*** 240,245 ****
--- 265,273 ----
  
    test(string_a, buf3a);
    test(string_b, buf3b);
+ 
+   test(string_a, buf4a);
+   test(string_b, buf4b);
  }
  
  int 



More information about the Gcc-patches mailing list