Eric Blake wrote: > According to Paolo Bonzini on 8/27/2008 5:48 AM: >> Under MacOS, getc is not a macro, only getc_unlocked is. This patch >> does two things: 1) it makes getdelim use getc_unlocked if it can wrap >> the calls with flockfile/funlockfile; 2) it makes getdelim omit the >> locking altogether if unlocked-io is in effect. It speeds up sed by >> almost 2x in very simple scripts with very little regular expression >> matching (such as '/^something/!d'). > >> Ok? > > Sounds interesting. How does this compare with the current approach used > by getndelim2, which uses freadptr to avoid getc?
I guess there's also this other possibility. lib/getdelim.c | 107 ++--------------------------------------------- m4/getdelim.m4 | 10 ----- modules/getdelim | 4 -- 3 files changed, 6 insertions(+), 115 deletions(-) The number of deletions makes it yummy... Paolo
diff --git a/lib/getdelim.c b/lib/getdelim.c index 2e127fc..f935d25 100644 --- a/lib/getdelim.c +++ b/lib/getdelim.c @@ -1,6 +1,5 @@ -/* getdelim.c --- Implementation of replacement getdelim function. - Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008 Free - Software Foundation, Inc. +/* getdelim.c --- Delegation of getdelim to getndelim2. + Copyright (C) 2008 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 @@ -17,30 +16,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* Ported from glibc by Simon Josefsson. */ - #include <config.h> - #include <stdio.h> - -#include <limits.h> -#include <stdlib.h> -#include <errno.h> - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif -#ifndef SSIZE_MAX -# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) -#endif -#if !HAVE_FLOCKFILE -# undef flockfile -# define flockfile(x) ((void) 0) -#endif -#if !HAVE_FUNLOCKFILE -# undef funlockfile -# define funlockfile(x) ((void) 0) -#endif +#include "getndelim2.h" /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and NUL-terminate it). *LINEPTR is a pointer returned from malloc (or @@ -49,82 +27,7 @@ the null terminator), or -1 on error or EOF. */ ssize_t -getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) +getdelim (char **lineptr, size_t *n, int delim, FILE *fp) { - ssize_t result; - size_t cur_len = 0; - - if (lineptr == NULL || n == NULL || fp == NULL) - { - errno = EINVAL; - return -1; - } - - flockfile (fp); - - if (*lineptr == NULL || *n == 0) - { - char *new_lineptr; - *n = 120; - new_lineptr = (char *) realloc (*lineptr, *n); - if (new_lineptr == NULL) - { - result = -1; - goto unlock_return; - } - *lineptr = new_lineptr; - } - - for (;;) - { - int i; - - i = getc (fp); - if (i == EOF) - { - result = -1; - break; - } - - /* Make enough space for len+1 (for final NUL) bytes. */ - if (cur_len + 1 >= *n) - { - size_t needed_max = - SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; - size_t needed = 2 * *n + 1; /* Be generous. */ - char *new_lineptr; - - if (needed_max < needed) - needed = needed_max; - if (cur_len + 1 >= needed) - { - result = -1; - errno = EOVERFLOW; - 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 ? cur_len : result; - - unlock_return: - funlockfile (fp); /* doesn't set errno */ - - return result; + return getndelim2 (lineptr, n, 0, GETNLINE_NO_LIMIT, delim, delim, fp); } diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 index 18b96be..3342488 100644 --- a/m4/getdelim.m4 +++ b/m4/getdelim.m4 @@ -18,17 +18,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], AC_REPLACE_FUNCS([getdelim]) AC_CHECK_DECLS_ONCE([getdelim]) - if test $ac_cv_func_getdelim = no; then - gl_PREREQ_GETDELIM - fi - if test $ac_cv_have_decl_getdelim = no; then HAVE_DECL_GETDELIM=0 fi ]) - -# Prerequisites of lib/getdelim.c. -AC_DEFUN([gl_PREREQ_GETDELIM], -[ - AC_CHECK_FUNCS([flockfile funlockfile]) -]) diff --git a/modules/getdelim b/modules/getdelim index 1bb24f5..1dbc914 100644 --- a/modules/getdelim +++ b/modules/getdelim @@ -6,10 +6,8 @@ lib/getdelim.c m4/getdelim.m4 Depends-on: -extensions +getndelim2 stdio -realloc-posix -EOVERFLOW configure.ac: gl_FUNC_GETDELIM