home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / fingercl.zip / getline.c < prev    next >
C/C++ Source or Header  |  1992-10-01  |  2KB  |  102 lines

  1. /* getline.c -- Replacement for GNU C library function getline ()
  2.  
  3.    Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5.    This program is free software; you can redistribute it and/or
  6.    modify it under the terms of the GNU General Public License as
  7.    published by the Free Software Foundation; either version 2 of the
  8.    License, or (at your option) any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful, but
  11.    WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.    General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  18.  
  19.  
  20. #include <stdio.h>
  21.  
  22. #define MAX_CANON 64
  23.  
  24. /* Read up to (and including) a newline from STREAM into *LINEPTR
  25.    (and NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
  26.    NULL), pointing to *N characters of space.  It is realloc'd as
  27.    necessary.  Returns the number of characters read (not including the
  28.    null terminator), or -1 on error or EOF.  */
  29.  
  30. int
  31. getline (lineptr, n, stream)
  32.   char **lineptr;
  33.   int *n;
  34.   FILE *stream;
  35. {
  36.   int nchars_avail;
  37.   char *read_pos;
  38.   extern char *malloc (), *realloc ();
  39.  
  40.  
  41.   if (!lineptr || !n || !stream)
  42.     return -1;
  43.  
  44.   nchars_avail = *n;
  45.  
  46.   if (!*lineptr)
  47.     {
  48.       if (!(*lineptr = malloc (MAX_CANON)))
  49.     return -1;
  50.  
  51.       *n = nchars_avail = MAX_CANON;
  52.     }
  53.  
  54.   read_pos = *lineptr;
  55.  
  56.   for (;;)
  57.     {
  58.       register char c = getc (stream);
  59.  
  60.       /* We always want at least one char left in buffer since we
  61.      always (unless we get an error while reading the first char)
  62.      NUL-terminate the line buffer. */
  63.  
  64.       if (nchars_avail < 1)
  65.     {
  66.       if (*n > MAX_CANON)
  67.         {
  68.           nchars_avail = *n;
  69.           *n *= 2;
  70.         }
  71.       else
  72.         {
  73.           nchars_avail = MAX_CANON;
  74.           *n += MAX_CANON;
  75.         }
  76.  
  77.       *lineptr = realloc (*lineptr, *n);
  78.       read_pos = *lineptr + (*n - nchars_avail);
  79.     }
  80.  
  81.       /* EOF or error */
  82.       if (feof (stream) || ferror (stream))
  83.  
  84.     /* Return partial line, if any */
  85.     if (read_pos == *lineptr)
  86.       return -1;
  87.     else
  88.       break;
  89.  
  90.       *read_pos++ = c;
  91.       nchars_avail--;
  92.  
  93.       /* Return line if NL */
  94.       if (c == '\n')
  95.     break;
  96.     }
  97.  
  98.   /* Done - NUL terminate and return number of chars read */
  99.   *read_pos = '\0';
  100.   return (*n - nchars_avail);
  101. }
  102.