Update spec to require automake >= 1.13
[platform/upstream/gawk.git] / re.c
1 /*
2  * re.c - compile regular expressions.
3  */
4
5 /* 
6  * Copyright (C) 1991-2013 the Free Software Foundation, Inc.
7  * 
8  * This file is part of GAWK, the GNU implementation of the
9  * AWK Programming Language.
10  * 
11  * GAWK is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  * 
16  * GAWK is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25
26 #include "awk.h"
27
28 static reg_syntax_t syn;
29 static void check_bracket_exp(char *s, size_t len);
30 const char *regexflags2str(int flags);
31
32 /* make_regexp --- generate compiled regular expressions */
33
34 Regexp *
35 make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal)
36 {
37         static char metas[] = ".*+(){}[]|?^$\\";
38         Regexp *rp;
39         const char *rerr;
40         const char *src = s;
41         static char *buf = NULL;
42         static size_t buflen;
43         const char *end = s + len;
44         char *dest;
45         int c, c2;
46         static bool first = true;
47         static bool no_dfa = false;
48         bool has_anchor = false;
49         reg_syntax_t dfa_syn;
50         int i;
51
52         /*
53          * The number of bytes in the current multibyte character.
54          * It is 0, when the current character is a singlebyte character.
55          */
56         size_t is_multibyte = 0;
57 #if MBS_SUPPORT
58         mbstate_t mbs;
59
60         if (gawk_mb_cur_max > 1)
61                 memset(&mbs, 0, sizeof(mbstate_t)); /* Initialize.  */
62 #endif
63
64         if (first) {
65                 first = false;
66                 /* for debugging and testing */
67                 no_dfa = (getenv("GAWK_NO_DFA") != NULL);
68         }
69
70         /* always check */
71         check_bracket_exp((char *) s, len);
72
73         /* Handle escaped characters first. */
74
75         /*
76          * Build a copy of the string (in buf) with the
77          * escaped characters translated, and generate the regex
78          * from that. 
79          */
80         if (buf == NULL) {
81                 emalloc(buf, char *, len + 2, "make_regexp");
82                 buflen = len;
83         } else if (len > buflen) {
84                 erealloc(buf, char *, len + 2, "make_regexp");
85                 buflen = len;
86         }
87         dest = buf;
88
89         while (src < end) {
90 #if MBS_SUPPORT
91                 if (gawk_mb_cur_max > 1 && ! is_multibyte) {
92                         /* The previous byte is a singlebyte character, or last byte
93                            of a multibyte character.  We check the next character.  */
94                         is_multibyte = mbrlen(src, end - src, &mbs);
95                         if (   is_multibyte == 1
96                             || is_multibyte == (size_t) -1
97                             || is_multibyte == (size_t) -2
98                             || is_multibyte == 0) {
99                                 /* We treat it as a single-byte character.  */
100                                 is_multibyte = 0;
101                         }
102                 }
103 #endif
104
105                 /* We skip multibyte character, since it must not be a special
106                    character.  */
107                 if ((gawk_mb_cur_max == 1 || ! is_multibyte) &&
108                     (*src == '\\')) {
109                         c = *++src;
110                         switch (c) {
111                         case 'a':
112                         case 'b':
113                         case 'f':
114                         case 'n':
115                         case 'r':
116                         case 't':
117                         case 'v':
118                         case 'x':
119                         case '0':
120                         case '1':
121                         case '2':
122                         case '3':
123                         case '4':
124                         case '5':
125                         case '6':
126                         case '7':
127                                 c2 = parse_escape(&src);
128                                 if (c2 < 0)
129                                         cant_happen();
130                                 /*
131                                  * Unix awk treats octal (and hex?) chars
132                                  * literally in re's, so escape regexp
133                                  * metacharacters.
134                                  */
135                                 if (do_traditional
136                                     && ! do_posix
137                                     && (isdigit(c) || c == 'x')
138                                     && strchr("()|*+?.^$\\[]", c2) != NULL)
139                                         *dest++ = '\\';
140                                 *dest++ = (char) c2;
141                                 break;
142                         case '8':
143                         case '9':       /* a\9b not valid */
144                                 *dest++ = c;
145                                 src++;
146                                 break;
147                         case 'y':       /* normally \b */
148                                 /* gnu regex op */
149                                 if (! do_traditional) {
150                                         *dest++ = '\\';
151                                         *dest++ = 'b';
152                                         src++;
153                                         break;
154                                 }
155                                 /* else, fall through */
156                         default:
157                                 *dest++ = '\\';
158                                 *dest++ = (char) c;
159                                 src++;
160                                 break;
161                         } /* switch */
162                 } else {
163                         c = *src;
164                         if (c == '^' || c == '$')
165                                 has_anchor = true;
166
167                         *dest++ = *src++;       /* not '\\' */
168                 }
169                 if (gawk_mb_cur_max > 1 && is_multibyte)
170                         is_multibyte--;
171         } /* while */
172
173         *dest = '\0';
174         len = dest - buf;
175
176         emalloc(rp, Regexp *, sizeof(*rp), "make_regexp");
177         memset((char *) rp, 0, sizeof(*rp));
178         rp->dfareg = NULL;
179         rp->pat.allocated = 0;  /* regex will allocate the buffer */
180         emalloc(rp->pat.fastmap, char *, 256, "make_regexp");
181
182         /*
183          * Lo these many years ago, had I known what a P.I.T.A. IGNORECASE
184          * was going to turn out to be, I wouldn't have bothered with it.
185          *
186          * In the case where we have a multibyte character set, we have no
187          * choice but to use RE_ICASE, since the casetable is for single-byte
188          * character sets only.
189          *
190          * On the other hand, if we do have a single-byte character set,
191          * using the casetable should give  a performance improvement, since
192          * it's computed only once, not each time a regex is compiled.  We
193          * also think it's probably better for portability.  See the
194          * discussion by the definition of casetable[] in eval.c.
195          */
196
197         ignorecase = !! ignorecase;     /* force to 1 or 0 */
198         if (ignorecase) {
199                 if (gawk_mb_cur_max > 1) {
200                         syn |= RE_ICASE;
201                         rp->pat.translate = NULL;
202                 } else {
203                         syn &= ~RE_ICASE;
204                         rp->pat.translate = (RE_TRANSLATE_TYPE) casetable;
205                 }
206         } else {
207                 rp->pat.translate = NULL;
208                 syn &= ~RE_ICASE;
209         }
210
211         dfa_syn = syn;
212         if (ignorecase)
213                 dfa_syn |= RE_ICASE;
214         dfasyntax(dfa_syn, ignorecase, '\n');
215         re_set_syntax(syn);
216
217         if ((rerr = re_compile_pattern(buf, len, &(rp->pat))) != NULL) {
218                 refree(rp);
219                 if (! canfatal) {
220                         /* rerr already gettextized inside regex routines */
221                         error("%s: /%s/", rerr, buf);
222                         return NULL;
223                 }
224                 fatal("%s: /%s/", rerr, buf);
225         }
226
227         /* gack. this must be done *after* re_compile_pattern */
228         rp->pat.newline_anchor = false; /* don't get \n in middle of string */
229         if (dfa && ! no_dfa) {
230                 rp->dfa = true;
231                 rp->dfareg = dfaalloc();
232                 dfacomp(buf, len, rp->dfareg, true);
233         } else
234                 rp->dfa = false;
235         rp->has_anchor = has_anchor;
236
237         /* Additional flags that help with RS as regexp. */
238         for (i = 0; i < len; i++) {
239                 if (strchr(metas, buf[i]) != NULL) {
240                         rp->has_meta = true;
241                         break;
242                 }
243         }
244
245         for (i = len - 1; i >= 0; i--) {
246                 if (strchr("*+|?", buf[i]) != NULL) {
247                         rp->maybe_long = true;
248                         break;
249                 }
250         }
251  
252         return rp;
253 }
254
255 /* research --- do a regexp search. use dfa if possible */
256
257 int
258 research(Regexp *rp, char *str, int start,
259          size_t len, int flags)
260 {
261         const char *ret = str;
262         int try_backref = false;
263         int need_start;
264         int no_bol;
265         int res;
266
267         need_start = ((flags & RE_NEED_START) != 0);
268         no_bol = ((flags & RE_NO_BOL) != 0);
269
270         if (no_bol)
271                 rp->pat.not_bol = 1;
272
273         /*
274          * Always do dfa search if can; if it fails, then even if
275          * need_start is true, we won't bother with the regex search.
276          *
277          * The dfa matcher doesn't have a no_bol flag, so don't bother
278          * trying it in that case.
279          *
280          * 7/2008: Skip the dfa matcher if need_start. The dfa matcher
281          * has bugs in certain multibyte cases and it's too difficult
282          * to try to special case things.
283          */
284         if (rp->dfa && ! no_bol && ! need_start) {
285                 char save;
286                 size_t count = 0;
287                 /*
288                  * dfa likes to stick a '\n' right after the matched
289                  * text.  So we just save and restore the character.
290                  */
291                 save = str[start+len];
292                 ret = dfaexec(rp->dfareg, str+start, str+start+len, true,
293                                         &count, &try_backref);
294                 str[start+len] = save;
295         }
296
297         if (ret) {
298                 if (need_start || rp->dfa == false || try_backref) {
299                         /*
300                          * Passing NULL as last arg speeds up search for cases
301                          * where we don't need the start/end info.
302                          */
303                         res = re_search(&(rp->pat), str, start+len,
304                                 start, len, need_start ? &(rp->regs) : NULL);
305                 } else
306                         res = 1;
307         } else
308                 res = -1;
309
310         rp->pat.not_bol = 0;
311         return res;
312 }
313
314 /* refree --- free up the dynamic memory used by a compiled regexp */
315
316 void
317 refree(Regexp *rp)
318 {
319         if (rp == NULL)
320                 return; 
321         rp->pat.translate = NULL;
322         regfree(& rp->pat);
323         if (rp->regs.start)
324                 free(rp->regs.start);
325         if (rp->regs.end)
326                 free(rp->regs.end);
327         if (rp->dfa) {
328                 dfafree(rp->dfareg);
329                 free(rp->dfareg);
330         }
331         efree(rp);
332 }
333
334 /* dfaerror --- print an error message for the dfa routines */
335
336 void
337 dfaerror(const char *s)
338 {
339         fatal("%s", s);
340         exit(EXIT_FATAL);       /* for DJGPP */
341 }
342
343 /* re_update --- recompile a dynamic regexp */
344
345 Regexp *
346 re_update(NODE *t)
347 {
348         NODE *t1;
349
350         if ((t->re_flags & CASE) == IGNORECASE) {
351                 /* regex was compiled with settings matching IGNORECASE */
352                 if ((t->re_flags & CONSTANT) != 0) {
353                         /* it's a constant, so just return it as is */
354                         assert(t->type == Node_regex);
355                         return t->re_reg;
356                 }
357                 t1 = t->re_exp;
358                 if (t->re_text != NULL) {
359                         /* if contents haven't changed, just return it */
360                         if (cmp_nodes(t->re_text, t1) == 0)
361                                 return t->re_reg;
362                         /* things changed, fall through to recompile */
363                         unref(t->re_text);
364                 }
365                 /* get fresh copy of the text of the regexp */
366                 t->re_text = dupnode(t1);
367         }
368         /* was compiled with different IGNORECASE or text changed */
369
370         /* free old */
371         if (t->re_reg != NULL)
372                 refree(t->re_reg);
373         if (t->re_cnt > 0)
374                 t->re_cnt++;
375         if (t->re_cnt > 10)
376                 t->re_cnt = 0;
377         if (t->re_text == NULL || (t->re_flags & CASE) != IGNORECASE) {
378                 /* reset regexp text if needed */
379                 t1 = t->re_exp;
380                 unref(t->re_text);
381                 t->re_text = dupnode(t1);
382         }
383         /* compile it */
384         t->re_reg = make_regexp(t->re_text->stptr, t->re_text->stlen,
385                                 IGNORECASE, t->re_cnt, true);
386
387         /* clear case flag */
388         t->re_flags &= ~CASE;
389         /* set current value of case flag */
390         t->re_flags |= IGNORECASE;
391         return t->re_reg;
392 }
393
394 /* resetup --- choose what kind of regexps we match */
395
396 void
397 resetup()
398 {
399         /*
400          * Syntax bits: _that_ is yet another mind trip.  Recreational drugs
401          * are helpful for recovering from the experience.
402          *
403          *      Aharon Robbins <arnold@skeeve.com>
404          *      Sun, 21 Oct 2007 23:55:33 +0200
405          */
406         if (do_posix)
407                 syn = RE_SYNTAX_POSIX_AWK;      /* strict POSIX re's */
408         else if (do_traditional)
409                 syn = RE_SYNTAX_AWK;            /* traditional Unix awk re's */
410         else
411                 syn = RE_SYNTAX_GNU_AWK;        /* POSIX re's + GNU ops */
412
413         /*
414          * Interval expressions are now on by default, as POSIX is
415          * wide-spread enough that people want it. The do_intervals
416          * variable remains for use with --traditional.
417          */
418         if (do_intervals)
419                 syn |= RE_INTERVALS | RE_INVALID_INTERVAL_ORD | RE_NO_BK_BRACES;
420
421         (void) re_set_syntax(syn);
422         dfasyntax(syn, false, '\n');
423 }
424
425 /* avoid_dfa --- return true if we should not use the DFA matcher */
426
427 int
428 avoid_dfa(NODE *re, char *str, size_t len)
429 {
430         char *end;
431
432         if (! re->re_reg->has_anchor)
433                 return false;
434
435         for (end = str + len; str < end; str++)
436                 if (*str == '\n')
437                         return true;
438
439         return false;
440 }
441
442 /* reisstring --- return true if the RE match is a simple string match */
443
444 int
445 reisstring(const char *text, size_t len, Regexp *re, const char *buf)
446 {
447         int res;
448         const char *matched;
449
450         /* simple checking for meta characters in re */
451         if (re->has_meta)
452                 return false;   /* give up early, can't be string match */
453
454         /* make accessable to gdb */
455         matched = &buf[RESTART(re, buf)];
456
457         res = (memcmp(text, matched, len) == 0);
458
459         return res;
460 }
461
462 /* reflags2str --- make a regex flags value readable */
463
464 const char *
465 reflags2str(int flagval)
466 {
467         static const struct flagtab values[] = {
468                 { RE_BACKSLASH_ESCAPE_IN_LISTS, "RE_BACKSLASH_ESCAPE_IN_LISTS" },
469                 { RE_BK_PLUS_QM, "RE_BK_PLUS_QM" },
470                 { RE_CHAR_CLASSES, "RE_CHAR_CLASSES" },
471                 { RE_CONTEXT_INDEP_ANCHORS, "RE_CONTEXT_INDEP_ANCHORS" },
472                 { RE_CONTEXT_INDEP_OPS, "RE_CONTEXT_INDEP_OPS" },
473                 { RE_CONTEXT_INVALID_OPS, "RE_CONTEXT_INVALID_OPS" },
474                 { RE_DOT_NEWLINE, "RE_DOT_NEWLINE" },
475                 { RE_DOT_NOT_NULL, "RE_DOT_NOT_NULL" },
476                 { RE_HAT_LISTS_NOT_NEWLINE, "RE_HAT_LISTS_NOT_NEWLINE" },
477                 { RE_INTERVALS, "RE_INTERVALS" },
478                 { RE_LIMITED_OPS, "RE_LIMITED_OPS" },
479                 { RE_NEWLINE_ALT, "RE_NEWLINE_ALT" },
480                 { RE_NO_BK_BRACES, "RE_NO_BK_BRACES" },
481                 { RE_NO_BK_PARENS, "RE_NO_BK_PARENS" },
482                 { RE_NO_BK_REFS, "RE_NO_BK_REFS" },
483                 { RE_NO_BK_VBAR, "RE_NO_BK_VBAR" },
484                 { RE_NO_EMPTY_RANGES, "RE_NO_EMPTY_RANGES" },
485                 { RE_UNMATCHED_RIGHT_PAREN_ORD, "RE_UNMATCHED_RIGHT_PAREN_ORD" },
486                 { RE_NO_POSIX_BACKTRACKING, "RE_NO_POSIX_BACKTRACKING" },
487                 { RE_NO_GNU_OPS, "RE_NO_GNU_OPS" },
488                 { RE_INVALID_INTERVAL_ORD, "RE_INVALID_INTERVAL_ORD" },
489                 { RE_ICASE, "RE_ICASE" },
490                 { RE_CARET_ANCHORS_HERE, "RE_CARET_ANCHORS_HERE" },
491                 { RE_CONTEXT_INVALID_DUP, "RE_CONTEXT_INVALID_DUP" },
492                 { RE_NO_SUB, "RE_NO_SUB" },
493                 { 0,    NULL },
494         };
495
496         if (flagval == RE_SYNTAX_EMACS) /* == 0 */
497                 return "RE_SYNTAX_EMACS";
498
499         return genflags2str(flagval, values);
500 }
501
502 /*
503  * dfawarn() is called by the dfa routines whenever a regex is compiled
504  * must supply a dfawarn.
505  */
506
507 void
508 dfawarn(const char *dfa_warning)
509 {
510         /*
511          * This routine does nothing, since gawk does its own
512          * (better) check for bad [[:foo:]] syntax.
513          */
514 }
515
516 /* check_bracket_exp --- look for /[:space:]/ that should be /[[:space:]]/ */
517
518 static void
519 check_bracket_exp(char *s, size_t length)
520 {
521         static struct reclass {
522                 const char *name;
523                 size_t len;
524                 bool warned;
525         } classes[] = {
526                 /*
527                  * Ordered by what we hope is frequency,
528                  * since it's linear searched.
529                  */
530                 { "[:alpha:]", 9, false },
531                 { "[:digit:]", 9, false },
532                 { "[:alnum:]", 9, false },
533                 { "[:upper:]", 9, false },
534                 { "[:lower:]", 9, false },
535                 { "[:space:]", 9, false },
536                 { "[:xdigit:]", 10, false },
537                 { "[:punct:]", 9, false },
538                 { "[:print:]", 9, false },
539                 { "[:graph:]", 9, false },
540                 { "[:cntrl:]", 9, false },
541                 { "[:blank:]", 9, false },
542                 { NULL, 0 }
543         };
544         int i;
545         bool found = false;
546         char save;
547         char *sp, *sp2, *end;
548         int len;
549         int count = 0;
550
551         if (length == 0)
552                 return;
553
554         end = s + length;
555         save = s[length];
556         s[length] = '\0';
557         sp = s;
558
559 again:
560         sp = sp2 = memchr(sp, '[', (end - sp));
561         if (sp == NULL)
562                 goto done;
563
564         for (count++, sp++; *sp != '\0'; sp++) {
565                 if (*sp == '[')
566                         count++;
567                 /*
568                  * ] as first char after open [ is skipped
569                  * \] is skipped
570                  * [^]] is skipped
571                  */
572                 if (*sp == ']' && sp > sp2) {
573                          if (sp[-1] != '['
574                              && sp[-1] != '\\')
575                                  ;
576                          else if ((sp - sp2) >= 2
577                                   && sp[-1] == '^' && sp[-2] == '[')
578                                  ;
579                          else
580                                 count--;
581                 }
582
583                 if (count == 0) {
584                         sp++;   /* skip past ']' */
585                         break;
586                 }
587         }
588
589         if (count > 0) {        /* bad regex, give up */
590                 goto done;
591         }
592
593         /* sp2 has start */
594
595         for (i = 0; classes[i].name != NULL; i++) {
596                 if (classes[i].warned)
597                         continue;
598                 len = classes[i].len;
599                 if (   len == (sp - sp2)
600                     && memcmp(sp2, classes[i].name, len) == 0) {
601                         found = true;
602                         break;
603                 }
604         }
605
606         if (found && ! classes[i].warned) {
607                 warning(_("regexp component `%.*s' should probably be `[%.*s]'"),
608                                 len, sp2, len, sp2);
609                 classes[i].warned = true;
610         }
611
612         if (sp < end) {
613                 found = false;
614                 goto again;
615         }
616 done:
617         s[length] = save;
618 }
619
620 /* regexflags2str --- make regex flags printable */
621
622 const char *
623 regexflags2str(int flags)
624 {
625         static const struct flagtab regextab[] = {
626                 { RE_BACKSLASH_ESCAPE_IN_LISTS, "RE_BACKSLASH_ESCAPE_IN_LISTS" },
627                 { RE_BK_PLUS_QM,                "RE_BK_PLUS_QM" },
628                 { RE_CHAR_CLASSES,              "RE_CHAR_CLASSES" },
629                 { RE_CONTEXT_INDEP_ANCHORS,     "RE_CONTEXT_INDEP_ANCHORS" },
630                 { RE_CONTEXT_INDEP_OPS,         "RE_CONTEXT_INDEP_OPS" },
631                 { RE_CONTEXT_INVALID_OPS,       "RE_CONTEXT_INVALID_OPS" },
632                 { RE_DOT_NEWLINE,               "RE_DOT_NEWLINE" },
633                 { RE_DOT_NOT_NULL,              "RE_DOT_NOT_NULL" },
634                 { RE_HAT_LISTS_NOT_NEWLINE,     "RE_HAT_LISTS_NOT_NEWLINE" },
635                 { RE_INTERVALS,                 "RE_INTERVALS" },
636                 { RE_LIMITED_OPS,               "RE_LIMITED_OPS" },
637                 { RE_NEWLINE_ALT,               "RE_NEWLINE_ALT" },
638                 { RE_NO_BK_BRACES,              "RE_NO_BK_BRACES" },
639                 { RE_NO_BK_PARENS,              "RE_NO_BK_PARENS" },
640                 { RE_NO_BK_REFS,                "RE_NO_BK_REFS" },
641                 { RE_NO_BK_VBAR,                "RE_NO_BK_VBAR" },
642                 { RE_NO_EMPTY_RANGES,           "RE_NO_EMPTY_RANGES" },
643                 { RE_UNMATCHED_RIGHT_PAREN_ORD, "RE_UNMATCHED_RIGHT_PAREN_ORD" },
644                 { RE_NO_POSIX_BACKTRACKING,     "RE_NO_POSIX_BACKTRACKING" },
645                 { RE_NO_GNU_OPS,                "RE_NO_GNU_OPS" },
646                 { RE_DEBUG,                     "RE_DEBUG" },
647                 { RE_INVALID_INTERVAL_ORD,      "RE_INVALID_INTERVAL_ORD" },
648                 { RE_ICASE,                     "RE_ICASE" },
649                 { RE_CARET_ANCHORS_HERE,        "RE_CARET_ANCHORS_HERE" },
650                 { RE_CONTEXT_INVALID_DUP,       "RE_CONTEXT_INVALID_DUP" },
651                 { 0,                            NULL }
652         };
653
654         return genflags2str(flags, regextab);
655 }