if (v->lblastcp != NULL)
FREE(v->lblastcp);
+#ifdef REG_DEBUG
+ if (v->eflags & (REG_FTRACE | REG_MTRACE))
+ fflush(stdout);
+#endif
+
return st;
}
if ((size_t) n >= v->nmatch)
return;
- MDEBUG(("setting %d\n", n));
+ MDEBUG(("%d: setting %d = %ld-%ld\n", sub->id, n, LOFF(begin), LOFF(end)));
v->pmatch[n].rm_so = OFF(begin);
v->pmatch[n].rm_eo = OFF(end);
}
int er;
assert(t != NULL);
- MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
+ MDEBUG(("%d: cdissect %c %ld-%ld\n", t->id, t->op, LOFF(begin), LOFF(end)));
/* handy place to check for operation cancel */
if (CANCEL_REQUESTED(v->re))
NOERR();
d2 = getsubdfa(v, t->right);
NOERR();
- MDEBUG(("cconcat %d\n", t->id));
+ MDEBUG(("%d: ccondissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
/* pick a tentative midpoint */
mid = longest(v, d, begin, end, (int *) NULL);
NOERR();
if (mid == NULL)
return REG_NOMATCH;
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+ MDEBUG(("%d: tentative midpoint %ld\n", t->id, LOFF(mid)));
/* iterate until satisfaction or failure */
for (;;)
if (er == REG_OKAY)
{
/* satisfaction */
- MDEBUG(("successful\n"));
+ MDEBUG(("%d: successful\n", t->id));
return REG_OKAY;
}
}
if (mid == begin)
{
/* all possibilities exhausted */
- MDEBUG(("%d no midpoint\n", t->id));
+ MDEBUG(("%d: no midpoint\n", t->id));
return REG_NOMATCH;
}
mid = longest(v, d, begin, mid - 1, (int *) NULL);
if (mid == NULL)
{
/* failed to find a new one */
- MDEBUG(("%d failed midpoint\n", t->id));
+ MDEBUG(("%d: failed midpoint\n", t->id));
return REG_NOMATCH;
}
MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
NOERR();
d2 = getsubdfa(v, t->right);
NOERR();
- MDEBUG(("crevcon %d\n", t->id));
+ MDEBUG(("%d: crevcondissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
/* pick a tentative midpoint */
mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
NOERR();
if (mid == NULL)
return REG_NOMATCH;
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+ MDEBUG(("%d: tentative midpoint %ld\n", t->id, LOFF(mid)));
/* iterate until satisfaction or failure */
for (;;)
if (er == REG_OKAY)
{
/* satisfaction */
- MDEBUG(("successful\n"));
+ MDEBUG(("%d: successful\n", t->id));
return REG_OKAY;
}
}
if (mid == end)
{
/* all possibilities exhausted */
- MDEBUG(("%d no midpoint\n", t->id));
+ MDEBUG(("%d: no midpoint\n", t->id));
return REG_NOMATCH;
}
mid = shortest(v, d, begin, mid + 1, end, (chr **) NULL, (int *) NULL);
if (mid == NULL)
{
/* failed to find a new one */
- MDEBUG(("%d failed midpoint\n", t->id));
+ MDEBUG(("%d: failed midpoint\n", t->id));
return REG_NOMATCH;
}
MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
assert(n >= 0);
assert((size_t) n < v->nmatch);
- MDEBUG(("cbackref n%d %d{%d-%d}\n", t->id, n, min, max));
+ MDEBUG(("%d: cbrdissect %d{%d-%d} %ld-%ld\n", t->id, n, min, max,
+ LOFF(begin), LOFF(end)));
/* get the backreferenced string */
if (v->pmatch[n].rm_so == -1)
*/
if (begin == end && min <= max)
{
- MDEBUG(("cbackref matched trivially\n"));
+ MDEBUG(("%d: backref matched trivially\n", t->id));
return REG_OKAY;
}
return REG_NOMATCH;
/* matches only if zero repetitions are okay */
if (min == 0)
{
- MDEBUG(("cbackref matched trivially\n"));
+ MDEBUG(("%d: backref matched trivially\n", t->id));
return REG_OKAY;
}
return REG_NOMATCH;
p += brlen;
}
- MDEBUG(("cbackref matched\n"));
+ MDEBUG(("%d: backref matched\n", t->id));
return REG_OKAY;
}
assert(t->op == '|');
assert(t->left != NULL && t->left->cnfa.nstates > 0);
- MDEBUG(("calt n%d\n", t->id));
+ MDEBUG(("%d: caltdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
d = getsubdfa(v, t->left);
NOERR();
if (longest(v, d, begin, end, (int *) NULL) == end)
{
- MDEBUG(("calt matched\n"));
+ MDEBUG(("%d: caltdissect matched\n", t->id));
er = cdissect(v, t->left, begin, end);
if (er != REG_NOMATCH)
return er;
assert(!(t->left->flags & SHORTER));
assert(begin <= end);
+ MDEBUG(("%d: citerdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
+
/*
* For the moment, assume the minimum number of matches is 1. If zero
* matches are allowed, and the target string is empty, we are allowed to
FREE(endpts);
return v->err;
}
- MDEBUG(("citer %d\n", t->id));
/*
* Our strategy is to first find a set of sub-match endpoints that are
if (i > k)
{
/* satisfaction */
- MDEBUG(("%d successful\n", t->id));
+ MDEBUG(("%d: successful\n", t->id));
FREE(endpts);
return REG_OKAY;
}
*/
if (t->min == 0 && begin == end)
{
- MDEBUG(("%d allowing zero matches\n", t->id));
+ MDEBUG(("%d: allowing zero matches\n", t->id));
return REG_OKAY;
}
- MDEBUG(("%d failed\n", t->id));
+ MDEBUG(("%d: failed\n", t->id));
return REG_NOMATCH;
}
assert(t->left->flags & SHORTER);
assert(begin <= end);
+ MDEBUG(("%d: creviterdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
+
/*
* If zero matches are allowed, and target string is empty, just declare
* victory. OTOH, if target string isn't empty, zero matches can't work
if (min_matches <= 0)
{
if (begin == end)
+ {
+ MDEBUG(("%d: allowing zero matches\n", t->id));
return REG_OKAY;
+ }
min_matches = 1;
}
FREE(endpts);
return v->err;
}
- MDEBUG(("creviter %d\n", t->id));
/*
* Our strategy is to first find a set of sub-match endpoints that are
if (i > k)
{
/* satisfaction */
- MDEBUG(("%d successful\n", t->id));
+ MDEBUG(("%d: successful\n", t->id));
FREE(endpts);
return REG_OKAY;
}
}
/* all possibilities exhausted */
- MDEBUG(("%d failed\n", t->id));
+ MDEBUG(("%d: failed\n", t->id));
FREE(endpts);
return REG_NOMATCH;
}
{0,REG_ULOOKAROUND,REG_UNONPOSIX}
(1 row)
+-- expectMatch 23.9 HP ...(?!.) abcde cde
+select * from test_regex('...(?!.)', 'abcde', 'HP');
+ test_regex
+-----------------------------------
+ {0,REG_ULOOKAROUND,REG_UNONPOSIX}
+ {cde}
+(2 rows)
+
+-- expectNomatch 23.10 HP ...(?=.) abc
+select * from test_regex('...(?=.)', 'abc', 'HP');
+ test_regex
+-----------------------------------
+ {0,REG_ULOOKAROUND,REG_UNONPOSIX}
+(1 row)
+
-- Postgres addition: lookbehind constraints
-- expectMatch 23.11 HPN (?<=a)b* ab b
select * from test_regex('(?<=a)b*', 'ab', 'HPN');
{0,REG_ULOOKAROUND,REG_UNONPOSIX}
(1 row)
+-- expectMatch 23.19 HP (?<=.).. abcde bc
+select * from test_regex('(?<=.)..', 'abcde', 'HP');
+ test_regex
+-----------------------------------
+ {0,REG_ULOOKAROUND,REG_UNONPOSIX}
+ {bc}
+(2 rows)
+
+-- expectMatch 23.20 HP (?<=..)a* aaabb a
+select * from test_regex('(?<=..)a*', 'aaabb', 'HP');
+ test_regex
+-----------------------------------
+ {0,REG_ULOOKAROUND,REG_UNONPOSIX}
+ {a}
+(2 rows)
+
+-- expectMatch 23.21 HP (?<=..)b* aaabb {}
+-- Note: empty match here is correct, it matches after the first 2 characters
+select * from test_regex('(?<=..)b*', 'aaabb', 'HP');
+ test_regex
+-----------------------------------
+ {0,REG_ULOOKAROUND,REG_UNONPOSIX}
+ {""}
+(2 rows)
+
+-- expectMatch 23.22 HP (?<=..)b+ aaabb bb
+select * from test_regex('(?<=..)b+', 'aaabb', 'HP');
+ test_regex
+-----------------------------------
+ {0,REG_ULOOKAROUND,REG_UNONPOSIX}
+ {bb}
+(2 rows)
+
-- doing 24 "non-greedy quantifiers"
-- expectMatch 24.1 PT ab+? abb ab
select * from test_regex('ab+?', 'abb', 'PT');
select * from test_regex('(?=b)b', 'b', 'HP');
-- expectNomatch 23.8 HP (?=b)b a
select * from test_regex('(?=b)b', 'a', 'HP');
+-- expectMatch 23.9 HP ...(?!.) abcde cde
+select * from test_regex('...(?!.)', 'abcde', 'HP');
+-- expectNomatch 23.10 HP ...(?=.) abc
+select * from test_regex('...(?=.)', 'abc', 'HP');
-- Postgres addition: lookbehind constraints
select * from test_regex('(?<=b)b', 'bb', 'HP');
-- expectNomatch 23.18 HP (?<=b)b b
select * from test_regex('(?<=b)b', 'b', 'HP');
+-- expectMatch 23.19 HP (?<=.).. abcde bc
+select * from test_regex('(?<=.)..', 'abcde', 'HP');
+-- expectMatch 23.20 HP (?<=..)a* aaabb a
+select * from test_regex('(?<=..)a*', 'aaabb', 'HP');
+-- expectMatch 23.21 HP (?<=..)b* aaabb {}
+-- Note: empty match here is correct, it matches after the first 2 characters
+select * from test_regex('(?<=..)b*', 'aaabb', 'HP');
+-- expectMatch 23.22 HP (?<=..)b+ aaabb bb
+select * from test_regex('(?<=..)b+', 'aaabb', 'HP');
-- doing 24 "non-greedy quantifiers"