Commit 3068e457 authored by Tom Lane's avatar Tom Lane

Handle interaction of regexp's makesearch and MATCHALL more honestly.

Second thoughts about commit 824bf719: we apply makesearch() to
an NFA after having determined whether it is a MATCHALL pattern.
Prepending ".*" doesn't make it non-MATCHALL, but it does change the
maximum possible match length, and makesearch() failed to update that.
This has no ill effects given the stylized usage of search NFAs, but
it seems like it's better to keep the data structure consistent.  In
particular, fixing this allows more honest handling of the MATCHALL
check in matchuntil(): we can now assert that maxmatchall is infinity,
instead of lamely assuming that it should act that way.

In passing, improve the code in dump[c]nfa so that infinite maxmatchall
is printed as "inf" not a magic number.
parent ba05dfe9
...@@ -3602,8 +3602,13 @@ dumpnfa(struct nfa *nfa, ...@@ -3602,8 +3602,13 @@ dumpnfa(struct nfa *nfa,
if (nfa->flags & HASLACONS) if (nfa->flags & HASLACONS)
fprintf(f, ", haslacons"); fprintf(f, ", haslacons");
if (nfa->flags & MATCHALL) if (nfa->flags & MATCHALL)
fprintf(f, ", minmatchall %d, maxmatchall %d", {
nfa->minmatchall, nfa->maxmatchall); fprintf(f, ", minmatchall %d", nfa->minmatchall);
if (nfa->maxmatchall == DUPINF)
fprintf(f, ", maxmatchall inf");
else
fprintf(f, ", maxmatchall %d", nfa->maxmatchall);
}
fprintf(f, "\n"); fprintf(f, "\n");
for (s = nfa->states; s != NULL; s = s->next) for (s = nfa->states; s != NULL; s = s->next)
{ {
...@@ -3766,8 +3771,13 @@ dumpcnfa(struct cnfa *cnfa, ...@@ -3766,8 +3771,13 @@ dumpcnfa(struct cnfa *cnfa,
if (cnfa->flags & HASLACONS) if (cnfa->flags & HASLACONS)
fprintf(f, ", haslacons"); fprintf(f, ", haslacons");
if (cnfa->flags & MATCHALL) if (cnfa->flags & MATCHALL)
fprintf(f, ", minmatchall %d, maxmatchall %d", {
cnfa->minmatchall, cnfa->maxmatchall); fprintf(f, ", minmatchall %d", cnfa->minmatchall);
if (cnfa->maxmatchall == DUPINF)
fprintf(f, ", maxmatchall inf");
else
fprintf(f, ", maxmatchall %d", cnfa->maxmatchall);
}
fprintf(f, "\n"); fprintf(f, "\n");
for (st = 0; st < cnfa->nstates; st++) for (st = 0; st < cnfa->nstates; st++)
dumpcstate(st, cnfa, f); dumpcstate(st, cnfa, f);
......
...@@ -598,6 +598,13 @@ makesearch(struct vars *v, ...@@ -598,6 +598,13 @@ makesearch(struct vars *v,
/* and ^* and \A* too -- not always necessary, but harmless */ /* and ^* and \A* too -- not always necessary, but harmless */
newarc(nfa, PLAIN, nfa->bos[0], pre, pre); newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
newarc(nfa, PLAIN, nfa->bos[1], pre, pre); newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
/*
* The pattern is still MATCHALL if it was before, but the max match
* length is now infinity.
*/
if (nfa->flags & MATCHALL)
nfa->maxmatchall = DUPINF;
} }
/* /*
......
...@@ -385,14 +385,10 @@ matchuntil(struct vars *v, ...@@ -385,14 +385,10 @@ matchuntil(struct vars *v,
{ {
size_t nchr = probe - v->start; size_t nchr = probe - v->start;
/*
* It might seem that we should check maxmatchall too, but the .* at
* the front of the pattern absorbs any extra characters (and it was
* tacked on *after* computing minmatchall/maxmatchall). Thus, we
* should match if there are at least minmatchall characters.
*/
if (nchr < d->cnfa->minmatchall) if (nchr < d->cnfa->minmatchall)
return 0; return 0;
/* maxmatchall will always be infinity, cf. makesearch() */
assert(d->cnfa->maxmatchall == DUPINF);
return 1; return 1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment