bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: getline


From: Simon Josefsson
Subject: Re: getline
Date: Mon, 18 Jul 2005 12:22:54 +0200
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/22.0.50 (gnu/linux)

Paul Eggert <address@hidden> writes:

> Simon Josefsson <address@hidden> writes:
>
>> 5. I have no idea whether using flockfile/funlockfile is appropriate.
>
> I'd say it's appropriate, but only if flockfile/funlockfile exist.
> They don't exist on all platforms.  POSIX says they're optional;
> they're part of the Thread Safe Functions extension.  On platforms
> where they don't exist, you can define them to be no-ops, as
> unlocked-io does.  Applications that are using unlocked-io should also
> make them no-ops.

Updated patch below.

>>    getndelim2 does not appear to do any locking, though.
>
> Correct.  Currently it's used only by single-threaded apps.  It could
> be upgraded to multithreaded, using the same technique that you are
> using for getdelim.

I don't need getndelim2 in any multi-threaded library now, so it
doesn't matter for me.  Perhaps avoiding the locking speed things up.

Thanks.

Index: modules/getline
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/getline,v
retrieving revision 1.9
diff -u -p -r1.9 getline
--- modules/getline     21 Mar 2005 22:07:25 -0000      1.9
+++ modules/getline     18 Jul 2005 10:21:37 -0000
@@ -4,25 +4,21 @@ Read a line from a stream.
 Files:
 lib/getline.h
 lib/getline.c
-lib/getndelim2.h
-lib/getndelim2.c
 m4/getline.m4
-m4/getndelim2.m4
-m4/ssize_t.m4
 
 Depends-on:
+getdelim
 
 configure.ac:
-AM_FUNC_GETLINE
+gl_FUNC_GETLINE
 
 Makefile.am:
-EXTRA_DIST += getndelim2.h getndelim2.c
 
 Include:
 "getline.h"
 
 License:
-GPL
+LGPL
 
 Maintainer:
-all
+Simon Josefsson
Index: modules/getdelim
===================================================================
RCS file: modules/getdelim
diff -N modules/getdelim
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ modules/getdelim    18 Jul 2005 10:21:37 -0000
@@ -0,0 +1,23 @@
+Description:
+Read character delimited data from a stream.
+
+Files:
+lib/getdelim.h
+lib/getdelim.c
+m4/getdelim.m4
+
+Depends-on:
+
+configure.ac:
+gl_FUNC_GETDELIM
+
+Makefile.am:
+
+Include:
+"getdelim.h"
+
+License:
+LGPL
+
+Maintainer:
+Simon Josefsson
Index: m4/getdelim.m4
===================================================================
RCS file: m4/getdelim.m4
diff -N m4/getdelim.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/getdelim.m4      18 Jul 2005 10:21:37 -0000
@@ -0,0 +1,30 @@
+# getdelim.m4 serial 1
+
+dnl Copyright (C) 2005 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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_PREREQ(2.52)
+
+AC_DEFUN([gl_FUNC_GETDELIM],
+[
+  AC_LIBSOURCES([getdelim.c, getdelim.h])
+
+  dnl Persuade glibc <stdio.h> to declare getdelim().
+  AC_REQUIRE([AC_GNU_SOURCE])
+
+  AC_REPLACE_FUNCS(getdelim)
+  AC_CHECK_DECLS_ONCE(getdelim)
+
+  if test $ac_cv_func_getdelim = no; then
+    gl_PREREQ_GETDELIM
+  fi
+])
+
+# Prerequisites of lib/getdelim.c.
+AC_DEFUN([gl_PREREQ_GETDELIM],
+[
+  AC_CHECK_FUNCS([flockfile funlockfile])
+])
Index: m4/getline.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/getline.m4,v
retrieving revision 1.15
diff -u -p -r1.15 getline.m4
--- m4/getline.m4       21 Mar 2005 22:06:27 -0000      1.15
+++ m4/getline.m4       18 Jul 2005 10:21:37 -0000
@@ -1,4 +1,4 @@
-# getline.m4 serial 12
+# getline.m4 serial 13
 
 dnl Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software
 dnl Foundation, Inc.
@@ -13,19 +13,21 @@ dnl See if there's a working, system-sup
 dnl We can't just do AC_REPLACE_FUNCS(getline) because some systems
 dnl have a function by that name in -linet that doesn't have anything
 dnl to do with the function we need.
-AC_DEFUN([AM_FUNC_GETLINE],
+AC_DEFUN([gl_FUNC_GETLINE],
 [
   AC_LIBSOURCES([getline.c, getline.h])
 
-  dnl Persuade glibc <stdio.h> to declare getline() and getdelim().
+  dnl Persuade glibc <stdio.h> to declare getline().
   AC_REQUIRE([AC_GNU_SOURCE])
 
-  am_getline_needs_run_time_check=no
+  AC_CHECK_DECLS([getline])
+
+  gl_getline_needs_run_time_check=no
   AC_CHECK_FUNC(getline,
                dnl Found it in some library.  Verify that it works.
-               am_getline_needs_run_time_check=yes,
+               gl_getline_needs_run_time_check=yes,
                am_cv_func_working_getline=no)
-  if test $am_getline_needs_run_time_check = yes; then
+  if test $gl_getline_needs_run_time_check = yes; then
     AC_CACHE_CHECK([for working getline function], am_cv_func_working_getline,
     [echo fooN |tr -d '\012'|tr N '\012' > conftest.data
     AC_TRY_RUN([
@@ -57,20 +59,12 @@ AC_DEFUN([AM_FUNC_GETLINE],
       [Define to a replacement function name for getline().])
     AC_LIBOBJ(getline)
 
-    # Avoid multiple inclusions of getndelim2.o into LIBOBJS.
-    # This hack won't be needed after gnulib requires Autoconf 2.58 or later.
-    case " $LIB@&address@hidden " in
-    *" getndelim2.$ac_objext "* ) ;;
-    *) AC_LIBOBJ(getndelim2);;
-    esac
-
     gl_PREREQ_GETLINE
-    gl_PREREQ_GETNDELIM2
   fi
 ])
 
 # Prerequisites of lib/getline.c.
 AC_DEFUN([gl_PREREQ_GETLINE],
 [
-  AC_CHECK_FUNCS(getdelim)
+  gl_FUNC_GETDELIM
 ])
Index: lib/getdelim.c
===================================================================
RCS file: lib/getdelim.c
diff -N lib/getdelim.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/getdelim.c      18 Jul 2005 10:21:37 -0000
@@ -0,0 +1,116 @@
+/* getdelim.c --- Implementation of replacement getdelim function.
+   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Ported from glibc by Simon Josefsson. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "getdelim.h"
+
+#if !HAVE_FLOCKFILE
+# undef flockfile
+# define flockfile(x) ((void) 0)
+#endif
+#if !HAVE_FUNLOCKFILE
+# undef funlockfile
+# define funlockfile(x) ((void) 0)
+#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
+   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 delimiter, FILE *fp)
+{
+  int result;
+  ssize_t cur_len = 0;
+  ssize_t len;
+
+  if (lineptr == NULL || n == NULL || fp == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  flockfile (fp);
+
+  if (*lineptr == NULL || *n == 0)
+    {
+      *n = 120;
+      *lineptr = (char *) malloc (*n);
+      if (*lineptr == NULL)
+       {
+         result = -1;
+         goto unlock_return;
+       }
+    }
+
+  for (;;)
+    {
+      char *t;
+      int i;
+
+      i = getc (fp);
+      if (i == EOF)
+       break;
+
+      /* Make enough space for len+1 (for final NUL) bytes.  */
+      if (cur_len + 1 >= *n)
+       {
+         size_t needed = 2 * (cur_len + 1) + 1;   /* Be generous. */
+         char *new_lineptr;
+
+         if (needed < cur_len)
+           {
+             result = -1;
+             goto unlock_return;
+           }
+
+         new_lineptr = (char *) realloc (*lineptr, needed);
+         if (new_lineptr == NULL)
+           {
+             result = -1;
+             goto unlock_return;
+           }
+
+         *lineptr = new_lineptr;
+         *n = needed;
+       }
+
+      (*lineptr)[cur_len] = i;
+      cur_len++;
+
+      if (i == delimiter)
+       break;
+    }
+  (*lineptr)[cur_len] = '\0';
+  result = cur_len;
+
+ unlock_return:
+  funlockfile (fp);
+  return result;
+}
Index: lib/getdelim.h
===================================================================
RCS file: lib/getdelim.h
diff -N lib/getdelim.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/getdelim.h      18 Jul 2005 10:21:37 -0000
@@ -0,0 +1,28 @@
+/* getdelim.h --- Prototype for replacement getdelim function.
+   Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Written by Simon Josefsson. */
+
+/* Get size_t, FILE, ssize_t.  And getdelim, if available.  */
+# include <stddef.h>
+# include <stdio.h>
+# include <sys/types.h>
+
+#if !HAVE_DECL_GETDELIM
+ssize_t getdelim (char **lineptr, size_t *n, int delimiter, FILE *stream);
+#endif /* !HAVE_GETDELIM */
Index: lib/getline.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getline.c,v
retrieving revision 1.18
diff -u -p -r1.18 getline.c
--- lib/getline.c       14 May 2005 06:03:58 -0000      1.18
+++ lib/getline.c       18 Jul 2005 10:21:37 -0000
@@ -1,44 +1,32 @@
-/* getline.c -- Replacement for GNU C library function getline
+/* getline.c --- Implementation of replacement getline function.
+   Copyright (C) 2005 Free Software Foundation, Inc.
 
-   Copyright (C) 1993, 1996, 1997, 1998, 2000, 2003, 2004 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.
+   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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   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 Jan Brittenson, address@hidden  */
+/* Written by Simon Josefsson. */
 
 #if HAVE_CONFIG_H
 # include <config.h>
 #endif
 
+#include "getdelim.h"
 #include "getline.h"
 
-#if ! (defined __GNU_LIBRARY__ && HAVE_GETDELIM)
-
-# include "getndelim2.h"
-
-ssize_t
-getdelim (char **lineptr, size_t *linesize, int delimiter, FILE *stream)
-{
-  return getndelim2 (lineptr, linesize, 0, GETNLINE_NO_LIMIT, delimiter, EOF,
-                     stream);
-}
-#endif
-
 ssize_t
-getline (char **lineptr, size_t *linesize, FILE *stream)
+getline (char **lineptr, size_t *n, FILE *stream)
 {
-  return getdelim (lineptr, linesize, '\n', stream);
+  return getdelim (lineptr, n, '\n', stream);
 }
Index: lib/getline.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getline.h,v
retrieving revision 1.15
diff -u -p -r1.15 getline.h
--- lib/getline.h       14 May 2005 06:03:58 -0000      1.15
+++ lib/getline.h       18 Jul 2005 10:21:37 -0000
@@ -1,39 +1,28 @@
-/* Replacement for GNU C library function getline
+/* getline.h --- Prototype for replacement getline function.
+   Copyright (C) 2005 Free Software Foundation, Inc.
 
-   Copyright (C) 1995, 1997, 1999, 2000, 2001, 2002, 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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 
 */
-
-#ifndef GETLINE_H_
-# define GETLINE_H_ 1
+/* Written by Simon Josefsson. */
 
+/* Get size_t, FILE, ssize_t.  And getline, if available.  */
 # include <stddef.h>
 # include <stdio.h>
-
-/* Get ssize_t.  */
 # include <sys/types.h>
 
-/* glibc2 has these functions declared in <stdio.h>.  Avoid redeclarations.  */
-# if __GLIBC__ < 2
-
-extern ssize_t getline (char **_lineptr, size_t *_linesize, FILE *_stream);
-
-extern ssize_t getdelim (char **_lineptr, size_t *_linesize, int _delimiter,
-                         FILE *_stream);
-
-# endif
-
-#endif /* not GETLINE_H_ */
+#if !HAVE_DECL_GETLINE
+ssize_t getline (char **lineptr, size_t *n, FILE *stream);
+#endif /* !HAVE_GETLINE */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]