obstack.m4 (gl_PREREQ_OBSTACK): Require
[gnulib.git] / lib / linebuffer.c
index 770ad62..67d0f1f 100644 (file)
 #endif
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include "linebuffer.h"
 #include "unlocked-io.h"
 #include "xalloc.h"
 
-void free ();
-
 /* Initialize linebuffer LINEBUFFER for use. */
 
 void
 initbuffer (struct linebuffer *linebuffer)
 {
-  linebuffer->length = 0;
-  linebuffer->size = 200;
-  linebuffer->buffer = xmalloc (linebuffer->size);
+  memset (linebuffer, 0, sizeof *linebuffer);
 }
 
 /* Read an arbitrarily long line of text from STREAM into LINEBUFFER.
@@ -46,7 +44,9 @@ initbuffer (struct linebuffer *linebuffer)
    that ends in a non-newline character.  Do not null terminate.
    Therefore the stream can contain NUL bytes, and the length
    (including the newline) is returned in linebuffer->length.
-   Return NULL upon error, or when STREAM is empty.
+   Return NULL when stream is empty.  Return NULL and set errno upon
+   error; callers can distinguish this case from the empty case by
+   invoking ferror (stream).
    Otherwise, return LINEBUFFER.  */
 struct linebuffer *
 readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
@@ -56,7 +56,7 @@ readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
   char *p = linebuffer->buffer;
   char *end = buffer + linebuffer->size; /* Sentinel. */
 
-  if (feof (stream) || ferror (stream))
+  if (feof (stream))
     return NULL;
 
   do
@@ -64,7 +64,7 @@ readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
       c = getc (stream);
       if (c == EOF)
        {
-         if (p == buffer)
+         if (p == buffer || ferror (stream))
            return NULL;
          if (p[-1] == '\n')
            break;
@@ -72,9 +72,9 @@ readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
        }
       if (p == end)
        {
-         linebuffer->size *= 2;
-         buffer = xrealloc (buffer, linebuffer->size);
-         p = p - linebuffer->buffer + buffer;
+         size_t oldsize = linebuffer->size;
+         buffer = x2realloc (buffer, &linebuffer->size);
+         p = buffer + oldsize;
          linebuffer->buffer = buffer;
          end = buffer + linebuffer->size;
        }
@@ -86,11 +86,10 @@ readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
   return linebuffer;
 }
 
-/* Free linebuffer LINEBUFFER and its data, all allocated with malloc. */
+/* Free the buffer that was allocated for linebuffer LINEBUFFER.  */
 
 void
 freebuffer (struct linebuffer *linebuffer)
 {
   free (linebuffer->buffer);
-  free (linebuffer);
 }