+2003-07-17 Bruno Haible <bruno@clisp.org>
+
+ * modules/getnline: New file.
+ * modules/getline: Add lib/getndelim2.c to source file list.
+ * MODULES.html.sh (func_all_modules): Add getnline.
+
2003-07-17 Bruno Haible <bruno@clisp.org>
* configure.in: Remove file.
func_begin_table
func_module diacrit
func_module getline
+ func_module getnline
func_module linebuffer
func_module obstack
func_module hash-pjw
+2003-07-17 Bruno Haible <bruno@clisp.org>
+
+ * getnline.h: New file.
+ * getnline.c: New file.
+ * getndelim2.c: New file, extracted from getline.c.
+ (getndelim2): Renamed from getdelim2, with added nmax argument.
+ * getline.c: Include getndelim2.c.
+ (getdelim2): Moved out to getndelim2.c.
+ (getline, getdelim): Update.
+
2003-07-15 <karl@gnu.org>
* vasnprintf.c: update from gettext.
# include <config.h>
#endif
+/* Specification. */
#include "getline.h"
/* The `getdelim' function is only declared if the following symbol
#else /* ! have getdelim */
-# if STDC_HEADERS
-# include <stdlib.h>
-# else
-char *malloc (), *realloc ();
-# endif
-
-#include "unlocked-io.h"
-
-/* Always add at least this many bytes when extending the buffer. */
-#define MIN_CHUNK 64
-
-/* Read up to (and including) a delimiter DELIM1 from STREAM into *LINEPTR
- + OFFSET (and NUL-terminate it). If DELIM2 is non-zero, then read up
- and including the first occurrence of DELIM1 or DELIM2. *LINEPTR is
- a pointer returned from malloc (or NULL), pointing to *N characters of
- space. It is realloc'd as necessary. Return the number of characters
- read (not including the NUL terminator), or -1 on error or EOF. */
-
-static int
-getdelim2 (char **lineptr, size_t *n, FILE *stream, int delim1, int delim2,
- size_t offset)
-{
- size_t nchars_avail; /* Allocated but unused chars in *LINEPTR. */
- char *read_pos; /* Where we're reading into *LINEPTR. */
- int ret;
-
- if (!lineptr || !n || !stream)
- return -1;
-
- if (!*lineptr)
- {
- *n = MIN_CHUNK;
- *lineptr = malloc (*n);
- if (!*lineptr)
- return -1;
- }
-
- if (*n < offset)
- return -1;
-
- nchars_avail = *n - offset;
- read_pos = *lineptr + offset;
-
- for (;;)
- {
- register int c = getc (stream);
-
- /* We always want at least one char left in the buffer, since we
- always (unless we get an error while reading the first char)
- NUL-terminate the line buffer. */
-
- if (nchars_avail < 2)
- {
- if (*n > MIN_CHUNK)
- *n *= 2;
- else
- *n += MIN_CHUNK;
-
- nchars_avail = *n + *lineptr - read_pos;
- *lineptr = realloc (*lineptr, *n);
- if (!*lineptr)
- return -1;
- read_pos = *n - nchars_avail + *lineptr;
- }
-
- if (c == EOF || ferror (stream))
- {
- /* Return partial line, if any. */
- if (read_pos == *lineptr)
- return -1;
- else
- break;
- }
-
- *read_pos++ = c;
- nchars_avail--;
-
- if (c == delim1 || (delim2 && c == delim2))
- /* Return the line. */
- break;
- }
-
- /* Done - NUL terminate and return the number of chars read. */
- *read_pos = '\0';
-
- ret = read_pos - (*lineptr + offset);
- return ret;
-}
-
+#include "getndelim2.c"
int
getline (char **lineptr, size_t *n, FILE *stream)
{
- return getdelim2 (lineptr, n, stream, '\n', 0, 0);
+ return getndelim2 (lineptr, n, (size_t)(-1), stream, '\n', 0, 0);
}
int
getdelim (char **lineptr, size_t *n, int delimiter, FILE *stream)
{
- return getdelim2 (lineptr, n, stream, delimiter, 0, 0);
+ return getndelim2 (lineptr, n, (size_t)(-1), stream, delimiter, 0, 0);
}
#endif
--- /dev/null
+/* getndelim2 - Core of getline, getdelim, getnline, getndelim.
+
+ Copyright (C) 1993, 1996, 1997, 1998, 2000, 2003 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if STDC_HEADERS
+# include <stdlib.h>
+#else
+char *malloc (), *realloc ();
+#endif
+
+#include "unlocked-io.h"
+
+/* Always add at least this many bytes when extending the buffer. */
+#define MIN_CHUNK 64
+
+/* Read up to (and including) a delimiter DELIM1 from STREAM into *LINEPTR
+ + OFFSET (and NUL-terminate it). If DELIM2 is non-zero, then read up
+ and including the first occurrence of DELIM1 or DELIM2. *LINEPTR is
+ a pointer returned from malloc (or NULL), pointing to *LINESIZE bytes of
+ space. It is realloc'd as necessary. Reallocation is limited to
+ NMAX bytes; if the line is longer than that, the extra bytes are read but
+ thrown away.
+ Return the number of bytes read and stored at *LINEPTR + OFFSET (not
+ including the NUL terminator), or -1 on error or EOF. */
+
+static int
+getndelim2 (char **lineptr, size_t *linesize, size_t nmax,
+ FILE *stream, int delim1, int delim2, size_t offset)
+{
+ size_t nbytes_avail; /* Allocated but unused chars in *LINEPTR. */
+ char *read_pos; /* Where we're reading into *LINEPTR. */
+
+ if (!lineptr || !linesize || !nmax || !stream)
+ return -1;
+
+ if (!*lineptr)
+ {
+ size_t newlinesize = MIN_CHUNK;
+
+ if (newlinesize > nmax)
+ newlinesize = nmax;
+
+ *linesize = newlinesize;
+ *lineptr = malloc (*linesize);
+ if (!*lineptr)
+ return -1;
+ }
+
+ if (*linesize < offset)
+ return -1;
+
+ nbytes_avail = *linesize - offset;
+ read_pos = *lineptr + offset;
+
+ if (nbytes_avail == 0 && *linesize >= nmax)
+ return -1;
+
+ for (;;)
+ {
+ /* Here always *lineptr + *linesize == read_pos + nbytes_avail. */
+
+ register int c = getc (stream);
+
+ /* We always want at least one char left in the buffer, since we
+ always (unless we get an error while reading the first char)
+ NUL-terminate the line buffer. */
+
+ if (nbytes_avail < 2 && *linesize < nmax)
+ {
+ size_t newlinesize =
+ (*linesize > MIN_CHUNK ? 2 * *linesize : *linesize + MIN_CHUNK);
+
+ if (newlinesize > nmax)
+ newlinesize = nmax;
+
+ if (newlinesize > *linesize)
+ {
+ *linesize = newlinesize;
+ nbytes_avail = *linesize + *lineptr - read_pos;
+ *lineptr = realloc (*lineptr, *linesize);
+ if (!*lineptr)
+ return -1;
+ read_pos = *linesize - nbytes_avail + *lineptr;
+ }
+ }
+
+ if (c == EOF || ferror (stream))
+ {
+ /* Return partial line, if any. */
+ if (read_pos == *lineptr)
+ return -1;
+ else
+ break;
+ }
+
+ if (nbytes_avail >= 2)
+ {
+ *read_pos++ = c;
+ nbytes_avail--;
+ }
+
+ if (c == delim1 || (delim2 && c == delim2))
+ /* Return the line. */
+ break;
+ }
+
+ /* Done - NUL terminate and return the number of chars read.
+ At this point we know that nbytes_avail >= 1. */
+ *read_pos = '\0';
+
+ return read_pos - (*lineptr + offset);
+}
--- /dev/null
+/* getnline - Read a line from a stream, with bounded memory allocation.
+
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification. */
+#include "getnline.h"
+
+ssize_t
+getnline (char **lineptr, size_t *linesize, size_t nmax, FILE *stream)
+{
+ return getndelim2 (lineptr, linesize, (size_t)(-1), stream, '\n', 0, 0);
+}
+
+ssize_t
+getndelim (char **lineptr, size_t *linesize, size_t nmax,
+ int delimiter, FILE *stream)
+{
+ return getndelim2 (lineptr, linesize, (size_t)(-1), stream, delimiter, 0, 0);
+}
--- /dev/null
+/* getnline - Read a line from a stream, with bounded memory allocation.
+
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GETNLINE_H
+#define GETNLINE_H 1
+
+#include <stddef.h>
+#include <stdio.h>
+
+/* Get ssize_t. */
+#include <sys/types.h>
+
+/* Read a line, up to the next newline, from STREAM, and store it in *LINEPTR.
+ *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE
+ bytes of space. It is realloc'd as necessary. Reallocation is limited to
+ NMAX bytes; if the line is longer than that, the extra bytes are read but
+ thrown away.
+ Return the number of bytes read and stored at *LINEPTR (not including the
+ NUL terminator), or -1 on error or EOF. */
+extern ssize_t getnline (char **lineptr, size_t *linesize, size_t nmax,
+ FILE *stream);
+
+/* Read a line, up to the next occurrence of DELIMITER, from STREAM, and store
+ it in *LINEPTR.
+ *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE
+ bytes of space. It is realloc'd as necessary. Reallocation is limited to
+ NMAX bytes; if the line is longer than that, the extra bytes are read but
+ thrown away.
+ Return the number of bytes read and stored at *LINEPTR (not including the
+ NUL terminator), or -1 on error or EOF. */
+extern ssize_t getndelim (char **lineptr, size_t *linesize, size_t nmax,
+ int delimiter, FILE *stream);
+
+#endif /* GETNLINE_H */
+2003-07-17 Bruno Haible <bruno@clisp.org>
+
+ * getnline.m4: New file.
+
2003-07-14 Simon Josefsson <jas@extundo.com>
* mempcpy.m4: New file.
--- /dev/null
+# getnline.m4 serial 1
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+AC_DEFUN([gl_GETNLINE],
+[
+ dnl Prerequisites of lib/getnline.h.
+ AC_REQUIRE([gt_TYPE_SSIZE_T])
+ dnl Prerequisites of lib/getnline.c.
+ AC_REQUIRE([AC_HEADER_STDC])
+])
Files:
lib/getline.h
lib/getline.c
+lib/getndelim2.c
m4/getline.m4
Depends-on:
Makefile.am:
lib_SOURCES += getline.h
+EXTRA_DIST += getndelim2.c
Include:
"getline.h"
--- /dev/null
+Description:
+Read a line from a stream, with bounded memory allocation.
+
+Files:
+lib/getnline.h
+lib/getnline.c
+lib/getndelim2.c
+m4/getnline.m4
+m4/ssize_t.m4
+
+Depends-on:
+unlocked-io
+
+configure.ac:
+gl_GETNLINE
+
+Makefile.am:
+lib_SOURCES += getnline.h
+EXTRA_DIST += getndelim2.c
+
+Include:
+"getnline.h"
+
+Maintainer:
+all
+