diff options
33 files changed, 1085 insertions, 12 deletions
diff --git a/Makefile.in b/Makefile.in index dbb93178..bdbff250 100644 --- a/Makefile.in +++ b/Makefile.in @@ -259,6 +259,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ @@ -1627,6 +1627,7 @@ m4_include([gnulib/m4/stdint_h.m4]) m4_include([gnulib/m4/stdio_h.m4]) m4_include([gnulib/m4/stdlib_h.m4]) m4_include([gnulib/m4/strcase.m4]) +m4_include([gnulib/m4/strcasestr.m4]) m4_include([gnulib/m4/strchrnul.m4]) m4_include([gnulib/m4/strdup.m4]) m4_include([gnulib/m4/strerror.m4]) diff --git a/config.h.in b/config.h.in index c6152191..06ba8af7 100644 --- a/config.h.in +++ b/config.h.in @@ -323,6 +323,9 @@ /* Define to 1 when the gnulib module stat should be tested. */ #undef GNULIB_TEST_STAT +/* Define to 1 when the gnulib module strcasestr should be tested. */ +#undef GNULIB_TEST_STRCASESTR + /* Define to 1 when the gnulib module strchrnul should be tested. */ #undef GNULIB_TEST_STRCHRNUL @@ -1610,6 +1613,9 @@ /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP +/* Define to 1 if you have the `strcasestr' function. */ +#undef HAVE_STRCASESTR + /* Define to 1 if you have the `strchrnul' function. */ #undef HAVE_STRCHRNUL @@ -15196,6 +15196,8 @@ fi # Code from module stdio: # Code from module stdlib: # Code from module strcase: + # Code from module strcasestr: + # Code from module strcasestr-simple: # Code from module strchrnul: # Code from module strdup-posix: # Code from module streq: @@ -26293,6 +26295,103 @@ fi + for ac_func in strcasestr +do : + ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" +if test "x$ac_cv_func_strcasestr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRCASESTR 1 +_ACEOF + +fi +done + + if test $ac_cv_func_strcasestr = no; then + HAVE_STRCASESTR=0 + else + if test "$gl_cv_func_memchr_works" != yes; then + REPLACE_STRCASESTR=1 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strcasestr works" >&5 +$as_echo_n "checking whether strcasestr works... " >&6; } +if ${gl_cv_func_strcasestr_works_always+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef __GNU_LIBRARY__ + #include <features.h> + #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ + || defined __UCLIBC__ + Lucky user + #endif +#elif defined __CYGWIN__ + #include <cygwin/version.h> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7) + Lucky user + #endif +#else + Lucky user +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Lucky user" >/dev/null 2>&1; then : + gl_cv_func_strcasestr_works_always="guessing yes" +else + gl_cv_func_strcasestr_works_always="guessing no" +fi +rm -f conftest* + + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <string.h> /* for strcasestr */ +#define P "_EF_BF_BD" +#define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P +#define NEEDLE P P P P P + +int +main () +{ +return !!strcasestr (HAYSTACK, NEEDLE); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_strcasestr_works_always=yes +else + gl_cv_func_strcasestr_works_always=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_strcasestr_works_always" >&5 +$as_echo "$gl_cv_func_strcasestr_works_always" >&6; } + case "$gl_cv_func_strcasestr_works_always" in + *yes) ;; + *) + REPLACE_STRCASESTR=1 + ;; + esac + fi + fi + + + + + + + ac_fn_c_check_decl "$LINENO" "strdup" "ac_cv_have_decl_strdup" "$ac_includes_default" if test "x$ac_cv_have_decl_strdup" = xyes; then : ac_have_decl=1 @@ -39143,6 +39242,245 @@ _ACEOF fi + if test $HAVE_STRCASESTR = 1 && test $REPLACE_STRCASESTR = 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strcasestr works in linear time" >&5 +$as_echo_n "checking whether strcasestr works in linear time... " >&6; } +if ${gl_cv_func_strcasestr_linear+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <features.h> +#ifdef __GNU_LIBRARY__ + #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ + && !defined __UCLIBC__ + Lucky user + #endif +#endif +#ifdef __CYGWIN__ + #include <cygwin/version.h> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7) + Lucky user + #endif +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Lucky user" >/dev/null 2>&1; then : + gl_cv_func_strcasestr_linear="guessing yes" +else + gl_cv_func_strcasestr_linear="guessing no" +fi +rm -f conftest* + + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <signal.h> /* for signal */ +#include <string.h> /* for strcasestr */ +#include <stdlib.h> /* for malloc */ +#include <unistd.h> /* for alarm */ +static void quit (int sig) { exit (sig + 128); } + +int +main () +{ + + int result = 0; + size_t m = 1000000; + char *haystack = (char *) malloc (2 * m + 2); + char *needle = (char *) malloc (m + 2); + /* Failure to compile this test due to missing alarm is okay, + since all such platforms (mingw) also lack strcasestr. */ + signal (SIGALRM, quit); + alarm (5); + /* Check for quadratic performance. */ + if (haystack && needle) + { + memset (haystack, 'A', 2 * m); + haystack[2 * m] = 'B'; + haystack[2 * m + 1] = 0; + memset (needle, 'A', m); + needle[m] = 'B'; + needle[m + 1] = 0; + if (!strcasestr (haystack, needle)) + result |= 1; + } + return result; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_strcasestr_linear=yes +else + gl_cv_func_strcasestr_linear=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_strcasestr_linear" >&5 +$as_echo "$gl_cv_func_strcasestr_linear" >&6; } + case "$gl_cv_func_strcasestr_linear" in + *yes) ;; + *) + REPLACE_STRCASESTR=1 + ;; + esac + fi + + if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS strcasestr.$ac_objext" + + + : + + fi + + + + + + + for ac_func in strcasestr +do : + ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" +if test "x$ac_cv_func_strcasestr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRCASESTR 1 +_ACEOF + +fi +done + + if test $ac_cv_func_strcasestr = no; then + HAVE_STRCASESTR=0 + else + if test "$gl_cv_func_memchr_works" != yes; then + REPLACE_STRCASESTR=1 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strcasestr works" >&5 +$as_echo_n "checking whether strcasestr works... " >&6; } +if ${gl_cv_func_strcasestr_works_always+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef __GNU_LIBRARY__ + #include <features.h> + #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ + || defined __UCLIBC__ + Lucky user + #endif +#elif defined __CYGWIN__ + #include <cygwin/version.h> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7) + Lucky user + #endif +#else + Lucky user +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Lucky user" >/dev/null 2>&1; then : + gl_cv_func_strcasestr_works_always="guessing yes" +else + gl_cv_func_strcasestr_works_always="guessing no" +fi +rm -f conftest* + + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <string.h> /* for strcasestr */ +#define P "_EF_BF_BD" +#define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P +#define NEEDLE P P P P P + +int +main () +{ +return !!strcasestr (HAYSTACK, NEEDLE); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_strcasestr_works_always=yes +else + gl_cv_func_strcasestr_works_always=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_strcasestr_works_always" >&5 +$as_echo "$gl_cv_func_strcasestr_works_always" >&6; } + case "$gl_cv_func_strcasestr_works_always" in + *yes) ;; + *) + REPLACE_STRCASESTR=1 + ;; + esac + fi + fi + + if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS strcasestr.$ac_objext" + + + : + + fi + + + + + + GNULIB_STRCASESTR=1 + + + + + +$as_echo "#define GNULIB_TEST_STRCASESTR 1" >>confdefs.h + + + + + for ac_func in strchrnul diff --git a/docs/Makefile.in b/docs/Makefile.in index 67481429..ea477605 100644 --- a/docs/Makefile.in +++ b/docs/Makefile.in @@ -246,6 +246,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/gnulib/lib/Makefile.am b/gnulib/lib/Makefile.am index e8afc556..d96bdf75 100644 --- a/gnulib/lib/Makefile.am +++ b/gnulib/lib/Makefile.am @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --po-base=gnulib/po --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl --po-domain=man-db --no-vc-files argp canonicalize closedir dirent dirname error flock fnmatch-gnu fstat futimens getline getopt-gnu gettext gitlog-to-changelog glob gnupload idpriv-drop idpriv-droptemp lib-ignore localcharset lock minmax mkdtemp mkstemp nanosleep nonblocking openat opendir regex rename setenv sigaction signal sigprocmask stat-time strerror strsep timespec unsetenv utimens warnings xalloc xgetcwd xstrndup xvasprintf +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --po-base=gnulib/po --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl --po-domain=man-db --no-vc-files argp canonicalize closedir dirent dirname error flock fnmatch-gnu fstat futimens getline getopt-gnu gettext gitlog-to-changelog glob gnupload idpriv-drop idpriv-droptemp lib-ignore localcharset lock minmax mkdtemp mkstemp nanosleep nonblocking openat opendir regex rename setenv sigaction signal sigprocmask stat-time strcasestr strerror strsep timespec unsetenv utimens warnings xalloc xgetcwd xstrndup xvasprintf AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects @@ -1878,6 +1878,15 @@ EXTRA_libgnu_la_SOURCES += strcasecmp.c strncasecmp.c ## end gnulib module strcase +## begin gnulib module strcasestr-simple + + +EXTRA_DIST += str-two-way.h strcasestr.c + +EXTRA_libgnu_la_SOURCES += strcasestr.c + +## end gnulib module strcasestr-simple + ## begin gnulib module strchrnul diff --git a/gnulib/lib/Makefile.in b/gnulib/lib/Makefile.in index b7642d0a..a0e47c64 100644 --- a/gnulib/lib/Makefile.in +++ b/gnulib/lib/Makefile.in @@ -35,7 +35,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --po-base=gnulib/po --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl --po-domain=man-db --no-vc-files argp canonicalize closedir dirent dirname error flock fnmatch-gnu fstat futimens getline getopt-gnu gettext gitlog-to-changelog glob gnupload idpriv-drop idpriv-droptemp lib-ignore localcharset lock minmax mkdtemp mkstemp nanosleep nonblocking openat opendir regex rename setenv sigaction signal sigprocmask stat-time strerror strsep timespec unsetenv utimens warnings xalloc xgetcwd xstrndup xvasprintf +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --po-base=gnulib/po --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl --po-domain=man-db --no-vc-files argp canonicalize closedir dirent dirname error flock fnmatch-gnu fstat futimens getline getopt-gnu gettext gitlog-to-changelog glob gnupload idpriv-drop idpriv-droptemp lib-ignore localcharset lock minmax mkdtemp mkstemp nanosleep nonblocking openat opendir regex rename setenv sigaction signal sigprocmask stat-time strcasestr strerror strsep timespec unsetenv utimens warnings xalloc xgetcwd xstrndup xvasprintf @@ -271,6 +271,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ @@ -1490,14 +1491,15 @@ EXTRA_DIST = alloca.c alloca.in.h areadlink.h openat-priv.h \ $(top_srcdir)/build-aux/snippet/warn-on-use.h w32sock.h stat.c \ stat-time.h stdalign.in.h stdarg.in.h stdbool.in.h stddef.in.h \ stdint.in.h stdio.in.h stdlib.in.h strcasecmp.c strncasecmp.c \ - strchrnul.c strchrnul.valgrind strdup.c streq.h strerror.c \ - strerror-override.c strerror-override.h string.in.h \ - strings.in.h strndup.c strnlen.c strsep.c sys_file.in.h \ - sys_ioctl.in.h sys_select.in.h sys_socket.in.h sys_stat.in.h \ - sys_time.in.h sys_types.in.h sys_uio.in.h sysexits.in.h \ - tempname.h $(top_srcdir)/build-aux/config.rpath time.in.h \ - timespec.h unistd.in.h unistd--.h unistd-safer.h unsetenv.c \ - utimens.h asnprintf.c float+.h printf-args.c printf-args.h \ + str-two-way.h strcasestr.c strchrnul.c strchrnul.valgrind \ + strdup.c streq.h strerror.c strerror-override.c \ + strerror-override.h string.in.h strings.in.h strndup.c \ + strnlen.c strsep.c sys_file.in.h sys_ioctl.in.h \ + sys_select.in.h sys_socket.in.h sys_stat.in.h sys_time.in.h \ + sys_types.in.h sys_uio.in.h sysexits.in.h tempname.h \ + $(top_srcdir)/build-aux/config.rpath time.in.h timespec.h \ + unistd.in.h unistd--.h unistd-safer.h unsetenv.c utimens.h \ + asnprintf.c float+.h printf-args.c printf-args.h \ printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h \ asprintf.c vasprintf.c verify.h vsnprintf.c wchar.in.h \ wcrtomb.c wctype.in.h xalloc.h xalloc-oversized.h xgetcwd.h \ @@ -1574,7 +1576,7 @@ EXTRA_libgnu_la_SOURCES = alloca.c openat-proc.c btowc.c \ regcomp.c regex.c regex_internal.c regexec.c rename.c \ rewinddir.c rmdir.c secure_getenv.c select.c setenv.c \ sigaction.c sigprocmask.c sleep.c stat.c strcasecmp.c \ - strncasecmp.c strchrnul.c strdup.c strerror.c \ + strncasecmp.c strcasestr.c strchrnul.c strdup.c strerror.c \ strerror-override.c strndup.c strnlen.c strsep.c unsetenv.c \ asnprintf.c printf-args.c printf-parse.c vasnprintf.c \ asprintf.c vasprintf.c vsnprintf.c wcrtomb.c @@ -1788,6 +1790,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio-read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio-write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasecmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasestr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchrnul.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strdup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strerror-override.Plo@am__quote@ diff --git a/gnulib/lib/str-two-way.h b/gnulib/lib/str-two-way.h new file mode 100644 index 00000000..49ee7469 --- /dev/null +++ b/gnulib/lib/str-two-way.h @@ -0,0 +1,452 @@ +/* Byte-wise substring search, using the Two-Way algorithm. + Copyright (C) 2008-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Eric Blake <ebb9@byu.net>, 2008. + + 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, see <http://www.gnu.org/licenses/>. */ + +/* Before including this file, you need to include <config.h> and + <string.h>, and define: + RESULT_TYPE A macro that expands to the return type. + AVAILABLE(h, h_l, j, n_l) + A macro that returns nonzero if there are + at least N_L bytes left starting at H[J]. + H is 'unsigned char *', H_L, J, and N_L + are 'size_t'; H_L is an lvalue. For + NUL-terminated searches, H_L can be + modified each iteration to avoid having + to compute the end of H up front. + + For case-insensitivity, you may optionally define: + CMP_FUNC(p1, p2, l) A macro that returns 0 iff the first L + characters of P1 and P2 are equal. + CANON_ELEMENT(c) A macro that canonicalizes an element right after + it has been fetched from one of the two strings. + The argument is an 'unsigned char'; the result + must be an 'unsigned char' as well. + + This file undefines the macros documented above, and defines + LONG_NEEDLE_THRESHOLD. +*/ + +#include <limits.h> +#include <stdint.h> + +/* We use the Two-Way string matching algorithm (also known as + Chrochemore-Perrin), which guarantees linear complexity with + constant space. Additionally, for long needles, we also use a bad + character shift table similar to the Boyer-Moore algorithm to + achieve improved (potentially sub-linear) performance. + + See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260, + http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm, + http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.6641&rep=rep1&type=pdf +*/ + +/* Point at which computing a bad-byte shift table is likely to be + worthwhile. Small needles should not compute a table, since it + adds (1 << CHAR_BIT) + NEEDLE_LEN computations of preparation for a + speedup no greater than a factor of NEEDLE_LEN. The larger the + needle, the better the potential performance gain. On the other + hand, on non-POSIX systems with CHAR_BIT larger than eight, the + memory required for the table is prohibitive. */ +#if CHAR_BIT < 10 +# define LONG_NEEDLE_THRESHOLD 32U +#else +# define LONG_NEEDLE_THRESHOLD SIZE_MAX +#endif + +#ifndef MAX +# define MAX(a, b) ((a < b) ? (b) : (a)) +#endif + +#ifndef CANON_ELEMENT +# define CANON_ELEMENT(c) c +#endif +#ifndef CMP_FUNC +# define CMP_FUNC memcmp +#endif + +/* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN. + Return the index of the first byte in the right half, and set + *PERIOD to the global period of the right half. + + The global period of a string is the smallest index (possibly its + length) at which all remaining bytes in the string are repetitions + of the prefix (the last repetition may be a subset of the prefix). + + When NEEDLE is factored into two halves, a local period is the + length of the smallest word that shares a suffix with the left half + and shares a prefix with the right half. All factorizations of a + non-empty NEEDLE have a local period of at least 1 and no greater + than NEEDLE_LEN. + + A critical factorization has the property that the local period + equals the global period. All strings have at least one critical + factorization with the left half smaller than the global period. + And while some strings have more than one critical factorization, + it is provable that with an ordered alphabet, at least one of the + critical factorizations corresponds to a maximal suffix. + + Given an ordered alphabet, a critical factorization can be computed + in linear time, with 2 * NEEDLE_LEN comparisons, by computing the + shorter of two ordered maximal suffixes. The ordered maximal + suffixes are determined by lexicographic comparison while tracking + periodicity. */ +static size_t +critical_factorization (const unsigned char *needle, size_t needle_len, + size_t *period) +{ + /* Index of last byte of left half, or SIZE_MAX. */ + size_t max_suffix, max_suffix_rev; + size_t j; /* Index into NEEDLE for current candidate suffix. */ + size_t k; /* Offset into current period. */ + size_t p; /* Intermediate period. */ + unsigned char a, b; /* Current comparison bytes. */ + + /* Special case NEEDLE_LEN of 1 or 2 (all callers already filtered + out 0-length needles. */ + if (needle_len < 3) + { + *period = 1; + return needle_len - 1; + } + + /* Invariants: + 0 <= j < NEEDLE_LEN - 1 + -1 <= max_suffix{,_rev} < j (treating SIZE_MAX as if it were signed) + min(max_suffix, max_suffix_rev) < global period of NEEDLE + 1 <= p <= global period of NEEDLE + p == global period of the substring NEEDLE[max_suffix{,_rev}+1...j] + 1 <= k <= p + */ + + /* Perform lexicographic search. */ + max_suffix = SIZE_MAX; + j = 0; + k = p = 1; + while (j + k < needle_len) + { + a = CANON_ELEMENT (needle[j + k]); + b = CANON_ELEMENT (needle[max_suffix + k]); + if (a < b) + { + /* Suffix is smaller, period is entire prefix so far. */ + j += k; + k = 1; + p = j - max_suffix; + } + else if (a == b) + { + /* Advance through repetition of the current period. */ + if (k != p) + ++k; + else + { + j += p; + k = 1; + } + } + else /* b < a */ + { + /* Suffix is larger, start over from current location. */ + max_suffix = j++; + k = p = 1; + } + } + *period = p; + + /* Perform reverse lexicographic search. */ + max_suffix_rev = SIZE_MAX; + j = 0; + k = p = 1; + while (j + k < needle_len) + { + a = CANON_ELEMENT (needle[j + k]); + b = CANON_ELEMENT (needle[max_suffix_rev + k]); + if (b < a) + { + /* Suffix is smaller, period is entire prefix so far. */ + j += k; + k = 1; + p = j - max_suffix_rev; + } + else if (a == b) + { + /* Advance through repetition of the current period. */ + if (k != p) + ++k; + else + { + j += p; + k = 1; + } + } + else /* a < b */ + { + /* Suffix is larger, start over from current location. */ + max_suffix_rev = j++; + k = p = 1; + } + } + + /* Choose the shorter suffix. Return the index of the first byte of + the right half, rather than the last byte of the left half. + + For some examples, 'banana' has two critical factorizations, both + exposed by the two lexicographic extreme suffixes of 'anana' and + 'nana', where both suffixes have a period of 2. On the other + hand, with 'aab' and 'bba', both strings have a single critical + factorization of the last byte, with the suffix having a period + of 1. While the maximal lexicographic suffix of 'aab' is 'b', + the maximal lexicographic suffix of 'bba' is 'ba', which is not a + critical factorization. Conversely, the maximal reverse + lexicographic suffix of 'a' works for 'bba', but not 'ab' for + 'aab'. The shorter suffix of the two will always be a critical + factorization. */ + if (max_suffix_rev + 1 < max_suffix + 1) + return max_suffix + 1; + *period = p; + return max_suffix_rev + 1; +} + +/* Return the first location of non-empty NEEDLE within HAYSTACK, or + NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This + method is optimized for NEEDLE_LEN < LONG_NEEDLE_THRESHOLD. + Performance is guaranteed to be linear, with an initialization cost + of 2 * NEEDLE_LEN comparisons. + + If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at + most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. + If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * + HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */ +static RETURN_TYPE +two_way_short_needle (const unsigned char *haystack, size_t haystack_len, + const unsigned char *needle, size_t needle_len) +{ + size_t i; /* Index into current byte of NEEDLE. */ + size_t j; /* Index into current window of HAYSTACK. */ + size_t period; /* The period of the right half of needle. */ + size_t suffix; /* The index of the right half of needle. */ + + /* Factor the needle into two halves, such that the left half is + smaller than the global period, and the right half is + periodic (with a period as large as NEEDLE_LEN - suffix). */ + suffix = critical_factorization (needle, needle_len, &period); + + /* Perform the search. Each iteration compares the right half + first. */ + if (CMP_FUNC (needle, needle + period, suffix) == 0) + { + /* Entire needle is periodic; a mismatch in the left half can + only advance by the period, so use memory to avoid rescanning + known occurrences of the period in the right half. */ + size_t memory = 0; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Scan for matches in right half. */ + i = MAX (suffix, memory); + while (i < needle_len && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (memory < i + 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i + 1 < memory + 1) + return (RETURN_TYPE) (haystack + j); + /* No match, so remember how many repetitions of period + on the right half were scanned. */ + j += period; + memory = needle_len - period; + } + else + { + j += i - suffix + 1; + memory = 0; + } + } + } + else + { + /* The two halves of needle are distinct; no extra memory is + required, and any mismatch results in a maximal shift. */ + period = MAX (suffix, needle_len - suffix) + 1; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Scan for matches in right half. */ + i = suffix; + while (i < needle_len && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (i != SIZE_MAX && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i == SIZE_MAX) + return (RETURN_TYPE) (haystack + j); + j += period; + } + else + j += i - suffix + 1; + } + } + return NULL; +} + +/* Return the first location of non-empty NEEDLE within HAYSTACK, or + NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This + method is optimized for LONG_NEEDLE_THRESHOLD <= NEEDLE_LEN. + Performance is guaranteed to be linear, with an initialization cost + of 3 * NEEDLE_LEN + (1 << CHAR_BIT) operations. + + If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at + most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, + and sublinear performance O(HAYSTACK_LEN / NEEDLE_LEN) is possible. + If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * + HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and + sublinear performance is not possible. */ +static RETURN_TYPE +two_way_long_needle (const unsigned char *haystack, size_t haystack_len, + const unsigned char *needle, size_t needle_len) +{ + size_t i; /* Index into current byte of NEEDLE. */ + size_t j; /* Index into current window of HAYSTACK. */ + size_t period; /* The period of the right half of needle. */ + size_t suffix; /* The index of the right half of needle. */ + size_t shift_table[1U << CHAR_BIT]; /* See below. */ + + /* Factor the needle into two halves, such that the left half is + smaller than the global period, and the right half is + periodic (with a period as large as NEEDLE_LEN - suffix). */ + suffix = critical_factorization (needle, needle_len, &period); + + /* Populate shift_table. For each possible byte value c, + shift_table[c] is the distance from the last occurrence of c to + the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE. + shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0. */ + for (i = 0; i < 1U << CHAR_BIT; i++) + shift_table[i] = needle_len; + for (i = 0; i < needle_len; i++) + shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1; + + /* Perform the search. Each iteration compares the right half + first. */ + if (CMP_FUNC (needle, needle + period, suffix) == 0) + { + /* Entire needle is periodic; a mismatch in the left half can + only advance by the period, so use memory to avoid rescanning + known occurrences of the period in the right half. */ + size_t memory = 0; + size_t shift; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Check the last byte first; if it does not match, then + shift to the next possible match location. */ + shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])]; + if (0 < shift) + { + if (memory && shift < period) + { + /* Since needle is periodic, but the last period has + a byte out of place, there can be no match until + after the mismatch. */ + shift = needle_len - period; + } + memory = 0; + j += shift; + continue; + } + /* Scan for matches in right half. The last byte has + already been matched, by virtue of the shift table. */ + i = MAX (suffix, memory); + while (i < needle_len - 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len - 1 <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (memory < i + 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i + 1 < memory + 1) + return (RETURN_TYPE) (haystack + j); + /* No match, so remember how many repetitions of period + on the right half were scanned. */ + j += period; + memory = needle_len - period; + } + else + { + j += i - suffix + 1; + memory = 0; + } + } + } + else + { + /* The two halves of needle are distinct; no extra memory is + required, and any mismatch results in a maximal shift. */ + size_t shift; + period = MAX (suffix, needle_len - suffix) + 1; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Check the last byte first; if it does not match, then + shift to the next possible match location. */ + shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])]; + if (0 < shift) + { + j += shift; + continue; + } + /* Scan for matches in right half. The last byte has + already been matched, by virtue of the shift table. */ + i = suffix; + while (i < needle_len - 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len - 1 <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (i != SIZE_MAX && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i == SIZE_MAX) + return (RETURN_TYPE) (haystack + j); + j += period; + } + else + j += i - suffix + 1; + } + } + return NULL; +} + +#undef AVAILABLE +#undef CANON_ELEMENT +#undef CMP_FUNC +#undef MAX +#undef RETURN_TYPE diff --git a/gnulib/lib/strcasestr.c b/gnulib/lib/strcasestr.c new file mode 100644 index 00000000..7ac738df --- /dev/null +++ b/gnulib/lib/strcasestr.c @@ -0,0 +1,82 @@ +/* Case-insensitive searching in a string. + Copyright (C) 2005-2014 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 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 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, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +#include <ctype.h> +#include <stdbool.h> +#include <strings.h> + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* Two-Way algorithm. */ +#define RETURN_TYPE char * +#define AVAILABLE(h, h_l, j, n_l) \ + (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ + && ((h_l) = (j) + (n_l))) +#define CANON_ELEMENT(c) TOLOWER (c) +#define CMP_FUNC(p1, p2, l) \ + strncasecmp ((const char *) (p1), (const char *) (p2), l) +#include "str-two-way.h" + +/* Find the first occurrence of NEEDLE in HAYSTACK, using + case-insensitive comparison. This function gives unspecified + results in multibyte locales. */ +char * +strcasestr (const char *haystack_start, const char *needle_start) +{ + const char *haystack = haystack_start; + const char *needle = needle_start; + size_t needle_len; /* Length of NEEDLE. */ + size_t haystack_len; /* Known minimum length of HAYSTACK. */ + bool ok = true; /* True if NEEDLE is prefix of HAYSTACK. */ + + /* Determine length of NEEDLE, and in the process, make sure + HAYSTACK is at least as long (no point processing all of a long + NEEDLE if HAYSTACK is too short). */ + while (*haystack && *needle) + { + ok &= (TOLOWER ((unsigned char) *haystack) + == TOLOWER ((unsigned char) *needle)); + haystack++; + needle++; + } + if (*needle) + return NULL; + if (ok) + return (char *) haystack_start; + needle_len = needle - needle_start; + haystack = haystack_start + 1; + haystack_len = needle_len - 1; + + /* Perform the search. Abstract memory is considered to be an array + of 'unsigned char' values, not an array of 'char' values. See + ISO C 99 section 6.2.6.1. */ + if (needle_len < LONG_NEEDLE_THRESHOLD) + return two_way_short_needle ((const unsigned char *) haystack, + haystack_len, + (const unsigned char *) needle_start, + needle_len); + return two_way_long_needle ((const unsigned char *) haystack, haystack_len, + (const unsigned char *) needle_start, + needle_len); +} + +#undef LONG_NEEDLE_THRESHOLD diff --git a/gnulib/m4/gnulib-cache.m4 b/gnulib/m4/gnulib-cache.m4 index 2c52f580..c031d6b3 100644 --- a/gnulib/m4/gnulib-cache.m4 +++ b/gnulib/m4/gnulib-cache.m4 @@ -27,7 +27,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --po-base=gnulib/po --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl --po-domain=man-db --no-vc-files argp canonicalize closedir dirent dirname error flock fnmatch-gnu fstat futimens getline getopt-gnu gettext gitlog-to-changelog glob gnupload idpriv-drop idpriv-droptemp lib-ignore localcharset lock minmax mkdtemp mkstemp nanosleep nonblocking openat opendir regex rename setenv sigaction signal sigprocmask stat-time strerror strsep timespec unsetenv utimens warnings xalloc xgetcwd xstrndup xvasprintf +# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --po-base=gnulib/po --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl --po-domain=man-db --no-vc-files argp canonicalize closedir dirent dirname error flock fnmatch-gnu fstat futimens getline getopt-gnu gettext gitlog-to-changelog glob gnupload idpriv-drop idpriv-droptemp lib-ignore localcharset lock minmax mkdtemp mkstemp nanosleep nonblocking openat opendir regex rename setenv sigaction signal sigprocmask stat-time strcasestr strerror strsep timespec unsetenv utimens warnings xalloc xgetcwd xstrndup xvasprintf # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) @@ -67,6 +67,7 @@ gl_MODULES([ signal sigprocmask stat-time + strcasestr strerror strsep timespec diff --git a/gnulib/m4/gnulib-comp.m4 b/gnulib/m4/gnulib-comp.m4 index c1cf59f9..02acc547 100644 --- a/gnulib/m4/gnulib-comp.m4 +++ b/gnulib/m4/gnulib-comp.m4 @@ -191,6 +191,8 @@ AC_DEFUN([gl_EARLY], # Code from module stdio: # Code from module stdlib: # Code from module strcase: + # Code from module strcasestr: + # Code from module strcasestr-simple: # Code from module strchrnul: # Code from module strdup-posix: # Code from module streq: @@ -717,6 +719,17 @@ AC_SUBST([LTALLOCA]) AC_LIBOBJ([strncasecmp]) gl_PREREQ_STRNCASECMP fi + gl_FUNC_STRCASESTR + if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then + AC_LIBOBJ([strcasestr]) + gl_PREREQ_STRCASESTR + fi + gl_FUNC_STRCASESTR_SIMPLE + if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then + AC_LIBOBJ([strcasestr]) + gl_PREREQ_STRCASESTR + fi + gl_STRING_MODULE_INDICATOR([strcasestr]) gl_FUNC_STRCHRNUL if test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1; then AC_LIBOBJ([strchrnul]) @@ -1150,7 +1163,9 @@ AC_DEFUN([gl_FILE_LIST], [ lib/stdio-write.c lib/stdio.in.h lib/stdlib.in.h + lib/str-two-way.h lib/strcasecmp.c + lib/strcasestr.c lib/strchrnul.c lib/strchrnul.valgrind lib/strdup.c @@ -1364,6 +1379,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/stdio_h.m4 m4/stdlib_h.m4 m4/strcase.m4 + m4/strcasestr.m4 m4/strchrnul.m4 m4/strdup.m4 m4/strerror.m4 diff --git a/gnulib/m4/strcasestr.m4 b/gnulib/m4/strcasestr.m4 new file mode 100644 index 00000000..e2d87fe6 --- /dev/null +++ b/gnulib/m4/strcasestr.m4 @@ -0,0 +1,142 @@ +# strcasestr.m4 serial 21 +dnl Copyright (C) 2005, 2007-2014 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. + +dnl Check that strcasestr is present and works. +AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE], +[ + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + + dnl Persuade glibc <string.h> to declare strcasestr(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_FUNC_MEMCHR]) + AC_CHECK_FUNCS([strcasestr]) + if test $ac_cv_func_strcasestr = no; then + HAVE_STRCASESTR=0 + else + if test "$gl_cv_func_memchr_works" != yes; then + REPLACE_STRCASESTR=1 + else + dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092. + AC_CACHE_CHECK([whether strcasestr works], + [gl_cv_func_strcasestr_works_always], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include <string.h> /* for strcasestr */ +#define P "_EF_BF_BD" +#define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P +#define NEEDLE P P P P P +]], [[return !!strcasestr (HAYSTACK, NEEDLE); + ]])], + [gl_cv_func_strcasestr_works_always=yes], + [gl_cv_func_strcasestr_works_always=no], + [dnl glibc 2.12 and cygwin 1.7.7 have a known bug. uClibc is not + dnl affected, since it uses different source code for strcasestr + dnl than glibc. + dnl Assume that it works on all other platforms, even if it is not + dnl linear. + AC_EGREP_CPP([Lucky user], + [ +#ifdef __GNU_LIBRARY__ + #include <features.h> + #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ + || defined __UCLIBC__ + Lucky user + #endif +#elif defined __CYGWIN__ + #include <cygwin/version.h> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7) + Lucky user + #endif +#else + Lucky user +#endif + ], + [gl_cv_func_strcasestr_works_always="guessing yes"], + [gl_cv_func_strcasestr_works_always="guessing no"]) + ]) + ]) + case "$gl_cv_func_strcasestr_works_always" in + *yes) ;; + *) + REPLACE_STRCASESTR=1 + ;; + esac + fi + fi +]) # gl_FUNC_STRCASESTR_SIMPLE + +dnl Additionally, check that strcasestr is efficient. +AC_DEFUN([gl_FUNC_STRCASESTR], +[ + AC_REQUIRE([gl_FUNC_STRCASESTR_SIMPLE]) + if test $HAVE_STRCASESTR = 1 && test $REPLACE_STRCASESTR = 0; then + AC_CACHE_CHECK([whether strcasestr works in linear time], + [gl_cv_func_strcasestr_linear], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include <signal.h> /* for signal */ +#include <string.h> /* for strcasestr */ +#include <stdlib.h> /* for malloc */ +#include <unistd.h> /* for alarm */ +static void quit (int sig) { exit (sig + 128); } +]], [[ + int result = 0; + size_t m = 1000000; + char *haystack = (char *) malloc (2 * m + 2); + char *needle = (char *) malloc (m + 2); + /* Failure to compile this test due to missing alarm is okay, + since all such platforms (mingw) also lack strcasestr. */ + signal (SIGALRM, quit); + alarm (5); + /* Check for quadratic performance. */ + if (haystack && needle) + { + memset (haystack, 'A', 2 * m); + haystack[2 * m] = 'B'; + haystack[2 * m + 1] = 0; + memset (needle, 'A', m); + needle[m] = 'B'; + needle[m + 1] = 0; + if (!strcasestr (haystack, needle)) + result |= 1; + } + return result; + ]])], + [gl_cv_func_strcasestr_linear=yes], [gl_cv_func_strcasestr_linear=no], + [dnl Only glibc > 2.12 and cygwin > 1.7.7 are known to have a + dnl strcasestr that works in linear time. + AC_EGREP_CPP([Lucky user], + [ +#include <features.h> +#ifdef __GNU_LIBRARY__ + #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ + && !defined __UCLIBC__ + Lucky user + #endif +#endif +#ifdef __CYGWIN__ + #include <cygwin/version.h> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7) + Lucky user + #endif +#endif + ], + [gl_cv_func_strcasestr_linear="guessing yes"], + [gl_cv_func_strcasestr_linear="guessing no"]) + ]) + ]) + case "$gl_cv_func_strcasestr_linear" in + *yes) ;; + *) + REPLACE_STRCASESTR=1 + ;; + esac + fi +]) # gl_FUNC_STRCASESTR + +# Prerequisites of lib/strcasestr.c. +AC_DEFUN([gl_PREREQ_STRCASESTR], [ + : +]) diff --git a/init/Makefile.in b/init/Makefile.in index 38d828ee..b6eb4d7d 100644 --- a/init/Makefile.in +++ b/init/Makefile.in @@ -244,6 +244,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/init/systemd/Makefile.in b/init/systemd/Makefile.in index 6f33be44..e00ab446 100644 --- a/init/systemd/Makefile.in +++ b/init/systemd/Makefile.in @@ -246,6 +246,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/lib/Makefile.in b/lib/Makefile.in index f52151f2..52ebafc5 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -247,6 +247,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/libdb/Makefile.in b/libdb/Makefile.in index 906d5997..8c267dd6 100644 --- a/libdb/Makefile.in +++ b/libdb/Makefile.in @@ -247,6 +247,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/Makefile.in b/man/Makefile.in index d6bae578..1d55db7d 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -246,6 +246,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/da/Makefile.in b/man/da/Makefile.in index 0831b74d..7a84bd42 100644 --- a/man/da/Makefile.in +++ b/man/da/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/de/Makefile.in b/man/de/Makefile.in index 767cbedc..ee1f7446 100644 --- a/man/de/Makefile.in +++ b/man/de/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/es/Makefile.in b/man/es/Makefile.in index d32a1437..202f0427 100644 --- a/man/es/Makefile.in +++ b/man/es/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/fr/Makefile.in b/man/fr/Makefile.in index e33f73f5..8c3a1d36 100644 --- a/man/fr/Makefile.in +++ b/man/fr/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/id/Makefile.in b/man/id/Makefile.in index 5910ee75..af864d2e 100644 --- a/man/id/Makefile.in +++ b/man/id/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/it/Makefile.in b/man/it/Makefile.in index 6c0d6803..1d4668dc 100644 --- a/man/it/Makefile.in +++ b/man/it/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/ja/Makefile.in b/man/ja/Makefile.in index 68051630..7e988eef 100644 --- a/man/ja/Makefile.in +++ b/man/ja/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/nl/Makefile.in b/man/nl/Makefile.in index 227e0754..937e19b1 100644 --- a/man/nl/Makefile.in +++ b/man/nl/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/pl/Makefile.in b/man/pl/Makefile.in index d860282b..7827b685 100644 --- a/man/pl/Makefile.in +++ b/man/pl/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/po4a/Makefile.in b/man/po4a/Makefile.in index 4f00ea72..b5add0f8 100644 --- a/man/po4a/Makefile.in +++ b/man/po4a/Makefile.in @@ -244,6 +244,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/ru/Makefile.in b/man/ru/Makefile.in index a87dd90a..b8c7a082 100644 --- a/man/ru/Makefile.in +++ b/man/ru/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/man/zh_CN/Makefile.in b/man/zh_CN/Makefile.in index f1f9f4d6..d6e27040 100644 --- a/man/zh_CN/Makefile.in +++ b/man/zh_CN/Makefile.in @@ -245,6 +245,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/manual/Makefile.in b/manual/Makefile.in index c1ea7b77..e37802b3 100644 --- a/manual/Makefile.in +++ b/manual/Makefile.in @@ -246,6 +246,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/src/Makefile.in b/src/Makefile.in index bcbbb9cb..012fa946 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -253,6 +253,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index d2e36671..650e6c0b 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -247,6 +247,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ diff --git a/tools/Makefile.in b/tools/Makefile.in index 8ee79dbc..a62cc50e 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -247,6 +247,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \ $(top_srcdir)/gnulib/m4/stdio_h.m4 \ $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ $(top_srcdir)/gnulib/m4/strcase.m4 \ + $(top_srcdir)/gnulib/m4/strcasestr.m4 \ $(top_srcdir)/gnulib/m4/strchrnul.m4 \ $(top_srcdir)/gnulib/m4/strdup.m4 \ $(top_srcdir)/gnulib/m4/strerror.m4 \ |