LCOV - code coverage report
Current view: top level - lib - linebuffer.c (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 27 31 87.1 %
Date: 2018-01-30 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /* linebuffer.c -- read arbitrarily long lines
       2             : 
       3             :    Copyright (C) 1986, 1991, 1998, 1999, 2001, 2003, 2004, 2006, 2007
       4             :    Free Software Foundation, Inc.
       5             : 
       6             :    This program is free software: you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      18             : 
      19             : /* Written by Richard Stallman. */
      20             : 
      21             : #include <config.h>
      22             : 
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <sys/types.h>
      27             : #include "linebuffer.h"
      28             : #include "xalloc.h"
      29             : 
      30             : #if USE_UNLOCKED_IO
      31             : # include "unlocked-io.h"
      32             : #endif
      33             : 
      34             : /* Initialize linebuffer LINEBUFFER for use. */
      35             : 
      36             : void
      37         920 : initbuffer (struct linebuffer *linebuffer)
      38             : {
      39         920 :   memset (linebuffer, 0, sizeof *linebuffer);
      40         920 : }
      41             : 
      42             : struct linebuffer *
      43        1319 : readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
      44             : {
      45        1319 :   return readlinebuffer_delim (linebuffer, stream, '\n');
      46             : }
      47             : 
      48             : /* Read an arbitrarily long line of text from STREAM into LINEBUFFER.
      49             :    Consider lines to be terminated by DELIMITER.
      50             :    Keep the delimiter; append DELIMITER if it's the last line of a file
      51             :    that ends in a character other than DELIMITER.  Do not NUL-terminate.
      52             :    Therefore the stream can contain NUL bytes, and the length
      53             :    (including the delimiter) is returned in linebuffer->length.
      54             :    Return NULL when stream is empty.  Return NULL and set errno upon
      55             :    error; callers can distinguish this case from the empty case by
      56             :    invoking ferror (stream).
      57             :    Otherwise, return LINEBUFFER.  */
      58             : struct linebuffer *
      59        1705 : readlinebuffer_delim (struct linebuffer *linebuffer, FILE *stream,
      60             :                       char delimiter)
      61             : {
      62             :   int c;
      63        1705 :   char *buffer = linebuffer->buffer;
      64        1705 :   char *p = linebuffer->buffer;
      65        1705 :   char *end = buffer + linebuffer->size; /* Sentinel. */
      66             : 
      67        1705 :   if (feof (stream))
      68          44 :     return NULL;
      69             : 
      70             :   do
      71             :     {
      72        1926 :       c = getc (stream);
      73        1926 :       if (c == EOF)
      74             :         {
      75         236 :           if (p == buffer || ferror (stream))
      76         204 :             return NULL;
      77          32 :           if (p[-1] == delimiter)
      78           0 :             break;
      79          32 :           c = delimiter;
      80             :         }
      81        1722 :       if (p == end)
      82             :         {
      83         542 :           size_t oldsize = linebuffer->size;
      84         542 :           buffer = x2realloc (buffer, &linebuffer->size);
      85         542 :           p = buffer + oldsize;
      86         542 :           linebuffer->buffer = buffer;
      87         542 :           end = buffer + linebuffer->size;
      88             :         }
      89        1722 :       *p++ = c;
      90             :     }
      91        1722 :   while (c != delimiter);
      92             : 
      93        1457 :   linebuffer->length = p - buffer;
      94        1457 :   return linebuffer;
      95             : }
      96             : 
      97             : /* Free the buffer that was allocated for linebuffer LINEBUFFER.  */
      98             : 
      99             : void
     100           0 : freebuffer (struct linebuffer *linebuffer)
     101             : {
     102           0 :   free (linebuffer->buffer);
     103           0 : }

Generated by: LCOV version 1.10