Exemplo n.º 1
0
/*
 * zapmem - initialize the retry memory of a subtree to zeros
 */
static void
zapmem(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);
}
Exemplo n.º 2
0
/*
 * 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						/* regexec return code */
crevdissect(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;
}
Exemplo n.º 3
0
/*
 * cfindloop - the heart of cfind
 */
static int
cfindloop(struct vars * v,
          struct cnfa * cnfa,
          struct colormap * cm,
          struct dfa * d,
          struct dfa * s,
          chr **coldp)			/* where to put coldstart pointer */
{
    chr		   *begin;
    chr		   *end;
    chr		   *cold;
    chr		   *open;			/* open and close of range of possible starts */
    chr		   *close;
    chr		   *estart;
    chr		   *estop;
    int			er;
    int			shorter = v->g->tree->flags & SHORTER;
    int			hitend;

    assert(d != NULL && s != NULL);
    cold = NULL;
    close = v->search_start;
    do
    {
        MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
        close = shortest(v, s, close, close, v->stop, &cold, (int *) NULL);
        if (close == NULL)
            break;				/* NOTE BREAK */
        assert(cold != NULL);
        open = cold;
        cold = NULL;
        MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
        for (begin = open; begin <= close; begin++)
        {
            MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
            estart = begin;
            estop = v->stop;
            for (;;)
            {
                if (shorter)
                    end = shortest(v, d, begin, estart,
                                   estop, (chr **) NULL, &hitend);
                else
                    end = longest(v, d, begin, estop,
                                  &hitend);
                if (hitend && cold == NULL)
                    cold = begin;
                if (end == NULL)
                    break;		/* NOTE BREAK OUT */
                MDEBUG(("tentative end %ld\n", LOFF(end)));
                zapsubs(v->pmatch, v->nmatch);
                zapmem(v, v->g->tree);
                er = cdissect(v, v->g->tree, begin, end);
                if (er == REG_OKAY)
                {
                    if (v->nmatch > 0)
                    {
                        v->pmatch[0].rm_so = OFF(begin);
                        v->pmatch[0].rm_eo = OFF(end);
                    }
                    *coldp = cold;
                    return REG_OKAY;
                }
                if (er != REG_NOMATCH)
                {
                    ERR(er);
                    *coldp = cold;
                    return er;
                }
                if ((shorter) ? end == estop : end == begin)
                {
                    /* no point in trying again */
                    *coldp = cold;
                    return REG_NOMATCH;
                }
                /* go around and try again */
                if (shorter)
                    estart = end + 1;
                else
                    estop = end - 1;
            }
        }
    } while (close < v->stop);

    *coldp = cold;
    return REG_NOMATCH;
}
Exemplo n.º 4
0
/*
 - 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(
    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, 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, 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, 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;
}