1# serial 73 2 3# Copyright (C) 1996-2001, 2003-2021 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 94 { 95 if (re_search (®ex, data, sizeof data - 1, 96 0, sizeof data - 1, ®s) 97 != -1) 98 result |= 1; 99 regfree (®ex); 100 } 101 } 102 103 { 104 /* This test is from glibc bug 15078. 105 The test case is from Andreas Schwab in 106 <https://sourceware.org/ml/libc-alpha/2013-01/msg00967.html>. 107 */ 108 static char const pat[] = "[^x]x"; 109 static char const data[] = 110 /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */ 111 "\xe1\x80\x80" 112 "\xe1\x80\xbb" 113 "\xe1\x80\xbd" 114 "\xe1\x80\x94" 115 "\xe1\x80\xba" 116 "\xe1\x80\xaf" 117 "\xe1\x80\x95" 118 "\xe1\x80\xba" 119 "x"; 120 re_set_syntax (0); 121 memset (®ex, 0, sizeof regex); 122 s = re_compile_pattern (pat, sizeof pat - 1, ®ex); 123 if (s) 124 result |= 1; 125 else 126 { 127 i = re_search (®ex, data, sizeof data - 1, 128 0, sizeof data - 1, 0); 129 if (i != 0 && i != 21) 130 result |= 1; 131 regfree (®ex); 132 } 133 } 134 135 if (! setlocale (LC_ALL, "C")) 136 return 1; 137 } 138 139 /* This test is from glibc bug 3957, reported by Andrew Mackey. */ 140 re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE); 141 memset (®ex, 0, sizeof regex); 142 s = re_compile_pattern ("a[^x]b", 6, ®ex); 143 if (s) 144 result |= 2; 145 else 146 { 147 /* This should fail, but succeeds for glibc-2.5. */ 148 if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) 149 result |= 2; 150 regfree (®ex); 151 } 152 153 /* This regular expression is from Spencer ere test number 75 154 in grep-2.3. */ 155 re_set_syntax (RE_SYNTAX_POSIX_EGREP); 156 memset (®ex, 0, sizeof regex); 157 for (i = 0; i <= UCHAR_MAX; i++) 158 folded_chars[i] = i; 159 regex.translate = folded_chars; 160 s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); 161 /* This should fail with _Invalid character class name_ error. */ 162 if (!s) 163 { 164 result |= 4; 165 regfree (®ex); 166 } 167 168 /* Ensure that [b-a] is diagnosed as invalid, when 169 using RE_NO_EMPTY_RANGES. */ 170 re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES); 171 memset (®ex, 0, sizeof regex); 172 s = re_compile_pattern ("a[b-a]", 6, ®ex); 173 if (s == 0) 174 { 175 result |= 8; 176 regfree (®ex); 177 } 178 179 /* This should succeed, but does not for glibc-2.1.3. */ 180 memset (®ex, 0, sizeof regex); 181 s = re_compile_pattern ("{1", 2, ®ex); 182 if (s) 183 result |= 8; 184 else 185 regfree (®ex); 186 187 /* The following example is derived from a problem report 188 against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */ 189 memset (®ex, 0, sizeof regex); 190 s = re_compile_pattern ("[an\371]*n", 7, ®ex); 191 if (s) 192 result |= 8; 193 else 194 { 195 /* This should match, but does not for glibc-2.2.1. */ 196 if (re_match (®ex, "an", 2, 0, ®s) != 2) 197 result |= 8; 198 else 199 { 200 free (regs.start); 201 free (regs.end); 202 } 203 regfree (®ex); 204 } 205 206 memset (®ex, 0, sizeof regex); 207 s = re_compile_pattern ("x", 1, ®ex); 208 if (s) 209 result |= 8; 210 else 211 { 212 /* glibc-2.2.93 does not work with a negative RANGE argument. */ 213 if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) 214 result |= 8; 215 else 216 { 217 free (regs.start); 218 free (regs.end); 219 } 220 regfree (®ex); 221 } 222 223 /* The version of regex.c in older versions of gnulib 224 ignored RE_ICASE. Detect that problem too. */ 225 re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE); 226 memset (®ex, 0, sizeof regex); 227 s = re_compile_pattern ("x", 1, ®ex); 228 if (s) 229 result |= 16; 230 else 231 { 232 if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) 233 result |= 16; 234 else 235 { 236 free (regs.start); 237 free (regs.end); 238 } 239 regfree (®ex); 240 } 241 242 /* Catch a bug reported by Vin Shelton in 243 https://lists.gnu.org/r/bug-coreutils/2007-06/msg00089.html 244 */ 245 re_set_syntax (RE_SYNTAX_POSIX_BASIC 246 & ~RE_CONTEXT_INVALID_DUP 247 & ~RE_NO_EMPTY_RANGES); 248 memset (®ex, 0, sizeof regex); 249 s = re_compile_pattern ("[[:alnum:]_-]\\\\+\$", 16, ®ex); 250 if (s) 251 result |= 32; 252 else 253 regfree (®ex); 254 255 /* REG_STARTEND was added to glibc on 2004-01-15. 256 Reject older versions. */ 257 if (! REG_STARTEND) 258 result |= 64; 259 260 /* Matching with the compiled form of this regexp would provoke 261 an assertion failure prior to glibc-2.28: 262 regexec.c:1375: pop_fail_stack: Assertion 'num >= 0' failed 263 With glibc-2.28, compilation fails and reports the invalid 264 back reference. */ 265 re_set_syntax (RE_SYNTAX_POSIX_EGREP); 266 memset (®ex, 0, sizeof regex); 267 s = re_compile_pattern ("0|()0|\\\\1|0", 10, ®ex); 268 if (!s) 269 { 270 memset (®s, 0, sizeof regs); 271 i = re_search (®ex, "x", 1, 0, 1, ®s); 272 if (i != -1) 273 result |= 64; 274 if (0 <= i) 275 { 276 free (regs.start); 277 free (regs.end); 278 } 279 regfree (®ex); 280 } 281 else 282 { 283 if (strcmp (s, "Invalid back reference")) 284 result |= 64; 285 } 286 287 /* glibc bug 11053. */ 288 re_set_syntax (RE_SYNTAX_POSIX_BASIC); 289 memset (®ex, 0, sizeof regex); 290 static char const pat_sub2[] = "\\\\(a*\\\\)*a*\\\\1"; 291 s = re_compile_pattern (pat_sub2, sizeof pat_sub2 - 1, ®ex); 292 if (s) 293 result |= 64; 294 else 295 { 296 memset (®s, 0, sizeof regs); 297 static char const data[] = "a"; 298 int datalen = sizeof data - 1; 299 i = re_search (®ex, data, datalen, 0, datalen, ®s); 300 if (i != 0) 301 result |= 64; 302 else if (regs.num_regs < 2) 303 result |= 64; 304 else if (! (regs.start[0] == 0 && regs.end[0] == 1)) 305 result |= 64; 306 else if (! (regs.start[1] == 0 && regs.end[1] == 0)) 307 result |= 64; 308 regfree (®ex); 309 free (regs.start); 310 free (regs.end); 311 } 312 313#if 0 314 /* It would be nice to reject hosts whose regoff_t values are too 315 narrow (including glibc on hosts with 64-bit ptrdiff_t and 316 32-bit int), but we should wait until glibc implements this 317 feature. Otherwise, support for equivalence classes and 318 multibyte collation symbols would always be broken except 319 when compiling --without-included-regex. */ 320 if (sizeof (regoff_t) < sizeof (ptrdiff_t) 321 || sizeof (regoff_t) < sizeof (ssize_t)) 322 result |= 64; 323#endif 324 325 return result; 326 ]])], 327 [gl_cv_func_re_compile_pattern_working=yes], 328 [gl_cv_func_re_compile_pattern_working=no], 329 [case "$host_os" in 330 # Guess no on native Windows. 331 mingw*) gl_cv_func_re_compile_pattern_working="guessing no" ;; 332 # Otherwise obey --enable-cross-guesses. 333 *) gl_cv_func_re_compile_pattern_working="$gl_cross_guess_normal" ;; 334 esac 335 ]) 336 ]) 337 case "$gl_cv_func_re_compile_pattern_working" in #( 338 *yes) ac_use_included_regex=no;; #( 339 *no) ac_use_included_regex=yes;; 340 esac 341 ;; 342 *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) 343 ;; 344 esac 345 346 if test $ac_use_included_regex = yes; then 347 AC_DEFINE([_REGEX_INCLUDE_LIMITS_H], [1], 348 [Define if you want <regex.h> to include <limits.h>, so that it 349 consistently overrides <limits.h>'s RE_DUP_MAX.]) 350 AC_DEFINE([_REGEX_LARGE_OFFSETS], [1], 351 [Define if you want regoff_t to be at least as wide POSIX requires.]) 352 AC_DEFINE([re_syntax_options], [rpl_re_syntax_options], 353 [Define to rpl_re_syntax_options if the replacement should be used.]) 354 AC_DEFINE([re_set_syntax], [rpl_re_set_syntax], 355 [Define to rpl_re_set_syntax if the replacement should be used.]) 356 AC_DEFINE([re_compile_pattern], [rpl_re_compile_pattern], 357 [Define to rpl_re_compile_pattern if the replacement should be used.]) 358 AC_DEFINE([re_compile_fastmap], [rpl_re_compile_fastmap], 359 [Define to rpl_re_compile_fastmap if the replacement should be used.]) 360 AC_DEFINE([re_search], [rpl_re_search], 361 [Define to rpl_re_search if the replacement should be used.]) 362 AC_DEFINE([re_search_2], [rpl_re_search_2], 363 [Define to rpl_re_search_2 if the replacement should be used.]) 364 AC_DEFINE([re_match], [rpl_re_match], 365 [Define to rpl_re_match if the replacement should be used.]) 366 AC_DEFINE([re_match_2], [rpl_re_match_2], 367 [Define to rpl_re_match_2 if the replacement should be used.]) 368 AC_DEFINE([re_set_registers], [rpl_re_set_registers], 369 [Define to rpl_re_set_registers if the replacement should be used.]) 370 AC_DEFINE([re_comp], [rpl_re_comp], 371 [Define to rpl_re_comp if the replacement should be used.]) 372 AC_DEFINE([re_exec], [rpl_re_exec], 373 [Define to rpl_re_exec if the replacement should be used.]) 374 AC_DEFINE([regcomp], [rpl_regcomp], 375 [Define to rpl_regcomp if the replacement should be used.]) 376 AC_DEFINE([regexec], [rpl_regexec], 377 [Define to rpl_regexec if the replacement should be used.]) 378 AC_DEFINE([regerror], [rpl_regerror], 379 [Define to rpl_regerror if the replacement should be used.]) 380 AC_DEFINE([regfree], [rpl_regfree], 381 [Define to rpl_regfree if the replacement should be used.]) 382 fi 383]) 384 385# Prerequisites of lib/regex.c and lib/regex_internal.c. 386AC_DEFUN([gl_PREREQ_REGEX], 387[ 388 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 389 AC_REQUIRE([AC_C_INLINE]) 390 AC_REQUIRE([AC_C_RESTRICT]) 391 AC_REQUIRE([AC_TYPE_MBSTATE_T]) 392 AC_REQUIRE([gl_EEMALLOC]) 393 AC_CHECK_HEADERS([libintl.h]) 394 AC_CHECK_FUNCS_ONCE([isblank iswctype]) 395 AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]]) 396]) 397