prefer new socket syscalls, fallback to SYS_socketcall only if needed
[musl.git] / src / regex / regcomp.c
blobfb24556ebe12e33cd07d86a7953e2ce30f45c3b7
1 /*
2 regcomp.c - TRE POSIX compatible regex compilation functions.
4 Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
5 All rights reserved.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <string.h>
33 #include <stdlib.h>
34 #include <regex.h>
35 #include <limits.h>
36 #include <stdint.h>
37 #include <ctype.h>
39 #include "tre.h"
41 #include <assert.h>
43 /***********************************************************************
44 from tre-compile.h
45 ***********************************************************************/
47 typedef struct {
48 int position;
49 int code_min;
50 int code_max;
51 int *tags;
52 int assertions;
53 tre_ctype_t class;
54 tre_ctype_t *neg_classes;
55 int backref;
56 } tre_pos_and_tags_t;
59 /***********************************************************************
60 from tre-ast.c and tre-ast.h
61 ***********************************************************************/
63 /* The different AST node types. */
64 typedef enum {
65 LITERAL,
66 CATENATION,
67 ITERATION,
68 UNION
69 } tre_ast_type_t;
71 /* Special subtypes of TRE_LITERAL. */
72 #define EMPTY -1 /* Empty leaf (denotes empty string). */
73 #define ASSERTION -2 /* Assertion leaf. */
74 #define TAG -3 /* Tag leaf. */
75 #define BACKREF -4 /* Back reference leaf. */
77 #define IS_SPECIAL(x) ((x)->code_min < 0)
78 #define IS_EMPTY(x) ((x)->code_min == EMPTY)
79 #define IS_ASSERTION(x) ((x)->code_min == ASSERTION)
80 #define IS_TAG(x) ((x)->code_min == TAG)
81 #define IS_BACKREF(x) ((x)->code_min == BACKREF)
84 /* A generic AST node. All AST nodes consist of this node on the top
85 level with `obj' pointing to the actual content. */
86 typedef struct {
87 tre_ast_type_t type; /* Type of the node. */
88 void *obj; /* Pointer to actual node. */
89 int nullable;
90 int submatch_id;
91 int num_submatches;
92 int num_tags;
93 tre_pos_and_tags_t *firstpos;
94 tre_pos_and_tags_t *lastpos;
95 } tre_ast_node_t;
98 /* A "literal" node. These are created for assertions, back references,
99 tags, matching parameter settings, and all expressions that match one
100 character. */
101 typedef struct {
102 long code_min;
103 long code_max;
104 int position;
105 tre_ctype_t class;
106 tre_ctype_t *neg_classes;
107 } tre_literal_t;
109 /* A "catenation" node. These are created when two regexps are concatenated.
110 If there are more than one subexpressions in sequence, the `left' part
111 holds all but the last, and `right' part holds the last subexpression
112 (catenation is left associative). */
113 typedef struct {
114 tre_ast_node_t *left;
115 tre_ast_node_t *right;
116 } tre_catenation_t;
118 /* An "iteration" node. These are created for the "*", "+", "?", and "{m,n}"
119 operators. */
120 typedef struct {
121 /* Subexpression to match. */
122 tre_ast_node_t *arg;
123 /* Minimum number of consecutive matches. */
124 int min;
125 /* Maximum number of consecutive matches. */
126 int max;
127 /* If 0, match as many characters as possible, if 1 match as few as
128 possible. Note that this does not always mean the same thing as
129 matching as many/few repetitions as possible. */
130 unsigned int minimal:1;
131 } tre_iteration_t;
133 /* An "union" node. These are created for the "|" operator. */
134 typedef struct {
135 tre_ast_node_t *left;
136 tre_ast_node_t *right;
137 } tre_union_t;
140 static tre_ast_node_t *
141 tre_ast_new_node(tre_mem_t mem, int type, void *obj)
143 tre_ast_node_t *node = tre_mem_calloc(mem, sizeof *node);
144 if (!node || !obj)
145 return 0;
146 node->obj = obj;
147 node->type = type;
148 node->nullable = -1;
149 node->submatch_id = -1;
150 return node;
153 static tre_ast_node_t *
154 tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
156 tre_ast_node_t *node;
157 tre_literal_t *lit;
159 lit = tre_mem_calloc(mem, sizeof *lit);
160 node = tre_ast_new_node(mem, LITERAL, lit);
161 if (!node)
162 return 0;
163 lit->code_min = code_min;
164 lit->code_max = code_max;
165 lit->position = position;
166 return node;
169 static tre_ast_node_t *
170 tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal)
172 tre_ast_node_t *node;
173 tre_iteration_t *iter;
175 iter = tre_mem_calloc(mem, sizeof *iter);
176 node = tre_ast_new_node(mem, ITERATION, iter);
177 if (!node)
178 return 0;
179 iter->arg = arg;
180 iter->min = min;
181 iter->max = max;
182 iter->minimal = minimal;
183 node->num_submatches = arg->num_submatches;
184 return node;
187 static tre_ast_node_t *
188 tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
190 tre_ast_node_t *node;
191 tre_union_t *un;
193 if (!left)
194 return right;
195 un = tre_mem_calloc(mem, sizeof *un);
196 node = tre_ast_new_node(mem, UNION, un);
197 if (!node || !right)
198 return 0;
199 un->left = left;
200 un->right = right;
201 node->num_submatches = left->num_submatches + right->num_submatches;
202 return node;
205 static tre_ast_node_t *
206 tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
208 tre_ast_node_t *node;
209 tre_catenation_t *cat;
211 if (!left)
212 return right;
213 cat = tre_mem_calloc(mem, sizeof *cat);
214 node = tre_ast_new_node(mem, CATENATION, cat);
215 if (!node)
216 return 0;
217 cat->left = left;
218 cat->right = right;
219 node->num_submatches = left->num_submatches + right->num_submatches;
220 return node;
224 /***********************************************************************
225 from tre-stack.c and tre-stack.h
226 ***********************************************************************/
228 typedef struct tre_stack_rec tre_stack_t;
230 /* Creates a new stack object. `size' is initial size in bytes, `max_size'
231 is maximum size, and `increment' specifies how much more space will be
232 allocated with realloc() if all space gets used up. Returns the stack
233 object or NULL if out of memory. */
234 static tre_stack_t *
235 tre_stack_new(int size, int max_size, int increment);
237 /* Frees the stack object. */
238 static void
239 tre_stack_destroy(tre_stack_t *s);
241 /* Returns the current number of objects in the stack. */
242 static int
243 tre_stack_num_objects(tre_stack_t *s);
245 /* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes
246 `value' on top of stack `s'. Returns REG_ESPACE if out of memory.
247 This tries to realloc() more space before failing if maximum size
248 has not yet been reached. Returns REG_OK if successful. */
249 #define declare_pushf(typetag, type) \
250 static reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)
252 declare_pushf(voidptr, void *);
253 declare_pushf(int, int);
255 /* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost
256 element off of stack `s' and returns it. The stack must not be
257 empty. */
258 #define declare_popf(typetag, type) \
259 static type tre_stack_pop_ ## typetag(tre_stack_t *s)
261 declare_popf(voidptr, void *);
262 declare_popf(int, int);
264 /* Just to save some typing. */
265 #define STACK_PUSH(s, typetag, value) \
266 do \
268 status = tre_stack_push_ ## typetag(s, value); \
270 while (/*CONSTCOND*/0)
272 #define STACK_PUSHX(s, typetag, value) \
274 status = tre_stack_push_ ## typetag(s, value); \
275 if (status != REG_OK) \
276 break; \
279 #define STACK_PUSHR(s, typetag, value) \
281 reg_errcode_t _status; \
282 _status = tre_stack_push_ ## typetag(s, value); \
283 if (_status != REG_OK) \
284 return _status; \
287 union tre_stack_item {
288 void *voidptr_value;
289 int int_value;
292 struct tre_stack_rec {
293 int size;
294 int max_size;
295 int increment;
296 int ptr;
297 union tre_stack_item *stack;
301 static tre_stack_t *
302 tre_stack_new(int size, int max_size, int increment)
304 tre_stack_t *s;
306 s = xmalloc(sizeof(*s));
307 if (s != NULL)
309 s->stack = xmalloc(sizeof(*s->stack) * size);
310 if (s->stack == NULL)
312 xfree(s);
313 return NULL;
315 s->size = size;
316 s->max_size = max_size;
317 s->increment = increment;
318 s->ptr = 0;
320 return s;
323 static void
324 tre_stack_destroy(tre_stack_t *s)
326 xfree(s->stack);
327 xfree(s);
330 static int
331 tre_stack_num_objects(tre_stack_t *s)
333 return s->ptr;
336 static reg_errcode_t
337 tre_stack_push(tre_stack_t *s, union tre_stack_item value)
339 if (s->ptr < s->size)
341 s->stack[s->ptr] = value;
342 s->ptr++;
344 else
346 if (s->size >= s->max_size)
348 return REG_ESPACE;
350 else
352 union tre_stack_item *new_buffer;
353 int new_size;
354 new_size = s->size + s->increment;
355 if (new_size > s->max_size)
356 new_size = s->max_size;
357 new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
358 if (new_buffer == NULL)
360 return REG_ESPACE;
362 assert(new_size > s->size);
363 s->size = new_size;
364 s->stack = new_buffer;
365 tre_stack_push(s, value);
368 return REG_OK;
371 #define define_pushf(typetag, type) \
372 declare_pushf(typetag, type) { \
373 union tre_stack_item item; \
374 item.typetag ## _value = value; \
375 return tre_stack_push(s, item); \
378 define_pushf(int, int)
379 define_pushf(voidptr, void *)
381 #define define_popf(typetag, type) \
382 declare_popf(typetag, type) { \
383 return s->stack[--s->ptr].typetag ## _value; \
386 define_popf(int, int)
387 define_popf(voidptr, void *)
390 /***********************************************************************
391 from tre-parse.c and tre-parse.h
392 ***********************************************************************/
394 /* Parse context. */
395 typedef struct {
396 /* Memory allocator. The AST is allocated using this. */
397 tre_mem_t mem;
398 /* Stack used for keeping track of regexp syntax. */
399 tre_stack_t *stack;
400 /* The parsed node after a parse function returns. */
401 tre_ast_node_t *n;
402 /* Position in the regexp pattern after a parse function returns. */
403 const char *s;
404 /* The first character of the last subexpression parsed. */
405 const char *start;
406 /* Current submatch ID. */
407 int submatch_id;
408 /* Current position (number of literal). */
409 int position;
410 /* The highest back reference or -1 if none seen so far. */
411 int max_backref;
412 /* Compilation flags. */
413 int cflags;
414 } tre_parse_ctx_t;
416 /* Some macros for expanding \w, \s, etc. */
417 static const struct {
418 char c;
419 const char *expansion;
420 } tre_macros[] = {
421 {'t', "\t"}, {'n', "\n"}, {'r', "\r"},
422 {'f', "\f"}, {'a', "\a"}, {'e', "\033"},
423 {'w', "[[:alnum:]_]"}, {'W', "[^[:alnum:]_]"}, {'s', "[[:space:]]"},
424 {'S', "[^[:space:]]"}, {'d', "[[:digit:]]"}, {'D', "[^[:digit:]]"},
425 { 0, 0 }
428 /* Expands a macro delimited by `regex' and `regex_end' to `buf', which
429 must have at least `len' items. Sets buf[0] to zero if the there
430 is no match in `tre_macros'. */
431 static const char *tre_expand_macro(const char *s)
433 int i;
434 for (i = 0; tre_macros[i].c && tre_macros[i].c != *s; i++);
435 return tre_macros[i].expansion;
438 static int
439 tre_compare_lit(const void *a, const void *b)
441 const tre_literal_t *const *la = a;
442 const tre_literal_t *const *lb = b;
443 /* assumes the range of valid code_min is < INT_MAX */
444 return la[0]->code_min - lb[0]->code_min;
447 struct literals {
448 tre_mem_t mem;
449 tre_literal_t **a;
450 int len;
451 int cap;
454 static tre_literal_t *tre_new_lit(struct literals *p)
456 tre_literal_t **a;
457 if (p->len >= p->cap) {
458 if (p->cap >= 1<<15)
459 return 0;
460 p->cap *= 2;
461 a = xrealloc(p->a, p->cap * sizeof *p->a);
462 if (!a)
463 return 0;
464 p->a = a;
466 a = p->a + p->len++;
467 *a = tre_mem_calloc(p->mem, sizeof **a);
468 return *a;
471 static int add_icase_literals(struct literals *ls, int min, int max)
473 tre_literal_t *lit;
474 int b, e, c;
475 for (c=min; c<=max; ) {
476 /* assumes islower(c) and isupper(c) are exclusive
477 and toupper(c)!=c if islower(c).
478 multiple opposite case characters are not supported */
479 if (tre_islower(c)) {
480 b = e = tre_toupper(c);
481 for (c++, e++; c<=max; c++, e++)
482 if (tre_toupper(c) != e) break;
483 } else if (tre_isupper(c)) {
484 b = e = tre_tolower(c);
485 for (c++, e++; c<=max; c++, e++)
486 if (tre_tolower(c) != e) break;
487 } else {
488 c++;
489 continue;
491 lit = tre_new_lit(ls);
492 if (!lit)
493 return -1;
494 lit->code_min = b;
495 lit->code_max = e-1;
496 lit->position = -1;
498 return 0;
502 /* Maximum number of character classes in a negated bracket expression. */
503 #define MAX_NEG_CLASSES 64
505 struct neg {
506 int negate;
507 int len;
508 tre_ctype_t a[MAX_NEG_CLASSES];
511 // TODO: parse bracket into a set of non-overlapping [lo,hi] ranges
514 bracket grammar:
515 Bracket = '[' List ']' | '[^' List ']'
516 List = Term | List Term
517 Term = Char | Range | Chclass | Eqclass
518 Range = Char '-' Char | Char '-' '-'
519 Char = Coll | coll_single
520 Meta = ']' | '-'
521 Coll = '[.' coll_single '.]' | '[.' coll_multi '.]' | '[.' Meta '.]'
522 Eqclass = '[=' coll_single '=]' | '[=' coll_multi '=]'
523 Chclass = '[:' class ':]'
525 coll_single is a single char collating element but it can be
526 '-' only at the beginning or end of a List and
527 ']' only at the beginning of a List and
528 '^' anywhere except after the openning '['
531 static reg_errcode_t parse_bracket_terms(tre_parse_ctx_t *ctx, const char *s, struct literals *ls, struct neg *neg)
533 const char *start = s;
534 tre_ctype_t class;
535 int min, max;
536 wchar_t wc;
537 int len;
539 for (;;) {
540 class = 0;
541 len = mbtowc(&wc, s, -1);
542 if (len <= 0)
543 return *s ? REG_BADPAT : REG_EBRACK;
544 if (*s == ']' && s != start) {
545 ctx->s = s+1;
546 return REG_OK;
548 if (*s == '-' && s != start && s[1] != ']' &&
549 /* extension: [a-z--@] is accepted as [a-z]|[--@] */
550 (s[1] != '-' || s[2] == ']'))
551 return REG_ERANGE;
552 if (*s == '[' && (s[1] == '.' || s[1] == '='))
553 /* collating symbols and equivalence classes are not supported */
554 return REG_ECOLLATE;
555 if (*s == '[' && s[1] == ':') {
556 char tmp[CHARCLASS_NAME_MAX+1];
557 s += 2;
558 for (len=0; len < CHARCLASS_NAME_MAX && s[len]; len++) {
559 if (s[len] == ':') {
560 memcpy(tmp, s, len);
561 tmp[len] = 0;
562 class = tre_ctype(tmp);
563 break;
566 if (!class || s[len+1] != ']')
567 return REG_ECTYPE;
568 min = 0;
569 max = TRE_CHAR_MAX;
570 s += len+2;
571 } else {
572 min = max = wc;
573 s += len;
574 if (*s == '-' && s[1] != ']') {
575 s++;
576 len = mbtowc(&wc, s, -1);
577 max = wc;
578 /* XXX - Should use collation order instead of
579 encoding values in character ranges. */
580 if (len <= 0 || min > max)
581 return REG_ERANGE;
582 s += len;
586 if (class && neg->negate) {
587 if (neg->len >= MAX_NEG_CLASSES)
588 return REG_ESPACE;
589 neg->a[neg->len++] = class;
590 } else {
591 tre_literal_t *lit = tre_new_lit(ls);
592 if (!lit)
593 return REG_ESPACE;
594 lit->code_min = min;
595 lit->code_max = max;
596 lit->class = class;
597 lit->position = -1;
599 /* Add opposite-case codepoints if REG_ICASE is present.
600 It seems that POSIX requires that bracket negation
601 should happen before case-folding, but most practical
602 implementations do it the other way around. Changing
603 the order would need efficient representation of
604 case-fold ranges and bracket range sets even with
605 simple patterns so this is ok for now. */
606 if (ctx->cflags & REG_ICASE && !class)
607 if (add_icase_literals(ls, min, max))
608 return REG_ESPACE;
613 static reg_errcode_t parse_bracket(tre_parse_ctx_t *ctx, const char *s)
615 int i, max, min, negmax, negmin;
616 tre_ast_node_t *node = 0, *n;
617 tre_ctype_t *nc = 0;
618 tre_literal_t *lit;
619 struct literals ls;
620 struct neg neg;
621 reg_errcode_t err;
623 ls.mem = ctx->mem;
624 ls.len = 0;
625 ls.cap = 32;
626 ls.a = xmalloc(ls.cap * sizeof *ls.a);
627 if (!ls.a)
628 return REG_ESPACE;
629 neg.len = 0;
630 neg.negate = *s == '^';
631 if (neg.negate)
632 s++;
634 err = parse_bracket_terms(ctx, s, &ls, &neg);
635 if (err != REG_OK)
636 goto parse_bracket_done;
638 if (neg.negate) {
640 * With REG_NEWLINE, POSIX requires that newlines are not matched by
641 * any form of a non-matching list.
643 if (ctx->cflags & REG_NEWLINE) {
644 lit = tre_new_lit(&ls);
645 if (!lit) {
646 err = REG_ESPACE;
647 goto parse_bracket_done;
649 lit->code_min = '\n';
650 lit->code_max = '\n';
651 lit->position = -1;
653 /* Sort the array if we need to negate it. */
654 qsort(ls.a, ls.len, sizeof *ls.a, tre_compare_lit);
655 /* extra lit for the last negated range */
656 lit = tre_new_lit(&ls);
657 if (!lit) {
658 err = REG_ESPACE;
659 goto parse_bracket_done;
661 lit->code_min = TRE_CHAR_MAX+1;
662 lit->code_max = TRE_CHAR_MAX+1;
663 lit->position = -1;
664 /* negated classes */
665 if (neg.len) {
666 nc = tre_mem_alloc(ctx->mem, (neg.len+1)*sizeof *neg.a);
667 if (!nc) {
668 err = REG_ESPACE;
669 goto parse_bracket_done;
671 memcpy(nc, neg.a, neg.len*sizeof *neg.a);
672 nc[neg.len] = 0;
676 /* Build a union of the items in the array, negated if necessary. */
677 negmax = negmin = 0;
678 for (i = 0; i < ls.len; i++) {
679 lit = ls.a[i];
680 min = lit->code_min;
681 max = lit->code_max;
682 if (neg.negate) {
683 if (min <= negmin) {
684 /* Overlap. */
685 negmin = MAX(max + 1, negmin);
686 continue;
688 negmax = min - 1;
689 lit->code_min = negmin;
690 lit->code_max = negmax;
691 negmin = max + 1;
693 lit->position = ctx->position;
694 lit->neg_classes = nc;
695 n = tre_ast_new_node(ctx->mem, LITERAL, lit);
696 node = tre_ast_new_union(ctx->mem, node, n);
697 if (!node) {
698 err = REG_ESPACE;
699 break;
703 parse_bracket_done:
704 xfree(ls.a);
705 ctx->position++;
706 ctx->n = node;
707 return err;
710 static const char *parse_dup_count(const char *s, int *n)
712 *n = -1;
713 if (!isdigit(*s))
714 return s;
715 *n = 0;
716 for (;;) {
717 *n = 10 * *n + (*s - '0');
718 s++;
719 if (!isdigit(*s) || *n > RE_DUP_MAX)
720 break;
722 return s;
725 static const char *parse_dup(const char *s, int ere, int *pmin, int *pmax)
727 int min, max;
729 s = parse_dup_count(s, &min);
730 if (*s == ',')
731 s = parse_dup_count(s+1, &max);
732 else
733 max = min;
735 if (
736 (max < min && max >= 0) ||
737 max > RE_DUP_MAX ||
738 min > RE_DUP_MAX ||
739 min < 0 ||
740 (!ere && *s++ != '\\') ||
741 *s++ != '}'
743 return 0;
744 *pmin = min;
745 *pmax = max;
746 return s;
749 static int hexval(unsigned c)
751 if (c-'0'<10) return c-'0';
752 c |= 32;
753 if (c-'a'<6) return c-'a'+10;
754 return -1;
757 static reg_errcode_t marksub(tre_parse_ctx_t *ctx, tre_ast_node_t *node, int subid)
759 if (node->submatch_id >= 0) {
760 tre_ast_node_t *n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
761 if (!n)
762 return REG_ESPACE;
763 n = tre_ast_new_catenation(ctx->mem, n, node);
764 if (!n)
765 return REG_ESPACE;
766 n->num_submatches = node->num_submatches;
767 node = n;
769 node->submatch_id = subid;
770 node->num_submatches++;
771 ctx->n = node;
772 return REG_OK;
776 BRE grammar:
777 Regex = Branch | '^' | '$' | '^$' | '^' Branch | Branch '$' | '^' Branch '$'
778 Branch = Atom | Branch Atom
779 Atom = char | quoted_char | '.' | Bracket | Atom Dup | '\(' Branch '\)' | back_ref
780 Dup = '*' | '\{' Count '\}' | '\{' Count ',\}' | '\{' Count ',' Count '\}'
782 (leading ^ and trailing $ in a sub expr may be an anchor or literal as well)
784 ERE grammar:
785 Regex = Branch | Regex '|' Branch
786 Branch = Atom | Branch Atom
787 Atom = char | quoted_char | '.' | Bracket | Atom Dup | '(' Regex ')' | '^' | '$'
788 Dup = '*' | '+' | '?' | '{' Count '}' | '{' Count ',}' | '{' Count ',' Count '}'
790 (a*+?, ^*, $+, \X, {, (|a) are unspecified)
793 static reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s)
795 int len, ere = ctx->cflags & REG_EXTENDED;
796 const char *p;
797 tre_ast_node_t *node;
798 wchar_t wc;
799 switch (*s) {
800 case '[':
801 return parse_bracket(ctx, s+1);
802 case '\\':
803 p = tre_expand_macro(s+1);
804 if (p) {
805 /* assume \X expansion is a single atom */
806 reg_errcode_t err = parse_atom(ctx, p);
807 ctx->s = s+2;
808 return err;
810 /* extensions: \b, \B, \<, \>, \xHH \x{HHHH} */
811 switch (*++s) {
812 case 0:
813 return REG_EESCAPE;
814 case 'b':
815 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB, -1);
816 break;
817 case 'B':
818 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB_NEG, -1);
819 break;
820 case '<':
821 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOW, -1);
822 break;
823 case '>':
824 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOW, -1);
825 break;
826 case 'x':
827 s++;
828 int i, v = 0, c;
829 len = 2;
830 if (*s == '{') {
831 len = 8;
832 s++;
834 for (i=0; i<len && v<0x110000; i++) {
835 c = hexval(s[i]);
836 if (c < 0) break;
837 v = 16*v + c;
839 s += i;
840 if (len == 8) {
841 if (*s != '}')
842 return REG_EBRACE;
843 s++;
845 node = tre_ast_new_literal(ctx->mem, v, v, ctx->position++);
846 s--;
847 break;
848 case '{':
849 case '+':
850 case '?':
851 /* extension: treat \+, \? as repetitions in BRE */
852 /* reject repetitions after empty expression in BRE */
853 if (!ere)
854 return REG_BADRPT;
855 case '|':
856 /* extension: treat \| as alternation in BRE */
857 if (!ere) {
858 node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
859 s--;
860 goto end;
862 /* fallthrough */
863 default:
864 if (!ere && (unsigned)*s-'1' < 9) {
865 /* back reference */
866 int val = *s - '0';
867 node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++);
868 ctx->max_backref = MAX(val, ctx->max_backref);
869 } else {
870 /* extension: accept unknown escaped char
871 as a literal */
872 goto parse_literal;
875 s++;
876 break;
877 case '.':
878 if (ctx->cflags & REG_NEWLINE) {
879 tre_ast_node_t *tmp1, *tmp2;
880 tmp1 = tre_ast_new_literal(ctx->mem, 0, '\n'-1, ctx->position++);
881 tmp2 = tre_ast_new_literal(ctx->mem, '\n'+1, TRE_CHAR_MAX, ctx->position++);
882 if (tmp1 && tmp2)
883 node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
884 else
885 node = 0;
886 } else {
887 node = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX, ctx->position++);
889 s++;
890 break;
891 case '^':
892 /* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */
893 if (!ere && s != ctx->start)
894 goto parse_literal;
895 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOL, -1);
896 s++;
897 break;
898 case '$':
899 /* '$' is special everywhere in EREs, and at the end of a BRE subexpression. */
900 if (!ere && s[1] && (s[1]!='\\'|| (s[2]!=')' && s[2]!='|')))
901 goto parse_literal;
902 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOL, -1);
903 s++;
904 break;
905 case '*':
906 case '{':
907 case '+':
908 case '?':
909 /* reject repetitions after empty expression in ERE */
910 if (ere)
911 return REG_BADRPT;
912 case '|':
913 if (!ere)
914 goto parse_literal;
915 case 0:
916 node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
917 break;
918 default:
919 parse_literal:
920 len = mbtowc(&wc, s, -1);
921 if (len < 0)
922 return REG_BADPAT;
923 if (ctx->cflags & REG_ICASE && (tre_isupper(wc) || tre_islower(wc))) {
924 tre_ast_node_t *tmp1, *tmp2;
925 /* multiple opposite case characters are not supported */
926 tmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(wc), tre_toupper(wc), ctx->position);
927 tmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(wc), tre_tolower(wc), ctx->position);
928 if (tmp1 && tmp2)
929 node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
930 else
931 node = 0;
932 } else {
933 node = tre_ast_new_literal(ctx->mem, wc, wc, ctx->position);
935 ctx->position++;
936 s += len;
937 break;
939 end:
940 if (!node)
941 return REG_ESPACE;
942 ctx->n = node;
943 ctx->s = s;
944 return REG_OK;
947 #define PUSHPTR(err, s, v) do { \
948 if ((err = tre_stack_push_voidptr(s, v)) != REG_OK) \
949 return err; \
950 } while(0)
952 #define PUSHINT(err, s, v) do { \
953 if ((err = tre_stack_push_int(s, v)) != REG_OK) \
954 return err; \
955 } while(0)
957 static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
959 tre_ast_node_t *nbranch=0, *nunion=0;
960 int ere = ctx->cflags & REG_EXTENDED;
961 const char *s = ctx->start;
962 int subid = 0;
963 int depth = 0;
964 reg_errcode_t err;
965 tre_stack_t *stack = ctx->stack;
967 PUSHINT(err, stack, subid++);
968 for (;;) {
969 if ((!ere && *s == '\\' && s[1] == '(') ||
970 (ere && *s == '(')) {
971 PUSHPTR(err, stack, nunion);
972 PUSHPTR(err, stack, nbranch);
973 PUSHINT(err, stack, subid++);
974 s++;
975 if (!ere)
976 s++;
977 depth++;
978 nbranch = nunion = 0;
979 ctx->start = s;
980 continue;
982 if ((!ere && *s == '\\' && s[1] == ')') ||
983 (ere && *s == ')' && depth)) {
984 ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
985 if (!ctx->n)
986 return REG_ESPACE;
987 } else {
988 err = parse_atom(ctx, s);
989 if (err != REG_OK)
990 return err;
991 s = ctx->s;
994 parse_iter:
995 for (;;) {
996 int min, max;
998 if (*s!='\\' && *s!='*') {
999 if (!ere)
1000 break;
1001 if (*s!='+' && *s!='?' && *s!='{')
1002 break;
1004 if (*s=='\\' && ere)
1005 break;
1006 /* extension: treat \+, \? as repetitions in BRE */
1007 if (*s=='\\' && s[1]!='+' && s[1]!='?' && s[1]!='{')
1008 break;
1009 if (*s=='\\')
1010 s++;
1012 /* handle ^* at the start of a BRE. */
1013 if (!ere && s==ctx->start+1 && s[-1]=='^')
1014 break;
1016 /* extension: multiple consecutive *+?{,} is unspecified,
1017 but (a+)+ has to be supported so accepting a++ makes
1018 sense, note however that the RE_DUP_MAX limit can be
1019 circumvented: (a{255}){255} uses a lot of memory.. */
1020 if (*s=='{') {
1021 s = parse_dup(s+1, ere, &min, &max);
1022 if (!s)
1023 return REG_BADBR;
1024 } else {
1025 min=0;
1026 max=-1;
1027 if (*s == '+')
1028 min = 1;
1029 if (*s == '?')
1030 max = 1;
1031 s++;
1033 if (max == 0)
1034 ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
1035 else
1036 ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
1037 if (!ctx->n)
1038 return REG_ESPACE;
1041 nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);
1042 if ((ere && *s == '|') ||
1043 (ere && *s == ')' && depth) ||
1044 (!ere && *s == '\\' && s[1] == ')') ||
1045 /* extension: treat \| as alternation in BRE */
1046 (!ere && *s == '\\' && s[1] == '|') ||
1047 !*s) {
1048 /* extension: empty branch is unspecified (), (|a), (a|)
1049 here they are not rejected but match on empty string */
1050 int c = *s;
1051 nunion = tre_ast_new_union(ctx->mem, nunion, nbranch);
1052 nbranch = 0;
1054 if (c == '\\' && s[1] == '|') {
1055 s+=2;
1056 ctx->start = s;
1057 } else if (c == '|') {
1058 s++;
1059 ctx->start = s;
1060 } else {
1061 if (c == '\\') {
1062 if (!depth) return REG_EPAREN;
1063 s+=2;
1064 } else if (c == ')')
1065 s++;
1066 depth--;
1067 err = marksub(ctx, nunion, tre_stack_pop_int(stack));
1068 if (err != REG_OK)
1069 return err;
1070 if (!c && depth<0) {
1071 ctx->submatch_id = subid;
1072 return REG_OK;
1074 if (!c || depth<0)
1075 return REG_EPAREN;
1076 nbranch = tre_stack_pop_voidptr(stack);
1077 nunion = tre_stack_pop_voidptr(stack);
1078 goto parse_iter;
1085 /***********************************************************************
1086 from tre-compile.c
1087 ***********************************************************************/
1091 TODO:
1092 - Fix tre_ast_to_tnfa() to recurse using a stack instead of recursive
1093 function calls.
1097 Algorithms to setup tags so that submatch addressing can be done.
1101 /* Inserts a catenation node to the root of the tree given in `node'.
1102 As the left child a new tag with number `tag_id' to `node' is added,
1103 and the right child is the old root. */
1104 static reg_errcode_t
1105 tre_add_tag_left(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
1107 tre_catenation_t *c;
1109 c = tre_mem_alloc(mem, sizeof(*c));
1110 if (c == NULL)
1111 return REG_ESPACE;
1112 c->left = tre_ast_new_literal(mem, TAG, tag_id, -1);
1113 if (c->left == NULL)
1114 return REG_ESPACE;
1115 c->right = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
1116 if (c->right == NULL)
1117 return REG_ESPACE;
1119 c->right->obj = node->obj;
1120 c->right->type = node->type;
1121 c->right->nullable = -1;
1122 c->right->submatch_id = -1;
1123 c->right->firstpos = NULL;
1124 c->right->lastpos = NULL;
1125 c->right->num_tags = 0;
1126 c->right->num_submatches = 0;
1127 node->obj = c;
1128 node->type = CATENATION;
1129 return REG_OK;
1132 /* Inserts a catenation node to the root of the tree given in `node'.
1133 As the right child a new tag with number `tag_id' to `node' is added,
1134 and the left child is the old root. */
1135 static reg_errcode_t
1136 tre_add_tag_right(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
1138 tre_catenation_t *c;
1140 c = tre_mem_alloc(mem, sizeof(*c));
1141 if (c == NULL)
1142 return REG_ESPACE;
1143 c->right = tre_ast_new_literal(mem, TAG, tag_id, -1);
1144 if (c->right == NULL)
1145 return REG_ESPACE;
1146 c->left = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
1147 if (c->left == NULL)
1148 return REG_ESPACE;
1150 c->left->obj = node->obj;
1151 c->left->type = node->type;
1152 c->left->nullable = -1;
1153 c->left->submatch_id = -1;
1154 c->left->firstpos = NULL;
1155 c->left->lastpos = NULL;
1156 c->left->num_tags = 0;
1157 c->left->num_submatches = 0;
1158 node->obj = c;
1159 node->type = CATENATION;
1160 return REG_OK;
1163 typedef enum {
1164 ADDTAGS_RECURSE,
1165 ADDTAGS_AFTER_ITERATION,
1166 ADDTAGS_AFTER_UNION_LEFT,
1167 ADDTAGS_AFTER_UNION_RIGHT,
1168 ADDTAGS_AFTER_CAT_LEFT,
1169 ADDTAGS_AFTER_CAT_RIGHT,
1170 ADDTAGS_SET_SUBMATCH_END
1171 } tre_addtags_symbol_t;
1174 typedef struct {
1175 int tag;
1176 int next_tag;
1177 } tre_tag_states_t;
1180 /* Go through `regset' and set submatch data for submatches that are
1181 using this tag. */
1182 static void
1183 tre_purge_regset(int *regset, tre_tnfa_t *tnfa, int tag)
1185 int i;
1187 for (i = 0; regset[i] >= 0; i++)
1189 int id = regset[i] / 2;
1190 int start = !(regset[i] % 2);
1191 if (start)
1192 tnfa->submatch_data[id].so_tag = tag;
1193 else
1194 tnfa->submatch_data[id].eo_tag = tag;
1196 regset[0] = -1;
1200 /* Adds tags to appropriate locations in the parse tree in `tree', so that
1201 subexpressions marked for submatch addressing can be traced. */
1202 static reg_errcode_t
1203 tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
1204 tre_tnfa_t *tnfa)
1206 reg_errcode_t status = REG_OK;
1207 tre_addtags_symbol_t symbol;
1208 tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */
1209 int bottom = tre_stack_num_objects(stack);
1210 /* True for first pass (counting number of needed tags) */
1211 int first_pass = (mem == NULL || tnfa == NULL);
1212 int *regset, *orig_regset;
1213 int num_tags = 0; /* Total number of tags. */
1214 int num_minimals = 0; /* Number of special minimal tags. */
1215 int tag = 0; /* The tag that is to be added next. */
1216 int next_tag = 1; /* Next tag to use after this one. */
1217 int *parents; /* Stack of submatches the current submatch is
1218 contained in. */
1219 int minimal_tag = -1; /* Tag that marks the beginning of a minimal match. */
1220 tre_tag_states_t *saved_states;
1222 tre_tag_direction_t direction = TRE_TAG_MINIMIZE;
1223 if (!first_pass)
1225 tnfa->end_tag = 0;
1226 tnfa->minimal_tags[0] = -1;
1229 regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2));
1230 if (regset == NULL)
1231 return REG_ESPACE;
1232 regset[0] = -1;
1233 orig_regset = regset;
1235 parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1));
1236 if (parents == NULL)
1238 xfree(regset);
1239 return REG_ESPACE;
1241 parents[0] = -1;
1243 saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1));
1244 if (saved_states == NULL)
1246 xfree(regset);
1247 xfree(parents);
1248 return REG_ESPACE;
1250 else
1252 unsigned int i;
1253 for (i = 0; i <= tnfa->num_submatches; i++)
1254 saved_states[i].tag = -1;
1257 STACK_PUSH(stack, voidptr, node);
1258 STACK_PUSH(stack, int, ADDTAGS_RECURSE);
1260 while (tre_stack_num_objects(stack) > bottom)
1262 if (status != REG_OK)
1263 break;
1265 symbol = (tre_addtags_symbol_t)tre_stack_pop_int(stack);
1266 switch (symbol)
1269 case ADDTAGS_SET_SUBMATCH_END:
1271 int id = tre_stack_pop_int(stack);
1272 int i;
1274 /* Add end of this submatch to regset. */
1275 for (i = 0; regset[i] >= 0; i++);
1276 regset[i] = id * 2 + 1;
1277 regset[i + 1] = -1;
1279 /* Pop this submatch from the parents stack. */
1280 for (i = 0; parents[i] >= 0; i++);
1281 parents[i - 1] = -1;
1282 break;
1285 case ADDTAGS_RECURSE:
1286 node = tre_stack_pop_voidptr(stack);
1288 if (node->submatch_id >= 0)
1290 int id = node->submatch_id;
1291 int i;
1294 /* Add start of this submatch to regset. */
1295 for (i = 0; regset[i] >= 0; i++);
1296 regset[i] = id * 2;
1297 regset[i + 1] = -1;
1299 if (!first_pass)
1301 for (i = 0; parents[i] >= 0; i++);
1302 tnfa->submatch_data[id].parents = NULL;
1303 if (i > 0)
1305 int *p = xmalloc(sizeof(*p) * (i + 1));
1306 if (p == NULL)
1308 status = REG_ESPACE;
1309 break;
1311 assert(tnfa->submatch_data[id].parents == NULL);
1312 tnfa->submatch_data[id].parents = p;
1313 for (i = 0; parents[i] >= 0; i++)
1314 p[i] = parents[i];
1315 p[i] = -1;
1319 /* Add end of this submatch to regset after processing this
1320 node. */
1321 STACK_PUSHX(stack, int, node->submatch_id);
1322 STACK_PUSHX(stack, int, ADDTAGS_SET_SUBMATCH_END);
1325 switch (node->type)
1327 case LITERAL:
1329 tre_literal_t *lit = node->obj;
1331 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1333 int i;
1334 if (regset[0] >= 0)
1336 /* Regset is not empty, so add a tag before the
1337 literal or backref. */
1338 if (!first_pass)
1340 status = tre_add_tag_left(mem, node, tag);
1341 tnfa->tag_directions[tag] = direction;
1342 if (minimal_tag >= 0)
1344 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1345 tnfa->minimal_tags[i] = tag;
1346 tnfa->minimal_tags[i + 1] = minimal_tag;
1347 tnfa->minimal_tags[i + 2] = -1;
1348 minimal_tag = -1;
1349 num_minimals++;
1351 tre_purge_regset(regset, tnfa, tag);
1353 else
1355 node->num_tags = 1;
1358 regset[0] = -1;
1359 tag = next_tag;
1360 num_tags++;
1361 next_tag++;
1364 else
1366 assert(!IS_TAG(lit));
1368 break;
1370 case CATENATION:
1372 tre_catenation_t *cat = node->obj;
1373 tre_ast_node_t *left = cat->left;
1374 tre_ast_node_t *right = cat->right;
1375 int reserved_tag = -1;
1378 /* After processing right child. */
1379 STACK_PUSHX(stack, voidptr, node);
1380 STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_RIGHT);
1382 /* Process right child. */
1383 STACK_PUSHX(stack, voidptr, right);
1384 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1386 /* After processing left child. */
1387 STACK_PUSHX(stack, int, next_tag + left->num_tags);
1388 if (left->num_tags > 0 && right->num_tags > 0)
1390 /* Reserve the next tag to the right child. */
1391 reserved_tag = next_tag;
1392 next_tag++;
1394 STACK_PUSHX(stack, int, reserved_tag);
1395 STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_LEFT);
1397 /* Process left child. */
1398 STACK_PUSHX(stack, voidptr, left);
1399 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1402 break;
1403 case ITERATION:
1405 tre_iteration_t *iter = node->obj;
1407 if (first_pass)
1409 STACK_PUSHX(stack, int, regset[0] >= 0 || iter->minimal);
1411 else
1413 STACK_PUSHX(stack, int, tag);
1414 STACK_PUSHX(stack, int, iter->minimal);
1416 STACK_PUSHX(stack, voidptr, node);
1417 STACK_PUSHX(stack, int, ADDTAGS_AFTER_ITERATION);
1419 STACK_PUSHX(stack, voidptr, iter->arg);
1420 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1422 /* Regset is not empty, so add a tag here. */
1423 if (regset[0] >= 0 || iter->minimal)
1425 if (!first_pass)
1427 int i;
1428 status = tre_add_tag_left(mem, node, tag);
1429 if (iter->minimal)
1430 tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;
1431 else
1432 tnfa->tag_directions[tag] = direction;
1433 if (minimal_tag >= 0)
1435 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1436 tnfa->minimal_tags[i] = tag;
1437 tnfa->minimal_tags[i + 1] = minimal_tag;
1438 tnfa->minimal_tags[i + 2] = -1;
1439 minimal_tag = -1;
1440 num_minimals++;
1442 tre_purge_regset(regset, tnfa, tag);
1445 regset[0] = -1;
1446 tag = next_tag;
1447 num_tags++;
1448 next_tag++;
1450 direction = TRE_TAG_MINIMIZE;
1452 break;
1453 case UNION:
1455 tre_union_t *uni = node->obj;
1456 tre_ast_node_t *left = uni->left;
1457 tre_ast_node_t *right = uni->right;
1458 int left_tag;
1459 int right_tag;
1461 if (regset[0] >= 0)
1463 left_tag = next_tag;
1464 right_tag = next_tag + 1;
1466 else
1468 left_tag = tag;
1469 right_tag = next_tag;
1472 /* After processing right child. */
1473 STACK_PUSHX(stack, int, right_tag);
1474 STACK_PUSHX(stack, int, left_tag);
1475 STACK_PUSHX(stack, voidptr, regset);
1476 STACK_PUSHX(stack, int, regset[0] >= 0);
1477 STACK_PUSHX(stack, voidptr, node);
1478 STACK_PUSHX(stack, voidptr, right);
1479 STACK_PUSHX(stack, voidptr, left);
1480 STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_RIGHT);
1482 /* Process right child. */
1483 STACK_PUSHX(stack, voidptr, right);
1484 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1486 /* After processing left child. */
1487 STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_LEFT);
1489 /* Process left child. */
1490 STACK_PUSHX(stack, voidptr, left);
1491 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1493 /* Regset is not empty, so add a tag here. */
1494 if (regset[0] >= 0)
1496 if (!first_pass)
1498 int i;
1499 status = tre_add_tag_left(mem, node, tag);
1500 tnfa->tag_directions[tag] = direction;
1501 if (minimal_tag >= 0)
1503 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1504 tnfa->minimal_tags[i] = tag;
1505 tnfa->minimal_tags[i + 1] = minimal_tag;
1506 tnfa->minimal_tags[i + 2] = -1;
1507 minimal_tag = -1;
1508 num_minimals++;
1510 tre_purge_regset(regset, tnfa, tag);
1513 regset[0] = -1;
1514 tag = next_tag;
1515 num_tags++;
1516 next_tag++;
1519 if (node->num_submatches > 0)
1521 /* The next two tags are reserved for markers. */
1522 next_tag++;
1523 tag = next_tag;
1524 next_tag++;
1527 break;
1531 if (node->submatch_id >= 0)
1533 int i;
1534 /* Push this submatch on the parents stack. */
1535 for (i = 0; parents[i] >= 0; i++);
1536 parents[i] = node->submatch_id;
1537 parents[i + 1] = -1;
1540 break; /* end case: ADDTAGS_RECURSE */
1542 case ADDTAGS_AFTER_ITERATION:
1544 int minimal = 0;
1545 int enter_tag;
1546 node = tre_stack_pop_voidptr(stack);
1547 if (first_pass)
1549 node->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags
1550 + tre_stack_pop_int(stack);
1551 minimal_tag = -1;
1553 else
1555 minimal = tre_stack_pop_int(stack);
1556 enter_tag = tre_stack_pop_int(stack);
1557 if (minimal)
1558 minimal_tag = enter_tag;
1561 if (!first_pass)
1563 if (minimal)
1564 direction = TRE_TAG_MINIMIZE;
1565 else
1566 direction = TRE_TAG_MAXIMIZE;
1568 break;
1571 case ADDTAGS_AFTER_CAT_LEFT:
1573 int new_tag = tre_stack_pop_int(stack);
1574 next_tag = tre_stack_pop_int(stack);
1575 if (new_tag >= 0)
1577 tag = new_tag;
1579 break;
1582 case ADDTAGS_AFTER_CAT_RIGHT:
1583 node = tre_stack_pop_voidptr(stack);
1584 if (first_pass)
1585 node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags
1586 + ((tre_catenation_t *)node->obj)->right->num_tags;
1587 break;
1589 case ADDTAGS_AFTER_UNION_LEFT:
1590 /* Lift the bottom of the `regset' array so that when processing
1591 the right operand the items currently in the array are
1592 invisible. The original bottom was saved at ADDTAGS_UNION and
1593 will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */
1594 while (*regset >= 0)
1595 regset++;
1596 break;
1598 case ADDTAGS_AFTER_UNION_RIGHT:
1600 int added_tags, tag_left, tag_right;
1601 tre_ast_node_t *left = tre_stack_pop_voidptr(stack);
1602 tre_ast_node_t *right = tre_stack_pop_voidptr(stack);
1603 node = tre_stack_pop_voidptr(stack);
1604 added_tags = tre_stack_pop_int(stack);
1605 if (first_pass)
1607 node->num_tags = ((tre_union_t *)node->obj)->left->num_tags
1608 + ((tre_union_t *)node->obj)->right->num_tags + added_tags
1609 + ((node->num_submatches > 0) ? 2 : 0);
1611 regset = tre_stack_pop_voidptr(stack);
1612 tag_left = tre_stack_pop_int(stack);
1613 tag_right = tre_stack_pop_int(stack);
1615 /* Add tags after both children, the left child gets a smaller
1616 tag than the right child. This guarantees that we prefer
1617 the left child over the right child. */
1618 /* XXX - This is not always necessary (if the children have
1619 tags which must be seen for every match of that child). */
1620 /* XXX - Check if this is the only place where tre_add_tag_right
1621 is used. If so, use tre_add_tag_left (putting the tag before
1622 the child as opposed after the child) and throw away
1623 tre_add_tag_right. */
1624 if (node->num_submatches > 0)
1626 if (!first_pass)
1628 status = tre_add_tag_right(mem, left, tag_left);
1629 tnfa->tag_directions[tag_left] = TRE_TAG_MAXIMIZE;
1630 if (status == REG_OK)
1631 status = tre_add_tag_right(mem, right, tag_right);
1632 tnfa->tag_directions[tag_right] = TRE_TAG_MAXIMIZE;
1634 num_tags += 2;
1636 direction = TRE_TAG_MAXIMIZE;
1637 break;
1640 default:
1641 assert(0);
1642 break;
1644 } /* end switch(symbol) */
1645 } /* end while(tre_stack_num_objects(stack) > bottom) */
1647 if (!first_pass)
1648 tre_purge_regset(regset, tnfa, tag);
1650 if (!first_pass && minimal_tag >= 0)
1652 int i;
1653 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1654 tnfa->minimal_tags[i] = tag;
1655 tnfa->minimal_tags[i + 1] = minimal_tag;
1656 tnfa->minimal_tags[i + 2] = -1;
1657 minimal_tag = -1;
1658 num_minimals++;
1661 assert(tree->num_tags == num_tags);
1662 tnfa->end_tag = num_tags;
1663 tnfa->num_tags = num_tags;
1664 tnfa->num_minimals = num_minimals;
1665 xfree(orig_regset);
1666 xfree(parents);
1667 xfree(saved_states);
1668 return status;
1674 AST to TNFA compilation routines.
1677 typedef enum {
1678 COPY_RECURSE,
1679 COPY_SET_RESULT_PTR
1680 } tre_copyast_symbol_t;
1682 /* Flags for tre_copy_ast(). */
1683 #define COPY_REMOVE_TAGS 1
1684 #define COPY_MAXIMIZE_FIRST_TAG 2
1686 static reg_errcode_t
1687 tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1688 int flags, int *pos_add, tre_tag_direction_t *tag_directions,
1689 tre_ast_node_t **copy, int *max_pos)
1691 reg_errcode_t status = REG_OK;
1692 int bottom = tre_stack_num_objects(stack);
1693 int num_copied = 0;
1694 int first_tag = 1;
1695 tre_ast_node_t **result = copy;
1696 tre_copyast_symbol_t symbol;
1698 STACK_PUSH(stack, voidptr, ast);
1699 STACK_PUSH(stack, int, COPY_RECURSE);
1701 while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
1703 tre_ast_node_t *node;
1704 if (status != REG_OK)
1705 break;
1707 symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack);
1708 switch (symbol)
1710 case COPY_SET_RESULT_PTR:
1711 result = tre_stack_pop_voidptr(stack);
1712 break;
1713 case COPY_RECURSE:
1714 node = tre_stack_pop_voidptr(stack);
1715 switch (node->type)
1717 case LITERAL:
1719 tre_literal_t *lit = node->obj;
1720 int pos = lit->position;
1721 int min = lit->code_min;
1722 int max = lit->code_max;
1723 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1725 /* XXX - e.g. [ab] has only one position but two
1726 nodes, so we are creating holes in the state space
1727 here. Not fatal, just wastes memory. */
1728 pos += *pos_add;
1729 num_copied++;
1731 else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))
1733 /* Change this tag to empty. */
1734 min = EMPTY;
1735 max = pos = -1;
1737 else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)
1738 && first_tag)
1740 /* Maximize the first tag. */
1741 tag_directions[max] = TRE_TAG_MAXIMIZE;
1742 first_tag = 0;
1744 *result = tre_ast_new_literal(mem, min, max, pos);
1745 if (*result == NULL)
1746 status = REG_ESPACE;
1747 else {
1748 tre_literal_t *p = (*result)->obj;
1749 p->class = lit->class;
1750 p->neg_classes = lit->neg_classes;
1753 if (pos > *max_pos)
1754 *max_pos = pos;
1755 break;
1757 case UNION:
1759 tre_union_t *uni = node->obj;
1760 tre_union_t *tmp;
1761 *result = tre_ast_new_union(mem, uni->left, uni->right);
1762 if (*result == NULL)
1764 status = REG_ESPACE;
1765 break;
1767 tmp = (*result)->obj;
1768 result = &tmp->left;
1769 STACK_PUSHX(stack, voidptr, uni->right);
1770 STACK_PUSHX(stack, int, COPY_RECURSE);
1771 STACK_PUSHX(stack, voidptr, &tmp->right);
1772 STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
1773 STACK_PUSHX(stack, voidptr, uni->left);
1774 STACK_PUSHX(stack, int, COPY_RECURSE);
1775 break;
1777 case CATENATION:
1779 tre_catenation_t *cat = node->obj;
1780 tre_catenation_t *tmp;
1781 *result = tre_ast_new_catenation(mem, cat->left, cat->right);
1782 if (*result == NULL)
1784 status = REG_ESPACE;
1785 break;
1787 tmp = (*result)->obj;
1788 tmp->left = NULL;
1789 tmp->right = NULL;
1790 result = &tmp->left;
1792 STACK_PUSHX(stack, voidptr, cat->right);
1793 STACK_PUSHX(stack, int, COPY_RECURSE);
1794 STACK_PUSHX(stack, voidptr, &tmp->right);
1795 STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
1796 STACK_PUSHX(stack, voidptr, cat->left);
1797 STACK_PUSHX(stack, int, COPY_RECURSE);
1798 break;
1800 case ITERATION:
1802 tre_iteration_t *iter = node->obj;
1803 STACK_PUSHX(stack, voidptr, iter->arg);
1804 STACK_PUSHX(stack, int, COPY_RECURSE);
1805 *result = tre_ast_new_iter(mem, iter->arg, iter->min,
1806 iter->max, iter->minimal);
1807 if (*result == NULL)
1809 status = REG_ESPACE;
1810 break;
1812 iter = (*result)->obj;
1813 result = &iter->arg;
1814 break;
1816 default:
1817 assert(0);
1818 break;
1820 break;
1823 *pos_add += num_copied;
1824 return status;
1827 typedef enum {
1828 EXPAND_RECURSE,
1829 EXPAND_AFTER_ITER
1830 } tre_expand_ast_symbol_t;
1832 /* Expands each iteration node that has a finite nonzero minimum or maximum
1833 iteration count to a catenated sequence of copies of the node. */
1834 static reg_errcode_t
1835 tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1836 int *position, tre_tag_direction_t *tag_directions)
1838 reg_errcode_t status = REG_OK;
1839 int bottom = tre_stack_num_objects(stack);
1840 int pos_add = 0;
1841 int pos_add_total = 0;
1842 int max_pos = 0;
1843 int iter_depth = 0;
1845 STACK_PUSHR(stack, voidptr, ast);
1846 STACK_PUSHR(stack, int, EXPAND_RECURSE);
1847 while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
1849 tre_ast_node_t *node;
1850 tre_expand_ast_symbol_t symbol;
1852 if (status != REG_OK)
1853 break;
1855 symbol = (tre_expand_ast_symbol_t)tre_stack_pop_int(stack);
1856 node = tre_stack_pop_voidptr(stack);
1857 switch (symbol)
1859 case EXPAND_RECURSE:
1860 switch (node->type)
1862 case LITERAL:
1864 tre_literal_t *lit= node->obj;
1865 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1867 lit->position += pos_add;
1868 if (lit->position > max_pos)
1869 max_pos = lit->position;
1871 break;
1873 case UNION:
1875 tre_union_t *uni = node->obj;
1876 STACK_PUSHX(stack, voidptr, uni->right);
1877 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1878 STACK_PUSHX(stack, voidptr, uni->left);
1879 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1880 break;
1882 case CATENATION:
1884 tre_catenation_t *cat = node->obj;
1885 STACK_PUSHX(stack, voidptr, cat->right);
1886 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1887 STACK_PUSHX(stack, voidptr, cat->left);
1888 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1889 break;
1891 case ITERATION:
1893 tre_iteration_t *iter = node->obj;
1894 STACK_PUSHX(stack, int, pos_add);
1895 STACK_PUSHX(stack, voidptr, node);
1896 STACK_PUSHX(stack, int, EXPAND_AFTER_ITER);
1897 STACK_PUSHX(stack, voidptr, iter->arg);
1898 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1899 /* If we are going to expand this node at EXPAND_AFTER_ITER
1900 then don't increase the `pos' fields of the nodes now, it
1901 will get done when expanding. */
1902 if (iter->min > 1 || iter->max > 1)
1903 pos_add = 0;
1904 iter_depth++;
1905 break;
1907 default:
1908 assert(0);
1909 break;
1911 break;
1912 case EXPAND_AFTER_ITER:
1914 tre_iteration_t *iter = node->obj;
1915 int pos_add_last;
1916 pos_add = tre_stack_pop_int(stack);
1917 pos_add_last = pos_add;
1918 if (iter->min > 1 || iter->max > 1)
1920 tre_ast_node_t *seq1 = NULL, *seq2 = NULL;
1921 int j;
1922 int pos_add_save = pos_add;
1924 /* Create a catenated sequence of copies of the node. */
1925 for (j = 0; j < iter->min; j++)
1927 tre_ast_node_t *copy;
1928 /* Remove tags from all but the last copy. */
1929 int flags = ((j + 1 < iter->min)
1930 ? COPY_REMOVE_TAGS
1931 : COPY_MAXIMIZE_FIRST_TAG);
1932 pos_add_save = pos_add;
1933 status = tre_copy_ast(mem, stack, iter->arg, flags,
1934 &pos_add, tag_directions, &copy,
1935 &max_pos);
1936 if (status != REG_OK)
1937 return status;
1938 if (seq1 != NULL)
1939 seq1 = tre_ast_new_catenation(mem, seq1, copy);
1940 else
1941 seq1 = copy;
1942 if (seq1 == NULL)
1943 return REG_ESPACE;
1946 if (iter->max == -1)
1948 /* No upper limit. */
1949 pos_add_save = pos_add;
1950 status = tre_copy_ast(mem, stack, iter->arg, 0,
1951 &pos_add, NULL, &seq2, &max_pos);
1952 if (status != REG_OK)
1953 return status;
1954 seq2 = tre_ast_new_iter(mem, seq2, 0, -1, 0);
1955 if (seq2 == NULL)
1956 return REG_ESPACE;
1958 else
1960 for (j = iter->min; j < iter->max; j++)
1962 tre_ast_node_t *tmp, *copy;
1963 pos_add_save = pos_add;
1964 status = tre_copy_ast(mem, stack, iter->arg, 0,
1965 &pos_add, NULL, &copy, &max_pos);
1966 if (status != REG_OK)
1967 return status;
1968 if (seq2 != NULL)
1969 seq2 = tre_ast_new_catenation(mem, copy, seq2);
1970 else
1971 seq2 = copy;
1972 if (seq2 == NULL)
1973 return REG_ESPACE;
1974 tmp = tre_ast_new_literal(mem, EMPTY, -1, -1);
1975 if (tmp == NULL)
1976 return REG_ESPACE;
1977 seq2 = tre_ast_new_union(mem, tmp, seq2);
1978 if (seq2 == NULL)
1979 return REG_ESPACE;
1983 pos_add = pos_add_save;
1984 if (seq1 == NULL)
1985 seq1 = seq2;
1986 else if (seq2 != NULL)
1987 seq1 = tre_ast_new_catenation(mem, seq1, seq2);
1988 if (seq1 == NULL)
1989 return REG_ESPACE;
1990 node->obj = seq1->obj;
1991 node->type = seq1->type;
1994 iter_depth--;
1995 pos_add_total += pos_add - pos_add_last;
1996 if (iter_depth == 0)
1997 pos_add = pos_add_total;
1999 break;
2001 default:
2002 assert(0);
2003 break;
2007 *position += pos_add_total;
2009 /* `max_pos' should never be larger than `*position' if the above
2010 code works, but just an extra safeguard let's make sure
2011 `*position' is set large enough so enough memory will be
2012 allocated for the transition table. */
2013 if (max_pos > *position)
2014 *position = max_pos;
2016 return status;
2019 static tre_pos_and_tags_t *
2020 tre_set_empty(tre_mem_t mem)
2022 tre_pos_and_tags_t *new_set;
2024 new_set = tre_mem_calloc(mem, sizeof(*new_set));
2025 if (new_set == NULL)
2026 return NULL;
2028 new_set[0].position = -1;
2029 new_set[0].code_min = -1;
2030 new_set[0].code_max = -1;
2032 return new_set;
2035 static tre_pos_and_tags_t *
2036 tre_set_one(tre_mem_t mem, int position, int code_min, int code_max,
2037 tre_ctype_t class, tre_ctype_t *neg_classes, int backref)
2039 tre_pos_and_tags_t *new_set;
2041 new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2);
2042 if (new_set == NULL)
2043 return NULL;
2045 new_set[0].position = position;
2046 new_set[0].code_min = code_min;
2047 new_set[0].code_max = code_max;
2048 new_set[0].class = class;
2049 new_set[0].neg_classes = neg_classes;
2050 new_set[0].backref = backref;
2051 new_set[1].position = -1;
2052 new_set[1].code_min = -1;
2053 new_set[1].code_max = -1;
2055 return new_set;
2058 static tre_pos_and_tags_t *
2059 tre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2,
2060 int *tags, int assertions)
2062 int s1, s2, i, j;
2063 tre_pos_and_tags_t *new_set;
2064 int *new_tags;
2065 int num_tags;
2067 for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++);
2068 for (s1 = 0; set1[s1].position >= 0; s1++);
2069 for (s2 = 0; set2[s2].position >= 0; s2++);
2070 new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1));
2071 if (!new_set )
2072 return NULL;
2074 for (s1 = 0; set1[s1].position >= 0; s1++)
2076 new_set[s1].position = set1[s1].position;
2077 new_set[s1].code_min = set1[s1].code_min;
2078 new_set[s1].code_max = set1[s1].code_max;
2079 new_set[s1].assertions = set1[s1].assertions | assertions;
2080 new_set[s1].class = set1[s1].class;
2081 new_set[s1].neg_classes = set1[s1].neg_classes;
2082 new_set[s1].backref = set1[s1].backref;
2083 if (set1[s1].tags == NULL && tags == NULL)
2084 new_set[s1].tags = NULL;
2085 else
2087 for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++);
2088 new_tags = tre_mem_alloc(mem, (sizeof(*new_tags)
2089 * (i + num_tags + 1)));
2090 if (new_tags == NULL)
2091 return NULL;
2092 for (j = 0; j < i; j++)
2093 new_tags[j] = set1[s1].tags[j];
2094 for (i = 0; i < num_tags; i++)
2095 new_tags[j + i] = tags[i];
2096 new_tags[j + i] = -1;
2097 new_set[s1].tags = new_tags;
2101 for (s2 = 0; set2[s2].position >= 0; s2++)
2103 new_set[s1 + s2].position = set2[s2].position;
2104 new_set[s1 + s2].code_min = set2[s2].code_min;
2105 new_set[s1 + s2].code_max = set2[s2].code_max;
2106 /* XXX - why not | assertions here as well? */
2107 new_set[s1 + s2].assertions = set2[s2].assertions;
2108 new_set[s1 + s2].class = set2[s2].class;
2109 new_set[s1 + s2].neg_classes = set2[s2].neg_classes;
2110 new_set[s1 + s2].backref = set2[s2].backref;
2111 if (set2[s2].tags == NULL)
2112 new_set[s1 + s2].tags = NULL;
2113 else
2115 for (i = 0; set2[s2].tags[i] >= 0; i++);
2116 new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1));
2117 if (new_tags == NULL)
2118 return NULL;
2119 for (j = 0; j < i; j++)
2120 new_tags[j] = set2[s2].tags[j];
2121 new_tags[j] = -1;
2122 new_set[s1 + s2].tags = new_tags;
2125 new_set[s1 + s2].position = -1;
2126 return new_set;
2129 /* Finds the empty path through `node' which is the one that should be
2130 taken according to POSIX.2 rules, and adds the tags on that path to
2131 `tags'. `tags' may be NULL. If `num_tags_seen' is not NULL, it is
2132 set to the number of tags seen on the path. */
2133 static reg_errcode_t
2134 tre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags,
2135 int *assertions, int *num_tags_seen)
2137 tre_literal_t *lit;
2138 tre_union_t *uni;
2139 tre_catenation_t *cat;
2140 tre_iteration_t *iter;
2141 int i;
2142 int bottom = tre_stack_num_objects(stack);
2143 reg_errcode_t status = REG_OK;
2144 if (num_tags_seen)
2145 *num_tags_seen = 0;
2147 status = tre_stack_push_voidptr(stack, node);
2149 /* Walk through the tree recursively. */
2150 while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
2152 node = tre_stack_pop_voidptr(stack);
2154 switch (node->type)
2156 case LITERAL:
2157 lit = (tre_literal_t *)node->obj;
2158 switch (lit->code_min)
2160 case TAG:
2161 if (lit->code_max >= 0)
2163 if (tags != NULL)
2165 /* Add the tag to `tags'. */
2166 for (i = 0; tags[i] >= 0; i++)
2167 if (tags[i] == lit->code_max)
2168 break;
2169 if (tags[i] < 0)
2171 tags[i] = lit->code_max;
2172 tags[i + 1] = -1;
2175 if (num_tags_seen)
2176 (*num_tags_seen)++;
2178 break;
2179 case ASSERTION:
2180 assert(lit->code_max >= 1
2181 || lit->code_max <= ASSERT_LAST);
2182 if (assertions != NULL)
2183 *assertions |= lit->code_max;
2184 break;
2185 case EMPTY:
2186 break;
2187 default:
2188 assert(0);
2189 break;
2191 break;
2193 case UNION:
2194 /* Subexpressions starting earlier take priority over ones
2195 starting later, so we prefer the left subexpression over the
2196 right subexpression. */
2197 uni = (tre_union_t *)node->obj;
2198 if (uni->left->nullable)
2199 STACK_PUSHX(stack, voidptr, uni->left)
2200 else if (uni->right->nullable)
2201 STACK_PUSHX(stack, voidptr, uni->right)
2202 else
2203 assert(0);
2204 break;
2206 case CATENATION:
2207 /* The path must go through both children. */
2208 cat = (tre_catenation_t *)node->obj;
2209 assert(cat->left->nullable);
2210 assert(cat->right->nullable);
2211 STACK_PUSHX(stack, voidptr, cat->left);
2212 STACK_PUSHX(stack, voidptr, cat->right);
2213 break;
2215 case ITERATION:
2216 /* A match with an empty string is preferred over no match at
2217 all, so we go through the argument if possible. */
2218 iter = (tre_iteration_t *)node->obj;
2219 if (iter->arg->nullable)
2220 STACK_PUSHX(stack, voidptr, iter->arg);
2221 break;
2223 default:
2224 assert(0);
2225 break;
2229 return status;
2233 typedef enum {
2234 NFL_RECURSE,
2235 NFL_POST_UNION,
2236 NFL_POST_CATENATION,
2237 NFL_POST_ITERATION
2238 } tre_nfl_stack_symbol_t;
2241 /* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for
2242 the nodes of the AST `tree'. */
2243 static reg_errcode_t
2244 tre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree)
2246 int bottom = tre_stack_num_objects(stack);
2248 STACK_PUSHR(stack, voidptr, tree);
2249 STACK_PUSHR(stack, int, NFL_RECURSE);
2251 while (tre_stack_num_objects(stack) > bottom)
2253 tre_nfl_stack_symbol_t symbol;
2254 tre_ast_node_t *node;
2256 symbol = (tre_nfl_stack_symbol_t)tre_stack_pop_int(stack);
2257 node = tre_stack_pop_voidptr(stack);
2258 switch (symbol)
2260 case NFL_RECURSE:
2261 switch (node->type)
2263 case LITERAL:
2265 tre_literal_t *lit = (tre_literal_t *)node->obj;
2266 if (IS_BACKREF(lit))
2268 /* Back references: nullable = false, firstpos = {i},
2269 lastpos = {i}. */
2270 node->nullable = 0;
2271 node->firstpos = tre_set_one(mem, lit->position, 0,
2272 TRE_CHAR_MAX, 0, NULL, -1);
2273 if (!node->firstpos)
2274 return REG_ESPACE;
2275 node->lastpos = tre_set_one(mem, lit->position, 0,
2276 TRE_CHAR_MAX, 0, NULL,
2277 (int)lit->code_max);
2278 if (!node->lastpos)
2279 return REG_ESPACE;
2281 else if (lit->code_min < 0)
2283 /* Tags, empty strings, params, and zero width assertions:
2284 nullable = true, firstpos = {}, and lastpos = {}. */
2285 node->nullable = 1;
2286 node->firstpos = tre_set_empty(mem);
2287 if (!node->firstpos)
2288 return REG_ESPACE;
2289 node->lastpos = tre_set_empty(mem);
2290 if (!node->lastpos)
2291 return REG_ESPACE;
2293 else
2295 /* Literal at position i: nullable = false, firstpos = {i},
2296 lastpos = {i}. */
2297 node->nullable = 0;
2298 node->firstpos =
2299 tre_set_one(mem, lit->position, (int)lit->code_min,
2300 (int)lit->code_max, 0, NULL, -1);
2301 if (!node->firstpos)
2302 return REG_ESPACE;
2303 node->lastpos = tre_set_one(mem, lit->position,
2304 (int)lit->code_min,
2305 (int)lit->code_max,
2306 lit->class, lit->neg_classes,
2307 -1);
2308 if (!node->lastpos)
2309 return REG_ESPACE;
2311 break;
2314 case UNION:
2315 /* Compute the attributes for the two subtrees, and after that
2316 for this node. */
2317 STACK_PUSHR(stack, voidptr, node);
2318 STACK_PUSHR(stack, int, NFL_POST_UNION);
2319 STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->right);
2320 STACK_PUSHR(stack, int, NFL_RECURSE);
2321 STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->left);
2322 STACK_PUSHR(stack, int, NFL_RECURSE);
2323 break;
2325 case CATENATION:
2326 /* Compute the attributes for the two subtrees, and after that
2327 for this node. */
2328 STACK_PUSHR(stack, voidptr, node);
2329 STACK_PUSHR(stack, int, NFL_POST_CATENATION);
2330 STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->right);
2331 STACK_PUSHR(stack, int, NFL_RECURSE);
2332 STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->left);
2333 STACK_PUSHR(stack, int, NFL_RECURSE);
2334 break;
2336 case ITERATION:
2337 /* Compute the attributes for the subtree, and after that for
2338 this node. */
2339 STACK_PUSHR(stack, voidptr, node);
2340 STACK_PUSHR(stack, int, NFL_POST_ITERATION);
2341 STACK_PUSHR(stack, voidptr, ((tre_iteration_t *)node->obj)->arg);
2342 STACK_PUSHR(stack, int, NFL_RECURSE);
2343 break;
2345 break; /* end case: NFL_RECURSE */
2347 case NFL_POST_UNION:
2349 tre_union_t *uni = (tre_union_t *)node->obj;
2350 node->nullable = uni->left->nullable || uni->right->nullable;
2351 node->firstpos = tre_set_union(mem, uni->left->firstpos,
2352 uni->right->firstpos, NULL, 0);
2353 if (!node->firstpos)
2354 return REG_ESPACE;
2355 node->lastpos = tre_set_union(mem, uni->left->lastpos,
2356 uni->right->lastpos, NULL, 0);
2357 if (!node->lastpos)
2358 return REG_ESPACE;
2359 break;
2362 case NFL_POST_ITERATION:
2364 tre_iteration_t *iter = (tre_iteration_t *)node->obj;
2366 if (iter->min == 0 || iter->arg->nullable)
2367 node->nullable = 1;
2368 else
2369 node->nullable = 0;
2370 node->firstpos = iter->arg->firstpos;
2371 node->lastpos = iter->arg->lastpos;
2372 break;
2375 case NFL_POST_CATENATION:
2377 int num_tags, *tags, assertions;
2378 reg_errcode_t status;
2379 tre_catenation_t *cat = node->obj;
2380 node->nullable = cat->left->nullable && cat->right->nullable;
2382 /* Compute firstpos. */
2383 if (cat->left->nullable)
2385 /* The left side matches the empty string. Make a first pass
2386 with tre_match_empty() to get the number of tags and
2387 parameters. */
2388 status = tre_match_empty(stack, cat->left,
2389 NULL, NULL, &num_tags);
2390 if (status != REG_OK)
2391 return status;
2392 /* Allocate arrays for the tags and parameters. */
2393 tags = xmalloc(sizeof(*tags) * (num_tags + 1));
2394 if (!tags)
2395 return REG_ESPACE;
2396 tags[0] = -1;
2397 assertions = 0;
2398 /* Second pass with tre_mach_empty() to get the list of
2399 tags and parameters. */
2400 status = tre_match_empty(stack, cat->left, tags,
2401 &assertions, NULL);
2402 if (status != REG_OK)
2404 xfree(tags);
2405 return status;
2407 node->firstpos =
2408 tre_set_union(mem, cat->right->firstpos, cat->left->firstpos,
2409 tags, assertions);
2410 xfree(tags);
2411 if (!node->firstpos)
2412 return REG_ESPACE;
2414 else
2416 node->firstpos = cat->left->firstpos;
2419 /* Compute lastpos. */
2420 if (cat->right->nullable)
2422 /* The right side matches the empty string. Make a first pass
2423 with tre_match_empty() to get the number of tags and
2424 parameters. */
2425 status = tre_match_empty(stack, cat->right,
2426 NULL, NULL, &num_tags);
2427 if (status != REG_OK)
2428 return status;
2429 /* Allocate arrays for the tags and parameters. */
2430 tags = xmalloc(sizeof(int) * (num_tags + 1));
2431 if (!tags)
2432 return REG_ESPACE;
2433 tags[0] = -1;
2434 assertions = 0;
2435 /* Second pass with tre_mach_empty() to get the list of
2436 tags and parameters. */
2437 status = tre_match_empty(stack, cat->right, tags,
2438 &assertions, NULL);
2439 if (status != REG_OK)
2441 xfree(tags);
2442 return status;
2444 node->lastpos =
2445 tre_set_union(mem, cat->left->lastpos, cat->right->lastpos,
2446 tags, assertions);
2447 xfree(tags);
2448 if (!node->lastpos)
2449 return REG_ESPACE;
2451 else
2453 node->lastpos = cat->right->lastpos;
2455 break;
2458 default:
2459 assert(0);
2460 break;
2464 return REG_OK;
2468 /* Adds a transition from each position in `p1' to each position in `p2'. */
2469 static reg_errcode_t
2470 tre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,
2471 tre_tnfa_transition_t *transitions,
2472 int *counts, int *offs)
2474 tre_pos_and_tags_t *orig_p2 = p2;
2475 tre_tnfa_transition_t *trans;
2476 int i, j, k, l, dup, prev_p2_pos;
2478 if (transitions != NULL)
2479 while (p1->position >= 0)
2481 p2 = orig_p2;
2482 prev_p2_pos = -1;
2483 while (p2->position >= 0)
2485 /* Optimization: if this position was already handled, skip it. */
2486 if (p2->position == prev_p2_pos)
2488 p2++;
2489 continue;
2491 prev_p2_pos = p2->position;
2492 /* Set `trans' to point to the next unused transition from
2493 position `p1->position'. */
2494 trans = transitions + offs[p1->position];
2495 while (trans->state != NULL)
2497 #if 0
2498 /* If we find a previous transition from `p1->position' to
2499 `p2->position', it is overwritten. This can happen only
2500 if there are nested loops in the regexp, like in "((a)*)*".
2501 In POSIX.2 repetition using the outer loop is always
2502 preferred over using the inner loop. Therefore the
2503 transition for the inner loop is useless and can be thrown
2504 away. */
2505 /* XXX - The same position is used for all nodes in a bracket
2506 expression, so this optimization cannot be used (it will
2507 break bracket expressions) unless I figure out a way to
2508 detect it here. */
2509 if (trans->state_id == p2->position)
2511 break;
2513 #endif
2514 trans++;
2517 if (trans->state == NULL)
2518 (trans + 1)->state = NULL;
2519 /* Use the character ranges, assertions, etc. from `p1' for
2520 the transition from `p1' to `p2'. */
2521 trans->code_min = p1->code_min;
2522 trans->code_max = p1->code_max;
2523 trans->state = transitions + offs[p2->position];
2524 trans->state_id = p2->position;
2525 trans->assertions = p1->assertions | p2->assertions
2526 | (p1->class ? ASSERT_CHAR_CLASS : 0)
2527 | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0);
2528 if (p1->backref >= 0)
2530 assert((trans->assertions & ASSERT_CHAR_CLASS) == 0);
2531 assert(p2->backref < 0);
2532 trans->u.backref = p1->backref;
2533 trans->assertions |= ASSERT_BACKREF;
2535 else
2536 trans->u.class = p1->class;
2537 if (p1->neg_classes != NULL)
2539 for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);
2540 trans->neg_classes =
2541 xmalloc(sizeof(*trans->neg_classes) * (i + 1));
2542 if (trans->neg_classes == NULL)
2543 return REG_ESPACE;
2544 for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)
2545 trans->neg_classes[i] = p1->neg_classes[i];
2546 trans->neg_classes[i] = (tre_ctype_t)0;
2548 else
2549 trans->neg_classes = NULL;
2551 /* Find out how many tags this transition has. */
2552 i = 0;
2553 if (p1->tags != NULL)
2554 while(p1->tags[i] >= 0)
2555 i++;
2556 j = 0;
2557 if (p2->tags != NULL)
2558 while(p2->tags[j] >= 0)
2559 j++;
2561 /* If we are overwriting a transition, free the old tag array. */
2562 if (trans->tags != NULL)
2563 xfree(trans->tags);
2564 trans->tags = NULL;
2566 /* If there were any tags, allocate an array and fill it. */
2567 if (i + j > 0)
2569 trans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1));
2570 if (!trans->tags)
2571 return REG_ESPACE;
2572 i = 0;
2573 if (p1->tags != NULL)
2574 while(p1->tags[i] >= 0)
2576 trans->tags[i] = p1->tags[i];
2577 i++;
2579 l = i;
2580 j = 0;
2581 if (p2->tags != NULL)
2582 while (p2->tags[j] >= 0)
2584 /* Don't add duplicates. */
2585 dup = 0;
2586 for (k = 0; k < i; k++)
2587 if (trans->tags[k] == p2->tags[j])
2589 dup = 1;
2590 break;
2592 if (!dup)
2593 trans->tags[l++] = p2->tags[j];
2594 j++;
2596 trans->tags[l] = -1;
2599 p2++;
2601 p1++;
2603 else
2604 /* Compute a maximum limit for the number of transitions leaving
2605 from each state. */
2606 while (p1->position >= 0)
2608 p2 = orig_p2;
2609 while (p2->position >= 0)
2611 counts[p1->position]++;
2612 p2++;
2614 p1++;
2616 return REG_OK;
2619 /* Converts the syntax tree to a TNFA. All the transitions in the TNFA are
2620 labelled with one character range (there are no transitions on empty
2621 strings). The TNFA takes O(n^2) space in the worst case, `n' is size of
2622 the regexp. */
2623 static reg_errcode_t
2624 tre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions,
2625 int *counts, int *offs)
2627 tre_union_t *uni;
2628 tre_catenation_t *cat;
2629 tre_iteration_t *iter;
2630 reg_errcode_t errcode = REG_OK;
2632 /* XXX - recurse using a stack!. */
2633 switch (node->type)
2635 case LITERAL:
2636 break;
2637 case UNION:
2638 uni = (tre_union_t *)node->obj;
2639 errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs);
2640 if (errcode != REG_OK)
2641 return errcode;
2642 errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs);
2643 break;
2645 case CATENATION:
2646 cat = (tre_catenation_t *)node->obj;
2647 /* Add a transition from each position in cat->left->lastpos
2648 to each position in cat->right->firstpos. */
2649 errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos,
2650 transitions, counts, offs);
2651 if (errcode != REG_OK)
2652 return errcode;
2653 errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs);
2654 if (errcode != REG_OK)
2655 return errcode;
2656 errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs);
2657 break;
2659 case ITERATION:
2660 iter = (tre_iteration_t *)node->obj;
2661 assert(iter->max == -1 || iter->max == 1);
2663 if (iter->max == -1)
2665 assert(iter->min == 0 || iter->min == 1);
2666 /* Add a transition from each last position in the iterated
2667 expression to each first position. */
2668 errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos,
2669 transitions, counts, offs);
2670 if (errcode != REG_OK)
2671 return errcode;
2673 errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs);
2674 break;
2676 return errcode;
2680 #define ERROR_EXIT(err) \
2681 do \
2683 errcode = err; \
2684 if (/*CONSTCOND*/1) \
2685 goto error_exit; \
2687 while (/*CONSTCOND*/0)
2691 regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
2693 tre_stack_t *stack;
2694 tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r;
2695 tre_pos_and_tags_t *p;
2696 int *counts = NULL, *offs = NULL;
2697 int i, add = 0;
2698 tre_tnfa_transition_t *transitions, *initial;
2699 tre_tnfa_t *tnfa = NULL;
2700 tre_submatch_data_t *submatch_data;
2701 tre_tag_direction_t *tag_directions = NULL;
2702 reg_errcode_t errcode;
2703 tre_mem_t mem;
2705 /* Parse context. */
2706 tre_parse_ctx_t parse_ctx;
2708 /* Allocate a stack used throughout the compilation process for various
2709 purposes. */
2710 stack = tre_stack_new(512, 1024000, 128);
2711 if (!stack)
2712 return REG_ESPACE;
2713 /* Allocate a fast memory allocator. */
2714 mem = tre_mem_new();
2715 if (!mem)
2717 tre_stack_destroy(stack);
2718 return REG_ESPACE;
2721 /* Parse the regexp. */
2722 memset(&parse_ctx, 0, sizeof(parse_ctx));
2723 parse_ctx.mem = mem;
2724 parse_ctx.stack = stack;
2725 parse_ctx.start = regex;
2726 parse_ctx.cflags = cflags;
2727 parse_ctx.max_backref = -1;
2728 errcode = tre_parse(&parse_ctx);
2729 if (errcode != REG_OK)
2730 ERROR_EXIT(errcode);
2731 preg->re_nsub = parse_ctx.submatch_id - 1;
2732 tree = parse_ctx.n;
2734 #ifdef TRE_DEBUG
2735 tre_ast_print(tree);
2736 #endif /* TRE_DEBUG */
2738 /* Referring to nonexistent subexpressions is illegal. */
2739 if (parse_ctx.max_backref > (int)preg->re_nsub)
2740 ERROR_EXIT(REG_ESUBREG);
2742 /* Allocate the TNFA struct. */
2743 tnfa = xcalloc(1, sizeof(tre_tnfa_t));
2744 if (tnfa == NULL)
2745 ERROR_EXIT(REG_ESPACE);
2746 tnfa->have_backrefs = parse_ctx.max_backref >= 0;
2747 tnfa->have_approx = 0;
2748 tnfa->num_submatches = parse_ctx.submatch_id;
2750 /* Set up tags for submatch addressing. If REG_NOSUB is set and the
2751 regexp does not have back references, this can be skipped. */
2752 if (tnfa->have_backrefs || !(cflags & REG_NOSUB))
2755 /* Figure out how many tags we will need. */
2756 errcode = tre_add_tags(NULL, stack, tree, tnfa);
2757 if (errcode != REG_OK)
2758 ERROR_EXIT(errcode);
2760 if (tnfa->num_tags > 0)
2762 tag_directions = xmalloc(sizeof(*tag_directions)
2763 * (tnfa->num_tags + 1));
2764 if (tag_directions == NULL)
2765 ERROR_EXIT(REG_ESPACE);
2766 tnfa->tag_directions = tag_directions;
2767 memset(tag_directions, -1,
2768 sizeof(*tag_directions) * (tnfa->num_tags + 1));
2770 tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1,
2771 sizeof(*tnfa->minimal_tags));
2772 if (tnfa->minimal_tags == NULL)
2773 ERROR_EXIT(REG_ESPACE);
2775 submatch_data = xcalloc((unsigned)parse_ctx.submatch_id,
2776 sizeof(*submatch_data));
2777 if (submatch_data == NULL)
2778 ERROR_EXIT(REG_ESPACE);
2779 tnfa->submatch_data = submatch_data;
2781 errcode = tre_add_tags(mem, stack, tree, tnfa);
2782 if (errcode != REG_OK)
2783 ERROR_EXIT(errcode);
2787 /* Expand iteration nodes. */
2788 errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position,
2789 tag_directions);
2790 if (errcode != REG_OK)
2791 ERROR_EXIT(errcode);
2793 /* Add a dummy node for the final state.
2794 XXX - For certain patterns this dummy node can be optimized away,
2795 for example "a*" or "ab*". Figure out a simple way to detect
2796 this possibility. */
2797 tmp_ast_l = tree;
2798 tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);
2799 if (tmp_ast_r == NULL)
2800 ERROR_EXIT(REG_ESPACE);
2802 tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
2803 if (tree == NULL)
2804 ERROR_EXIT(REG_ESPACE);
2806 errcode = tre_compute_nfl(mem, stack, tree);
2807 if (errcode != REG_OK)
2808 ERROR_EXIT(errcode);
2810 counts = xmalloc(sizeof(int) * parse_ctx.position);
2811 if (counts == NULL)
2812 ERROR_EXIT(REG_ESPACE);
2814 offs = xmalloc(sizeof(int) * parse_ctx.position);
2815 if (offs == NULL)
2816 ERROR_EXIT(REG_ESPACE);
2818 for (i = 0; i < parse_ctx.position; i++)
2819 counts[i] = 0;
2820 tre_ast_to_tnfa(tree, NULL, counts, NULL);
2822 add = 0;
2823 for (i = 0; i < parse_ctx.position; i++)
2825 offs[i] = add;
2826 add += counts[i] + 1;
2827 counts[i] = 0;
2829 transitions = xcalloc((unsigned)add + 1, sizeof(*transitions));
2830 if (transitions == NULL)
2831 ERROR_EXIT(REG_ESPACE);
2832 tnfa->transitions = transitions;
2833 tnfa->num_transitions = add;
2835 errcode = tre_ast_to_tnfa(tree, transitions, counts, offs);
2836 if (errcode != REG_OK)
2837 ERROR_EXIT(errcode);
2839 tnfa->firstpos_chars = NULL;
2841 p = tree->firstpos;
2842 i = 0;
2843 while (p->position >= 0)
2845 i++;
2846 p++;
2849 initial = xcalloc((unsigned)i + 1, sizeof(tre_tnfa_transition_t));
2850 if (initial == NULL)
2851 ERROR_EXIT(REG_ESPACE);
2852 tnfa->initial = initial;
2854 i = 0;
2855 for (p = tree->firstpos; p->position >= 0; p++)
2857 initial[i].state = transitions + offs[p->position];
2858 initial[i].state_id = p->position;
2859 initial[i].tags = NULL;
2860 /* Copy the arrays p->tags, and p->params, they are allocated
2861 from a tre_mem object. */
2862 if (p->tags)
2864 int j;
2865 for (j = 0; p->tags[j] >= 0; j++);
2866 initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1));
2867 if (!initial[i].tags)
2868 ERROR_EXIT(REG_ESPACE);
2869 memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1));
2871 initial[i].assertions = p->assertions;
2872 i++;
2874 initial[i].state = NULL;
2876 tnfa->num_transitions = add;
2877 tnfa->final = transitions + offs[tree->lastpos[0].position];
2878 tnfa->num_states = parse_ctx.position;
2879 tnfa->cflags = cflags;
2881 tre_mem_destroy(mem);
2882 tre_stack_destroy(stack);
2883 xfree(counts);
2884 xfree(offs);
2886 preg->TRE_REGEX_T_FIELD = (void *)tnfa;
2887 return REG_OK;
2889 error_exit:
2890 /* Free everything that was allocated and return the error code. */
2891 tre_mem_destroy(mem);
2892 if (stack != NULL)
2893 tre_stack_destroy(stack);
2894 if (counts != NULL)
2895 xfree(counts);
2896 if (offs != NULL)
2897 xfree(offs);
2898 preg->TRE_REGEX_T_FIELD = (void *)tnfa;
2899 regfree(preg);
2900 return errcode;
2906 void
2907 regfree(regex_t *preg)
2909 tre_tnfa_t *tnfa;
2910 unsigned int i;
2911 tre_tnfa_transition_t *trans;
2913 tnfa = (void *)preg->TRE_REGEX_T_FIELD;
2914 if (!tnfa)
2915 return;
2917 for (i = 0; i < tnfa->num_transitions; i++)
2918 if (tnfa->transitions[i].state)
2920 if (tnfa->transitions[i].tags)
2921 xfree(tnfa->transitions[i].tags);
2922 if (tnfa->transitions[i].neg_classes)
2923 xfree(tnfa->transitions[i].neg_classes);
2925 if (tnfa->transitions)
2926 xfree(tnfa->transitions);
2928 if (tnfa->initial)
2930 for (trans = tnfa->initial; trans->state; trans++)
2932 if (trans->tags)
2933 xfree(trans->tags);
2935 xfree(tnfa->initial);
2938 if (tnfa->submatch_data)
2940 for (i = 0; i < tnfa->num_submatches; i++)
2941 if (tnfa->submatch_data[i].parents)
2942 xfree(tnfa->submatch_data[i].parents);
2943 xfree(tnfa->submatch_data);
2946 if (tnfa->tag_directions)
2947 xfree(tnfa->tag_directions);
2948 if (tnfa->firstpos_chars)
2949 xfree(tnfa->firstpos_chars);
2950 if (tnfa->minimal_tags)
2951 xfree(tnfa->minimal_tags);
2952 xfree(tnfa);