Blame m4/strstr.m4

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