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]

stream::get(streambuf& sb, char delim) called too many times at EOF


The following message is a courtesy copy of an article
that has been posted to cygnus.egcs.bugs as well.

Enclosed is a copy of a bug report (with a possible patch) againt
libg++ that I sent out over a year ago. This bug is also present in
all the versions of egcs that I have tried.

istream::get(streambuf& sb, char delim) is called 1 too many times in the
following code:

#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
#include <strstream.h>

int
main()
{
  // bug.dat can be any text file
  ifstream input("bug.dat", ios::in);
  if (!input) {
    cerr << "unable to open 'bug.dat'" << endl;
    return(1);
  }

  size_t line_num = 0;

  for (;;) {
    strstreambuf line;
    input.get(line, '\n');	// problem here - eofbit not set correctly
    if (input.eof()) {
      break;
    }
    else if (input.fail()) {
      cerr << "failure on line " << line_num << endl;
      return 1;
    }

    input.ignore(1, '\n');	// skip newline
    ++line_num;
  }

  cerr << "read " << line_num << " lines" << endl;
  return 0;
}

The problem is really noticable if you run this code that reads from stdin
and you enter text interactively (you have to enter ^D twice to get it to
terminate):

#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
#include <strstream.h>

int
main()
{
  size_t line_num = 0;

  for (;;) {
    strstreambuf line;
    cin.get(line, '\n');	// problem here - eofbit not set correctly
    if (cin.eof()) {
      break;
    }
    else if (cin.fail()) {
      cerr << "failure on line " << line_num << endl;
      return 1;
    }

    cin.ignore(1, '\n');	// skip newline
    ++line_num;
  }

  cerr << "read " << line_num << " lines" << endl;
  return 0;
}

A possible patch:

--- isgetsb.cc.buggy	Thu Jun 15 22:42:10 1995
+++ isgetsb.cc	Mon Mar 31 14:16:08 1997
@@ -37,7 +37,13 @@
 	  streamsize len = isb->_IO_read_end - isb->_IO_read_ptr;
 	  if (len <= 0)
 	    if (__underflow(isb) == EOF)
-	      break;
+	      {
+		if (_gcount == 0) 
+		  {
+		    set(ios::failbit | ios::eofbit);
+		  }
+		break;
+	      }
 	    else
 	      len = isb->_IO_read_end - isb->_IO_read_ptr;
 	  char *delimp = (char*)memchr((void*)isb->_IO_read_ptr, delim, len);

I don't know enough about the libio internals to know if this patch is 
correct but, it makes the above programs give the expected results.

--
Rick Ohnemus, Eclectic Computing Concepts, (972) 964-2655, rick@ecompcon.com


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