Here are some modules that contain nontrivial changes, synced from gnulib. Most of these have to do with the new changes for getline and case-insensitive string comparison and getting canonical host names.
2005-09-21 Paul Eggert <[EMAIL PROTECTED]> * canon-host.c, getline.c, getline.h, getpass.c, strcasecmp.c: * strncasecmp.c, strstr.c: Nontrivial sync from gnulib. * canon-host.m4, getline.m4, mbrtowc.m4, strcase.m4, strstr.m4: Nontrivial sync from gnulib. Index: lib/canon-host.c =================================================================== RCS file: /fetish/cu/lib/canon-host.c,v retrieving revision 1.21 diff -p -u -r1.21 canon-host.c --- lib/canon-host.c 2 Jul 2005 08:41:46 -0000 1.21 +++ lib/canon-host.c 22 Sep 2005 06:44:10 -0000 @@ -1,9 +1,8 @@ /* Host name canonicalization - Copyright (C) 1995, 1999, 2000, 2002, 2003, 2004, 2005 Free Software - Foundation, Inc. + Copyright (C) 2005 Free Software Foundation, Inc. - Written by Miles Bader <[EMAIL PROTECTED]> + Written by Derek Price <[EMAIL PROTECTED]>. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -23,103 +22,69 @@ # include <config.h> #endif -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_NETDB_H -# include <netdb.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -# include <sys/socket.h> -#endif - -#ifdef HAVE_NETINET_IN_H -# include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -# include <arpa/inet.h> -#endif +#include "canon-host.h" +#include "getaddrinfo.h" #include "strdup.h" -/* Returns the canonical hostname associated with HOST (allocated in a static - buffer), or NULL if it can't be determined. */ +/* Store the last error for the single-threaded version of this function. */ +static int last_cherror; + +/* Single-threaded of wrapper for canon_host_r. After a NULL return, error + messages may be retrieved via ch_strerror(). */ char * -canon_host (char const *host) +canon_host (const char *host) { - char *h_addr_copy = NULL; - -#if HAVE_GETADDRINFO - { - struct addrinfo hint = { 0, }; - struct addrinfo *res = NULL; - hint.ai_flags = AI_CANONNAME; - if (getaddrinfo (host, NULL, &hint, &res) == 0) - { - h_addr_copy = strdup (res->ai_canonname); - freeaddrinfo (res); - } - } -#elif HAVE_GETHOSTBYNAME - { - struct hostent *he = gethostbyname (host); - - if (he) - { -# ifdef HAVE_GETHOSTBYADDR - char *addr = NULL; - - /* Try and get an ascii version of the numeric host address. */ - switch (he->h_addrtype) - { -# ifdef HAVE_INET_NTOA - case AF_INET: - addr = inet_ntoa (*(struct in_addr *) he->h_addr); - break; -# endif /* HAVE_INET_NTOA */ - } - - if (addr && strcmp (he->h_name, addr) == 0) - { - /* gethostbyname has returned a string representation of the IP - address, for example, "127.0.0.1". So now, look up the host - name via the address. Although it may seem reasonable to look - up the host name via the address, we must not pass `he->h_addr' - directly to gethostbyaddr because on some systems he->h_addr - is located in a static library buffer that is reused in the - gethostbyaddr call. Make a copy and use that instead. */ - h_addr_copy = (char *) malloc (he->h_length); - if (h_addr_copy == NULL) - he = NULL; - else - { - memcpy (h_addr_copy, he->h_addr, he->h_length); - he = gethostbyaddr (h_addr_copy, he->h_length, he->h_addrtype); - free (h_addr_copy); - } - } -# endif /* HAVE_GETHOSTBYADDR */ - - if (he) - h_addr_copy = strdup (he->h_name); - } - } -#endif /* HAVE_GETHOSTBYNAME */ - - return h_addr_copy; + return canon_host_r (host, &last_cherror); } -#ifdef TEST_CANON_HOST -int -main (int argc, char **argv) +/* Return a malloc'd string containing the canonical hostname associated with + HOST, or NULL if a canonical name cannot be determined. On NULL return, + if CHERROR is not NULL, set *CHERROR to an error code as returned by + getaddrinfo(). Use ch_strerror_r() or gai_strerror() to convert a *CHERROR + value to a string suitable for error messages. + + WARNINGS + HOST must be a string representation of a resolvable name for this host. + Strings containing an IP address in dotted decimal notation will be + returned as-is, without further resolution. + + The use of the word "canonical" in this context is unfortunate but + entrenched. The value returned by this function will be the end result + of the resolution of any CNAME chains in the DNS. There may only be one + such value for any given hostname, though the actual IP address + referenced by this value and the device using that IP address may each + actually have any number of such "canonical" hostnames. See the POSIX + getaddrinfo spec <http://www.opengroup.org/susv3xsh/getaddrinfo.html">, + RFC 1034 <http://www.faqs.org/rfcs/rfc1034.html>, & RFC 2181 + <http://www.faqs.org/rfcs/rfc2181.html> for more on what this confusing + term really refers to. */ +char * +canon_host_r (char const *host, int *cherror) { - int i; - for (i = 1; i < argc; i++) + char *retval = NULL; + static struct addrinfo hints; + struct addrinfo *res = NULL; + int status; + + hints.ai_flags = AI_CANONNAME; + status = getaddrinfo (host, NULL, &hints, &res); + if (!status) { - char *s = canon_host (argv[i]); - printf ("%s: %s\n", argv[i], (s ? s : "<undef>")); + retval = strdup (res->ai_canonname); + if (!retval && cherror) + *cherror = EAI_MEMORY; + freeaddrinfo (res); } - exit (0); + else if (cherror) + *cherror = status; + + return retval; +} + +/* Return a string describing the last error encountered by canon_host. */ +const char * +ch_strerror (void) +{ + return gai_strerror (last_cherror); } -#endif /* TEST_CANON_HOST */ Index: lib/getline.c =================================================================== RCS file: /fetish/cu/lib/getline.c,v retrieving revision 1.15 diff -p -u -r1.15 getline.c --- lib/getline.c 14 May 2005 07:58:06 -0000 1.15 +++ lib/getline.c 22 Sep 2005 06:44:10 -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, [EMAIL PROTECTED] */ +/* Written by Simon Josefsson. */ -#if HAVE_CONFIG_H +#ifdef 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: /fetish/cu/lib/getline.h,v retrieving revision 1.14 diff -p -u -r1.14 getline.h --- lib/getline.h 14 May 2005 07:58:06 -0000 1.14 +++ lib/getline.h 22 Sep 2005 06:44:10 -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 */ Index: lib/getpass.c =================================================================== RCS file: /fetish/cu/lib/getpass.c,v retrieving revision 1.10 diff -p -u -r1.10 getpass.c --- lib/getpass.c 14 May 2005 07:58:06 -0000 1.10 +++ lib/getpass.c 22 Sep 2005 06:44:10 -0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 1992-2001, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1992-2001, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify @@ -15,47 +15,32 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include <config.h> #endif -#if !_LIBC -# include "getpass.h" -#endif +#include "getpass.h" -#if _LIBC -# define HAVE_STDIO_EXT_H 1 -#endif +#include <stdio.h> + +#if !defined _WIN32 #include <stdbool.h> -#include <stdio.h> #if HAVE_STDIO_EXT_H # include <stdio_ext.h> -#else -# define __fsetlocking(stream, type) /* empty */ #endif -#if !_LIBC -# include "getline.h" +#if !HAVE___FSETLOCKING +# define __fsetlocking(stream, type) /* empty */ #endif -#include <termios.h> -#include <unistd.h> - -#if _LIBC -# include <wchar.h> +#if HAVE_TERMIOS_H +# include <termios.h> #endif -#if _LIBC -# define NOTCANCEL_MODE "c" -#else -# define NOTCANCEL_MODE -#endif +#include "getline.h" -#if _LIBC -# define flockfile(s) _IO_flockfile (s) -# define funlockfile(s) _IO_funlockfile (s) -#elif USE_UNLOCKED_IO +#if USE_UNLOCKED_IO # include "unlocked-io.h" #else # if !HAVE_DECL_FFLUSH_UNLOCKED @@ -80,18 +65,6 @@ # endif #endif -#if _LIBC -# include <bits/libc-lock.h> -#else -# define __libc_cleanup_push(function, arg) /* empty */ -# define __libc_cleanup_pop(execute) /* empty */ -#endif - -#if !_LIBC -# define __getline getline -# define __tcgetattr tcgetattr -#endif - /* It is desirable to use this bit on systems that have it. The only bit of terminal state we want to twiddle is echoing, which is done in software; there is no need to change the state of the terminal @@ -114,7 +87,7 @@ getpass (const char *prompt) FILE *tty; FILE *in, *out; struct termios s, t; - bool tty_changed; + bool tty_changed = false; static char *buf; static size_t bufsize; ssize_t nread; @@ -122,7 +95,7 @@ getpass (const char *prompt) /* Try to write to and read from the terminal if we can. If we can't open the terminal, use stderr and stdin. */ - tty = fopen ("/dev/tty", "w+" NOTCANCEL_MODE); + tty = fopen ("/dev/tty", "w+"); if (tty == NULL) { in = stdin; @@ -136,39 +109,26 @@ getpass (const char *prompt) out = in = tty; } - /* Make sure the stream we opened is closed even if the thread is - canceled. */ - __libc_cleanup_push (call_fclose, tty); - flockfile (out); /* Turn echoing off if it is on now. */ - - if (__tcgetattr (fileno (in), &t) == 0) +#if HAVE_TCGETATTR + if (tcgetattr (fileno (in), &t) == 0) { /* Save the old one. */ s = t; /* Tricky, tricky. */ - t.c_lflag &= ~(ECHO|ISIG); - tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0); + t.c_lflag &= ~(ECHO | ISIG); + tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0); } - else - tty_changed = false; +#endif /* Write the prompt. */ -#ifdef USE_IN_LIBIO - if (_IO_fwide (out, 0) > 0) - __fwprintf (out, L"%s", prompt); - else -#endif - fputs_unlocked (prompt, out); + fputs_unlocked (prompt, out); fflush_unlocked (out); /* Read the password. */ - nread = __getline (&buf, &bufsize, in); - -#if !_LIBC - /* As far as is known, glibc doesn't need this no-op fseek. */ + nread = getline (&buf, &bufsize, in); /* According to the C standard, input may not be followed by output on the same stream without an intervening call to a file @@ -180,7 +140,6 @@ getpass (const char *prompt) from POSIX version to POSIX version, so play it safe and invoke fseek even if in != out. */ fseek (out, 0, SEEK_CUR); -#endif if (buf != NULL) { @@ -193,25 +152,75 @@ getpass (const char *prompt) if (tty_changed) { /* Write the newline that was not echoed. */ -#ifdef USE_IN_LIBIO - if (_IO_fwide (out, 0) > 0) - putwc_unlocked (L'\n', out); - else -#endif - putc_unlocked ('\n', out); + putc_unlocked ('\n', out); } } } /* Restore the original setting. */ +#if HAVE_TCSETATTR if (tty_changed) - (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s); + tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s); +#endif funlockfile (out); - __libc_cleanup_pop (0); - call_fclose (tty); return buf; } + +#else /* WIN32 */ + +/* Windows implementation by Martin Lambers <[EMAIL PROTECTED]>, + improved by Simon Josefsson. */ + +/* For PASS_MAX. */ +#include <limits.h> + +#ifndef PASS_MAX +# define PASS_MAX 512 +#endif + +char * +getpass (const char *prompt) +{ + char getpassbuf[PASS_MAX + 1]; + size_t i = 0; + int c; + + if (prompt) + { + fputs (prompt, stderr); + fflush (stderr); + } + + for (;;) + { + c = _getch (); + if (c == '\r') + { + getpassbuf[i] = '\0'; + break; + } + else if (i < PASS_MAX) + { + getpassbuf[i++] = c; + } + + if (i >= PASS_MAX) + { + getpassbuf[i] = '\0'; + break; + } + } + + if (prompt) + { + fputs ("\r\n", stderr); + fflush (stderr); + } + + return strdup (getpassbuf); +} +#endif Index: lib/strcasecmp.c =================================================================== RCS file: /fetish/cu/lib/strcasecmp.c,v retrieving revision 1.6 diff -p -u -r1.6 strcasecmp.c --- lib/strcasecmp.c 14 May 2005 07:58:07 -0000 1.6 +++ lib/strcasecmp.c 22 Sep 2005 06:44:10 -0000 @@ -1,5 +1,7 @@ -/* strcasecmp.c -- case insensitive string comparator - Copyright (C) 1998, 1999 Free Software Foundation, Inc. +/* Case-insensitive string comparison function. + Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc. + Written by Bruno Haible <[EMAIL PROTECTED]>, 2005, + based on earlier glibc code. 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 @@ -15,52 +17,82 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include <config.h> #endif -#ifdef LENGTH_LIMIT -# define STRXCASECMP_FUNCTION strncasecmp -# define STRXCASECMP_DECLARE_N , size_t n -# define LENGTH_LIMIT_EXPR(Expr) Expr -#else -# define STRXCASECMP_FUNCTION strcasecmp -# define STRXCASECMP_DECLARE_N /* empty */ -# define LENGTH_LIMIT_EXPR(Expr) 0 -#endif +/* Specification. */ +#include "strcase.h" -#include <stddef.h> #include <ctype.h> -#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) +#if HAVE_MBRTOWC +# include "mbuiter.h" +#endif -/* Compare {{no more than N characters of }}strings S1 and S2, - ignoring case, returning less than, equal to or - greater than zero if S1 is lexicographically less - than, equal to or greater than S2. */ +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. + Note: This function may, in multibyte locales, return 0 for strings of + different lengths! */ int -STRXCASECMP_FUNCTION (const char *s1, const char *s2 STRXCASECMP_DECLARE_N) +strcasecmp (const char *s1, const char *s2) { - register const unsigned char *p1 = (const unsigned char *) s1; - register const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - if (p1 == p2 || LENGTH_LIMIT_EXPR (n == 0)) + if (s1 == s2) return 0; - do + /* Be careful not to look at the entire extent of s1 or s2 until needed. + This is useful because when two strings differ, the difference is + most often already in the very few first characters. */ +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) { - c1 = TOLOWER (*p1); - c2 = TOLOWER (*p2); + mbui_iterator_t iter1; + mbui_iterator_t iter2; - if (LENGTH_LIMIT_EXPR (--n == 0) || c1 == '\0') - break; + mbui_init (iter1, s1); + mbui_init (iter2, s2); - ++p1; - ++p2; + while (mbui_avail (iter1) && mbui_avail (iter2)) + { + int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2)); + + if (cmp != 0) + return cmp; + + mbui_advance (iter1); + mbui_advance (iter2); + } + if (mbui_avail (iter1)) + /* s2 terminated before s1. */ + return 1; + if (mbui_avail (iter2)) + /* s1 terminated before s2. */ + return -1; + return 0; } - while (c1 == c2); + else +#endif + { + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + do + { + c1 = TOLOWER (*p1); + c2 = TOLOWER (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); - return c1 - c2; + return c1 - c2; + } } Index: lib/strncasecmp.c =================================================================== RCS file: /fetish/cu/lib/strncasecmp.c,v retrieving revision 1.4 diff -p -u -r1.4 strncasecmp.c --- lib/strncasecmp.c 2 Jan 1999 15:55:44 -0000 1.4 +++ lib/strncasecmp.c 22 Sep 2005 06:44:10 -0000 @@ -1,2 +1,58 @@ -#define LENGTH_LIMIT -#include "strcasecmp.c" +/* strncasecmp.c -- case insensitive string comparator + Copyright (C) 1998, 1999 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. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Specification. */ +#include "strcase.h" + +#include <ctype.h> + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* Compare no more than N bytes of strings S1 and S2, + ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less + than, equal to or greater than S2. */ + +int +strncasecmp (const char *s1, const char *s2, size_t n) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = TOLOWER (*p1); + c2 = TOLOWER (*p2); + + if (--n == 0 || c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + return c1 - c2; +} Index: lib/strstr.c =================================================================== RCS file: /fetish/cu/lib/strstr.c,v retrieving revision 1.12 diff -p -u -r1.12 strstr.c --- lib/strstr.c 14 May 2005 07:58:07 -0000 1.12 +++ lib/strstr.c 22 Sep 2005 06:44:10 -0000 @@ -1,119 +1,128 @@ -/* Copyright (C) 1994, 1999, 2002-2003 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Searching in a string. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Bruno Haible <[EMAIL PROTECTED]>, 2005. + + 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. */ - -/* - * My personal strstr() implementation that beats most other algorithms. - * Until someone tells me otherwise, I assume that this is the - * fastest implementation of strstr() in C. - * I deliberately chose not to comment it. You should have at least - * as much fun trying to understand it, as I had to write it :-). - * - * Stephen R. van den Berg, [EMAIL PROTECTED] */ - -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include <config.h> #endif -#include <string.h> +/* Specification. */ +#include "strstr.h" -typedef unsigned chartype; +#include <stddef.h> /* for NULL */ -#undef strstr +#if HAVE_MBRTOWC +# include "mbuiter.h" +#endif +/* Find the first occurrence of NEEDLE in HAYSTACK. */ char * -strstr (const char *phaystack, const char *pneedle) +strstr (const char *haystack, const char *needle) { - register const unsigned char *haystack, *needle; - register chartype b, c; + /* Be careful not to look at the entire extent of haystack or needle + until needed. This is useful because of these two cases: + - haystack may be very long, and a match of needle found early, + - needle may be very long, and not even a short initial segment of + needle may be found in haystack. */ +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) + { + mbui_iterator_t iter_needle; - haystack = (const unsigned char *) phaystack; - needle = (const unsigned char *) pneedle; + mbui_init (iter_needle, needle); + if (mbui_avail (iter_needle)) + { + mbui_iterator_t iter_haystack; - b = *needle; - if (b != '\0') + mbui_init (iter_haystack, haystack); + for (;; mbui_advance (iter_haystack)) + { + if (!mbui_avail (iter_haystack)) + /* No match. */ + return NULL; + + if (mb_equal (mbui_cur (iter_haystack), mbui_cur (iter_needle))) + /* The first character matches. */ + { + mbui_iterator_t rhaystack; + mbui_iterator_t rneedle; + + memcpy (&rhaystack, &iter_haystack, sizeof (mbui_iterator_t)); + mbui_advance (rhaystack); + + mbui_init (rneedle, needle); + if (!mbui_avail (rneedle)) + abort (); + mbui_advance (rneedle); + + for (;; mbui_advance (rhaystack), mbui_advance (rneedle)) + { + if (!mbui_avail (rneedle)) + /* Found a match. */ + return (char *) mbui_cur_ptr (iter_haystack); + if (!mbui_avail (rhaystack)) + /* No match. */ + return NULL; + if (!mb_equal (mbui_cur (rhaystack), mbui_cur (rneedle))) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; + } + else +#endif { - haystack--; /* possible ANSI violation */ - do + if (*needle != '\0') { - c = *++haystack; - if (c == '\0') - goto ret0; - } - while (c != b); + /* Speed up the following searches of needle by caching its first + character. */ + char b = *needle++; - c = *++needle; - if (c == '\0') - goto foundneedle; - ++needle; - goto jin; - - for (;;) - { - register chartype a; - register const unsigned char *rhaystack, *rneedle; - - do + for (;; haystack++) { - a = *++haystack; - if (a == '\0') - goto ret0; - if (a == b) - break; - a = *++haystack; - if (a == '\0') - goto ret0; -shloop:; } - while (a != b); - -jin: a = *++haystack; - if (a == '\0') - goto ret0; - - if (a != c) - goto shloop; - - rhaystack = haystack-- + 1; - rneedle = needle; - a = *rneedle; - - if (*rhaystack == a) - do - { - if (a == '\0') - goto foundneedle; - ++rhaystack; - a = *++needle; - if (*rhaystack != a) - break; - if (a == '\0') - goto foundneedle; - ++rhaystack; - a = *++needle; - } - while (*rhaystack == a); - - needle = rneedle; /* took the register-poor approach */ - - if (a == '\0') - break; - } + if (*haystack == '\0') + /* No match. */ + return NULL; + if (*haystack == b) + /* The first character matches. */ + { + const char *rhaystack = haystack + 1; + const char *rneedle = needle; + + for (;; rhaystack++, rneedle++) + { + if (*rneedle == '\0') + /* Found a match. */ + return (char *) haystack; + if (*rhaystack == '\0') + /* No match. */ + return NULL; + if (*rhaystack != *rneedle) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; } -foundneedle: - return (char*) haystack; -ret0: - return 0; } Index: m4/canon-host.m4 =================================================================== RCS file: /fetish/cu/m4/canon-host.m4,v retrieving revision 1.5 diff -p -u -r1.5 canon-host.m4 --- m4/canon-host.m4 29 Jan 2005 00:16:39 -0000 1.5 +++ m4/canon-host.m4 22 Sep 2005 06:44:10 -0000 @@ -1,4 +1,4 @@ -# canon-host.m4 serial 6 +# canon-host.m4 serial 7 dnl Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -6,18 +6,11 @@ dnl with or without modifications, as lo AC_DEFUN([gl_CANON_HOST], [ - AC_LIBSOURCES([canon-host.c]) + AC_LIBSOURCES([canon-host.c, canon-host.h]) AC_LIBOBJ([canon-host]) + gl_PREREQ_CANON_HOST +]) - dnl Prerequisites of lib/canon-host.c. - AC_CHECK_HEADERS_ONCE(unistd.h) - AC_CHECK_HEADERS(netdb.h sys/socket.h netinet/in.h arpa/inet.h) - - dnl Add any libraries as early as possible. - dnl In particular, inet_ntoa needs -lnsl at least on Solaris 2.5.1, - dnl so we have to add -lnsl to LIBS before checking for that function. - AC_SEARCH_LIBS(gethostbyname, [inet nsl]) - - dnl These come from -lnsl on Solaris 2.5.1. - AC_CHECK_FUNCS(getaddrinfo gethostbyname gethostbyaddr inet_ntoa) +AC_DEFUN([gl_PREREQ_CANON_HOST], [ + AC_REQUIRE([gl_GETADDRINFO]) ]) Index: m4/getline.m4 =================================================================== RCS file: /fetish/cu/m4/getline.m4,v retrieving revision 1.14 diff -p -u -r1.14 getline.m4 --- m4/getline.m4 29 Jan 2005 00:16:39 -0000 1.14 +++ m4/getline.m4 22 Sep 2005 06:44:11 -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@&[EMAIL PROTECTED] " 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: m4/mbrtowc.m4 =================================================================== RCS file: /fetish/cu/m4/mbrtowc.m4,v retrieving revision 1.9 diff -p -u -r1.9 mbrtowc.m4 --- m4/mbrtowc.m4 22 Jan 2005 06:25:53 -0000 1.9 +++ m4/mbrtowc.m4 22 Sep 2005 06:44:11 -0000 @@ -1,5 +1,5 @@ -# mbrtowc.m4 serial 7 -dnl Copyright (C) 2001-2002, 2004 Free Software Foundation, Inc. +# mbrtowc.m4 serial 8 +dnl Copyright (C) 2001-2002, 2004-2005 Free Software Foundation, Inc. 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. @@ -7,19 +7,25 @@ dnl with or without modifications, as lo dnl From Paul Eggert dnl This file can be removed, and gl_FUNC_MBRTOWC replaced with -dnl AC_FUNC_MBRTOWC, when autoconf 2.57 can be assumed everywhere. +dnl AC_FUNC_MBRTOWC, when autoconf 2.60 can be assumed everywhere. AC_DEFUN([gl_FUNC_MBRTOWC], [ + dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], gl_cv_func_mbrtowc, - [AC_TRY_LINK( - [#include <wchar.h>], - [mbstate_t state; return ! (sizeof state && mbrtowc);], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <wchar.h>]], + [[wchar_t wc; + char const s[] = ""; + size_t n = 1; + mbstate_t state; + return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], gl_cv_func_mbrtowc=yes, gl_cv_func_mbrtowc=no)]) if test $gl_cv_func_mbrtowc = yes; then - AC_DEFINE(HAVE_MBRTOWC, 1, + AC_DEFINE([HAVE_MBRTOWC], 1, [Define to 1 if mbrtowc and mbstate_t are properly declared.]) fi ]) Index: m4/strcase.m4 =================================================================== RCS file: /fetish/cu/m4/strcase.m4,v retrieving revision 1.2 diff -p -u -r1.2 strcase.m4 --- m4/strcase.m4 22 Jan 2005 06:25:53 -0000 1.2 +++ m4/strcase.m4 22 Sep 2005 06:44:11 -0000 @@ -1,5 +1,5 @@ -# strcase.m4 serial 1 -dnl Copyright (C) 2002 Free Software Foundation, Inc. +# strcase.m4 serial 2 +dnl Copyright (C) 2002, 2005 Free Software Foundation, Inc. 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. @@ -12,10 +12,11 @@ AC_DEFUN([gl_STRCASE], AC_DEFUN([gl_FUNC_STRCASECMP], [ - AC_REPLACE_FUNCS(strcasecmp) - if test $ac_cv_func_strcasecmp = no; then - gl_PREREQ_STRCASECMP - fi + dnl No known system has a strcasecmp() function that works correctly in + dnl multibyte locales. Therefore we use our version always. + AC_LIBOBJ(strcasecmp) + AC_DEFINE(strcasecmp, rpl_strcasecmp, [Define to rpl_strcasecmp always.]) + gl_PREREQ_STRCASECMP ]) AC_DEFUN([gl_FUNC_STRNCASECMP], @@ -28,7 +29,7 @@ AC_DEFUN([gl_FUNC_STRNCASECMP], # Prerequisites of lib/strcasecmp.c. AC_DEFUN([gl_PREREQ_STRCASECMP], [ - : + gl_FUNC_MBRTOWC ]) # Prerequisites of lib/strncasecmp.c. Index: m4/strstr.m4 =================================================================== RCS file: /fetish/cu/m4/strstr.m4,v retrieving revision 1.3 diff -p -u -r1.3 strstr.m4 --- m4/strstr.m4 22 Jan 2005 06:25:53 -0000 1.3 +++ m4/strstr.m4 22 Sep 2005 06:44:11 -0000 @@ -1,16 +1,18 @@ -# strstr.m4 serial 2 -dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. +# strstr.m4 serial 4 +dnl Copyright (C) 2002-2003, 2005 Free Software Foundation, Inc. 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_DEFUN([gl_FUNC_STRSTR], [ - AC_REPLACE_FUNCS(strstr) - if test $ac_cv_func_strstr = no; then - gl_PREREQ_STRSTR - fi + dnl No known system has a strstr() function that works correctly in + dnl multibyte locales. Therefore we use our version always. + AC_LIBOBJ(strstr) + gl_PREREQ_STRSTR ]) # Prerequisites of lib/strstr.c. -AC_DEFUN([gl_PREREQ_STRSTR], [:]) +AC_DEFUN([gl_PREREQ_STRSTR], [ + gl_FUNC_MBRTOWC +]) _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils