summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2007-08-22 12:54:21 +0000
committerEric Blake <ebb9@byu.net>2007-08-22 12:54:21 +0000
commitd68417c03e69fde605af699ba9a9671c663d8baf (patch)
tree5ab8a71b84ce6ae1e24722666f0c106523060201
parent7042775894700f8be0e6bc2a5ff3c49fc77296bc (diff)
downloadgnulib-d68417c03e69fde605af699ba9a9671c663d8baf.tar.gz
Move getline and getdelim into stdio.h, per POSIX 200x.
* modules/getline (Files): Remove getline.h. (Depends-on): Add stdio. (configure.ac): Add module indicator. * modules/getdelim (Files): Remove getdelim.h. (Depends-on): Add stdio. (configure.ac): Add module indicator. * modules/stdio (Makefile.am): Work with new indicators. * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Add new defaults. * m4/getdelim.m4 (gl_FUNC_GETDELIM): Work with stdio needs. * m4/getline.m4 (gl_FUNC_GETLINE): Likewise. * lib/getdelim.h: Delete. * lib/getline.h: Delete. * lib/stdio_.h (getdelim, getline): Declare. * modules/getdelim-tests: New module. * modules/getline-tests: Likewise. * tests/test-getdelim.c: New file. * tests/test-getline.c: Likewise. * NEWS: Document the change. * lib/getline.c: Update choice of header. * lib/csharpcomp.c: Likewise. * lib/getpass.c: Likewise. * lib/javacomp.c: Likewise. * lib/javaversion.c: Likewise. * lib/yesno.c: Likewise. * lib/getdelim.c: Likewise. (getdelim): Set errno on failure, and avoid memory leak.
-rw-r--r--ChangeLog30
-rw-r--r--NEWS4
-rw-r--r--lib/csharpcomp.c1
-rw-r--r--lib/getdelim.c14
-rw-r--r--lib/getline.c5
-rw-r--r--lib/getpass.c2
-rw-r--r--lib/javacomp.c1
-rw-r--r--lib/javaversion.c3
-rw-r--r--lib/stdio_.h45
-rw-r--r--lib/yesno.c4
-rw-r--r--m4/getdelim.m46
-rw-r--r--m4/getline.m418
-rw-r--r--m4/stdio_h.m45
-rw-r--r--modules/getdelim5
-rw-r--r--modules/getdelim-tests11
-rw-r--r--modules/getline5
-rw-r--r--modules/getline-tests11
-rw-r--r--modules/stdio5
-rw-r--r--tests/test-getdelim.c89
-rw-r--r--tests/test-getline.c89
20 files changed, 320 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 9fd9405b32..b3e22bab33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2007-08-22 Eric Blake <ebb9@byu.net>
+
+ Move getline and getdelim into stdio.h, per POSIX 200x.
+ * modules/getline (Files): Remove getline.h.
+ (Depends-on): Add stdio.
+ (configure.ac): Add module indicator.
+ * modules/getdelim (Files): Remove getdelim.h.
+ (Depends-on): Add stdio.
+ (configure.ac): Add module indicator.
+ * modules/stdio (Makefile.am): Work with new indicators.
+ * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Add new defaults.
+ * m4/getdelim.m4 (gl_FUNC_GETDELIM): Work with stdio needs.
+ * m4/getline.m4 (gl_FUNC_GETLINE): Likewise.
+ * lib/getdelim.h: Delete.
+ * lib/getline.h: Delete.
+ * lib/stdio_.h (getdelim, getline): Declare.
+ * modules/getdelim-tests: New module.
+ * modules/getline-tests: Likewise.
+ * tests/test-getdelim.c: New file.
+ * tests/test-getline.c: Likewise.
+ * NEWS: Document the change.
+ * lib/getline.c: Update choice of header.
+ * lib/csharpcomp.c: Likewise.
+ * lib/getpass.c: Likewise.
+ * lib/javacomp.c: Likewise.
+ * lib/javaversion.c: Likewise.
+ * lib/yesno.c: Likewise.
+ * lib/getdelim.c: Likewise.
+ (getdelim): Set errno on failure, and avoid memory leak.
+
2007-08-19 Bruno Haible <bruno@clisp.org>
* modules/closein (Depends-on): Add freadahead.
diff --git a/NEWS b/NEWS
index e4009e1c0f..438644ca07 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ User visible incompatible changes
Date Modules Changes
+2007-08-22 getdelim, getline
+ The include file is changed from "getdelim.h"
+ and "getline.h" to the POSIX 200x <stdio.h>.
+
2007-08-18 idcache Now provides prototypes in "idcache.h".
2007-08-10 xstrtol The STRTOL_FATAL_ERROR macro is removed.
diff --git a/lib/csharpcomp.c b/lib/csharpcomp.c
index e046114392..16646dc463 100644
--- a/lib/csharpcomp.c
+++ b/lib/csharpcomp.c
@@ -30,7 +30,6 @@
#include "execute.h"
#include "pipe.h"
#include "wait-process.h"
-#include "getline.h"
#include "sh-quote.h"
#include "safe-read.h"
#include "xmalloca.h"
diff --git a/lib/getdelim.c b/lib/getdelim.c
index e0b8a708ba..352b5974ba 100644
--- a/lib/getdelim.c
+++ b/lib/getdelim.c
@@ -1,5 +1,5 @@
/* getdelim.c --- Implementation of replacement getdelim function.
- Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006 Free
+ Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007 Free
Software Foundation, Inc.
This program is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@
#include <config.h>
-#include "getdelim.h"
+#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
@@ -42,6 +42,11 @@
# define funlockfile(x) ((void) 0)
#endif
+/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
+#ifndef EOVERFLOW
+# define EOVERFLOW E2BIG
+#endif
+
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
NULL), pointing to *N characters of space. It is realloc'ed as
@@ -62,10 +67,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
flockfile (fp);
- if (*lineptr == NULL || *n == 0)
+ if (*n == 0)
{
*n = 120;
- *lineptr = (char *) malloc (*n);
+ *lineptr = (char *) realloc (*lineptr, 120);
if (*lineptr == NULL)
{
result = -1;
@@ -97,6 +102,7 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
if (cur_len + 1 >= needed)
{
result = -1;
+ errno = EOVERFLOW;
goto unlock_return;
}
diff --git a/lib/getline.c b/lib/getline.c
index c8c9244a04..817c2813b3 100644
--- a/lib/getline.c
+++ b/lib/getline.c
@@ -1,5 +1,5 @@
/* getline.c --- Implementation of replacement getline function.
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2007 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
@@ -20,8 +20,7 @@
#include <config.h>
-#include "getdelim.h"
-#include "getline.h"
+#include <stdio.h>
ssize_t
getline (char **lineptr, size_t *n, FILE *stream)
diff --git a/lib/getpass.c b/lib/getpass.c
index 4ae233305d..17d513720e 100644
--- a/lib/getpass.c
+++ b/lib/getpass.c
@@ -41,8 +41,6 @@
# include <termios.h>
#endif
-#include "getline.h"
-
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#else
diff --git a/lib/javacomp.c b/lib/javacomp.c
index b17883a279..490eed1bcd 100644
--- a/lib/javacomp.c
+++ b/lib/javacomp.c
@@ -42,7 +42,6 @@
#include "safe-read.h"
#include "xalloc.h"
#include "xmalloca.h"
-#include "getline.h"
#include "filename.h"
#include "fwriteerror.h"
#include "clean-temp.h"
diff --git a/lib/javaversion.c b/lib/javaversion.c
index e00929abe9..3f2a79c5b7 100644
--- a/lib/javaversion.c
+++ b/lib/javaversion.c
@@ -1,5 +1,5 @@
/* Determine the Java version supported by javaexec.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This program is free software; you can redistribute it and/or modify
@@ -38,7 +38,6 @@
#include "pipe.h"
#include "wait-process.h"
#include "error.h"
-#include "getline.h"
#include "gettext.h"
#define _(str) gettext (str)
diff --git a/lib/stdio_.h b/lib/stdio_.h
index 7d77c5e56f..03d85e3d63 100644
--- a/lib/stdio_.h
+++ b/lib/stdio_.h
@@ -35,8 +35,11 @@
#include <stdarg.h>
#include <stddef.h>
-#if (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) || (@GNULIB_FTELLO@ && @REPLACE_FTELLO@)
-/* Get off_t. */
+#if (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) \
+ || (@GNULIB_FTELLO@ && @REPLACE_FTELLO@) \
+ || (@GNULIB_GETDELIM@ && !@HAVE_DECL_GETDELIM@) \
+ || (@GNULIB_GETLINE@ && (!@HAVE_DECL_GETLINE@ || @REPLACE_GETLINE@))
+/* Get off_t and ssize_t. */
# include <sys/types.h>
#endif
@@ -303,6 +306,44 @@ extern long rpl_ftell (FILE *fp);
fflush (f))
#endif
+#if @GNULIB_GETDELIM@
+# if !@HAVE_DECL_GETDELIM@
+ /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
+ NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
+ NULL), pointing to *N characters of space. It is realloc'ed as
+ necessary. Returns the number of characters read (not including
+ the null terminator), or -1 on error or EOF. */
+ extern ssize_t getdelim (char **, size_t *, int delim, FILE *);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getdelim
+# define getdelim(l, s, d, f) \
+ (GL_LINK_WARNING ("getdelim is unportable - " \
+ "use gnulib module getdelim for portability"), \
+ getdelim (l, s, d, f))
+#endif
+
+#if @GNULIB_GETLINE@
+# if @REPLACE_GETLINE@
+# undef getline
+# define getline rpl_getline
+# endif
+# if !@HAVE_DECL_GETLINE@
+ /* Read up to (and including) a newline from FP into *LINEPTR (and
+ NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
+ NULL), pointing to *N characters of space. It is realloc'ed as
+ necessary. Returns the number of characters read (not including
+ the null terminator), or -1 on error or EOF. */
+ extern ssize_t getline (char **, size_t *, FILE *);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getline
+# define getline(l, s, f) \
+ (GL_LINK_WARNING ("getline is unportable - " \
+ "use gnulib module getline for portability"), \
+ getline (l, s, f))
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/yesno.c b/lib/yesno.c
index 3db2d6ce0c..8ec798b63a 100644
--- a/lib/yesno.c
+++ b/lib/yesno.c
@@ -24,10 +24,6 @@
#include <stdlib.h>
#include <stdio.h>
-#if ENABLE_NLS
-# include "getline.h"
-#endif
-
extern int rpmatch (char const *response);
/* Return true if we read an affirmative line from standard input.
diff --git a/m4/getdelim.m4 b/m4/getdelim.m4
index 2a738f680a..21be20c3a1 100644
--- a/m4/getdelim.m4
+++ b/m4/getdelim.m4
@@ -1,6 +1,6 @@
-# getdelim.m4 serial 2
+# getdelim.m4 serial 3
-dnl Copyright (C) 2005, 2006 Free Software dnl Foundation, Inc.
+dnl Copyright (C) 2005, 2006, 2007 Free Software dnl Foundation, Inc.
dnl
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -10,6 +10,7 @@ AC_PREREQ(2.52)
AC_DEFUN([gl_FUNC_GETDELIM],
[
+ AC_REQUIRE([gl_STDIO_H_DEFAULTS])
dnl Persuade glibc <stdio.h> to declare getdelim().
AC_REQUIRE([AC_GNU_SOURCE])
@@ -19,6 +20,7 @@ AC_DEFUN([gl_FUNC_GETDELIM],
if test $ac_cv_func_getdelim = no; then
gl_PREREQ_GETDELIM
+ HAVE_DECL_GETDELIM=0
fi
])
diff --git a/m4/getline.m4 b/m4/getline.m4
index 5b55c3045b..421710595d 100644
--- a/m4/getline.m4
+++ b/m4/getline.m4
@@ -1,7 +1,7 @@
-# getline.m4 serial 15
+# getline.m4 serial 16
-dnl Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software
-dnl Foundation, Inc.
+dnl Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 Free
+dnl Software Foundation, Inc.
dnl
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -15,6 +15,8 @@ dnl have a function by that name in -linet that doesn't have anything
dnl to do with the function we need.
AC_DEFUN([gl_FUNC_GETLINE],
[
+ AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+
dnl Persuade glibc <stdio.h> to declare getline().
AC_REQUIRE([AC_GNU_SOURCE])
@@ -60,12 +62,12 @@ AC_DEFUN([gl_FUNC_GETLINE],
)])
fi
+ if test $ac_cv_func_getline = no; then
+ HAVE_DECL_GETLINE=0
+ fi
+
if test $am_cv_func_working_getline = no; then
- dnl We must choose a different name for our function, since on ELF systems
- dnl a broken getline() in libc.so would override our getline() in
- dnl libgettextlib.so.
- AC_DEFINE([getline], [gnu_getline],
- [Define to a replacement function name for getline().])
+ REPLACE_GETLINE=1
AC_LIBOBJ(getline)
gl_PREREQ_GETLINE
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index 721c826299..b9a69984f6 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -33,6 +33,8 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS],
GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL])
GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO])
GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH])
+ GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM])
+ GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE])
dnl Assume proper GNU behavior unless another module says otherwise.
REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF])
REPLACE_VFPRINTF=0; AC_SUBST([REPLACE_VFPRINTF])
@@ -53,6 +55,9 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS],
REPLACE_FTELLO=0; AC_SUBST([REPLACE_FTELLO])
REPLACE_FTELL=0; AC_SUBST([REPLACE_FTELL])
REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH])
+ HAVE_DECL_GETDELIM=1; AC_SUBST([HAVE_DECL_GETDELIM])
+ HAVE_DECL_GETLINE=1; AC_SUBST([HAVE_DECL_GETLINE])
+ REPLACE_GETLINE=0; AC_SUBST([REPLACE_GETLINE])
])
dnl Code shared by fseeko and ftello. Determine if large files are supported,
diff --git a/modules/getdelim b/modules/getdelim
index b198443dec..3c70791940 100644
--- a/modules/getdelim
+++ b/modules/getdelim
@@ -2,19 +2,20 @@ Description:
Read character delimited data from a stream.
Files:
-lib/getdelim.h
lib/getdelim.c
m4/getdelim.m4
Depends-on:
+stdio
configure.ac:
gl_FUNC_GETDELIM
+gl_STDIO_MODULE_INDICATOR([getdelim])
Makefile.am:
Include:
-"getdelim.h"
+<stdio.h>
License:
LGPLv2+
diff --git a/modules/getdelim-tests b/modules/getdelim-tests
new file mode 100644
index 0000000000..33e04e38ac
--- /dev/null
+++ b/modules/getdelim-tests
@@ -0,0 +1,11 @@
+Files:
+tests/test-getdelim.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getdelim
+check_PROGRAMS += test-getdelim
+MOSTLYCLEANFILES += test-getdelim.txt
diff --git a/modules/getline b/modules/getline
index 345850b285..82901293bd 100644
--- a/modules/getline
+++ b/modules/getline
@@ -2,20 +2,21 @@ Description:
Read a line from a stream.
Files:
-lib/getline.h
lib/getline.c
m4/getline.m4
Depends-on:
getdelim
+stdio
configure.ac:
gl_FUNC_GETLINE
+gl_STDIO_MODULE_INDICATOR([getline])
Makefile.am:
Include:
-"getline.h"
+<stdio.h>
License:
LGPLv2+
diff --git a/modules/getline-tests b/modules/getline-tests
new file mode 100644
index 0000000000..dae21bec92
--- /dev/null
+++ b/modules/getline-tests
@@ -0,0 +1,11 @@
+Files:
+tests/test-getline.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getline
+check_PROGRAMS += test-getline
+MOSTLYCLEANFILES += test-getline.txt
diff --git a/modules/stdio b/modules/stdio
index 924630a5bf..1a6f0b5cc9 100644
--- a/modules/stdio
+++ b/modules/stdio
@@ -36,6 +36,8 @@ stdio.h: stdio_.h
-e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \
-e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \
-e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \
+ -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \
+ -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \
-e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \
-e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \
-e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \
@@ -53,6 +55,9 @@ stdio.h: stdio_.h
-e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \
-e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \
-e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \
+ -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \
+ -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \
+ -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \
-e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
< $(srcdir)/stdio_.h; \
} > $@-t
diff --git a/tests/test-getdelim.c b/tests/test-getdelim.c
new file mode 100644
index 0000000000..e33099b9ce
--- /dev/null
+++ b/tests/test-getdelim.c
@@ -0,0 +1,89 @@
+/* Test of getdelim() function.
+ Copyright (C) 2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ASSERT(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ abort (); \
+ } \
+ } \
+ while (0)
+
+int
+main (int argc, char **argv)
+{
+ FILE *f;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t result;
+
+ /* Create test file. */
+ f = fopen ("test-getdelim.txt", "wb");
+ if (!f || fwrite ("anbcnd\0f", 1, 8, f) != 8 || fclose (f) != 0)
+ {
+ fputs ("Failed to create sample file.\n", stderr);
+ unlink ("test-getdelim.txt");
+ return 1;
+ }
+ f = fopen ("test-getdelim.txt", "rb");
+ if (!f)
+ {
+ fputs ("Failed to reopen sample file.\n", stderr);
+ unlink ("test-getdelim.txt");
+ return 1;
+ }
+
+ /* Test initial allocation, which must include trailing NUL. */
+ result = getdelim (&line, &len, 'n', f);
+ ASSERT (result == 2);
+ ASSERT (strcmp (line, "an") == 0);
+ ASSERT (2 < len);
+
+ /* Test growth of buffer. */
+ free (line);
+ line = malloc (1);
+ len = 1;
+ result = getdelim (&line, &len, 'n', f);
+ ASSERT (result == 3);
+ ASSERT (strcmp (line, "bcn") == 0);
+ ASSERT (3 < len);
+
+ /* Test embedded NULs and EOF behavior. */
+ result = getdelim (&line, &len, 'n', f);
+ ASSERT (result == 3);
+ ASSERT (memcmp (line, "d\0f", 4) == 0);
+ ASSERT (3 < len);
+
+ result = getdelim (&line, &len, 'n', f);
+ ASSERT (result == -1);
+
+ free (line);
+ fclose (f);
+ unlink ("test-getdelim.txt");
+ return 0;
+}
diff --git a/tests/test-getline.c b/tests/test-getline.c
new file mode 100644
index 0000000000..6b66d71dbe
--- /dev/null
+++ b/tests/test-getline.c
@@ -0,0 +1,89 @@
+/* Test of getline() function.
+ Copyright (C) 2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ASSERT(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ abort (); \
+ } \
+ } \
+ while (0)
+
+int
+main (int argc, char **argv)
+{
+ FILE *f;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t result;
+
+ /* Create test file. */
+ f = fopen ("test-getline.txt", "wb");
+ if (!f || fwrite ("a\nbc\nd\0f", 1, 8, f) != 8 || fclose (f) != 0)
+ {
+ fputs ("Failed to create sample file.\n", stderr);
+ unlink ("test-getline.txt");
+ return 1;
+ }
+ f = fopen ("test-getline.txt", "rb");
+ if (!f)
+ {
+ fputs ("Failed to reopen sample file.\n", stderr);
+ unlink ("test-getline.txt");
+ return 1;
+ }
+
+ /* Test initial allocation, which must include trailing NUL. */
+ result = getline (&line, &len, f);
+ ASSERT (result == 2);
+ ASSERT (strcmp (line, "a\n") == 0);
+ ASSERT (2 < len);
+
+ /* Test growth of buffer, must not leak. */
+ free (line);
+ line = malloc (1);
+ len = 0;
+ result = getline (&line, &len, f);
+ ASSERT (result == 3);
+ ASSERT (strcmp (line, "bc\n") == 0);
+ ASSERT (3 < len);
+
+ /* Test embedded NULs and EOF behavior. */
+ result = getline (&line, &len, f);
+ ASSERT (result == 3);
+ ASSERT (memcmp (line, "d\0f", 4) == 0);
+ ASSERT (3 < len);
+
+ result = getline (&line, &len, f);
+ ASSERT (result == -1);
+
+ free (line);
+ fclose (f);
+ unlink ("test-getline.txt");
+ return 0;
+}