chr *search_start; /* search start of string */
chr *stop; /* just past end of string */
int err; /* error code if any (0 none) */
- regoff_t *mem; /* memory vector for backtracking */
struct smalldfa dfa1;
struct smalldfa dfa2;
};
static int find(struct vars *, struct cnfa *, struct colormap *);
static int cfind(struct vars *, struct cnfa *, struct colormap *);
static int cfindloop(struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **);
-static void zapsubs(regmatch_t *, size_t);
-static void zapmem(struct vars *, struct subre *);
+static void zapallsubs(regmatch_t *, size_t);
+static void zaptreesubs(struct vars *, struct subre *);
static void subset(struct vars *, struct subre *, chr *, chr *);
static int dissect(struct vars *, struct subre *, chr *, chr *);
static int condissect(struct vars *, struct subre *, chr *, chr *);
#define LOCALMAT 20
regmatch_t mat[LOCALMAT];
-#define LOCALMEM 40
- regoff_t mem[LOCALMEM];
-
/* sanity checks */
if (re == NULL || string == NULL || re->re_magic != REMAGIC)
return REG_INVARG;
v->search_start = (chr *) string + search_start;
v->stop = (chr *) string + len;
v->err = 0;
- if (backref)
- {
- /* need retry memory */
- assert(v->g->ntree >= 0);
- n = (size_t) v->g->ntree;
- if (n <= LOCALMEM)
- v->mem = mem;
- else
- v->mem = (regoff_t *) MALLOC(n * sizeof(regoff_t));
- if (v->mem == NULL)
- {
- if (v->pmatch != pmatch && v->pmatch != mat)
- FREE(v->pmatch);
- return REG_ESPACE;
- }
- }
- else
- v->mem = NULL;
/* do it */
assert(v->g->tree != NULL);
/* copy (portion of) match vector over if necessary */
if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0)
{
- zapsubs(pmatch, nmatch);
+ zapallsubs(pmatch, nmatch);
n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
memcpy(VS(pmatch), VS(v->pmatch), n * sizeof(regmatch_t));
}
/* clean up */
if (v->pmatch != pmatch && v->pmatch != mat)
FREE(v->pmatch);
- if (v->mem != NULL && v->mem != mem)
- FREE(v->mem);
return st;
}
return REG_OKAY;
/* submatches */
- zapsubs(v->pmatch, v->nmatch);
+ zapallsubs(v->pmatch, v->nmatch);
return dissect(v, v->g->tree, begin, end);
}
if (end == NULL)
break; /* NOTE BREAK OUT */
MDEBUG(("tentative end %ld\n", LOFF(end)));
- zapsubs(v->pmatch, v->nmatch);
- zapmem(v, v->g->tree);
+ zapallsubs(v->pmatch, v->nmatch);
er = cdissect(v, v->g->tree, begin, end);
if (er == REG_OKAY)
{
}
/*
- * zapsubs - initialize the subexpression matches to "no match"
+ * zapallsubs - initialize all subexpression matches to "no match"
*/
static void
-zapsubs(regmatch_t *p,
- size_t n)
+zapallsubs(regmatch_t *p,
+ size_t n)
{
size_t i;
}
/*
- * zapmem - initialize the retry memory of a subtree to zeros
+ * zaptreesubs - initialize subexpressions within subtree to "no match"
*/
static void
-zapmem(struct vars * v,
- struct subre * t)
+zaptreesubs(struct vars * v,
+ struct subre * t)
{
- if (t == NULL)
- return;
-
- assert(v->mem != NULL);
- v->mem[t->retry] = 0;
if (t->op == '(')
{
assert(t->subno > 0);
}
if (t->left != NULL)
- zapmem(v, t->left);
+ zaptreesubs(v, t->left);
if (t->right != NULL)
- zapmem(v, t->right);
+ zaptreesubs(v, t->right);
}
/*
FREE(endpts);
return v->err;
}
- MDEBUG(("iter %d\n", t->retry));
+ MDEBUG(("iter %d\n", t->id));
/*
* Our strategy is to first find a set of sub-match endpoints that are
goto backtrack;
}
MDEBUG(("%d: working endpoint %d: %ld\n",
- t->retry, k, LOFF(endpts[k])));
+ t->id, k, LOFF(endpts[k])));
/* k'th sub-match can no longer be considered verified */
if (nverified >= k)
if (k < min_matches)
goto backtrack;
- MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k));
+ MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
for (i = nverified + 1; i <= k; i++)
{
if (i > k)
{
/* satisfaction */
- MDEBUG(("%d successful\n", t->retry));
+ MDEBUG(("%d successful\n", t->id));
freedfa(d);
FREE(endpts);
return REG_OKAY;
}
/* all possibilities exhausted - shouldn't happen in uncomplicated mode */
- MDEBUG(("%d failed\n", t->retry));
+ MDEBUG(("%d failed\n", t->id));
freedfa(d);
FREE(endpts);
return REG_ASSERT;
FREE(endpts);
return v->err;
}
- MDEBUG(("reviter %d\n", t->retry));
+ MDEBUG(("reviter %d\n", t->id));
/*
* Our strategy is to first find a set of sub-match endpoints that are
goto backtrack;
}
MDEBUG(("%d: working endpoint %d: %ld\n",
- t->retry, k, LOFF(endpts[k])));
+ t->id, k, LOFF(endpts[k])));
/* k'th sub-match can no longer be considered verified */
if (nverified >= k)
if (k < min_matches)
goto backtrack;
- MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k));
+ MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
for (i = nverified + 1; i <= k; i++)
{
if (i > k)
{
/* satisfaction */
- MDEBUG(("%d successful\n", t->retry));
+ MDEBUG(("%d successful\n", t->id));
freedfa(d);
FREE(endpts);
return REG_OKAY;
}
/* all possibilities exhausted - shouldn't happen in uncomplicated mode */
- MDEBUG(("%d failed\n", t->retry));
+ MDEBUG(("%d failed\n", t->id));
freedfa(d);
FREE(endpts);
return REG_ASSERT;
/*
* cdissect - determine subexpression matches (with complications)
- * The retry memory stores the offset of the trial midpoint from begin,
- * plus 1 so that 0 uniquely means "clean slate".
*/
static int /* regexec return code */
cdissect(struct vars * v,
/*
* ccondissect - concatenation subexpression matches (with complications)
- * The retry memory stores the offset of the trial midpoint from begin,
- * plus 1 so that 0 uniquely means "clean slate".
*/
static int /* regexec return code */
ccondissect(struct vars * v,
freedfa(d);
return v->err;
}
- MDEBUG(("cconcat %d\n", t->retry));
+ MDEBUG(("cconcat %d\n", t->id));
/* pick a tentative midpoint */
- if (v->mem[t->retry] == 0)
- {
- mid = longest(v, d, begin, end, (int *) NULL);
- if (mid == NULL)
- {
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
- }
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- }
- else
+ mid = longest(v, d, begin, end, (int *) NULL);
+ if (mid == NULL)
{
- mid = begin + (v->mem[t->retry] - 1);
- MDEBUG(("working midpoint %ld\n", LOFF(mid)));
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
+ MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
/* iterate until satisfaction or failure */
for (;;)
if (mid == begin)
{
/* all possibilities exhausted */
- MDEBUG(("%d no midpoint\n", t->retry));
+ MDEBUG(("%d no midpoint\n", t->id));
freedfa(d);
freedfa(d2);
return REG_NOMATCH;
if (mid == NULL)
{
/* failed to find a new one */
- MDEBUG(("%d failed midpoint\n", t->retry));
+ MDEBUG(("%d failed midpoint\n", t->id));
freedfa(d);
freedfa(d2);
return REG_NOMATCH;
}
- MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- zapmem(v, t->left);
- zapmem(v, t->right);
+ MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
+ zaptreesubs(v, t->left);
+ zaptreesubs(v, t->right);
}
/* can't get here */
/*
* crevdissect - shortest-first concatenation subexpression matches
- * The retry memory stores the offset of the trial midpoint from begin,
- * plus 1 so that 0 uniquely means "clean slate".
*/
static int /* regexec return code */
crevdissect(struct vars * v,
freedfa(d);
return v->err;
}
- MDEBUG(("crev %d\n", t->retry));
+ MDEBUG(("crev %d\n", t->id));
/* pick a tentative midpoint */
- if (v->mem[t->retry] == 0)
- {
- mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
- if (mid == NULL)
- {
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
- }
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- }
- else
+ mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
+ if (mid == NULL)
{
- mid = begin + (v->mem[t->retry] - 1);
- MDEBUG(("working midpoint %ld\n", LOFF(mid)));
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
+ MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
/* iterate until satisfaction or failure */
for (;;)
if (mid == end)
{
/* all possibilities exhausted */
- MDEBUG(("%d no midpoint\n", t->retry));
+ MDEBUG(("%d no midpoint\n", t->id));
freedfa(d);
freedfa(d2);
return REG_NOMATCH;
if (mid == NULL)
{
/* failed to find a new one */
- MDEBUG(("%d failed midpoint\n", t->retry));
+ MDEBUG(("%d failed midpoint\n", t->id));
freedfa(d);
freedfa(d2);
return REG_NOMATCH;
}
- MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- zapmem(v, t->left);
- zapmem(v, t->right);
+ MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
+ zaptreesubs(v, t->left);
+ zaptreesubs(v, t->right);
}
/* can't get here */
assert(n >= 0);
assert((size_t) n < v->nmatch);
- MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
+ MDEBUG(("cbackref n%d %d{%d-%d}\n", t->id, n, min, max));
/* get the backreferenced string */
if (v->pmatch[n].rm_so == -1)
brstring = v->start + v->pmatch[n].rm_so;
brlen = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
- /* no room to maneuver -- retries are pointless */
- if (v->mem[t->retry])
- return REG_NOMATCH;
- v->mem[t->retry] = 1;
-
/* special cases for zero-length strings */
if (brlen == 0)
{
struct dfa *d;
int er;
-#define UNTRIED 0 /* not yet tried at all */
-#define TRYING 1 /* top matched, trying submatches */
-#define TRIED 2 /* top didn't match or submatches exhausted */
-
if (t == NULL)
return REG_NOMATCH;
- assert(t->op == '|');
- if (v->mem[t->retry] == TRIED)
- return caltdissect(v, t->right, begin, end);
- MDEBUG(("calt n%d\n", t->retry));
+ assert(t->op == '|');
assert(t->left != NULL);
- if (v->mem[t->retry] == UNTRIED)
+ MDEBUG(("calt n%d\n", t->id));
+
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR())
+ return v->err;
+ if (longest(v, d, begin, end, (int *) NULL) != end)
{
- d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
- if (ISERR())
- return v->err;
- if (longest(v, d, begin, end, (int *) NULL) != end)
- {
- freedfa(d);
- v->mem[t->retry] = TRIED;
- return caltdissect(v, t->right, begin, end);
- }
freedfa(d);
- MDEBUG(("calt matched\n"));
- v->mem[t->retry] = TRYING;
+ return caltdissect(v, t->right, begin, end);
}
+ freedfa(d);
+ MDEBUG(("calt matched\n"));
er = cdissect(v, t->left, begin, end);
if (er != REG_NOMATCH)
return er;
- v->mem[t->retry] = TRIED;
return caltdissect(v, t->right, begin, end);
}
FREE(endpts);
return v->err;
}
- MDEBUG(("citer %d\n", t->retry));
+ MDEBUG(("citer %d\n", t->id));
/*
* Our strategy is to first find a set of sub-match endpoints that are
goto backtrack;
}
MDEBUG(("%d: working endpoint %d: %ld\n",
- t->retry, k, LOFF(endpts[k])));
+ t->id, k, LOFF(endpts[k])));
/* k'th sub-match can no longer be considered verified */
if (nverified >= k)
if (k < min_matches)
goto backtrack;
- MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k));
+ MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
for (i = nverified + 1; i <= k; i++)
{
- zapmem(v, t->left);
+ zaptreesubs(v, t->left);
er = cdissect(v, t->left, endpts[i - 1], endpts[i]);
if (er == REG_OKAY)
{
if (i > k)
{
/* satisfaction */
- MDEBUG(("%d successful\n", t->retry));
+ MDEBUG(("%d successful\n", t->id));
freedfa(d);
FREE(endpts);
return REG_OKAY;
}
/* all possibilities exhausted */
- MDEBUG(("%d failed\n", t->retry));
+ MDEBUG(("%d failed\n", t->id));
freedfa(d);
FREE(endpts);
return REG_NOMATCH;
FREE(endpts);
return v->err;
}
- MDEBUG(("creviter %d\n", t->retry));
+ MDEBUG(("creviter %d\n", t->id));
/*
* Our strategy is to first find a set of sub-match endpoints that are
goto backtrack;
}
MDEBUG(("%d: working endpoint %d: %ld\n",
- t->retry, k, LOFF(endpts[k])));
+ t->id, k, LOFF(endpts[k])));
/* k'th sub-match can no longer be considered verified */
if (nverified >= k)
if (k < min_matches)
goto backtrack;
- MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k));
+ MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
for (i = nverified + 1; i <= k; i++)
{
- zapmem(v, t->left);
+ zaptreesubs(v, t->left);
er = cdissect(v, t->left, endpts[i - 1], endpts[i]);
if (er == REG_OKAY)
{
if (i > k)
{
/* satisfaction */
- MDEBUG(("%d successful\n", t->retry));
+ MDEBUG(("%d successful\n", t->id));
freedfa(d);
FREE(endpts);
return REG_OKAY;
}
/* all possibilities exhausted */
- MDEBUG(("%d failed\n", t->retry));
+ MDEBUG(("%d failed\n", t->id));
freedfa(d);
FREE(endpts);
return REG_NOMATCH;