Ejemplo n.º 1
0
Archivo: regexec.c Proyecto: nawawi/tcl
/*
 - complicatedFindLoop - the heart of complicatedFind
 ^ static int complicatedFindLoop(struct vars *, struct cnfa *, struct colormap *,
 ^	struct dfa *, struct dfa *, chr **);
 */
static int
complicatedFindLoop(
    struct vars *const v,
    struct cnfa *const cnfa,
    struct colormap *const cm,
    struct dfa *const d,
    struct dfa *const s,
    chr **const coldp)		/* where to put coldstart pointer */
{
    chr *begin, *end;
    chr *cold;
    chr *open, *close;		/* Open and close of range of possible
				 * starts */
    chr *estart, *estop;
    int er, hitend;
    int shorter = v->g->tree->flags&SHORTER;

    assert(d != NULL && s != NULL);
    cold = NULL;
    close = v->start;
    do {
	MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
	close = shortest(v, s, close, close, v->stop, &cold, 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(("\ncomplicatedFind trying at %ld\n", LOFF(begin)));
	    estart = begin;
	    estop = v->stop;
	    for (;;) {
		if (shorter) {
		    end = shortest(v, d, begin, estart, estop, 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)));
		zapallsubs(v->pmatch, v->nmatch);
		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) {
		    break;
		}

		/*
		 * Go around and try again
		 */

		if (shorter) {
		    estart = end + 1;
		} else {
		    estop = end - 1;
		}
	    }
	}
    } while (close < v->stop);

    *coldp = cold;
    return REG_NOMATCH;
}
Ejemplo n.º 2
0
Archivo: regexec.c Proyecto: nawawi/tcl
/*
 - simpleFind - find a match for the main NFA (no-complications case)
 ^ static int simpleFind(struct vars *, struct cnfa *, struct colormap *);
 */
static int
simpleFind(
    struct vars *const v,
    struct cnfa *const cnfa,
    struct colormap *const cm)
{
    struct dfa *s, *d;
    chr *begin, *end = NULL;
    chr *cold;
    chr *open, *close;		/* Open and close of range of possible
				 * starts */
    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->start, v->start, v->stop, &cold, 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, NULL, &hitend);
	} else {
	    end = longest(v, d, begin, v->stop, &hitend);
	}
	if (ISERR()) {
	    freeDFA(d);
	    return v->err;
	}
	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;
    }

    /*
     * Find submatches.
     */

    zapallsubs(v->pmatch, v->nmatch);
    return cdissect(v, v->g->tree, begin, end);
}
Ejemplo n.º 3
0
Archivo: regexec.c Proyecto: nawawi/tcl
/*
 - 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, backref;
    size_t n;
    size_t i;
#define	LOCALMAT	20
    regmatch_t mat[LOCALMAT];
#define LOCALDFAS	40
    struct dfa *subdfas[LOCALDFAS];

    /*
     * 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;
    assert(v->g->ntree >= 0);
    n = (size_t) v->g->ntree;
    if (n <= LOCALDFAS)
	v->subdfas = subdfas;
    else
	v->subdfas = (struct dfa **) MALLOC(n * sizeof(struct dfa *));
    if (v->subdfas == NULL) {
	if (v->pmatch != pmatch && v->pmatch != mat)
	    FREE(v->pmatch);
	FreeVars(v);
	return REG_ESPACE;
    }
    for (i = 0; i < n; i++)
	v->subdfas[i] = NULL;

    /*
     * Do it.
     */

    assert(v->g->tree != NULL);
    if (backref) {
	st = complicatedFind(v, &v->g->tree->cnfa, &v->g->cmap);
    } else {
	st = simpleFind(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) {
	zapallsubs(pmatch, nmatch);
	n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
	memcpy((void*)(pmatch), (void*)(v->pmatch), n*sizeof(regmatch_t));
    }

    /*
     * Clean up.
     */

    if (v->pmatch != pmatch && v->pmatch != mat) {
	FREE(v->pmatch);
    }
    n = (size_t) v->g->ntree;
    for (i = 0; i < n; i++) {
	if (v->subdfas[i] != NULL)
	    freeDFA(v->subdfas[i]);
    }
    if (v->subdfas != subdfas)
	FREE(v->subdfas);
    FreeVars(v);
    return st;
}
Ejemplo n.º 4
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)));
				zapallsubs(v->pmatch, v->nmatch);
				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;
				}
				/* try next shorter/longer match with same begin point */
				if (shorter)
				{
					if (end == estop)
						break;	/* NOTE BREAK OUT */
					estart = end + 1;
				}
				else
				{
					if (end == begin)
						break;	/* NOTE BREAK OUT */
					estop = end - 1;
				}
			}					/* end loop over endpoint positions */
		}						/* end loop over beginning positions */
	} while (close < v->stop);

	*coldp = cold;
	return REG_NOMATCH;
}
Ejemplo n.º 5
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;

	/* find submatches */
	zapallsubs(v->pmatch, v->nmatch);
	return cdissect(v, v->g->tree, begin, end);
}
Ejemplo n.º 6
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;
	size_t		i;
	int			backref;

#define  LOCALMAT	 20
	regmatch_t	mat[LOCALMAT];

#define  LOCALDFAS	 40
	struct dfa *subdfas[LOCALDFAS];

	/* sanity checks */
	if (re == NULL || string == NULL || re->re_magic != REMAGIC)
		return REG_INVARG;
	if (re->re_csize != sizeof(chr))
		return REG_MIXED;

	/* Initialize locale-dependent support */
	pg_set_regex_collation(re->re_collation);

	/* 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;
	assert(v->g->ntree >= 0);
	n = (size_t) v->g->ntree;
	if (n <= LOCALDFAS)
		v->subdfas = subdfas;
	else
		v->subdfas = (struct dfa **) MALLOC(n * sizeof(struct dfa *));
	if (v->subdfas == NULL)
	{
		if (v->pmatch != pmatch && v->pmatch != mat)
			FREE(v->pmatch);
		return REG_ESPACE;
	}
	for (i = 0; i < n; i++)
		v->subdfas[i] = 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)
	{
		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);
	n = (size_t) v->g->ntree;
	for (i = 0; i < n; i++)
	{
		if (v->subdfas[i] != NULL)
			freedfa(v->subdfas[i]);
	}
	if (v->subdfas != subdfas)
		FREE(v->subdfas);

	return st;
}