From f58214d62e0c8a65aa13cf38ea148cef2547a06d Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 10 Mar 2008 02:01:23 +0100 Subject: [PATCH] Take into account the number of pushed-back bytes (ungetc). --- ChangeLog | 8 ++++++++ NEWS | 3 +++ lib/freadahead.c | 32 +++++++++++++++++++++++++------- lib/freadahead.h | 4 +++- tests/test-freadahead.c | 27 ++++++++++++++++++++++++--- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00888a834..73abc6cc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-03-09 Bruno Haible + * lib/freadahead.h (freadahead): Document more precisely. + * lib/freadahead.c (freadahead): When an ungetc is in effect, return + the sum of both buffer sizes. + * tests/test-freadahead.c (main): Also test behaviour after ungetc. + * NEWS: Document the change. + +2008-03-09 Bruno Haible + Extend freadptr to return also the buffer size. * lib/freadptr.h (freadptr): Add sizep argument. * lib/freadptr.c: Include freadptr.h, not freadahead.h. diff --git a/NEWS b/NEWS index f541b6144..95ca64ac9 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,9 @@ User visible incompatible changes Date Modules Changes +2008-03-06 freadahead The return value's computation has changed. It + now increases by 1 after ungetc. + 2008-01-26 isnan-nolibm The module name is changed from isnan-nolibm to isnand-nolibm. The include file is changed from "isnan.h" to "isnand.h". The function that it diff --git a/lib/freadahead.c b/lib/freadahead.c index daad2901a..a28595d39 100644 --- a/lib/freadahead.c +++ b/lib/freadahead.c @@ -1,5 +1,5 @@ /* Retrieve information about a FILE stream. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,11 +25,24 @@ freadahead (FILE *fp) #if defined _IO_ferror_unlocked /* GNU libc, BeOS */ if (fp->_IO_write_ptr > fp->_IO_write_base) return 0; - return fp->_IO_read_end - fp->_IO_read_ptr; + return (fp->_IO_read_end - fp->_IO_read_ptr) + + (fp->_flags & _IO_IN_BACKUP ? fp->_IO_save_end - fp->_IO_save_base : + 0); #elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ +# if defined __NetBSD__ || defined __OpenBSD__ + struct __sfileext + { + struct __sbuf _ub; /* ungetc buffer */ + /* More fields, not relevant here. */ + }; +# define HASUB(fp) (((struct __sfileext *) (fp)->_ext._base)->_ub._base != NULL) +# else +# define HASUB(fp) ((fp)->_ub._base != NULL) +# endif if ((fp->_flags & __SWR) != 0 || fp->_r < 0) return 0; - return fp->_r; + return fp->_r + + (HASUB (fp) ? fp->_ur : 0); #elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */ # if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ # define fp_ ((struct { unsigned char *_ptr; \ @@ -51,16 +64,21 @@ freadahead (FILE *fp) # ifdef __STDIO_BUFFERS if (fp->__modeflags & __FLAG_WRITING) return 0; - return fp->__bufread - fp->__bufpos; + return (fp->__bufread - fp->__bufpos) + + (fp->__modeflags & __FLAG_UNGOT ? 1 : 0); # else return 0; # endif #elif defined __QNX__ /* QNX */ if ((fp->_Mode & 0x2000 /* _MWRITE */) != 0) return 0; - /* fp->_Buf <= fp->_Next <= fp->_Rend */ - return fp->_Rend - fp->_Next; + /* fp->_Buf <= fp->_Next <= fp->_Rend, + and fp->_Rend may be overridden by fp->_Rsave. */ + return ((fp->_Rsave ? fp->_Rsave : fp->_Rend) - fp->_Next) + + (fp->_Mode & 0x4000 /* _MBYTE */ + ? (fp->_Back + sizeof (fp->_Back)) - fp->_Rback + : 0); #else - #error "Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread on your system, then report this to bug-gnulib." + #error "Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib." #endif } diff --git a/lib/freadahead.h b/lib/freadahead.h index 430dcf870..96a97d192 100644 --- a/lib/freadahead.h +++ b/lib/freadahead.h @@ -1,5 +1,5 @@ /* Retrieve information about a FILE stream. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,8 @@ extern "C" { /* Assuming the stream STREAM is open for reading: Return the number of bytes waiting in the input buffer of STREAM. + This includes both the bytes that have been read from the underlying input + source and the bytes that have been pushed back through 'ungetc'. If this number is 0 and the stream is not currently writing, fflush (STREAM) is known to be a no-op. diff --git a/tests/test-freadahead.c b/tests/test-freadahead.c index d4b098a45..447b188b8 100644 --- a/tests/test-freadahead.c +++ b/tests/test-freadahead.c @@ -1,5 +1,5 @@ /* Test of freadahead() function. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,8 +54,29 @@ main (int argc, char **argv) __STDIO_BUFFERS. */ ASSERT (freadahead (stdin) == 0); else - /* Normal buffered stdio. */ - ASSERT (freadahead (stdin) != 0); + { + /* Normal buffered stdio. */ + size_t buffered; + int c, c2; + + ASSERT (freadahead (stdin) != 0); + buffered = freadahead (stdin); + + c = fgetc (stdin); + ASSERT (freadahead (stdin) == buffered - 1); + ungetc (c, stdin); + ASSERT (freadahead (stdin) == buffered); + c2 = fgetc (stdin); + ASSERT (c2 == c); + ASSERT (freadahead (stdin) == buffered - 1); + + c = '@'; + ungetc (c, stdin); + ASSERT (freadahead (stdin) == buffered); + c2 = fgetc (stdin); + ASSERT (c2 == c); + ASSERT (freadahead (stdin) == buffered - 1); + } } return 0; -- 2.11.0