strstr.m4 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # strstr.m4 serial 17
  2. dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
  3. dnl This file is free software; the Free Software Foundation
  4. dnl gives unlimited permission to copy and/or distribute it,
  5. dnl with or without modifications, as long as this notice is preserved.
  6. dnl Check that strstr works.
  7. AC_DEFUN([gl_FUNC_STRSTR_SIMPLE],
  8. [
  9. AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
  10. AC_REQUIRE([gl_FUNC_MEMCHR])
  11. if test "$gl_cv_func_memchr_works" != yes; then
  12. REPLACE_STRSTR=1
  13. else
  14. dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092.
  15. AC_CACHE_CHECK([whether strstr works],
  16. [gl_cv_func_strstr_works_always],
  17. [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
  18. #include <string.h> /* for strstr */
  19. #define P "_EF_BF_BD"
  20. #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P
  21. #define NEEDLE P P P P P
  22. ]], [[return !!strstr (HAYSTACK, NEEDLE);
  23. ]])],
  24. [gl_cv_func_strstr_works_always=yes],
  25. [gl_cv_func_strstr_works_always=no],
  26. [dnl glibc 2.12 and cygwin 1.7.7 have a known bug. uClibc is not
  27. dnl affected, since it uses different source code for strstr than
  28. dnl glibc.
  29. dnl Assume that it works on all other platforms, even if it is not
  30. dnl linear.
  31. AC_EGREP_CPP([Lucky user],
  32. [
  33. #ifdef __GNU_LIBRARY__
  34. #include <features.h>
  35. #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
  36. || defined __UCLIBC__
  37. Lucky user
  38. #endif
  39. #elif defined __CYGWIN__
  40. #include <cygwin/version.h>
  41. #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
  42. Lucky user
  43. #endif
  44. #else
  45. Lucky user
  46. #endif
  47. ],
  48. [gl_cv_func_strstr_works_always="guessing yes"],
  49. [gl_cv_func_strstr_works_always="guessing no"])
  50. ])
  51. ])
  52. case "$gl_cv_func_strstr_works_always" in
  53. *yes) ;;
  54. *)
  55. REPLACE_STRSTR=1
  56. ;;
  57. esac
  58. fi
  59. ]) # gl_FUNC_STRSTR_SIMPLE
  60. dnl Additionally, check that strstr is efficient.
  61. AC_DEFUN([gl_FUNC_STRSTR],
  62. [
  63. AC_REQUIRE([gl_FUNC_STRSTR_SIMPLE])
  64. if test $REPLACE_STRSTR = 0; then
  65. AC_CACHE_CHECK([whether strstr works in linear time],
  66. [gl_cv_func_strstr_linear],
  67. [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
  68. #ifdef __MVS__
  69. /* z/OS does not deliver signals while strstr() is running (thanks to
  70. restrictions on its LE runtime), which prevents us from limiting the
  71. running time of this test. */
  72. # error "This test does not work properly on z/OS"
  73. #endif
  74. #include <signal.h> /* for signal */
  75. #include <string.h> /* for strstr */
  76. #include <stdlib.h> /* for malloc */
  77. #include <unistd.h> /* for alarm */
  78. static void quit (int sig) { _exit (sig + 128); }
  79. ]], [[
  80. int result = 0;
  81. size_t m = 1000000;
  82. char *haystack = (char *) malloc (2 * m + 2);
  83. char *needle = (char *) malloc (m + 2);
  84. /* Failure to compile this test due to missing alarm is okay,
  85. since all such platforms (mingw) also have quadratic strstr. */
  86. signal (SIGALRM, quit);
  87. alarm (5);
  88. /* Check for quadratic performance. */
  89. if (haystack && needle)
  90. {
  91. memset (haystack, 'A', 2 * m);
  92. haystack[2 * m] = 'B';
  93. haystack[2 * m + 1] = 0;
  94. memset (needle, 'A', m);
  95. needle[m] = 'B';
  96. needle[m + 1] = 0;
  97. if (!strstr (haystack, needle))
  98. result |= 1;
  99. }
  100. return result;
  101. ]])],
  102. [gl_cv_func_strstr_linear=yes], [gl_cv_func_strstr_linear=no],
  103. [dnl Only glibc > 2.12 on processors without SSE 4.2 instructions and
  104. dnl cygwin > 1.7.7 are known to have a bug-free strstr that works in
  105. dnl linear time.
  106. AC_EGREP_CPP([Lucky user],
  107. [
  108. #include <features.h>
  109. #ifdef __GNU_LIBRARY__
  110. #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
  111. && !(defined __i386__ || defined __x86_64__) \
  112. && !defined __UCLIBC__
  113. Lucky user
  114. #endif
  115. #endif
  116. #ifdef __CYGWIN__
  117. #include <cygwin/version.h>
  118. #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 7)
  119. Lucky user
  120. #endif
  121. #endif
  122. ],
  123. [gl_cv_func_strstr_linear="guessing yes"],
  124. [gl_cv_func_strstr_linear="guessing no"])
  125. ])
  126. ])
  127. case "$gl_cv_func_strstr_linear" in
  128. *yes) ;;
  129. *)
  130. REPLACE_STRSTR=1
  131. ;;
  132. esac
  133. fi
  134. ]) # gl_FUNC_STRSTR