e3bb83bc05abf5fad745b3483e6291ef6cebf9fc
[gnulib.git] / m4 / memmem.m4
1 # memmem.m4 serial 21
2 dnl Copyright (C) 2002, 2003, 2004, 2007, 2008, 2009, 2010 Free Software
3 dnl Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
7
8 dnl Check that memmem is present.
9 AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE],
10 [
11   dnl Persuade glibc <string.h> to declare memmem().
12   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
13
14   AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
15   AC_REPLACE_FUNCS([memmem])
16   AC_CHECK_DECLS_ONCE([memmem])
17   if test $ac_cv_have_decl_memmem = no; then
18     HAVE_DECL_MEMMEM=0
19   else
20     dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092.
21     AC_CACHE_CHECK([whether memmem works],
22       [gl_cv_func_memmem_works_always],
23       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
24 #include <string.h> /* for memmem */
25 #define P "_EF_BF_BD"
26 #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
27 #define NEEDLE P P P P P
28 ]], [[return !!memmem (HAYSTACK, strlen (HAYSTACK), NEEDLE, strlen (NEEDLE));
29     ]])],
30         [gl_cv_func_memmem_works_always=yes],
31         [gl_cv_func_memmem_works_always=no],
32         [dnl glibc 2.12 and cygwin 1.7.7 have a known bug.  uClibc is not
33          dnl affected, since it uses different source code for memmem than
34          dnl glibc.
35          dnl Assume that it works on all other platforms, even if it is not
36          dnl linear.
37          AC_EGREP_CPP([Lucky user],
38            [
39 #ifdef __GNU_LIBRARY__
40  #include <features.h>
41  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
42      || defined __UCLIBC__
43   Lucky user
44  #endif
45 #elif defined __CYGWIN__
46  #include <cygwin/version.h>
47  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
48   Lucky user
49  #endif
50 #else
51   Lucky user
52 #endif
53            ],
54            [gl_cv_func_memmem_works_always=yes],
55            [gl_cv_func_memmem_works_always="guessing no"])
56         ])
57       ])
58     if test "$gl_cv_func_memmem_works_always" != yes; then
59       REPLACE_MEMMEM=1
60       AC_LIBOBJ([memmem])
61     fi
62   fi
63   gl_PREREQ_MEMMEM
64 ]) # gl_FUNC_MEMMEM_SIMPLE
65
66 dnl Additionally, check that memmem is efficient and handles empty needles.
67 AC_DEFUN([gl_FUNC_MEMMEM],
68 [
69   AC_REQUIRE([gl_FUNC_MEMMEM_SIMPLE])
70   if test $HAVE_DECL_MEMMEM = 1 && test $REPLACE_MEMMEM = 0; then
71     AC_CACHE_CHECK([whether memmem works in linear time],
72       [gl_cv_func_memmem_works_fast],
73       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
74 #include <signal.h> /* for signal */
75 #include <string.h> /* for memmem */
76 #include <stdlib.h> /* for malloc */
77 #include <unistd.h> /* for alarm */
78 static void quit (int sig) { exit (sig + 128); }
79 ]], [[
80     int result = 0;
81     size_t m = 1000000;
82     char *haystack = (char *) malloc (2 * m + 1);
83     char *needle = (char *) malloc (m + 1);
84     /* Failure to compile this test due to missing alarm is okay,
85        since all such platforms (mingw) also lack memmem.  */
86     signal (SIGALRM, quit);
87     alarm (5);
88     /* Check for quadratic performance.  */
89     if (haystack && needle)
90       {
91         memset (haystack, 'A', 2 * m);
92         haystack[2 * m] = 'B';
93         memset (needle, 'A', m);
94         needle[m] = 'B';
95         if (!memmem (haystack, 2 * m + 1, needle, m + 1))
96           result |= 1;
97       }
98     /* Check for empty needle behavior.  */
99     if (!memmem ("a", 1, 0, 0))
100       result |= 2;
101     return result;
102     ]])],
103         [gl_cv_func_memmem_works_fast=yes], [gl_cv_func_memmem_works_fast=no],
104         [dnl Only glibc > 2.12 and cygwin > 1.7.7 are known to have a
105          dnl bug-free memmem that works in linear time.
106          AC_EGREP_CPP([Lucky user],
107            [
108 #include <features.h>
109 #ifdef __GNU_LIBRARY__
110  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
111      && !defined __UCLIBC__
112   Lucky user
113  #endif
114 #endif
115 #ifdef __CYGWIN__
116  #include <cygwin/version.h>
117  #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
118   Lucky user
119  #endif
120 #endif
121            ],
122            [gl_cv_func_memmem_works_fast=yes],
123            [gl_cv_func_memmem_works_fast="guessing no"])
124         ])
125       ])
126     if test "$gl_cv_func_memmem_works_fast" != yes; then
127       REPLACE_MEMMEM=1
128       AC_LIBOBJ([memmem])
129     fi
130   fi
131 ]) # gl_FUNC_MEMMEM
132
133 # Prerequisites of lib/memmem.c.
134 AC_DEFUN([gl_PREREQ_MEMMEM], [:])