Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Copyright 2002, Red Hat Inc. - all rights reserved */
  2. /*
  3. FUNCTION
  4. <<getdelim>>---read a line up to a specified line delimiter
  5.  
  6. INDEX
  7.         getdelim
  8.  
  9. ANSI_SYNOPSIS
  10.         #include <stdio.h>
  11.         int getdelim(char **<[bufptr]>, size_t *<[n]>,
  12.                      int <[delim]>, FILE *<[fp]>);
  13.  
  14. TRAD_SYNOPSIS
  15.         #include <stdio.h>
  16.         int getdelim(<[bufptr]>, <[n]>, <[delim]>, <[fp]>)
  17.         char **<[bufptr]>;
  18.         size_t *<[n]>;
  19.         int <[delim]>;
  20.         FILE *<[fp]>;
  21.  
  22. DESCRIPTION
  23. <<getdelim>> reads a file <[fp]> up to and possibly including a specified
  24. delimiter <[delim]>.  The line is read into a buffer pointed to
  25. by <[bufptr]> and designated with size *<[n]>.  If the buffer is
  26. not large enough, it will be dynamically grown by <<getdelim>>.
  27. As the buffer is grown, the pointer to the size <[n]> will be
  28. updated.
  29.  
  30. RETURNS
  31. <<getdelim>> returns <<-1>> if no characters were successfully read;
  32. otherwise, it returns the number of bytes successfully read.
  33. At end of file, the result is nonzero.
  34.  
  35. PORTABILITY
  36. <<getdelim>> is a glibc extension.
  37.  
  38. No supporting OS subroutines are directly required.
  39. */
  40.  
  41. #include <_ansi.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <errno.h>
  45. #include "local.h"
  46.  
  47. #define MIN_LINE_SIZE 4
  48. #define DEFAULT_LINE_SIZE 128
  49.  
  50. ssize_t
  51. _DEFUN(__getdelim, (bufptr, n, delim, fp),
  52.        char **bufptr _AND
  53.        size_t *n     _AND
  54.        int delim     _AND
  55.        FILE *fp)
  56. {
  57.   char *buf;
  58.   char *ptr;
  59.   size_t newsize, numbytes;
  60.   int pos;
  61.   int ch;
  62.   int cont;
  63.  
  64.   if (fp == NULL || bufptr == NULL || n == NULL)
  65.     {
  66.       errno = EINVAL;
  67.       return -1;
  68.     }
  69.  
  70.   buf = *bufptr;
  71.   if (buf == NULL || *n < MIN_LINE_SIZE)
  72.     {
  73.       buf = (char *)realloc (*bufptr, DEFAULT_LINE_SIZE);
  74.       if (buf == NULL)
  75.         {
  76.           return -1;
  77.         }
  78.       *bufptr = buf;
  79.       *n = DEFAULT_LINE_SIZE;
  80.     }
  81.  
  82.   CHECK_INIT (_REENT, fp);
  83.  
  84.   _newlib_flockfile_start (fp);
  85.  
  86.   numbytes = *n;
  87.   ptr = buf;
  88.  
  89.   cont = 1;
  90.  
  91.   while (cont)
  92.     {
  93.       /* fill buffer - leaving room for nul-terminator */
  94.       while (--numbytes > 0)
  95.         {
  96.           if ((ch = getc_unlocked (fp)) == EOF)
  97.             {
  98.               cont = 0;
  99.               break;
  100.             }
  101.           else
  102.             {
  103.               *ptr++ = ch;
  104.               if (ch == delim)
  105.                 {
  106.                   cont = 0;
  107.                   break;
  108.                 }
  109.             }
  110.         }
  111.  
  112.       if (cont)
  113.         {
  114.           /* Buffer is too small so reallocate a larger buffer.  */
  115.           pos = ptr - buf;
  116.           newsize = (*n << 1);
  117.           buf = realloc (buf, newsize);
  118.           if (buf == NULL)
  119.             {
  120.               cont = 0;
  121.               break;
  122.             }
  123.  
  124.           /* After reallocating, continue in new buffer */          
  125.           *bufptr = buf;
  126.           *n = newsize;
  127.           ptr = buf + pos;
  128.           numbytes = newsize - pos;
  129.         }
  130.     }
  131.  
  132.   _newlib_flockfile_end (fp);
  133.  
  134.   /* if no input data, return failure */
  135.   if (ptr == buf)
  136.     return -1;
  137.  
  138.   /* otherwise, nul-terminate and return number of bytes read */
  139.   *ptr = '\0';
  140.   return (ssize_t)(ptr - buf);
  141. }
  142.  
  143.