Beispiel #1
0
fa *mkdfa(const char *s, int anchor)	/* does the real work of making a dfa */
/* anchor = 1 for anchored matches, else 0 */
{
    Node *p, *p1;
    fa *f;

    p = reparse(s);
    p1 = op2(CAT, op2(STAR, op2(ALL, NIL, NIL), NIL), p);
    /* put ALL STAR in front of reg.  exp. */
    p1 = op2(CAT, p1, op2(FINAL, NIL, NIL));
    /* put FINAL after reg.  exp. */

    poscnt = 0;
    penter(p1);	/* enter parent pointers and leaf indices */
    if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL)
        overflo("out of space for fa");
    f->accept = poscnt-1;	/* penter has computed number of positions in re */
    cfoll(f, p1);	/* set up follow sets */
    freetr(p1);
    if ((f->posns[0] = (int *) calloc(1, *(f->re[0].lfollow)*sizeof(int))) == NULL)
        overflo("out of space in makedfa");
    if ((f->posns[1] = (int *) calloc(1, sizeof(int))) == NULL)
        overflo("out of space in makedfa");
    *f->posns[1] = 0;
    f->initstat = makeinit(f, anchor);
    f->anchor = anchor;
    f->restr = (uschar *) tostring(s);
    return f;
}
Beispiel #2
0
int pmatch(fa *f, const char *p0)	/* longest match, for sub */
{
    int s, ns;
    uschar *p = (uschar *) p0;
    uschar *q;
    int i, k;

    /* s = f->reset ? makeinit(f,1) : f->initstat; */
    if (f->reset) {
        f->initstat = s = makeinit(f,1);
    } else {
        s = f->initstat;
    }
    patbeg = (char *) p;
    patlen = -1;
    do {
        q = p;
        do {
            if (f->out[s])		/* final state */
                patlen = q-p;
            /* assert(*q < NCHARS); */
            if ((ns = f->gototab[s][*q]) != 0)
                s = ns;
            else
                s = cgoto(f, s, *q);
            if (s == 1) {	/* no transition */
                if (patlen >= 0) {
                    patbeg = (char *) p;
                    return(1);
                }
                else
                    goto nextin;	/* no match */
            }
        } while (*q++ != 0);
        if (f->out[s])
            patlen = q-p-1;	/* don't count $ */
        if (patlen >= 0) {
            patbeg = (char *) p;
            return(1);
        }
nextin:
        s = 2;
        if (f->reset) {
            for (i = 2; i <= f->curstat; i++)
                xfree(f->posns[i]);
            k = *f->posns[0];
            if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL)
                overflo("out of space in pmatch");
            for (i = 0; i <= k; i++)
                (f->posns[2])[i] = (f->posns[0])[i];
            f->initstat = f->curstat = 2;
            f->out[2] = f->out[0];
            for (i = 0; i < NCHARS; i++)
                f->gototab[2][i] = 0;
        }
    } while (*p++ != 0);
    return (0);
}
Beispiel #3
0
int nematch(fa *f, char *p0)	/* non-empty match, for sub */
{
	int s, ns;
	uschar *p = (uschar *) p0;
	uschar *q;
	int i, k;

	s = f->reset ? makeinit(f,1) : f->initstat;
	patlen = -1;
	while (*p) {
		q = p;
		do {
			if (f->out[s])		/* final state */
				patlen = q-p;
			if ((ns = f->gototab[s][*q]) != 0)
				s = ns;
			else
				s = cgoto(f, s, *q);
			if (s == 1)	/* no transition */
				if (patlen > 0) {
					patbeg = (char *) p;
					return(1);
				} else
					goto nnextin;	/* no nonempty match */
		} while (*q++ != 0);
		if (f->out[s])
			patlen = q-p-1;	/* don't count $ */
		if (patlen > 0 ) {
			patbeg = (char *) p;
			return(1);
		}
	nnextin:
		s = 2;
		if (f->reset) {
			for (i = 2; i <= f->curstat; i++)
				xfree(f->posns[i]);
			k = *f->posns[0];			
			if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL)
				overflo("out of state space");
			for (i = 0; i <= k; i++)
				(f->posns[2])[i] = (f->posns[0])[i];
			f->initstat = f->curstat = 2;
			f->out[2] = f->out[0];
			for (i = 0; i < NCHARS; i++)
				f->gototab[2][i] = 0;
		}
		p++;
	}
	return (0);
}
Beispiel #4
0
int match(fa *f, char *p0)	/* shortest match ? */
{
	int s, ns;
	uschar *p = (uschar *) p0;

	s = f->reset ? makeinit(f,0) : f->initstat;
	if (f->out[s])
		return(1);
	do {
		if ((ns = f->gototab[s][*p]) != 0)
			s = ns;
		else
			s = cgoto(f, s, *p);
		if (f->out[s])
			return(1);
	} while (*p++ != 0);
	return(0);
}