diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2002-06-21 18:29:23 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2002-06-21 18:29:23 +0000 |
commit | d427d09204c97df14607149e94a1da9beddd76ab (patch) | |
tree | 364e68aebab51cfb339ff2b0f21a1f97d22a131d /newlib/libc/stdio/getdelim.c | |
parent | 35728d4f142bbab0d8a963561d76b9066421b1ac (diff) | |
download | cygnal-d427d09204c97df14607149e94a1da9beddd76ab.tar.gz cygnal-d427d09204c97df14607149e94a1da9beddd76ab.tar.bz2 cygnal-d427d09204c97df14607149e94a1da9beddd76ab.zip |
2002-06-21 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/stdio.h (__getline, __getdelim): New prototypes.
* libc/include/time.h [HAVE_GETDATE](getdate, getdate_r): Ditto.
[HAVE_GETDATE](getdate_err): New error code.
* libc/stdio/Makefile.am: Add support for getline.c and getdelim.c.
* libc/stdio/Makefile.in: Regenerated.
* libc/stdio/getdelim.c: New file.
* libc/stdio/getline.c: Ditto.
* libc/sys/linux/Makefile.am: Add support for getdate.c, getdate_err.c
and ntp_gettime.c. Also add AM_CFLAGS to point to libc/stdio.
* libc/sys/linux/Makefile.in: Regenerated.
* libc/sys/linux/getdate.c: New file.
* libc/sys/linux/getdate_err.c: Ditto.
* libc/sys/linux/ntp_gettime.c: Ditto.
* libc/sys/linux/time.c (adjtimex, ntp_adjtime): New functions.
* libc/sys/linux/sys/stdio.h (getline, getdelim): New macros.
Diffstat (limited to 'newlib/libc/stdio/getdelim.c')
-rw-r--r-- | newlib/libc/stdio/getdelim.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/newlib/libc/stdio/getdelim.c b/newlib/libc/stdio/getdelim.c new file mode 100644 index 000000000..8ec9d40c8 --- /dev/null +++ b/newlib/libc/stdio/getdelim.c @@ -0,0 +1,139 @@ +/* +FUNCTION +<<getdelim>>---read a line up to a specified line delimeter + +INDEX + getdelim + +ANSI_SYNOPSIS + #include <stdio.h> + int getdelim(char **<[bufptr]>, size_t *<[n]>, + int <[delim]>, FILE *<[fp]>); + +TRAD_SYNOPSIS + #include <stdio.h> + int getdelim(<[bufptr]>, <[n]>, <[delim]>, <[fp]>) + char **<[bufptr]>; + size_t *<[n]>; + int <[delim]>; + FILE *<[fp]>; + +DESCRIPTION +<<getdelim>> reads a file <[fp]> up to and possibly including a specified +delimeter <[delim]>. The line is read into a buffer pointed to +by <[bufptr]> and designated with size *<[n]>. If the buffer is +not large enough, it will be dynamically grown by <<getdelim>>. +As the buffer is grown, the pointer to the size <[n]> will be +updated. + +RETURNS +<<getdelim>> returns <<-1>> if no characters were successfully read, +otherwise, it returns the number of bytes successfully read. +at end of file, the result is nonzero. + +PORTABILITY +<<getdelim>> is a glibc extension. + +No supporting OS subroutines are directly required. +*/ + +/* Copyright 2002, Red Hat Inc. - all rights reserved */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include "local.h" + +#define MIN_LINE_SIZE 4 +#define DEFAULT_LINE_SIZE 128 + +ssize_t +__getdelim (bufptr, n, delim, fp) + char **bufptr; + size_t *n; + int delim; + FILE *fp; +{ + char *buf; + char *ptr; + size_t newsize, numbytes; + int pos; + int ch; + int cont; + + if (fp == NULL || bufptr == NULL || n == NULL) + { + errno = EINVAL; + return -1; + } + + buf = *bufptr; + if (buf == NULL || *n < MIN_LINE_SIZE) + { + buf = (char *)realloc (*bufptr, DEFAULT_LINE_SIZE); + if (buf == NULL) + { + return -1; + } + *bufptr = buf; + *n = DEFAULT_LINE_SIZE; + } + + _flockfile(fp); + + CHECK_INIT(fp); + + numbytes = *n; + ptr = buf; + + cont = 1; + + while (cont) + { + /* fill buffer - leaving room for nul-terminator */ + while (--numbytes > 0) + { + if ((ch = getc_unlocked (fp)) == EOF) + { + cont = 0; + break; + } + else + { + *ptr++ = ch; + if (ch == delim) + { + cont = 0; + break; + } + } + } + + /* Buffer is too small so reallocate a larger buffer. */ + pos = ptr - buf; + newsize = (*n << 1); + buf = realloc (buf, newsize); + if (buf == NULL) + { + cont = 0; + break; + } + + /* After reallocating, continue in new buffer */ + *bufptr = buf; + *n = newsize; + ptr = buf + pos; + numbytes = newsize - pos; + } + + _funlockfile (fp); + + /* if no input data, return failure */ + if (ptr == buf) + return -1; + + /* otherwise, nul-terminate and return number of bytes read */ + *ptr = '\0'; + return (ssize_t)(ptr - buf); +} + |