Blame m4/strstr.m4

Packit 709fb3
# strstr.m4 serial 18
Packit 709fb3
dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
Packit 709fb3
dnl This file is free software; the Free Software Foundation
Packit 709fb3
dnl gives unlimited permission to copy and/or distribute it,
Packit 709fb3
dnl with or without modifications, as long as this notice is preserved.
Packit 709fb3
Packit 709fb3
dnl Check that strstr works.
Packit 709fb3
AC_DEFUN([gl_FUNC_STRSTR_SIMPLE],
Packit 709fb3
[
Packit 709fb3
  AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
Packit 709fb3
  AC_REQUIRE([gl_FUNC_MEMCHR])
Packit 709fb3
  if test "$gl_cv_func_memchr_works" != yes; then
Packit 709fb3
    REPLACE_STRSTR=1
Packit 709fb3
  else
Packit 709fb3
    dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092.
Packit 709fb3
    AC_CACHE_CHECK([whether strstr works],
Packit 709fb3
      [gl_cv_func_strstr_works_always],
Packit 709fb3
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
Packit 709fb3
#include <string.h> /* for strstr */
Packit 709fb3
#define P "_EF_BF_BD"
Packit 709fb3
#define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
Packit 709fb3
#define NEEDLE P P P P P
Packit 709fb3
]], [[return !!strstr (HAYSTACK, NEEDLE);
Packit 709fb3
    ]])],
Packit 709fb3
        [gl_cv_func_strstr_works_always=yes],
Packit 709fb3
        [gl_cv_func_strstr_works_always=no],
Packit 709fb3
        [dnl glibc 2.12 and cygwin 1.7.7 have a known bug.  uClibc is not
Packit 709fb3
         dnl affected, since it uses different source code for strstr than
Packit 709fb3
         dnl glibc.
Packit 709fb3
         dnl Assume that it works on all other platforms, even if it is not
Packit 709fb3
         dnl linear.
Packit 709fb3
         AC_EGREP_CPP([Lucky user],
Packit 709fb3
           [
Packit 709fb3
#ifdef __GNU_LIBRARY__
Packit 709fb3
 #include <features.h>
Packit 709fb3
 #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
Packit 709fb3
     || defined __UCLIBC__
Packit 709fb3
  Lucky user
Packit 709fb3
 #endif
Packit 709fb3
#elif defined __CYGWIN__
Packit 709fb3
 #include <cygwin/version.h>
Packit 709fb3
 #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
Packit 709fb3
  Lucky user
Packit 709fb3
 #endif
Packit 709fb3
#else
Packit 709fb3
  Lucky user
Packit 709fb3
#endif
Packit 709fb3
           ],
Packit 709fb3
           [gl_cv_func_strstr_works_always="guessing yes"],
Packit 709fb3
           [gl_cv_func_strstr_works_always="guessing no"])
Packit 709fb3
        ])
Packit 709fb3
      ])
Packit 709fb3
    case "$gl_cv_func_strstr_works_always" in
Packit 709fb3
      *yes) ;;
Packit 709fb3
      *)
Packit 709fb3
        REPLACE_STRSTR=1
Packit 709fb3
        ;;
Packit 709fb3
    esac
Packit 709fb3
  fi
Packit 709fb3
]) # gl_FUNC_STRSTR_SIMPLE
Packit 709fb3
Packit 709fb3
dnl Additionally, check that strstr is efficient.
Packit 709fb3
AC_DEFUN([gl_FUNC_STRSTR],
Packit 709fb3
[
Packit 709fb3
  AC_REQUIRE([gl_FUNC_STRSTR_SIMPLE])
Packit 709fb3
  if test $REPLACE_STRSTR = 0; then
Packit 709fb3
    AC_CACHE_CHECK([whether strstr works in linear time],
Packit 709fb3
      [gl_cv_func_strstr_linear],
Packit 709fb3
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
Packit 709fb3
#ifdef __MVS__
Packit 709fb3
/* z/OS does not deliver signals while strstr() is running (thanks to
Packit 709fb3
   restrictions on its LE runtime), which prevents us from limiting the
Packit 709fb3
   running time of this test.  */
Packit 709fb3
# error "This test does not work properly on z/OS"
Packit 709fb3
#endif
Packit 709fb3
#include <signal.h> /* for signal */
Packit 709fb3
#include <string.h> /* for strstr */
Packit 709fb3
#include <stdlib.h> /* for malloc */
Packit 709fb3
#include <unistd.h> /* for alarm */
Packit 709fb3
static void quit (int sig) { _exit (sig + 128); }
Packit 709fb3
]], [[
Packit 709fb3
    int result = 0;
Packit 709fb3
    size_t m = 1000000;
Packit 709fb3
    char *haystack = (char *) malloc (2 * m + 2);
Packit 709fb3
    char *needle = (char *) malloc (m + 2);
Packit 709fb3
    /* Failure to compile this test due to missing alarm is okay,
Packit 709fb3
       since all such platforms (mingw) also have quadratic strstr.  */
Packit 709fb3
    signal (SIGALRM, quit);
Packit 709fb3
    alarm (5);
Packit 709fb3
    /* Check for quadratic performance.  */
Packit 709fb3
    if (haystack && needle)
Packit 709fb3
      {
Packit 709fb3
        memset (haystack, 'A', 2 * m);
Packit 709fb3
        haystack[2 * m] = 'B';
Packit 709fb3
        haystack[2 * m + 1] = 0;
Packit 709fb3
        memset (needle, 'A', m);
Packit 709fb3
        needle[m] = 'B';
Packit 709fb3
        needle[m + 1] = 0;
Packit 709fb3
        if (!strstr (haystack, needle))
Packit 709fb3
          result |= 1;
Packit 709fb3
      }
Packit 709fb3
    /* Free allocated memory, in case some sanitizer is watching.  */
Packit 709fb3
    free (haystack);
Packit 709fb3
    free (needle);
Packit 709fb3
    return result;
Packit 709fb3
    ]])],
Packit 709fb3
        [gl_cv_func_strstr_linear=yes], [gl_cv_func_strstr_linear=no],
Packit 709fb3
        [dnl Only glibc > 2.12 on processors without SSE 4.2 instructions and
Packit 709fb3
         dnl cygwin > 1.7.7 are known to have a bug-free strstr that works in
Packit 709fb3
         dnl linear time.
Packit 709fb3
         AC_EGREP_CPP([Lucky user],
Packit 709fb3
           [
Packit 709fb3
#include <features.h>
Packit 709fb3
#ifdef __GNU_LIBRARY__
Packit 709fb3
 #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
Packit 709fb3
     && !(defined __i386__ || defined __x86_64__) \
Packit 709fb3
     && !defined __UCLIBC__
Packit 709fb3
  Lucky user
Packit 709fb3
 #endif
Packit 709fb3
#endif
Packit 709fb3
#ifdef __CYGWIN__
Packit 709fb3
 #include <cygwin/version.h>
Packit 709fb3
 #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
Packit 709fb3
  Lucky user
Packit 709fb3
 #endif
Packit 709fb3
#endif
Packit 709fb3
           ],
Packit 709fb3
           [gl_cv_func_strstr_linear="guessing yes"],
Packit 709fb3
           [gl_cv_func_strstr_linear="guessing no"])
Packit 709fb3
        ])
Packit 709fb3
      ])
Packit 709fb3
    case "$gl_cv_func_strstr_linear" in
Packit 709fb3
      *yes) ;;
Packit 709fb3
      *)
Packit 709fb3
        REPLACE_STRSTR=1
Packit 709fb3
        ;;
Packit 709fb3
    esac
Packit 709fb3
  fi
Packit 709fb3
]) # gl_FUNC_STRSTR