-
-/*
- - zapmem - initialize the retry memory of a subtree to zeros
- ^ static VOID zapmem(struct vars *, struct subre *);
- */
-static VOID
-zapmem(v, t)
-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);
-               v->pmatch[t->subno].rm_so = -1;
-               v->pmatch[t->subno].rm_eo = -1;
-       }
-
-       if (t->left != NULL)
-               zapmem(v, t->left);
-       if (t->right != NULL)
-               zapmem(v, t->right);
-}
-
-/*
- - subset - set any subexpression relevant to a successful subre
- ^ static VOID subset(struct vars *, struct subre *, chr *, chr *);
- */
-static VOID
-subset(v, sub, begin, end)
-struct vars *v;
-struct subre *sub;
-chr *begin;
-chr *end;
-{
-       int n = sub->subno;
-
-       assert(n > 0);
-       if ((size_t)n >= v->nmatch)
-               return;
-
-       MDEBUG(("setting %d\n", n));
-       v->pmatch[n].rm_so = OFF(begin);
-       v->pmatch[n].rm_eo = OFF(end);
-}
-
-/*
- - dissect - determine subexpression matches (uncomplicated case)
- ^ static int dissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-dissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       assert(t != NULL);
-       MDEBUG(("dissect %ld-%ld\n", LOFF(begin), LOFF(end)));
-
-       switch (t->op) {
-       case '=':               /* terminal node */
-               assert(t->left == NULL && t->right == NULL);
-               return REG_OKAY;        /* no action, parent did the work */
-               break;
-       case '|':               /* alternation */
-               assert(t->left != NULL);
-               return altdissect(v, t, begin, end);
-               break;
-       case 'b':               /* back ref -- shouldn't be calling us! */
-               return REG_ASSERT;
-               break;
-       case '.':               /* concatenation */
-               assert(t->left != NULL && t->right != NULL);
-               return condissect(v, t, begin, end);
-               break;
-       case '(':               /* capturing */
-               assert(t->left != NULL && t->right == NULL);
-               assert(t->subno > 0);
-               subset(v, t, begin, end);
-               return dissect(v, t->left, begin, end);
-               break;
-       default:
-               return REG_ASSERT;
-               break;
-       }
-}
-
-/*
- - condissect - determine concatenation subexpression matches (uncomplicated)
- ^ static int condissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-condissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       struct dfa *d;
-       struct dfa *d2;
-       chr *mid;
-       int i;
-       int shorter = (t->left->flags&SHORTER) ? 1 : 0;
-       chr *stop = (shorter) ? end : begin;
-
-       assert(t->op == '.');
-       assert(t->left != NULL && t->left->cnfa.nstates > 0);
-       assert(t->right != NULL && t->right->cnfa.nstates > 0);
-
-       d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
-       NOERR();
-       d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &v->dfa2);
-       if (ISERR()) {
-               assert(d2 == NULL);
-               freedfa(d);
-               return v->err;
-       }
-
-       /* pick a tentative midpoint */
-       if (shorter)
-               mid = shortest(v, d, begin, begin, end, (chr **)NULL,
-                                                               (int *)NULL);
-       else
-               mid = longest(v, d, begin, end, (int *)NULL);
-       if (mid == NULL) {
-               freedfa(d);
-               freedfa(d2);
-               return REG_ASSERT;
-       }
-       MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
-
-       /* iterate until satisfaction or failure */
-       while (longest(v, d2, mid, end, (int *)NULL) != end) {
-               /* that midpoint didn't work, find a new one */
-               if (mid == stop) {
-                       /* all possibilities exhausted! */
-                       MDEBUG(("no midpoint!\n"));
-                       freedfa(d);
-                       freedfa(d2);
-                       return REG_ASSERT;
-               }
-               if (shorter)
-                       mid = shortest(v, d, begin, mid+1, end, (chr **)NULL,
-                                                               (int *)NULL);
-               else
-                       mid = longest(v, d, begin, mid-1, (int *)NULL);
-               if (mid == NULL) {
-                       /* failed to find a new one! */
-                       MDEBUG(("failed midpoint!\n"));
-                       freedfa(d);
-                       freedfa(d2);
-                       return REG_ASSERT;
-               }
-               MDEBUG(("new midpoint %ld\n", LOFF(mid)));
-       }
-
-       /* satisfaction */
-       MDEBUG(("successful\n"));
-       freedfa(d);
-       freedfa(d2);
-       i = dissect(v, t->left, begin, mid);
-       if (i != REG_OKAY)
-               return i;
-       return dissect(v, t->right, mid, end);
-}
-
-/*
- - altdissect - determine alternative subexpression matches (uncomplicated)
- ^ static int altdissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-altdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       struct dfa *d;
-       int i;
-
-       assert(t != NULL);
-       assert(t->op == '|');
-
-       for (i = 0; t != NULL; t = t->right, i++) {
-               MDEBUG(("trying %dth\n", i));
-               assert(t->left != NULL && t->left->cnfa.nstates > 0);
-               d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
-               if (ISERR())
-                       return v->err;
-               if (longest(v, d, begin, end, (int *)NULL) == end) {
-                       MDEBUG(("success\n"));
-                       freedfa(d);
-                       return dissect(v, t->left, begin, end);
-               }
-               freedfa(d);
-       }
-       return REG_ASSERT;      /* none of them matched?!? */
-}
-
-/*
- - 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 cdissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-cdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       int er;
-
-       assert(t != NULL);
-       MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
-
-       switch (t->op) {
-       case '=':               /* terminal node */
-               assert(t->left == NULL && t->right == NULL);
-               return REG_OKAY;        /* no action, parent did the work */
-               break;
-       case '|':               /* alternation */
-               assert(t->left != NULL);
-               return caltdissect(v, t, begin, end);
-               break;
-       case 'b':               /* back ref -- shouldn't be calling us! */
-               assert(t->left == NULL && t->right == NULL);
-               return cbrdissect(v, t, begin, end);
-               break;
-       case '.':               /* concatenation */
-               assert(t->left != NULL && t->right != NULL);
-               return ccondissect(v, t, begin, end);
-               break;
-       case '(':               /* capturing */
-               assert(t->left != NULL && t->right == NULL);
-               assert(t->subno > 0);
-               er = cdissect(v, t->left, begin, end);
-               if (er == REG_OKAY)
-                       subset(v, t, begin, end);
-               return er;
-               break;
-       default:
-               return REG_ASSERT;
-               break;
-       }
-}
-
-/*
- - 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 ccondissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-ccondissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       struct dfa *d;
-       struct dfa *d2;
-       chr *mid;
-       int er;
-
-       assert(t->op == '.');
-       assert(t->left != NULL && t->left->cnfa.nstates > 0);
-       assert(t->right != NULL && t->right->cnfa.nstates > 0);
-
-       if (t->left->flags&SHORTER)             /* reverse scan */
-               return crevdissect(v, t, begin, end);
-
-       d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
-       if (ISERR())
-               return v->err;
-       d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
-       if (ISERR()) {
-               freedfa(d);
-               return v->err;
-       }
-       MDEBUG(("cconcat %d\n", t->retry));
-
-       /* 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 = begin + (v->mem[t->retry] - 1);
-               MDEBUG(("working midpoint %ld\n", LOFF(mid)));
-       }
-
-       /* iterate until satisfaction or failure */
-       for (;;) {
-               /* try this midpoint on for size */
-               er = cdissect(v, t->left, begin, mid);
-               if (er == REG_OKAY &&
-                               longest(v, d2, mid, end, (int *)NULL) == end &&
-                               (er = cdissect(v, t->right, mid, end)) == 
-                                                               REG_OKAY)
-                       break;                  /* NOTE BREAK OUT */
-               if (er != REG_OKAY && er != REG_NOMATCH) {
-                       freedfa(d);
-                       freedfa(d2);
-                       return er;
-               }
-
-               /* that midpoint didn't work, find a new one */
-               if (mid == begin) {
-                       /* all possibilities exhausted */
-                       MDEBUG(("%d no midpoint\n", t->retry));
-                       freedfa(d);
-                       freedfa(d2);
-                       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->retry));
-                       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);
-       }
-
-       /* satisfaction */
-       MDEBUG(("successful\n"));
-       freedfa(d);
-       freedfa(d2);
-       return REG_OKAY;
-}
-
-/*
- - crevdissect - determine backref shortest-first 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 crevdissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-crevdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       struct dfa *d;
-       struct dfa *d2;
-       chr *mid;
-       int er;
-
-       assert(t->op == '.');
-       assert(t->left != NULL && t->left->cnfa.nstates > 0);
-       assert(t->right != NULL && t->right->cnfa.nstates > 0);
-       assert(t->left->flags&SHORTER);
-
-       /* concatenation -- need to split the substring between parts */
-       d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
-       if (ISERR())
-               return v->err;
-       d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
-       if (ISERR()) {
-               freedfa(d);
-               return v->err;
-       }
-       MDEBUG(("crev %d\n", t->retry));
-
-       /* 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 = begin + (v->mem[t->retry] - 1);
-               MDEBUG(("working midpoint %ld\n", LOFF(mid)));
-       }
-
-       /* iterate until satisfaction or failure */
-       for (;;) {
-               /* try this midpoint on for size */
-               er = cdissect(v, t->left, begin, mid);
-               if (er == REG_OKAY &&
-                               longest(v, d2, mid, end, (int *)NULL) == end &&
-                               (er = cdissect(v, t->right, mid, end)) == 
-                                                               REG_OKAY)
-                       break;                  /* NOTE BREAK OUT */
-               if (er != REG_OKAY && er != REG_NOMATCH) {
-                       freedfa(d);
-                       freedfa(d2);
-                       return er;
-               }
-
-               /* that midpoint didn't work, find a new one */
-               if (mid == end) {
-                       /* all possibilities exhausted */
-                       MDEBUG(("%d no midpoint\n", t->retry));
-                       freedfa(d);
-                       freedfa(d2);
-                       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->retry));
-                       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);
-       }
-
-       /* satisfaction */
-       MDEBUG(("successful\n"));
-       freedfa(d);
-       freedfa(d2);
-       return REG_OKAY;
-}
-
-/*
- - cbrdissect - determine backref subexpression matches
- ^ static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-cbrdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       int i;
-       int n = t->subno;
-       size_t len;
-       chr *paren;
-       chr *p;
-       chr *stop;
-       int min = t->min;
-       int max = t->max;
-
-       assert(t != NULL);
-       assert(t->op == 'b');
-       assert(n >= 0);
-       assert((size_t)n < v->nmatch);
-
-       MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
-
-       if (v->pmatch[n].rm_so == -1)
-               return REG_NOMATCH;
-       paren = v->start + v->pmatch[n].rm_so;
-       len = 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-case zero-length string */
-       if (len == 0) {
-               if (begin == end)
-                       return REG_OKAY;
-               return REG_NOMATCH;
-       }
-
-       /* and too-short string */
-       assert(end >= begin);
-       if ((size_t)(end - begin) < len)
-               return REG_NOMATCH;
-       stop = end - len;
-
-       /* count occurrences */
-       i = 0;
-       for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
-               if ((*v->g->compare)(paren, p, len) != 0)
-                               break;
-               i++;
-       }
-       MDEBUG(("cbackref found %d\n", i));
-
-       /* and sort it out */
-       if (p != end)                   /* didn't consume all of it */
-               return REG_NOMATCH;
-       if (min <= i && (i <= max || max == INFINITY))
-               return REG_OKAY;
-       return REG_NOMATCH;             /* out of range */
-}
-
-/*
- - caltdissect - determine alternative subexpression matches (w. complications)
- ^ static int caltdissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int                     /* regexec return code */
-caltdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin;                    /* beginning of relevant substring */
-chr *end;                      /* end of same */
-{
-       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->left != NULL);
-
-       if (v->mem[t->retry] == UNTRIED) {
-               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;
-       }
-
-       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);
-}
-
-
-
-#include "rege_dfa.c"