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