| 1 | # strstr.m4 serial 24
 | 
|---|
| 2 | dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
 | 
|---|
| 3 | dnl This file is free software; the Free Software Foundation
 | 
|---|
| 4 | dnl gives unlimited permission to copy and/or distribute it,
 | 
|---|
| 5 | dnl with or without modifications, as long as this notice is preserved.
 | 
|---|
| 6 | 
 | 
|---|
| 7 | dnl Check that strstr works.
 | 
|---|
| 8 | AC_DEFUN([gl_FUNC_STRSTR_SIMPLE],
 | 
|---|
| 9 | [
 | 
|---|
| 10 |   AC_REQUIRE([gl_STRING_H_DEFAULTS])
 | 
|---|
| 11 |   AC_REQUIRE([gl_FUNC_MEMCHR])
 | 
|---|
| 12 |   if test $REPLACE_MEMCHR = 1; then
 | 
|---|
| 13 |     REPLACE_STRSTR=1
 | 
|---|
| 14 |   else
 | 
|---|
| 15 |     dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092
 | 
|---|
| 16 |     dnl and https://sourceware.org/bugzilla/show_bug.cgi?id=23637.
 | 
|---|
| 17 |     AC_CACHE_CHECK([whether strstr works],
 | 
|---|
| 18 |       [gl_cv_func_strstr_works_always],
 | 
|---|
| 19 |       [AC_RUN_IFELSE(
 | 
|---|
| 20 |          [AC_LANG_PROGRAM([[
 | 
|---|
| 21 | #include <string.h> /* for __GNU_LIBRARY__, strstr */
 | 
|---|
| 22 | #ifdef __GNU_LIBRARY__
 | 
|---|
| 23 |  #include <features.h>
 | 
|---|
| 24 |  #if __GLIBC__ == 2 && __GLIBC_MINOR__ == 28
 | 
|---|
| 25 |   Unlucky user
 | 
|---|
| 26 |  #endif
 | 
|---|
| 27 | #endif
 | 
|---|
| 28 | #define P "_EF_BF_BD"
 | 
|---|
| 29 | #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
 | 
|---|
| 30 | #define NEEDLE P P P P P
 | 
|---|
| 31 | ]],
 | 
|---|
| 32 |             [[return !!strstr (HAYSTACK, NEEDLE);
 | 
|---|
| 33 |             ]])],
 | 
|---|
| 34 |          [gl_cv_func_strstr_works_always=yes],
 | 
|---|
| 35 |          [gl_cv_func_strstr_works_always=no],
 | 
|---|
| 36 |          [dnl glibc 2.12 and cygwin 1.7.7 have a known bug.  uClibc is not
 | 
|---|
| 37 |           dnl affected, since it uses different source code for strstr than
 | 
|---|
| 38 |           dnl glibc.
 | 
|---|
| 39 |           dnl Assume that it works on all other platforms, even if it is not
 | 
|---|
| 40 |           dnl linear.
 | 
|---|
| 41 |           AC_EGREP_CPP([Lucky user],
 | 
|---|
| 42 |             [
 | 
|---|
| 43 | #include <string.h> /* for __GNU_LIBRARY__ */
 | 
|---|
| 44 | #ifdef __GNU_LIBRARY__
 | 
|---|
| 45 |  #include <features.h>
 | 
|---|
| 46 |  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
 | 
|---|
| 47 |      || defined __UCLIBC__
 | 
|---|
| 48 |   Lucky user
 | 
|---|
| 49 |  #endif
 | 
|---|
| 50 | #elif defined __CYGWIN__
 | 
|---|
| 51 |  #include <cygwin/version.h>
 | 
|---|
| 52 |  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
 | 
|---|
| 53 |   Lucky user
 | 
|---|
| 54 |  #endif
 | 
|---|
| 55 | #else
 | 
|---|
| 56 |   Lucky user
 | 
|---|
| 57 | #endif
 | 
|---|
| 58 |             ],
 | 
|---|
| 59 |             [gl_cv_func_strstr_works_always="guessing yes"],
 | 
|---|
| 60 |             [gl_cv_func_strstr_works_always="$gl_cross_guess_normal"])
 | 
|---|
| 61 |          ])
 | 
|---|
| 62 |       ])
 | 
|---|
| 63 |     case "$gl_cv_func_strstr_works_always" in
 | 
|---|
| 64 |       *yes) ;;
 | 
|---|
| 65 |       *)
 | 
|---|
| 66 |         REPLACE_STRSTR=1
 | 
|---|
| 67 |         ;;
 | 
|---|
| 68 |     esac
 | 
|---|
| 69 |   fi
 | 
|---|
| 70 | ]) # gl_FUNC_STRSTR_SIMPLE
 | 
|---|
| 71 | 
 | 
|---|
| 72 | dnl Additionally, check that strstr is efficient.
 | 
|---|
| 73 | AC_DEFUN([gl_FUNC_STRSTR],
 | 
|---|
| 74 | [
 | 
|---|
| 75 |   AC_REQUIRE([gl_FUNC_STRSTR_SIMPLE])
 | 
|---|
| 76 |   if test $REPLACE_STRSTR = 0; then
 | 
|---|
| 77 |     AC_CACHE_CHECK([whether strstr works in linear time],
 | 
|---|
| 78 |       [gl_cv_func_strstr_linear],
 | 
|---|
| 79 |       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
 | 
|---|
| 80 | #ifdef __MVS__
 | 
|---|
| 81 | /* z/OS does not deliver signals while strstr() is running (thanks to
 | 
|---|
| 82 |    restrictions on its LE runtime), which prevents us from limiting the
 | 
|---|
| 83 |    running time of this test.  */
 | 
|---|
| 84 | # error "This test does not work properly on z/OS"
 | 
|---|
| 85 | #endif
 | 
|---|
| 86 | #include <signal.h> /* for signal */
 | 
|---|
| 87 | #include <string.h> /* for strstr */
 | 
|---|
| 88 | #include <stdlib.h> /* for malloc */
 | 
|---|
| 89 | #include <unistd.h> /* for alarm */
 | 
|---|
| 90 | static void quit (int sig) { _exit (sig + 128); }
 | 
|---|
| 91 | ]], [[
 | 
|---|
| 92 |     int result = 0;
 | 
|---|
| 93 |     size_t m = 1000000;
 | 
|---|
| 94 |     char *haystack = (char *) malloc (2 * m + 2);
 | 
|---|
| 95 |     char *needle = (char *) malloc (m + 2);
 | 
|---|
| 96 |     /* Failure to compile this test due to missing alarm is okay,
 | 
|---|
| 97 |        since all such platforms (mingw) also have quadratic strstr.  */
 | 
|---|
| 98 |     signal (SIGALRM, quit);
 | 
|---|
| 99 |     alarm (5);
 | 
|---|
| 100 |     /* Check for quadratic performance.  */
 | 
|---|
| 101 |     if (haystack && needle)
 | 
|---|
| 102 |       {
 | 
|---|
| 103 |         memset (haystack, 'A', 2 * m);
 | 
|---|
| 104 |         haystack[2 * m] = 'B';
 | 
|---|
| 105 |         haystack[2 * m + 1] = 0;
 | 
|---|
| 106 |         memset (needle, 'A', m);
 | 
|---|
| 107 |         needle[m] = 'B';
 | 
|---|
| 108 |         needle[m + 1] = 0;
 | 
|---|
| 109 |         if (!strstr (haystack, needle))
 | 
|---|
| 110 |           result |= 1;
 | 
|---|
| 111 |       }
 | 
|---|
| 112 |     /* Free allocated memory, in case some sanitizer is watching.  */
 | 
|---|
| 113 |     free (haystack);
 | 
|---|
| 114 |     free (needle);
 | 
|---|
| 115 |     return result;
 | 
|---|
| 116 |     ]])],
 | 
|---|
| 117 |         [gl_cv_func_strstr_linear=yes], [gl_cv_func_strstr_linear=no],
 | 
|---|
| 118 |         [dnl Only glibc > 2.12 on processors without SSE 4.2 instructions and
 | 
|---|
| 119 |          dnl cygwin > 1.7.7 are known to have a bug-free strstr that works in
 | 
|---|
| 120 |          dnl linear time.
 | 
|---|
| 121 |          AC_EGREP_CPP([Lucky user],
 | 
|---|
| 122 |            [
 | 
|---|
| 123 | #include <features.h>
 | 
|---|
| 124 | #ifdef __GNU_LIBRARY__
 | 
|---|
| 125 |  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
 | 
|---|
| 126 |      && !(defined __i386__ || defined __x86_64__) \
 | 
|---|
| 127 |      && !defined __UCLIBC__
 | 
|---|
| 128 |   Lucky user
 | 
|---|
| 129 |  #endif
 | 
|---|
| 130 | #endif
 | 
|---|
| 131 | #ifdef __CYGWIN__
 | 
|---|
| 132 |  #include <cygwin/version.h>
 | 
|---|
| 133 |  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
 | 
|---|
| 134 |   Lucky user
 | 
|---|
| 135 |  #endif
 | 
|---|
| 136 | #endif
 | 
|---|
| 137 |            ],
 | 
|---|
| 138 |            [gl_cv_func_strstr_linear="guessing yes"],
 | 
|---|
| 139 |            [gl_cv_func_strstr_linear="$gl_cross_guess_normal"])
 | 
|---|
| 140 |         ])
 | 
|---|
| 141 |       ])
 | 
|---|
| 142 |     case "$gl_cv_func_strstr_linear" in
 | 
|---|
| 143 |       *yes) ;;
 | 
|---|
| 144 |       *)
 | 
|---|
| 145 |         REPLACE_STRSTR=1
 | 
|---|
| 146 |         ;;
 | 
|---|
| 147 |     esac
 | 
|---|
| 148 |   fi
 | 
|---|
| 149 | ]) # gl_FUNC_STRSTR
 | 
|---|