1# serial 69 2 3# Copyright (C) 1996-2001, 2003-2020 Free Software Foundation, Inc. 4# 5# This file is free software; the Free Software Foundation 6# gives unlimited permission to copy and/or distribute it, 7# with or without modifications, as long as this notice is preserved. 8 9dnl Initially derived from code in GNU grep. 10dnl Mostly written by Jim Meyering. 11 12AC_PREREQ([2.50]) 13 14AC_DEFUN([gl_REGEX], 15[ 16 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 17 AC_ARG_WITH([included-regex], 18 [AS_HELP_STRING([--without-included-regex], 19 [don't compile regex; this is the default on systems 20 with recent-enough versions of the GNU C Library 21 (use with caution on other systems).])]) 22 23 case $with_included_regex in #( 24 yes|no) ac_use_included_regex=$with_included_regex 25 ;; 26 '') 27 # If the system regex support is good enough that it passes the 28 # following run test, then default to *not* using the included regex.c. 29 # If cross compiling, assume the test would fail and use the included 30 # regex.c. 31 AC_CHECK_DECLS_ONCE([alarm]) 32 AC_CHECK_HEADERS_ONCE([malloc.h]) 33 AC_CACHE_CHECK([for working re_compile_pattern], 34 [gl_cv_func_re_compile_pattern_working], 35 [AC_RUN_IFELSE( 36 [AC_LANG_PROGRAM( 37 [[#include <regex.h> 38 39 #include <locale.h> 40 #include <limits.h> 41 #include <string.h> 42 43 #if defined M_CHECK_ACTION || HAVE_DECL_ALARM 44 # include <signal.h> 45 # include <unistd.h> 46 #endif 47 48 #if HAVE_MALLOC_H 49 # include <malloc.h> 50 #endif 51 52 #ifdef M_CHECK_ACTION 53 /* Exit with distinguishable exit code. */ 54 static void sigabrt_no_core (int sig) { raise (SIGTERM); } 55 #endif 56 ]], 57 [[int result = 0; 58 static struct re_pattern_buffer regex; 59 unsigned char folded_chars[UCHAR_MAX + 1]; 60 int i; 61 const char *s; 62 struct re_registers regs; 63 64 /* Some builds of glibc go into an infinite loop on this 65 test. Use alarm to force death, and mallopt to avoid 66 malloc recursion in diagnosing the corrupted heap. */ 67#if HAVE_DECL_ALARM 68 signal (SIGALRM, SIG_DFL); 69 alarm (2); 70#endif 71#ifdef M_CHECK_ACTION 72 signal (SIGABRT, sigabrt_no_core); 73 mallopt (M_CHECK_ACTION, 2); 74#endif 75 76 if (setlocale (LC_ALL, "en_US.UTF-8")) 77 { 78 { 79 /* https://sourceware.org/ml/libc-hacker/2006-09/msg00008.html 80 This test needs valgrind to catch the bug on Debian 81 GNU/Linux 3.1 x86, but it might catch the bug better 82 on other platforms and it shouldn't hurt to try the 83 test here. */ 84 static char const pat[] = "insert into"; 85 static char const data[] = 86 "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK"; 87 re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE 88 | RE_ICASE); 89 memset (®ex, 0, sizeof regex); 90 s = re_compile_pattern (pat, sizeof pat - 1, ®ex); 91 if (s) 92 result |= 1; 93 else if (re_search (®ex, data, sizeof data - 1, 94 0, sizeof data - 1, ®s) 95 != -1) 96 result |= 1; 97 regfree (®ex); 98 } 99 100 { 101 /* This test is from glibc bug 15078. 102 The test case is from Andreas Schwab in 103 <https://sourceware.org/ml/libc-alpha/2013-01/msg00967.html>. 104 */ 105 static char const pat[] = "[^x]x"; 106 static char const data[] = 107 /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */ 108 "\xe1\x80\x80" 109 "\xe1\x80\xbb" 110 "\xe1\x80\xbd" 111 "\xe1\x80\x94" 112 "\xe1\x80\xba" 113 "\xe1\x80\xaf" 114 "\xe1\x80\x95" 115 "\xe1\x80\xba" 116 "x"; 117 re_set_syntax (0); 118 memset (®ex, 0, sizeof regex); 119 s = re_compile_pattern (pat, sizeof pat - 1, ®ex); 120 if (s) 121 result |= 1; 122 else 123 { 124 i = re_search (®ex, data, sizeof data - 1, 125 0, sizeof data - 1, 0); 126 if (i != 0 && i != 21) 127 result |= 1; 128 } 129 regfree (®ex); 130 } 131 132 if (! setlocale (LC_ALL, "C")) 133 return 1; 134 } 135 136 /* This test is from glibc bug 3957, reported by Andrew Mackey. */ 137 re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE); 138 memset (®ex, 0, sizeof regex); 139 s = re_compile_pattern ("a[^x]b", 6, ®ex); 140 if (s) 141 result |= 2; 142 /* This should fail, but succeeds for glibc-2.5. */ 143 else if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) 144 result |= 2; 145 146 /* This regular expression is from Spencer ere test number 75 147 in grep-2.3. */ 148 re_set_syntax (RE_SYNTAX_POSIX_EGREP); 149 memset (®ex, 0, sizeof regex); 150 for (i = 0; i <= UCHAR_MAX; i++) 151 folded_chars[i] = i; 152 regex.translate = folded_chars; 153 s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); 154 /* This should fail with _Invalid character class name_ error. */ 155 if (!s) 156 result |= 4; 157 158 /* Ensure that [b-a] is diagnosed as invalid, when 159 using RE_NO_EMPTY_RANGES. */ 160 re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES); 161 memset (®ex, 0, sizeof regex); 162 s = re_compile_pattern ("a[b-a]", 6, ®ex); 163 if (s == 0) 164 result |= 8; 165 166 /* This should succeed, but does not for glibc-2.1.3. */ 167 memset (®ex, 0, sizeof regex); 168 s = re_compile_pattern ("{1", 2, ®ex); 169 if (s) 170 result |= 8; 171 172 /* The following example is derived from a problem report 173 against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */ 174 memset (®ex, 0, sizeof regex); 175 s = re_compile_pattern ("[an\371]*n", 7, ®ex); 176 if (s) 177 result |= 8; 178 /* This should match, but does not for glibc-2.2.1. */ 179 else if (re_match (®ex, "an", 2, 0, ®s) != 2) 180 result |= 8; 181 182 memset (®ex, 0, sizeof regex); 183 s = re_compile_pattern ("x", 1, ®ex); 184 if (s) 185 result |= 8; 186 /* glibc-2.2.93 does not work with a negative RANGE argument. */ 187 else if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) 188 result |= 8; 189 190 /* The version of regex.c in older versions of gnulib 191 ignored RE_ICASE. Detect that problem too. */ 192 re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE); 193 memset (®ex, 0, sizeof regex); 194 s = re_compile_pattern ("x", 1, ®ex); 195 if (s) 196 result |= 16; 197 else if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) 198 result |= 16; 199 200 /* Catch a bug reported by Vin Shelton in 201 https://lists.gnu.org/r/bug-coreutils/2007-06/msg00089.html 202 */ 203 re_set_syntax (RE_SYNTAX_POSIX_BASIC 204 & ~RE_CONTEXT_INVALID_DUP 205 & ~RE_NO_EMPTY_RANGES); 206 memset (®ex, 0, sizeof regex); 207 s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); 208 if (s) 209 result |= 32; 210 211 /* REG_STARTEND was added to glibc on 2004-01-15. 212 Reject older versions. */ 213 if (! REG_STARTEND) 214 result |= 64; 215 216 /* Matching with the compiled form of this regexp would provoke 217 an assertion failure prior to glibc-2.28: 218 regexec.c:1375: pop_fail_stack: Assertion 'num >= 0' failed 219 With glibc-2.28, compilation fails and reports the invalid 220 back reference. */ 221 re_set_syntax (RE_SYNTAX_POSIX_EGREP); 222 memset (®ex, 0, sizeof regex); 223 s = re_compile_pattern ("0|()0|\\1|0", 10, ®ex); 224 if (!s || strcmp (s, "Invalid back reference")) 225 result |= 64; 226 227#if 0 228 /* It would be nice to reject hosts whose regoff_t values are too 229 narrow (including glibc on hosts with 64-bit ptrdiff_t and 230 32-bit int), but we should wait until glibc implements this 231 feature. Otherwise, support for equivalence classes and 232 multibyte collation symbols would always be broken except 233 when compiling --without-included-regex. */ 234 if (sizeof (regoff_t) < sizeof (ptrdiff_t) 235 || sizeof (regoff_t) < sizeof (ssize_t)) 236 result |= 64; 237#endif 238 239 return result; 240 ]])], 241 [gl_cv_func_re_compile_pattern_working=yes], 242 [gl_cv_func_re_compile_pattern_working=no], 243 [case "$host_os" in 244 # Guess no on native Windows. 245 mingw*) gl_cv_func_re_compile_pattern_working="guessing no" ;; 246 # Otherwise obey --enable-cross-guesses. 247 *) gl_cv_func_re_compile_pattern_working="$gl_cross_guess_normal" ;; 248 esac 249 ]) 250 ]) 251 case "$gl_cv_func_re_compile_pattern_working" in #( 252 *yes) ac_use_included_regex=no;; #( 253 *no) ac_use_included_regex=yes;; 254 esac 255 ;; 256 *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) 257 ;; 258 esac 259 260 if test $ac_use_included_regex = yes; then 261 AC_DEFINE([_REGEX_INCLUDE_LIMITS_H], [1], 262 [Define if you want <regex.h> to include <limits.h>, so that it 263 consistently overrides <limits.h>'s RE_DUP_MAX.]) 264 AC_DEFINE([_REGEX_LARGE_OFFSETS], [1], 265 [Define if you want regoff_t to be at least as wide POSIX requires.]) 266 AC_DEFINE([re_syntax_options], [rpl_re_syntax_options], 267 [Define to rpl_re_syntax_options if the replacement should be used.]) 268 AC_DEFINE([re_set_syntax], [rpl_re_set_syntax], 269 [Define to rpl_re_set_syntax if the replacement should be used.]) 270 AC_DEFINE([re_compile_pattern], [rpl_re_compile_pattern], 271 [Define to rpl_re_compile_pattern if the replacement should be used.]) 272 AC_DEFINE([re_compile_fastmap], [rpl_re_compile_fastmap], 273 [Define to rpl_re_compile_fastmap if the replacement should be used.]) 274 AC_DEFINE([re_search], [rpl_re_search], 275 [Define to rpl_re_search if the replacement should be used.]) 276 AC_DEFINE([re_search_2], [rpl_re_search_2], 277 [Define to rpl_re_search_2 if the replacement should be used.]) 278 AC_DEFINE([re_match], [rpl_re_match], 279 [Define to rpl_re_match if the replacement should be used.]) 280 AC_DEFINE([re_match_2], [rpl_re_match_2], 281 [Define to rpl_re_match_2 if the replacement should be used.]) 282 AC_DEFINE([re_set_registers], [rpl_re_set_registers], 283 [Define to rpl_re_set_registers if the replacement should be used.]) 284 AC_DEFINE([re_comp], [rpl_re_comp], 285 [Define to rpl_re_comp if the replacement should be used.]) 286 AC_DEFINE([re_exec], [rpl_re_exec], 287 [Define to rpl_re_exec if the replacement should be used.]) 288 AC_DEFINE([regcomp], [rpl_regcomp], 289 [Define to rpl_regcomp if the replacement should be used.]) 290 AC_DEFINE([regexec], [rpl_regexec], 291 [Define to rpl_regexec if the replacement should be used.]) 292 AC_DEFINE([regerror], [rpl_regerror], 293 [Define to rpl_regerror if the replacement should be used.]) 294 AC_DEFINE([regfree], [rpl_regfree], 295 [Define to rpl_regfree if the replacement should be used.]) 296 fi 297]) 298 299# Prerequisites of lib/regex.c and lib/regex_internal.c. 300AC_DEFUN([gl_PREREQ_REGEX], 301[ 302 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 303 AC_REQUIRE([AC_C_INLINE]) 304 AC_REQUIRE([AC_C_RESTRICT]) 305 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 306 AC_REQUIRE([gl_EEMALLOC]) 307 AC_REQUIRE([gl_GLIBC21]) 308 AC_CHECK_HEADERS([libintl.h]) 309 AC_CHECK_FUNCS_ONCE([isblank iswctype]) 310 AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]]) 311]) 312