2
* re_*exec and friends - match REs
4
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
6
* Development of this software was funded, in part, by Cray Research Inc.,
7
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
8
* Corporation, none of whom are responsible for the results. The author
11
* Redistribution and use in source and binary forms -- with or without
12
* modification -- are permitted for any purpose, provided that
13
* redistributions in source form retain this entire copyright notice and
14
* indicate the origin and nature of any modifications.
16
* I'd appreciate being given credit for this package in the documentation
17
* of software which uses it, but that is not a requirement.
19
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
* src/backend/regex/regexec.c
34
#include "regex/regguts.h"
38
/* lazy-DFA representation */
40
{ /* "pointer" to an outarc */
47
unsigned *states; /* pointer to bitvector */
48
unsigned hash; /* hash of bitvector */
49
#define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
50
#define HIT(h,bv,ss,nw) ((ss)->hash == (h) && ((nw) == 1 || \
51
memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
53
#define STARTER 01 /* the initial state set */
54
#define POSTSTATE 02 /* includes the goal state */
55
#define LOCKED 04 /* locked in cache */
56
#define NOPROGRESS 010 /* zero-progress state set */
57
struct arcp ins; /* chain of inarcs pointing here */
58
chr *lastseen; /* last entered on arrival here */
59
struct sset **outs; /* outarc vector indexed by color */
60
struct arcp *inchain; /* chain-pointer vector for outarcs */
65
int nssets; /* size of cache */
66
int nssused; /* how many entries occupied yet */
67
int nstates; /* number of states */
68
int ncolors; /* length of outarc and inchain vectors */
69
int wordsper; /* length of state-set bitvectors */
70
struct sset *ssets; /* state-set cache */
71
unsigned *statesarea; /* bitvector storage */
72
unsigned *work; /* pointer to work area within statesarea */
73
struct sset **outsarea; /* outarc-vector storage */
74
struct arcp *incarea; /* inchain storage */
77
chr *lastpost; /* location of last cache-flushed success */
78
chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
79
struct sset *search; /* replacement-search-pointer memory */
80
int cptsmalloced; /* were the areas individually malloced? */
81
char *mallocarea; /* self, or master malloced area, or NULL */
84
#define WORK 1 /* number of work bitvectors needed */
86
/* setup for non-malloc allocation for small cases */
87
#define FEWSTATES 20 /* must be less than UBITS */
92
struct sset ssets[FEWSTATES * 2];
93
unsigned statesarea[FEWSTATES * 2 + WORK];
94
struct sset *outsarea[FEWSTATES * 2 * FEWCOLORS];
95
struct arcp incarea[FEWSTATES * 2 * FEWCOLORS];
98
#define DOMALLOC ((struct smalldfa *)NULL) /* force malloc */
102
/* internal variables, bundled for easy passing around */
107
int eflags; /* copies of arguments */
110
rm_detail_t *details;
111
chr *start; /* start of string */
112
chr *search_start; /* search start of string */
113
chr *stop; /* just past end of string */
114
int err; /* error code if any (0 none) */
115
regoff_t *mem; /* memory vector for backtracking */
116
struct smalldfa dfa1;
117
struct smalldfa dfa2;
120
#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
121
#define ISERR() VISERR(v)
122
#define VERR(vv,e) ((vv)->err = ((vv)->err ? (vv)->err : (e)))
123
#define ERR(e) VERR(v, e) /* record an error */
124
#define NOERR() {if (ISERR()) return v->err;} /* if error seen, return it */
125
#define OFF(p) ((p) - v->start)
126
#define LOFF(p) ((long)OFF(p))
131
* forward declarations
133
/* === regexec.c === */
134
static int find(struct vars *, struct cnfa *, struct colormap *);
135
static int cfind(struct vars *, struct cnfa *, struct colormap *);
136
static int cfindloop(struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **);
137
static void zapsubs(regmatch_t *, size_t);
138
static void zapmem(struct vars *, struct subre *);
139
static void subset(struct vars *, struct subre *, chr *, chr *);
140
static int dissect(struct vars *, struct subre *, chr *, chr *);
141
static int condissect(struct vars *, struct subre *, chr *, chr *);
142
static int altdissect(struct vars *, struct subre *, chr *, chr *);
143
static int cdissect(struct vars *, struct subre *, chr *, chr *);
144
static int ccaptdissect(struct vars *, struct subre *, chr *, chr *);
145
static int ccondissect(struct vars *, struct subre *, chr *, chr *);
146
static int crevdissect(struct vars *, struct subre *, chr *, chr *);
147
static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
148
static int caltdissect(struct vars *, struct subre *, chr *, chr *);
150
/* === rege_dfa.c === */
151
static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
152
static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *);
153
static chr *lastcold(struct vars *, struct dfa *);
154
static struct dfa *newdfa(struct vars *, struct cnfa *, struct colormap *, struct smalldfa *);
155
static void freedfa(struct dfa *);
156
static unsigned hash(unsigned *, int);
157
static struct sset *initialize(struct vars *, struct dfa *, chr *);
158
static struct sset *miss(struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *);
159
static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
160
static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
161
static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
165
* pg_regexec - match regular expression
168
pg_regexec(regex_t *re,
172
rm_detail_t *details,
178
register struct vars *v = &var;
184
regmatch_t mat[LOCALMAT];
187
regoff_t mem[LOCALMEM];
190
if (re == NULL || string == NULL || re->re_magic != REMAGIC)
192
if (re->re_csize != sizeof(chr))
195
/* Initialize locale-dependent support */
196
pg_set_regex_collation(re->re_collation);
200
v->g = (struct guts *) re->re_guts;
201
if ((v->g->cflags & REG_EXPECT) && details == NULL)
203
if (v->g->info & REG_UIMPOSSIBLE)
205
backref = (v->g->info & REG_UBACKREF) ? 1 : 0;
207
if (v->g->cflags & REG_NOSUB)
208
nmatch = 0; /* override client */
213
if (v->g->nsub + 1 <= LOCALMAT)
216
v->pmatch = (regmatch_t *) MALLOC((v->g->nsub + 1) *
218
if (v->pmatch == NULL)
220
v->nmatch = v->g->nsub + 1;
224
v->details = details;
225
v->start = (chr *) string;
226
v->search_start = (chr *) string + search_start;
227
v->stop = (chr *) string + len;
231
/* need retry memory */
232
assert(v->g->ntree >= 0);
233
n = (size_t) v->g->ntree;
237
v->mem = (regoff_t *) MALLOC(n * sizeof(regoff_t));
240
if (v->pmatch != pmatch && v->pmatch != mat)
249
assert(v->g->tree != NULL);
251
st = cfind(v, &v->g->tree->cnfa, &v->g->cmap);
253
st = find(v, &v->g->tree->cnfa, &v->g->cmap);
255
/* copy (portion of) match vector over if necessary */
256
if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0)
258
zapsubs(pmatch, nmatch);
259
n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
260
memcpy(VS(pmatch), VS(v->pmatch), n * sizeof(regmatch_t));
264
if (v->pmatch != pmatch && v->pmatch != mat)
266
if (v->mem != NULL && v->mem != mem)
272
* find - find a match for the main NFA (no-complications case)
275
find(struct vars * v,
277
struct colormap * cm)
284
chr *open; /* open and close of range of possible starts */
287
int shorter = (v->g->tree->flags & SHORTER) ? 1 : 0;
289
/* first, a shot with the search RE */
290
s = newdfa(v, &v->g->search, cm, &v->dfa1);
291
assert(!(ISERR() && s != NULL));
293
MDEBUG(("\nsearch at %ld\n", LOFF(v->start)));
295
close = shortest(v, s, v->search_start, v->search_start, v->stop,
296
&cold, (int *) NULL);
299
if (v->g->cflags & REG_EXPECT)
301
assert(v->details != NULL);
303
v->details->rm_extend.rm_so = OFF(cold);
305
v->details->rm_extend.rm_so = OFF(v->stop);
306
v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
308
if (close == NULL) /* not found */
310
if (v->nmatch == 0) /* found, don't need exact location */
313
/* find starting point and match */
314
assert(cold != NULL);
317
MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close)));
318
d = newdfa(v, cnfa, cm, &v->dfa1);
319
assert(!(ISERR() && d != NULL));
321
for (begin = open; begin <= close; begin++)
323
MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
325
end = shortest(v, d, begin, begin, v->stop,
326
(chr **) NULL, &hitend);
328
end = longest(v, d, begin, v->stop, &hitend);
330
if (hitend && cold == NULL)
333
break; /* NOTE BREAK OUT */
335
assert(end != NULL); /* search RE succeeded so loop should */
338
/* and pin down details */
339
assert(v->nmatch > 0);
340
v->pmatch[0].rm_so = OFF(begin);
341
v->pmatch[0].rm_eo = OFF(end);
342
if (v->g->cflags & REG_EXPECT)
345
v->details->rm_extend.rm_so = OFF(cold);
347
v->details->rm_extend.rm_so = OFF(v->stop);
348
v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
350
if (v->nmatch == 1) /* no need for submatches */
354
zapsubs(v->pmatch, v->nmatch);
355
return dissect(v, v->g->tree, begin, end);
359
* cfind - find a match for the main NFA (with complications)
362
cfind(struct vars * v,
364
struct colormap * cm)
371
s = newdfa(v, &v->g->search, cm, &v->dfa1);
373
d = newdfa(v, cnfa, cm, &v->dfa2);
381
ret = cfindloop(v, cnfa, cm, d, s, &cold);
386
if (v->g->cflags & REG_EXPECT)
388
assert(v->details != NULL);
390
v->details->rm_extend.rm_so = OFF(cold);
392
v->details->rm_extend.rm_so = OFF(v->stop);
393
v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
399
* cfindloop - the heart of cfind
402
cfindloop(struct vars * v,
404
struct colormap * cm,
407
chr **coldp) /* where to put coldstart pointer */
412
chr *open; /* open and close of range of possible starts */
417
int shorter = v->g->tree->flags & SHORTER;
420
assert(d != NULL && s != NULL);
422
close = v->search_start;
425
MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
426
close = shortest(v, s, close, close, v->stop, &cold, (int *) NULL);
428
break; /* NOTE BREAK */
429
assert(cold != NULL);
432
MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
433
for (begin = open; begin <= close; begin++)
435
MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
441
end = shortest(v, d, begin, estart,
442
estop, (chr **) NULL, &hitend);
444
end = longest(v, d, begin, estop,
446
if (hitend && cold == NULL)
449
break; /* NOTE BREAK OUT */
450
MDEBUG(("tentative end %ld\n", LOFF(end)));
451
zapsubs(v->pmatch, v->nmatch);
452
zapmem(v, v->g->tree);
453
er = cdissect(v, v->g->tree, begin, end);
458
v->pmatch[0].rm_so = OFF(begin);
459
v->pmatch[0].rm_eo = OFF(end);
464
if (er != REG_NOMATCH)
470
if ((shorter) ? end == estop : end == begin)
472
/* no point in trying again */
476
/* go around and try again */
483
} while (close < v->stop);
490
* zapsubs - initialize the subexpression matches to "no match"
493
zapsubs(regmatch_t *p,
498
for (i = n - 1; i > 0; i--)
506
* zapmem - initialize the retry memory of a subtree to zeros
509
zapmem(struct vars * v,
515
assert(v->mem != NULL);
516
v->mem[t->retry] = 0;
519
assert(t->subno > 0);
520
v->pmatch[t->subno].rm_so = -1;
521
v->pmatch[t->subno].rm_eo = -1;
526
if (t->right != NULL)
531
* subset - set any subexpression relevant to a successful subre
534
subset(struct vars * v,
542
if ((size_t) n >= v->nmatch)
545
MDEBUG(("setting %d\n", n));
546
v->pmatch[n].rm_so = OFF(begin);
547
v->pmatch[n].rm_eo = OFF(end);
551
* dissect - determine subexpression matches (uncomplicated case)
553
static int /* regexec return code */
554
dissect(struct vars * v,
556
chr *begin, /* beginning of relevant substring */
557
chr *end) /* end of same */
560
MDEBUG(("dissect %ld-%ld\n", LOFF(begin), LOFF(end)));
564
case '=': /* terminal node */
565
assert(t->left == NULL && t->right == NULL);
566
return REG_OKAY; /* no action, parent did the work */
567
case '|': /* alternation */
568
assert(t->left != NULL);
569
return altdissect(v, t, begin, end);
570
case 'b': /* back ref -- shouldn't be calling us! */
572
case '.': /* concatenation */
573
assert(t->left != NULL && t->right != NULL);
574
return condissect(v, t, begin, end);
575
case '(': /* capturing */
576
assert(t->left != NULL && t->right == NULL);
577
assert(t->subno > 0);
578
subset(v, t, begin, end);
579
return dissect(v, t->left, begin, end);
586
* condissect - determine concatenation subexpression matches (uncomplicated)
588
static int /* regexec return code */
589
condissect(struct vars * v,
591
chr *begin, /* beginning of relevant substring */
592
chr *end) /* end of same */
598
int shorter = (t->left->flags & SHORTER) ? 1 : 0;
599
chr *stop = (shorter) ? end : begin;
601
assert(t->op == '.');
602
assert(t->left != NULL && t->left->cnfa.nstates > 0);
603
assert(t->right != NULL && t->right->cnfa.nstates > 0);
605
d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
607
d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &v->dfa2);
615
/* pick a tentative midpoint */
617
mid = shortest(v, d, begin, begin, end, (chr **) NULL,
620
mid = longest(v, d, begin, end, (int *) NULL);
627
MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
629
/* iterate until satisfaction or failure */
630
while (longest(v, d2, mid, end, (int *) NULL) != end)
632
/* that midpoint didn't work, find a new one */
635
/* all possibilities exhausted! */
636
MDEBUG(("no midpoint!\n"));
642
mid = shortest(v, d, begin, mid + 1, end, (chr **) NULL,
645
mid = longest(v, d, begin, mid - 1, (int *) NULL);
648
/* failed to find a new one! */
649
MDEBUG(("failed midpoint!\n"));
654
MDEBUG(("new midpoint %ld\n", LOFF(mid)));
658
MDEBUG(("successful\n"));
661
i = dissect(v, t->left, begin, mid);
664
return dissect(v, t->right, mid, end);
668
* altdissect - determine alternative subexpression matches (uncomplicated)
670
static int /* regexec return code */
671
altdissect(struct vars * v,
673
chr *begin, /* beginning of relevant substring */
674
chr *end) /* end of same */
680
assert(t->op == '|');
682
for (i = 0; t != NULL; t = t->right, i++)
684
MDEBUG(("trying %dth\n", i));
685
assert(t->left != NULL && t->left->cnfa.nstates > 0);
686
d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
689
if (longest(v, d, begin, end, (int *) NULL) == end)
691
MDEBUG(("success\n"));
693
return dissect(v, t->left, begin, end);
697
return REG_ASSERT; /* none of them matched?!? */
701
* cdissect - determine subexpression matches (with complications)
702
* The retry memory stores the offset of the trial midpoint from begin,
703
* plus 1 so that 0 uniquely means "clean slate".
705
static int /* regexec return code */
706
cdissect(struct vars * v,
708
chr *begin, /* beginning of relevant substring */
709
chr *end) /* end of same */
712
MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
716
case '=': /* terminal node */
717
assert(t->left == NULL && t->right == NULL);
718
return REG_OKAY; /* no action, parent did the work */
719
case '|': /* alternation */
720
assert(t->left != NULL);
721
return caltdissect(v, t, begin, end);
722
case 'b': /* back ref -- shouldn't be calling us! */
723
assert(t->left == NULL && t->right == NULL);
724
return cbrdissect(v, t, begin, end);
725
case '.': /* concatenation */
726
assert(t->left != NULL && t->right != NULL);
727
return ccondissect(v, t, begin, end);
728
case '(': /* capturing */
729
assert(t->left != NULL && t->right == NULL);
730
return ccaptdissect(v, t, begin, end);
737
* ccaptdissect - capture subexpression matches (with complications)
739
static int /* regexec return code */
740
ccaptdissect(struct vars * v,
742
chr *begin, /* beginning of relevant substring */
743
chr *end) /* end of same */
747
assert(t->subno > 0);
749
er = cdissect(v, t->left, begin, end);
751
subset(v, t, begin, end);
756
* ccondissect - concatenation subexpression matches (with complications)
757
* The retry memory stores the offset of the trial midpoint from begin,
758
* plus 1 so that 0 uniquely means "clean slate".
760
static int /* regexec return code */
761
ccondissect(struct vars * v,
763
chr *begin, /* beginning of relevant substring */
764
chr *end) /* end of same */
771
assert(t->op == '.');
772
assert(t->left != NULL && t->left->cnfa.nstates > 0);
773
assert(t->right != NULL && t->right->cnfa.nstates > 0);
775
if (t->left->flags & SHORTER) /* reverse scan */
776
return crevdissect(v, t, begin, end);
778
d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
781
d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
787
MDEBUG(("cconcat %d\n", t->retry));
789
/* pick a tentative midpoint */
790
if (v->mem[t->retry] == 0)
792
mid = longest(v, d, begin, end, (int *) NULL);
799
MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
800
v->mem[t->retry] = (mid - begin) + 1;
804
mid = begin + (v->mem[t->retry] - 1);
805
MDEBUG(("working midpoint %ld\n", LOFF(mid)));
808
/* iterate until satisfaction or failure */
811
/* try this midpoint on for size */
812
if (longest(v, d2, mid, end, (int *) NULL) == end)
814
er = cdissect(v, t->left, begin, mid);
817
er = cdissect(v, t->right, mid, end);
821
MDEBUG(("successful\n"));
827
if (er != REG_OKAY && er != REG_NOMATCH)
835
/* that midpoint didn't work, find a new one */
838
/* all possibilities exhausted */
839
MDEBUG(("%d no midpoint\n", t->retry));
844
mid = longest(v, d, begin, mid - 1, (int *) NULL);
847
/* failed to find a new one */
848
MDEBUG(("%d failed midpoint\n", t->retry));
853
MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
854
v->mem[t->retry] = (mid - begin) + 1;
864
* crevdissect - determine backref shortest-first subexpression matches
865
* The retry memory stores the offset of the trial midpoint from begin,
866
* plus 1 so that 0 uniquely means "clean slate".
868
static int /* regexec return code */
869
crevdissect(struct vars * v,
871
chr *begin, /* beginning of relevant substring */
872
chr *end) /* end of same */
879
assert(t->op == '.');
880
assert(t->left != NULL && t->left->cnfa.nstates > 0);
881
assert(t->right != NULL && t->right->cnfa.nstates > 0);
882
assert(t->left->flags & SHORTER);
884
/* concatenation -- need to split the substring between parts */
885
d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
888
d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
894
MDEBUG(("crev %d\n", t->retry));
896
/* pick a tentative midpoint */
897
if (v->mem[t->retry] == 0)
899
mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
906
MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
907
v->mem[t->retry] = (mid - begin) + 1;
911
mid = begin + (v->mem[t->retry] - 1);
912
MDEBUG(("working midpoint %ld\n", LOFF(mid)));
915
/* iterate until satisfaction or failure */
918
/* try this midpoint on for size */
919
if (longest(v, d2, mid, end, (int *) NULL) == end)
921
er = cdissect(v, t->left, begin, mid);
924
er = cdissect(v, t->right, mid, end);
928
MDEBUG(("successful\n"));
934
if (er != REG_OKAY && er != REG_NOMATCH)
942
/* that midpoint didn't work, find a new one */
945
/* all possibilities exhausted */
946
MDEBUG(("%d no midpoint\n", t->retry));
951
mid = shortest(v, d, begin, mid + 1, end, (chr **) NULL, (int *) NULL);
954
/* failed to find a new one */
955
MDEBUG(("%d failed midpoint\n", t->retry));
960
MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
961
v->mem[t->retry] = (mid - begin) + 1;
971
* cbrdissect - determine backref subexpression matches
973
static int /* regexec return code */
974
cbrdissect(struct vars * v,
976
chr *begin, /* beginning of relevant substring */
977
chr *end) /* end of same */
989
assert(t->op == 'b');
991
assert((size_t) n < v->nmatch);
993
MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
995
if (v->pmatch[n].rm_so == -1)
997
paren = v->start + v->pmatch[n].rm_so;
998
len = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
1000
/* no room to maneuver -- retries are pointless */
1001
if (v->mem[t->retry])
1003
v->mem[t->retry] = 1;
1005
/* special-case zero-length string */
1013
/* and too-short string */
1014
assert(end >= begin);
1015
if ((size_t) (end - begin) < len)
1019
/* count occurrences */
1021
for (p = begin; p <= stop && (i < max || max == INFINITY); p += len)
1023
if ((*v->g->compare) (paren, p, len) != 0)
1027
MDEBUG(("cbackref found %d\n", i));
1029
/* and sort it out */
1030
if (p != end) /* didn't consume all of it */
1032
if (min <= i && (i <= max || max == INFINITY))
1034
return REG_NOMATCH; /* out of range */
1038
* caltdissect - determine alternative subexpression matches (w. complications)
1040
static int /* regexec return code */
1041
caltdissect(struct vars * v,
1043
chr *begin, /* beginning of relevant substring */
1044
chr *end) /* end of same */
1049
#define UNTRIED 0 /* not yet tried at all */
1050
#define TRYING 1 /* top matched, trying submatches */
1051
#define TRIED 2 /* top didn't match or submatches exhausted */
1055
assert(t->op == '|');
1056
if (v->mem[t->retry] == TRIED)
1057
return caltdissect(v, t->right, begin, end);
1059
MDEBUG(("calt n%d\n", t->retry));
1060
assert(t->left != NULL);
1062
if (v->mem[t->retry] == UNTRIED)
1064
d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
1067
if (longest(v, d, begin, end, (int *) NULL) != end)
1070
v->mem[t->retry] = TRIED;
1071
return caltdissect(v, t->right, begin, end);
1074
MDEBUG(("calt matched\n"));
1075
v->mem[t->retry] = TRYING;
1078
er = cdissect(v, t->left, begin, end);
1079
if (er != REG_NOMATCH)
1082
v->mem[t->retry] = TRIED;
1083
return caltdissect(v, t->right, begin, end);
1088
#include "rege_dfa.c"