immutable: Add tests.
[gnulib.git] / m4 / strcasestr.m4
blob5fabaa9564e4b33a33a0569eb2475e4ea172822d
1 # strcasestr.m4 serial 26
2 dnl Copyright (C) 2005, 2007-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.
7 dnl Check that strcasestr is present and works.
8 AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE],
10   AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
12   dnl Persuade glibc <string.h> to declare strcasestr().
13   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
15   AC_REQUIRE([gl_FUNC_MEMCHR])
16   AC_CHECK_FUNCS([strcasestr])
17   if test $ac_cv_func_strcasestr = no; then
18     HAVE_STRCASESTR=0
19   else
20     if test $REPLACE_MEMCHR = 1; then
21       REPLACE_STRCASESTR=1
22     else
23       dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092
24       dnl and https://sourceware.org/bugzilla/show_bug.cgi?id=23637.
25       AC_CACHE_CHECK([whether strcasestr works],
26         [gl_cv_func_strcasestr_works_always],
27         [AC_RUN_IFELSE(
28            [AC_LANG_PROGRAM([[
29 #include <string.h> /* for strcasestr */
30 #ifdef __GNU_LIBRARY__
31  #include <features.h>
32  #if __GLIBC__ == 2 && __GLIBC_MINOR__ == 28
33   Unlucky user
34  #endif
35 #endif
36 #define P "_EF_BF_BD"
37 #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
38 #define NEEDLE P P P P P
39 ]],
40               [[return !!strcasestr (HAYSTACK, NEEDLE);
41               ]])],
42            [gl_cv_func_strcasestr_works_always=yes],
43            [gl_cv_func_strcasestr_works_always=no],
44            [dnl glibc 2.12 and cygwin 1.7.7 have a known bug.  uClibc is not
45             dnl affected, since it uses different source code for strcasestr
46             dnl than glibc.
47             dnl Assume that it works on all other platforms, even if it is not
48             dnl linear.
49             AC_EGREP_CPP([Lucky user],
50               [
51 #ifdef __GNU_LIBRARY__
52  #include <features.h>
53  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
54      || defined __UCLIBC__
55   Lucky user
56  #endif
57 #elif defined __CYGWIN__
58  #include <cygwin/version.h>
59  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
60   Lucky user
61  #endif
62 #else
63   Lucky user
64 #endif
65               ],
66               [gl_cv_func_strcasestr_works_always="guessing yes"],
67               [gl_cv_func_strcasestr_works_always="$gl_cross_guess_normal"])
68            ])
69         ])
70       case "$gl_cv_func_strcasestr_works_always" in
71         *yes) ;;
72         *)
73           REPLACE_STRCASESTR=1
74           ;;
75       esac
76     fi
77   fi
78 ]) # gl_FUNC_STRCASESTR_SIMPLE
80 dnl Additionally, check that strcasestr is efficient.
81 AC_DEFUN([gl_FUNC_STRCASESTR],
83   AC_REQUIRE([gl_FUNC_STRCASESTR_SIMPLE])
84   if test $HAVE_STRCASESTR = 1 && test $REPLACE_STRCASESTR = 0; then
85     AC_CACHE_CHECK([whether strcasestr works in linear time],
86       [gl_cv_func_strcasestr_linear],
87       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
88 #include <signal.h> /* for signal */
89 #include <string.h> /* for strcasestr */
90 #include <stdlib.h> /* for malloc */
91 #include <unistd.h> /* for alarm */
92 static void quit (int sig) { _exit (sig + 128); }
93 ]], [[
94     int result = 0;
95     size_t m = 1000000;
96     char *haystack = (char *) malloc (2 * m + 2);
97     char *needle = (char *) malloc (m + 2);
98     /* Failure to compile this test due to missing alarm is okay,
99        since all such platforms (mingw) also lack strcasestr.  */
100     signal (SIGALRM, quit);
101     alarm (5);
102     /* Check for quadratic performance.  */
103     if (haystack && needle)
104       {
105         memset (haystack, 'A', 2 * m);
106         haystack[2 * m] = 'B';
107         haystack[2 * m + 1] = 0;
108         memset (needle, 'A', m);
109         needle[m] = 'B';
110         needle[m + 1] = 0;
111         if (!strcasestr (haystack, needle))
112           result |= 1;
113       }
114     /* Free allocated memory, in case some sanitizer is watching.  */
115     free (haystack);
116     free (needle);
117     return result;
118     ]])],
119         [gl_cv_func_strcasestr_linear=yes], [gl_cv_func_strcasestr_linear=no],
120         [dnl Only glibc > 2.12 and cygwin > 1.7.7 are known to have a
121          dnl strcasestr that works in linear time.
122          AC_EGREP_CPP([Lucky user],
123            [
124 #include <features.h>
125 #ifdef __GNU_LIBRARY__
126  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
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_strcasestr_linear="guessing yes"],
139            [gl_cv_func_strcasestr_linear="$gl_cross_guess_normal"])
140         ])
141       ])
142     case "$gl_cv_func_strcasestr_linear" in
143       *yes) ;;
144       *)
145         REPLACE_STRCASESTR=1
146         ;;
147     esac
148   fi
149 ]) # gl_FUNC_STRCASESTR
151 # Prerequisites of lib/strcasestr.c.
152 AC_DEFUN([gl_PREREQ_STRCASESTR], [
153   :