A getline patch for libio in glibc and egcs

Per Bothner bothner@cygnus.com
Fri Feb 13 17:41:00 GMT 1998


After thing about it, I agree it is better to use __uflow instead
of __underflow.  However, I think the following is simpler and
more robust.  For one thing, it does not break in the case that
(1) A call to __uflow might allocate a buffer even if __underflow didn't,
and:
(2) __uflow does not not check that the buffer is empty.
(I'm not sure what the standard says - whether uflow is allowed to
 assume that the buffer is empty.)

Also, this change is smaller (except for white-space re-formatting).

However, I haven't tested it, beyond checking that it compiles.
Could you try it?

	--Per Bothner
Cygnus Solutions     bothner@cygnus.com     http://www.cygnus.com/~bothner

Index: iogetline.c
===================================================================
RCS file: /cvs/cvsfiles/devo/libio/iogetline.c,v
retrieving revision 1.9
diff -c -r1.9 iogetline.c
*** iogetline.c	1997/09/04 23:55:53	1.9
--- iogetline.c	1998/02/14 01:10:02
***************
*** 48,78 ****
        _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr;
        char *t;
        if (len <= 0)
- 	if (__underflow (fp) == EOF)
- 	  break;
- 	else
- 	  len = fp->_IO_read_end - fp->_IO_read_ptr;
-       if ((_IO_size_t) len >= n)
- 	len = n;
-       t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len);
-       if (t != NULL)
  	{
! 	  _IO_size_t old_len = ptr-buf;
! 	  len = t - fp->_IO_read_ptr;
! 	  if (extract_delim >= 0)
  	    {
- 	      ++t;
  	      if (extract_delim > 0)
! 		++len;
  	    }
! 	  memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
! 	  fp->_IO_read_ptr = t;
! 	  return old_len + len;
  	}
!       memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
!       fp->_IO_read_ptr += len;
!       ptr += len;
!       n -= len;
      } while (n != 0);
    return ptr - buf;
  }
--- 48,92 ----
        _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr;
        char *t;
        if (len <= 0)
  	{
! 	  int c = __uflow (fp);
! 	  if (c == EOF)
! 	    break;
! 	  if (c == delim)
  	    {
  	      if (extract_delim > 0)
! 		*ptr++ = c;
! 	      else if (extract_delim < 0)
! 		_IO_sputbackc (fp, c);
! 	      return ptr - buf;
  	    }
! 	  *ptr++ = c;
! 	  n--;
  	}
! 	else
! 	  {
! 	    if ((_IO_size_t) len >= n)
! 	      len = n;
! 	    t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len);
! 	    if (t != NULL)
! 	      {
! 		_IO_size_t old_len = ptr-buf;
! 		len = t - fp->_IO_read_ptr;
! 		if (extract_delim >= 0)
! 		  {
! 		    ++t;
! 		    if (extract_delim > 0)
! 		      ++len;
! 		  }
! 		memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
! 		fp->_IO_read_ptr = t;
! 		return old_len + len;
! 	      }
! 	    memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
! 	    fp->_IO_read_ptr += len;
! 	    ptr += len;
! 	    n -= len;
! 	  }
      } while (n != 0);
    return ptr - buf;
  }



More information about the Gcc mailing list