Blame m4/strstr.m4

Packit 8f70b4
# strstr.m4 serial 19
Packit 8f70b4
dnl Copyright (C) 2008-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 strstr works.
Packit 8f70b4
AC_DEFUN([gl_FUNC_STRSTR_SIMPLE],
Packit 8f70b4
[
Packit 8f70b4
  AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
Packit 8f70b4
  AC_REQUIRE([gl_FUNC_MEMCHR])
Packit 8f70b4
  if test $HAVE_MEMCHR = 0 || test $REPLACE_MEMCHR = 1; then
Packit 8f70b4
    REPLACE_STRSTR=1
Packit 8f70b4
  else
Packit 8f70b4
    dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092.
Packit 8f70b4
    AC_CACHE_CHECK([whether strstr works],
Packit 8f70b4
      [gl_cv_func_strstr_works_always],
Packit 8f70b4
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
Packit 8f70b4
#include <string.h> /* for strstr */
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
]], [[return !!strstr (HAYSTACK, NEEDLE);
Packit 8f70b4
    ]])],
Packit 8f70b4
        [gl_cv_func_strstr_works_always=yes],
Packit 8f70b4
        [gl_cv_func_strstr_works_always=no],
Packit 8f70b4
        [dnl glibc 2.12 and cygwin 1.7.7 have a known bug.  uClibc is not
Packit 8f70b4
         dnl affected, since it uses different source code for strstr than
Packit 8f70b4
         dnl glibc.
Packit 8f70b4
         dnl Assume that it works on all other platforms, even if it is not
Packit 8f70b4
         dnl 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__ > 12) || (__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_strstr_works_always="guessing yes"],
Packit 8f70b4
           [gl_cv_func_strstr_works_always="guessing no"])
Packit 8f70b4
        ])
Packit 8f70b4
      ])
Packit 8f70b4
    case "$gl_cv_func_strstr_works_always" in
Packit 8f70b4
      *yes) ;;
Packit 8f70b4
      *)
Packit 8f70b4
        REPLACE_STRSTR=1
Packit 8f70b4
        ;;
Packit 8f70b4
    esac
Packit 8f70b4
  fi
Packit 8f70b4
]) # gl_FUNC_STRSTR_SIMPLE
Packit 8f70b4
Packit 8f70b4
dnl Additionally, check that strstr is efficient.
Packit 8f70b4
AC_DEFUN([gl_FUNC_STRSTR],
Packit 8f70b4
[
Packit 8f70b4
  AC_REQUIRE([gl_FUNC_STRSTR_SIMPLE])
Packit 8f70b4
  if test $REPLACE_STRSTR = 0; then
Packit 8f70b4
    AC_CACHE_CHECK([whether strstr works in linear time],
Packit 8f70b4
      [gl_cv_func_strstr_linear],
Packit 8f70b4
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
Packit 8f70b4
#ifdef __MVS__
Packit 8f70b4
/* z/OS does not deliver signals while strstr() is running (thanks to
Packit 8f70b4
   restrictions on its LE runtime), which prevents us from limiting the
Packit 8f70b4
   running time of this test.  */
Packit 8f70b4
# error "This test does not work properly on z/OS"
Packit 8f70b4
#endif
Packit 8f70b4
#include <signal.h> /* for signal */
Packit 8f70b4
#include <string.h> /* for strstr */
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 + 2);
Packit 8f70b4
    char *needle = (char *) malloc (m + 2);
Packit 8f70b4
    /* Failure to compile this test due to missing alarm is okay,
Packit 8f70b4
       since all such platforms (mingw) also have quadratic strstr.  */
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
        haystack[2 * m + 1] = 0;
Packit 8f70b4
        memset (needle, 'A', m);
Packit 8f70b4
        needle[m] = 'B';
Packit 8f70b4
        needle[m + 1] = 0;
Packit 8f70b4
        if (!strstr (haystack, needle))
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_strstr_linear=yes], [gl_cv_func_strstr_linear=no],
Packit 8f70b4
        [dnl Only glibc > 2.12 on processors without SSE 4.2 instructions and
Packit 8f70b4
         dnl cygwin > 1.7.7 are known to have a bug-free strstr that works in
Packit 8f70b4
         dnl 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__ > 12) || (__GLIBC__ > 2)) \
Packit 8f70b4
     && !(defined __i386__ || defined __x86_64__) \
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, 7)
Packit 8f70b4
  Lucky user
Packit 8f70b4
 #endif
Packit 8f70b4
#endif
Packit 8f70b4
           ],
Packit 8f70b4
           [gl_cv_func_strstr_linear="guessing yes"],
Packit 8f70b4
           [gl_cv_func_strstr_linear="guessing no"])
Packit 8f70b4
        ])
Packit 8f70b4
      ])
Packit 8f70b4
    case "$gl_cv_func_strstr_linear" in
Packit 8f70b4
      *yes) ;;
Packit 8f70b4
      *)
Packit 8f70b4
        REPLACE_STRSTR=1
Packit 8f70b4
        ;;
Packit 8f70b4
    esac
Packit 8f70b4
  fi
Packit 8f70b4
]) # gl_FUNC_STRSTR