Fix bug #67773. sr=brendan, r=rginda. Fixes doubly nested quantifiers in

reg.exps when deeper sub-expression has to backup without failing. Some
other clean-up changes, too.
This commit is contained in:
rogerl%netscape.com 2001-03-02 00:17:48 +00:00
Родитель 51e609da91
Коммит 9d57bb12b9
1 изменённых файлов: 46 добавлений и 22 удалений

Просмотреть файл

@ -1379,14 +1379,13 @@ static const jschar *greedyRecurse(GreedyState *grState, const jschar *cp, const
kidMatch = matchRENodes(grState->state, grState->kid, grState->next, cp);
if (kidMatch == NULL) {
match = matchRENodes(grState->state, grState->next, NULL, cp);
match = matchRENodes(grState->state, grState->next, grState->stop, cp);
if (match) {
grState->state->parenCount = num;
if (previousKid != NULL)
matchRENodes(grState->state, grState->kid, grState->next, previousKid);
return cp;
}
else
return NULL;
}
else {
@ -1395,17 +1394,18 @@ static const jschar *greedyRecurse(GreedyState *grState, const jschar *cp, const
matchRENodes(grState->state, grState->kid, grState->next, previousKid);
return kidMatch; /* no point pursuing an empty match forever */
}
if ((grState->maxKid == 0) || (++grState->kidCount < grState->maxKid)) {
if (!grState->maxKid || (++grState->kidCount < grState->maxKid)) {
match = greedyRecurse(grState, kidMatch, cp);
if (match) return match;
if (match)
return match;
if (grState->maxKid)
--grState->kidCount;
}
grState->state->parenCount = num;
if (matchRENodes(grState->state, grState->next, NULL, kidMatch)) {
if (matchRENodes(grState->state, grState->next, grState->stop, kidMatch)) {
matchRENodes(grState->state, grState->kid, grState->next, cp);
return kidMatch;
}
else
return NULL;
}
}
@ -1414,12 +1414,22 @@ static const jschar *matchGreedyKid(MatchState *state, RENode *ren, RENode *stop
int kidCount, const jschar *cp, const jschar *previousKid)
{
GreedyState grState;
const jschar *match;
grState.state = state;
grState.kid = (RENode *)ren->kid;
grState.next = ren->next;
grState.stop = stop;
grState.kidCount = kidCount;
grState.maxKid = (ren->op == REOP_QUANT) ? ren->u.range.max : 0;
/*
We try to match the sub-tree to completion first, and if that
doesn't work, match only up to the given end of the sub-tree.
*/
grState.stop = NULL;
match = greedyRecurse(&grState, cp, previousKid);
if (match || !stop)
return match;
grState.kidCount = kidCount;
grState.stop = stop;
return greedyRecurse(&grState, cp, previousKid);
}
@ -1436,11 +1446,10 @@ static const jschar *matchNonGreedyKid(MatchState *state, RENode *ren,
kidMatch = matchRENodes(state, (RENode *)ren->kid, ren->next, cp);
if (kidMatch == NULL)
return NULL;
else {
if (kidMatch == cp) return kidMatch; /* no point pursuing an empty match forever */
if (kidMatch == cp)
return kidMatch; /* no point pursuing an empty match forever */
return matchNonGreedyKid(state, ren, kidCount, maxKid, kidMatch);
}
}
static void calcBMSize(MatchState *state, RENode *ren)
{
@ -1709,7 +1718,8 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
}
num = state->parenCount;
kidMatch = matchRENodes(state, (RENode *)ren->kid, stop, cp);
if (kidMatch != NULL) return kidMatch;
if (kidMatch != NULL)
return kidMatch;
for (i = num; i < state->parenCount; i++)
state->parens[i].length = 0;
state->parenCount = num;
@ -1727,13 +1737,19 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
if (num == ren->u.range.max) break;
if ((ren->flags & RENODE_MINIMAL) == 0) {
cp2 = matchGreedyKid(state, ren, stop, num, cp, lastKid);
if (cp2)
if (cp2 == NULL) {
if (lastKid)
cp = matchRENodes(state, (RENode *)ren->kid, ren->next,
lastKid);
}
else
cp = cp2;
}
else {
cp = matchNonGreedyKid(state, ren, num,
ren->u.range.max, cp);
if (cp == NULL) return NULL;
if (cp == NULL)
return NULL;
}
break;
case REOP_PLUS:
@ -1742,13 +1758,16 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
if (kidMatch == NULL)
return NULL;
if ((ren->flags & RENODE_MINIMAL) == 0) {
cp = matchGreedyKid(state, ren, stop, 1, kidMatch, cp);
if (cp == NULL)
cp = kidMatch;
cp2 = matchGreedyKid(state, ren, stop, 1, kidMatch, cp);
if (cp2 == NULL)
cp = matchRENodes(state, (RENode *)ren->kid, ren->next, cp);
else
cp = cp2;
}
else
cp = matchNonGreedyKid(state, ren, 1, 0, kidMatch);
if (cp == NULL) return NULL;
if (cp == NULL)
return NULL;
break;
case REOP_STAR:
if ((ren->flags & RENODE_MINIMAL) == 0) {
@ -1758,7 +1777,8 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
}
else {
cp = matchNonGreedyKid(state, ren, 0, 0, cp);
if (cp == NULL) return NULL;
if (cp == NULL)
return NULL;
}
break;
case REOP_OPT:
@ -1766,7 +1786,8 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
if (ren->flags & RENODE_MINIMAL) {
const jschar *restMatch = matchRENodes(state, ren->next,
stop, cp);
if (restMatch != NULL) return restMatch;
if (restMatch != NULL)
return restMatch;
}
kidMatch = matchRENodes(state, (RENode *)ren->kid,
ren->next, cp);
@ -1807,12 +1828,14 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
case REOP_ASSERT:
kidMatch = matchRENodes(state, (RENode *)ren->kid,
ren->next, cp);
if (kidMatch == NULL) return NULL;
if (kidMatch == NULL)
return NULL;
break;
case REOP_ASSERT_NOT:
kidMatch = matchRENodes(state, (RENode *)ren->kid,
ren->next, cp);
if (kidMatch != NULL) return NULL;
if (kidMatch != NULL)
return NULL;
break;
case REOP_BACKREF:
num = ren->u.num;
@ -1871,7 +1894,8 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
case REOP_DOTSTARMIN:
for (cp2 = cp; cp2 < cpend; cp2++) {
const jschar *cp3 = matchRENodes(state, ren->next, stop, cp2);
if (cp3 != NULL) return cp3;
if (cp3 != NULL)
return cp3;
if (*cp2 == '\n')
return NULL;
}