cygwin: use more robust version check
[gnulib.git] / m4 / strstr.m4
1 # strstr.m4 serial 10
2 dnl Copyright (C) 2008, 2009, 2010 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_HEADER_STRING_H_DEFAULTS])
11   AC_REQUIRE([gl_FUNC_MEMCHR])
12   if test "$gl_cv_func_memchr_works" != yes; then
13     REPLACE_STRSTR=1
14     AC_LIBOBJ([strstr])
15   else
16     dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092.
17     AC_CACHE_CHECK([whether strstr works],
18       [gl_cv_func_strstr_works_always],
19       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
20 #include <string.h> /* for strstr */
21 #define P "_EF_BF_BD"
22 #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
23 #define NEEDLE P P P P P
24 ]], [[return !!strstr (HAYSTACK, NEEDLE);
25     ]])],
26         [gl_cv_func_strstr_works_always=yes],
27         [gl_cv_func_strstr_works_always=no],
28         [dnl glibc 2.12 and cygwin 1.7.7 have a known bug.  Assume that it
29          dnl works on all other platforms, even if it is not linear.
30          AC_EGREP_CPP([Lucky user],
31            [
32 #ifdef __GNU_LIBRARY__
33  #include <features.h>
34  #if (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)
35   Lucky user
36  #endif
37 #elif defined __CYGWIN__
38  #include <cygwin/version.h>
39  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
40   Lucky user
41  #endif
42 #else
43   Lucky user
44 #endif
45            ],
46            [gl_cv_func_strstr_works_always=yes],
47            [gl_cv_func_strstr_works_always="guessing no"])
48         ])
49       ])
50     if test "$gl_cv_func_strstr_works_always" != yes; then
51       REPLACE_STRSTR=1
52       AC_LIBOBJ([strstr])
53     fi
54   fi
55 ]) # gl_FUNC_STRSTR_SIMPLE
56
57 dnl Additionally, check that strstr is efficient.
58 AC_DEFUN([gl_FUNC_STRSTR],
59 [
60   AC_REQUIRE([gl_FUNC_STRSTR_SIMPLE])
61   if test $REPLACE_STRSTR = 0; then
62     AC_CACHE_CHECK([whether strstr works in linear time],
63       [gl_cv_func_strstr_linear],
64       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
65 #include <signal.h> /* for signal */
66 #include <string.h> /* for strstr */
67 #include <stdlib.h> /* for malloc */
68 #include <unistd.h> /* for alarm */
69 static void quit (int sig) { exit (sig + 128); }
70 ]], [[size_t m = 1000000;
71     char *haystack = (char *) malloc (2 * m + 2);
72     char *needle = (char *) malloc (m + 2);
73     void *result = 0;
74     /* Failure to compile this test due to missing alarm is okay,
75        since all such platforms (mingw) also have quadratic strstr.  */
76     signal (SIGALRM, quit);
77     alarm (5);
78     /* Check for quadratic performance.  */
79     if (haystack && needle)
80       {
81         memset (haystack, 'A', 2 * m);
82         haystack[2 * m] = 'B';
83         haystack[2 * m + 1] = 0;
84         memset (needle, 'A', m);
85         needle[m] = 'B';
86         needle[m + 1] = 0;
87         result = strstr (haystack, needle);
88       }
89     return !result;]])],
90         [gl_cv_func_strstr_linear=yes], [gl_cv_func_strstr_linear=no],
91         [dnl Only glibc > 2.12 and cygwin > 1.7.7 are known to have a
92          dnl bug-free strstr that works in linear time.
93          AC_EGREP_CPP([Lucky user],
94            [
95 #include <features.h>
96 #ifdef __GNU_LIBRARY__
97  #if (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)
98   Lucky user
99  #endif
100 #endif
101 #ifdef __CYGWIN__
102  #include <cygwin/version.h>
103  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
104   Lucky user
105  #endif
106 #endif
107            ],
108            [gl_cv_func_strstr_linear=yes],
109            [gl_cv_func_strstr_linear="guessing no"])
110         ])
111       ])
112     if test "$gl_cv_func_strstr_linear" != yes; then
113       REPLACE_STRSTR=1
114     fi
115   fi
116   if test $REPLACE_STRSTR = 1; then
117     AC_LIBOBJ([strstr])
118   fi
119 ]) # gl_FUNC_STRSTR