Blame m4/memmem.m4

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