Blame m4/memmem.m4

Packit aea12f
# memmem.m4 serial 25
Packit aea12f
dnl Copyright (C) 2002-2004, 2007-2019 Free Software Foundation, Inc.
Packit aea12f
dnl This file is free software; the Free Software Foundation
Packit aea12f
dnl gives unlimited permission to copy and/or distribute it,
Packit aea12f
dnl with or without modifications, as long as this notice is preserved.
Packit aea12f
Packit aea12f
dnl Check that memmem is present and functional.
Packit aea12f
AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE],
Packit aea12f
[
Packit aea12f
  dnl Persuade glibc <string.h> to declare memmem().
Packit aea12f
  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
Packit aea12f
Packit aea12f
  AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
Packit aea12f
  AC_CHECK_FUNCS([memmem])
Packit aea12f
  if test $ac_cv_func_memmem = yes; then
Packit aea12f
    HAVE_MEMMEM=1
Packit aea12f
  else
Packit aea12f
    HAVE_MEMMEM=0
Packit aea12f
  fi
Packit aea12f
  AC_CHECK_DECLS_ONCE([memmem])
Packit aea12f
  if test $ac_cv_have_decl_memmem = no; then
Packit aea12f
    HAVE_DECL_MEMMEM=0
Packit aea12f
  else
Packit aea12f
    dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092.
Packit aea12f
    dnl Also check that we handle empty needles correctly.
Packit aea12f
    AC_CACHE_CHECK([whether memmem works],
Packit aea12f
      [gl_cv_func_memmem_works_always],
Packit aea12f
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
Packit aea12f
#include <string.h> /* for memmem */
Packit aea12f
#define P "_EF_BF_BD"
Packit aea12f
#define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
Packit aea12f
#define NEEDLE P P P P P
Packit aea12f
]], [[
Packit aea12f
    int result = 0;
Packit aea12f
    if (memmem (HAYSTACK, strlen (HAYSTACK), NEEDLE, strlen (NEEDLE)))
Packit aea12f
      result |= 1;
Packit aea12f
    /* Check for empty needle behavior.  */
Packit aea12f
    {
Packit aea12f
      const char *haystack = "AAA";
Packit aea12f
      if (memmem (haystack, 3, NULL, 0) != haystack)
Packit aea12f
        result |= 2;
Packit aea12f
    }
Packit aea12f
    return result;
Packit aea12f
    ]])],
Packit aea12f
        [gl_cv_func_memmem_works_always=yes],
Packit aea12f
        [gl_cv_func_memmem_works_always=no],
Packit aea12f
        [dnl glibc 2.9..2.12 and cygwin 1.7.7 have issue #12092 above.
Packit aea12f
         dnl Also empty needles work on glibc >= 2.1 and cygwin >= 1.7.0.
Packit aea12f
         dnl uClibc is not affected, since it uses different source code.
Packit aea12f
         dnl Assume that it works on all other platforms (even if not linear).
Packit aea12f
         AC_EGREP_CPP([Lucky user],
Packit aea12f
           [
Packit aea12f
#ifdef __GNU_LIBRARY__
Packit aea12f
 #include <features.h>
Packit aea12f
 #if ((__GLIBC__ == 2 && ((__GLIBC_MINOR > 0 && __GLIBC_MINOR__ < 9) \
Packit aea12f
                          || __GLIBC_MINOR__ > 12)) \
Packit aea12f
      || (__GLIBC__ > 2)) \
Packit aea12f
     || defined __UCLIBC__
Packit aea12f
  Lucky user
Packit aea12f
 #endif
Packit aea12f
#elif defined __CYGWIN__
Packit aea12f
 #include <cygwin/version.h>
Packit aea12f
 #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
Packit aea12f
  Lucky user
Packit aea12f
 #endif
Packit aea12f
#else
Packit aea12f
  Lucky user
Packit aea12f
#endif
Packit aea12f
           ],
Packit aea12f
           [gl_cv_func_memmem_works_always="guessing yes"],
Packit aea12f
           [gl_cv_func_memmem_works_always="guessing no"])
Packit aea12f
        ])
Packit aea12f
      ])
Packit aea12f
    case "$gl_cv_func_memmem_works_always" in
Packit aea12f
      *yes) ;;
Packit aea12f
      *)
Packit aea12f
        REPLACE_MEMMEM=1
Packit aea12f
        ;;
Packit aea12f
    esac
Packit aea12f
  fi
Packit aea12f
  gl_PREREQ_MEMMEM
Packit aea12f
]) # gl_FUNC_MEMMEM_SIMPLE
Packit aea12f
Packit aea12f
dnl Additionally, check that memmem has linear performance characteristics
Packit aea12f
AC_DEFUN([gl_FUNC_MEMMEM],
Packit aea12f
[
Packit aea12f
  AC_REQUIRE([gl_FUNC_MEMMEM_SIMPLE])
Packit aea12f
  if test $HAVE_DECL_MEMMEM = 1 && test $REPLACE_MEMMEM = 0; then
Packit aea12f
    AC_CACHE_CHECK([whether memmem works in linear time],
Packit aea12f
      [gl_cv_func_memmem_works_fast],
Packit aea12f
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
Packit aea12f
#include <signal.h> /* for signal */
Packit aea12f
#include <string.h> /* for memmem */
Packit aea12f
#include <stdlib.h> /* for malloc */
Packit aea12f
#include <unistd.h> /* for alarm */
Packit aea12f
static void quit (int sig) { _exit (sig + 128); }
Packit aea12f
]], [[
Packit aea12f
    int result = 0;
Packit aea12f
    size_t m = 1000000;
Packit aea12f
    char *haystack = (char *) malloc (2 * m + 1);
Packit aea12f
    char *needle = (char *) malloc (m + 1);
Packit aea12f
    /* Failure to compile this test due to missing alarm is okay,
Packit aea12f
       since all such platforms (mingw) also lack memmem.  */
Packit aea12f
    signal (SIGALRM, quit);
Packit aea12f
    alarm (5);
Packit aea12f
    /* Check for quadratic performance.  */
Packit aea12f
    if (haystack && needle)
Packit aea12f
      {
Packit aea12f
        memset (haystack, 'A', 2 * m);
Packit aea12f
        haystack[2 * m] = 'B';
Packit aea12f
        memset (needle, 'A', m);
Packit aea12f
        needle[m] = 'B';
Packit aea12f
        if (!memmem (haystack, 2 * m + 1, needle, m + 1))
Packit aea12f
          result |= 1;
Packit aea12f
      }
Packit aea12f
    /* Free allocated memory, in case some sanitizer is watching.  */
Packit aea12f
    free (haystack);
Packit aea12f
    free (needle);
Packit aea12f
    return result;
Packit aea12f
    ]])],
Packit aea12f
        [gl_cv_func_memmem_works_fast=yes], [gl_cv_func_memmem_works_fast=no],
Packit aea12f
        [dnl Only glibc >= 2.9 and cygwin > 1.7.0 are known to have a
Packit aea12f
         dnl memmem that works in linear time.
Packit aea12f
         AC_EGREP_CPP([Lucky user],
Packit aea12f
           [
Packit aea12f
#include <features.h>
Packit aea12f
#ifdef __GNU_LIBRARY__
Packit aea12f
 #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 9) || (__GLIBC__ > 2)) \
Packit aea12f
     && !defined __UCLIBC__
Packit aea12f
  Lucky user
Packit aea12f
 #endif
Packit aea12f
#endif
Packit aea12f
#ifdef __CYGWIN__
Packit aea12f
 #include <cygwin/version.h>
Packit aea12f
 #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 0)
Packit aea12f
  Lucky user
Packit aea12f
 #endif
Packit aea12f
#endif
Packit aea12f
           ],
Packit aea12f
           [gl_cv_func_memmem_works_fast="guessing yes"],
Packit aea12f
           [gl_cv_func_memmem_works_fast="guessing no"])
Packit aea12f
        ])
Packit aea12f
      ])
Packit aea12f
    case "$gl_cv_func_memmem_works_fast" in
Packit aea12f
      *yes) ;;
Packit aea12f
      *)
Packit aea12f
        REPLACE_MEMMEM=1
Packit aea12f
        ;;
Packit aea12f
    esac
Packit aea12f
  fi
Packit aea12f
]) # gl_FUNC_MEMMEM
Packit aea12f
Packit aea12f
# Prerequisites of lib/memmem.c.
Packit aea12f
AC_DEFUN([gl_PREREQ_MEMMEM], [:])