home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * $Source: /unixb/home/unixlib/source/unixlib37/src/stdio/c/RCS/getdelim,v $
- * $Date: 1996/11/06 22:01:42 $
- * $Revision: 1.1 $
- * $State: Rel $
- * $Author: unixlib $
- *
- * $Log: getdelim,v $
- * Revision 1.1 1996/11/06 22:01:42 unixlib
- * Initial revision
- *
- ***************************************************************************/
-
- /* c.getdelim. Written by Nick Burrett, 27 October 1996. */
-
- static const char rcs_id[] = "$Id: getdelim,v 1.1 1996/11/06 22:01:42 unixlib Rel $";
-
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include <sys/types.h>
-
- /* Read up to (and including) a terminator from stream into *lineptr
- (and null-terminate it). *lineptr is a pointer returned from malloc
- (or NULL), pointing to *n charcters of space. It is realloc'd as
- necessary. Returns the number of characters read (not including the
- null terminator), or -1 on error or EOF. */
-
- ssize_t
- getdelim (char **lineptr, size_t *n, int terminator, FILE *stream)
- {
- char *line, *p;
- size_t size, copy;
-
- /* Validity check. */
- if (stream == NULL || lineptr == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (ferror (stream))
- return -1;
-
- /* Make sure we have a line buffer to start with. */
- if (*lineptr == NULL || *n < 2)
- {
- line = realloc (*lineptr, MAX_CANON);
- if (line == NULL)
- return -1;
- *lineptr = line;
- *n = MAX_CANON;
- }
-
- line = *lineptr;
- size = *n;
-
- copy = size;
- p = line;
-
- for (;;)
- {
- size_t len;
-
- /* Get the characters, byte by byte, into buffer line until
- we reach the termination character, or we run out of buffer
- space. */
- while (--copy > 0)
- {
- int c = getc (stream);
- if (c == EOF)
- {
- if (p == *lineptr)
- return -1;
- /* Return a partial line since we got an error in the middle. */
- *p = '\0';
- return p - *lineptr;
- }
- else if ((*p++ = c) == terminator)
- {
- *p = '\0';
- return p - *lineptr;
- }
- }
-
- /* Need to enlarge the line buffer. */
- len = p - line;
- size *= 2;
- line = realloc (line, size);
- /* Bit of a memory problem, break out of while() and return
- what we managed to obtain. */
- if (line == NULL)
- break;
- *lineptr = line;
- *n = size;
- p = line + len;
- copy = size - len;
- }
-
- if (p == *lineptr)
- return -1;
-
- *p = '\0';
- return p - *lineptr;
- }
-
- ssize_t
- getline (char **lineptr, size_t *n, FILE *stream)
- {
- return getdelim (lineptr, n, '\n', stream);
- }
-