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