Blame m4/memmem.m4

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