Exemple #1
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;
}
Exemple #2
0
/*
 * pg_regexec - match regular expression
 */
int
pg_regexec(regex_t *re,
           const chr *string,
           size_t len,
           size_t search_start,
           rm_detail_t *details,
           size_t nmatch,
           regmatch_t pmatch[],
           int flags)
{
    struct vars var;
    register struct vars *v = &var;
    int			st;
    size_t		n;
    int			backref;

#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;
    if (re->re_csize != sizeof(chr))
        return REG_MIXED;

    /* setup */
    v->re = re;
    v->g = (struct guts *) re->re_guts;
    if ((v->g->cflags & REG_EXPECT) && details == NULL)
        return REG_INVARG;
    if (v->g->info & REG_UIMPOSSIBLE)
        return REG_NOMATCH;
    backref = (v->g->info & REG_UBACKREF) ? 1 : 0;
    v->eflags = flags;
    if (v->g->cflags & REG_NOSUB)
        nmatch = 0;				/* override client */
    v->nmatch = nmatch;
    if (backref)
    {
        /* need work area */
        if (v->g->nsub + 1 <= LOCALMAT)
            v->pmatch = mat;
        else
            v->pmatch = (regmatch_t *) MALLOC((v->g->nsub + 1) *
                                              sizeof(regmatch_t));
        if (v->pmatch == NULL)
            return REG_ESPACE;
        v->nmatch = v->g->nsub + 1;
    }
    else
        v->pmatch = pmatch;
    v->details = details;
    v->start = (chr *) string;
    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);
    if (backref)
        st = cfind(v, &v->g->tree->cnfa, &v->g->cmap);
    else
        st = find(v, &v->g->tree->cnfa, &v->g->cmap);

    /* copy (portion of) match vector over if necessary */
    if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0)
    {
        zapsubs(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;
}
Exemple #3
0
/*
 * find - find a match for the main NFA (no-complications case)
 */
static int
find(struct vars * v,
     struct cnfa * cnfa,
     struct colormap * cm)
{
    struct dfa *s;
    struct dfa *d;
    chr		   *begin;
    chr		   *end = NULL;
    chr		   *cold;
    chr		   *open;			/* open and close of range of possible starts */
    chr		   *close;
    int			hitend;
    int			shorter = (v->g->tree->flags & SHORTER) ? 1 : 0;

    /* first, a shot with the search RE */
    s = newdfa(v, &v->g->search, cm, &v->dfa1);
    assert(!(ISERR() && s != NULL));
    NOERR();
    MDEBUG(("\nsearch at %ld\n", LOFF(v->start)));
    cold = NULL;
    close = shortest(v, s, v->search_start, v->search_start, v->stop,
                     &cold, (int *) NULL);
    freedfa(s);
    NOERR();
    if (v->g->cflags & REG_EXPECT)
    {
        assert(v->details != NULL);
        if (cold != NULL)
            v->details->rm_extend.rm_so = OFF(cold);
        else
            v->details->rm_extend.rm_so = OFF(v->stop);
        v->details->rm_extend.rm_eo = OFF(v->stop);		/* unknown */
    }
    if (close == NULL)			/* not found */
        return REG_NOMATCH;
    if (v->nmatch == 0)			/* found, don't need exact location */
        return REG_OKAY;

    /* find starting point and match */
    assert(cold != NULL);
    open = cold;
    cold = NULL;
    MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close)));
    d = newdfa(v, cnfa, cm, &v->dfa1);
    assert(!(ISERR() && d != NULL));
    NOERR();
    for (begin = open; begin <= close; begin++)
    {
        MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
        if (shorter)
            end = shortest(v, d, begin, begin, v->stop,
                           (chr **) NULL, &hitend);
        else
            end = longest(v, d, begin, v->stop, &hitend);
        NOERR();
        if (hitend && cold == NULL)
            cold = begin;
        if (end != NULL)
            break;				/* NOTE BREAK OUT */
    }
    assert(end != NULL);		/* search RE succeeded so loop should */
    freedfa(d);

    /* and pin down details */
    assert(v->nmatch > 0);
    v->pmatch[0].rm_so = OFF(begin);
    v->pmatch[0].rm_eo = OFF(end);
    if (v->g->cflags & REG_EXPECT)
    {
        if (cold != NULL)
            v->details->rm_extend.rm_so = OFF(cold);
        else
            v->details->rm_extend.rm_so = OFF(v->stop);
        v->details->rm_extend.rm_eo = OFF(v->stop);		/* unknown */
    }
    if (v->nmatch == 1)			/* no need for submatches */
        return REG_OKAY;

    /* submatches */
    zapsubs(v->pmatch, v->nmatch);
    return dissect(v, v->g->tree, begin, end);
}
Exemple #4
0
/*
 - exec - match regular expression
 ^ int exec(regex_t *, const chr *, size_t, rm_detail_t *,
 ^					size_t, regmatch_t [], int);
 */
int
exec(
    regex_t *re,
    const chr *string,
    size_t len,
    rm_detail_t *details,
    size_t nmatch,
    regmatch_t pmatch[],
    int flags)
{
    AllocVars(v);
    int st;
    size_t n;
    int backref;
#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) {
	FreeVars(v);
	return REG_INVARG;
    }
    if (re->re_csize != sizeof(chr)) {
	FreeVars(v);
	return REG_MIXED;
    }

    /*
     * Setup.
     */

    v->re = re;
    v->g = (struct guts *)re->re_guts;
    if ((v->g->cflags&REG_EXPECT) && details == NULL) {
	FreeVars(v);
	return REG_INVARG;
    }
    if (v->g->info&REG_UIMPOSSIBLE) {
	FreeVars(v);
	return REG_NOMATCH;
    }
    backref = (v->g->info&REG_UBACKREF) ? 1 : 0;
    v->eflags = flags;
    if (v->g->cflags&REG_NOSUB) {
	nmatch = 0;		/* override client */
    }
    v->nmatch = nmatch;
    if (backref) {
	/*
	 * Need work area.
	 */

	if (v->g->nsub + 1 <= LOCALMAT) {
	    v->pmatch = mat;
	} else {
	    v->pmatch = (regmatch_t *)
		    MALLOC((v->g->nsub + 1) * sizeof(regmatch_t));
	}
	if (v->pmatch == NULL) {
	    FreeVars(v);
	    return REG_ESPACE;
	}
	v->nmatch = v->g->nsub + 1;
    } else {
	v->pmatch = pmatch;
    }
    v->details = details;
    v->start = (chr *)string;
    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);
	    }
	    FreeVars(v);
	    return REG_ESPACE;
	}
    } else {
	v->mem = NULL;
    }

    /*
     * Do it.
     */

    assert(v->g->tree != NULL);
    if (backref) {
	st = cfind(v, &v->g->tree->cnfa, &v->g->cmap);
    } else {
	st = find(v, &v->g->tree->cnfa, &v->g->cmap);
    }

    /*
     * Copy (portion of) match vector over if necessary.
     */

    if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) {
	zapsubs(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);
    }
    FreeVars(v);
    return st;
}