예제 #1
0
파일: regexec.c 프로젝트: dgsb/tcl
/*
 - complicatedDissect - 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 complicatedDissect(struct vars *, struct subre *, chr *, chr *);
 */
static inline int		/* regexec return code */
complicatedDissect(
    struct vars *const v,
    struct subre *const t,
    chr *const begin,		/* beginning of relevant substring */
    chr *const end)		/* end of same */
{
    assert(t != NULL);
    MDEBUG(("complicatedDissect %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 */
    case '|':			/* alternation */
	assert(t->left != NULL);
	return complicatedAlternationDissect(v, t, begin, end);
    case 'b':			/* back ref -- shouldn't be calling us! */
	assert(t->left == NULL && t->right == NULL);
	return complicatedBackrefDissect(v, t, begin, end);
    case '.':			/* concatenation */
	assert(t->left != NULL && t->right != NULL);
	return complicatedConcatenationDissect(v, t, begin, end);
    case '(':			/* capturing */
	assert(t->left != NULL && t->right == NULL);
	assert(t->subno > 0);
	return complicatedCapturingDissect(v, t, begin, end);
    default:
	return REG_ASSERT;
    }
}
예제 #2
0
/*
 - 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(
    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;
    }
}
예제 #3
0
파일: regexec.c 프로젝트: dgsb/tcl
/*
 - dissect - determine subexpression matches (uncomplicated case)
 ^ static int dissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
dissect(
    struct vars *const v,
    struct subre *t,
    chr *const begin,		/* beginning of relevant substring */
    chr *const end)		/* end of same */
{
#ifndef COMPILER_DOES_TAILCALL_OPTIMIZATION
  restart:
#endif
    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 */
    case '|':			/* alternation */
	assert(t->left != NULL);
	return alternationDissect(v, t, begin, end);
    case 'b':			/* back ref -- shouldn't be calling us! */
	return REG_ASSERT;
    case '.':			/* concatenation */
	assert(t->left != NULL && t->right != NULL);
	return concatenationDissect(v, t, begin, end);
    case '(':			/* capturing */
	assert(t->left != NULL && t->right == NULL);
	assert(t->subno > 0);
	subset(v, t, begin, end);
#ifndef COMPILER_DOES_TAILCALL_OPTIMIZATION
	t = t->left;
	goto restart;
#else
	return dissect(v, t->left, begin, end);
#endif
    default:
	return REG_ASSERT;
    }
}
예제 #4
0
파일: dir.c 프로젝트: crossmeta/sgi
static int	dir_leaf_hdr_count(void *obj, int startoff);
static int	dir_leaf_name_count(void *obj, int startoff);
static int	dir_leaf_namelist_count(void *obj, int startoff);
static int	dir_leaf_namelist_offset(void *obj, int startoff, int idx);
static int	dir_node_btree_count(void *obj, int startoff);
static int	dir_node_hdr_count(void *obj, int startoff);

const field_t	dir_hfld[] = {
	{ "", FLDT_DIR, OI(0), C1, 0, TYP_NONE },
	{ NULL }
};

#define	LOFF(f)	bitize(offsetof(xfs_dir_leafblock_t, f))
#define	NOFF(f)	bitize(offsetof(xfs_da_intnode_t, f))
const field_t	dir_flds[] = {
	{ "lhdr", FLDT_DIR_LEAF_HDR, OI(LOFF(hdr)), dir_leaf_hdr_count,
	  FLD_COUNT, TYP_NONE },
	{ "nhdr", FLDT_DIR_NODE_HDR, OI(NOFF(hdr)), dir_node_hdr_count,
	  FLD_COUNT, TYP_NONE },
	{ "entries", FLDT_DIR_LEAF_ENTRY, OI(LOFF(entries)),
	  dir_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
	{ "btree", FLDT_DIR_NODE_ENTRY, OI(NOFF(btree)),
	  dir_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
	{ "namelist", FLDT_DIR_LEAF_NAME, dir_leaf_namelist_offset,
	  dir_leaf_namelist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
	{ NULL }
};

#define	BOFF(f)	bitize(offsetof(xfs_da_blkinfo_t, f))
const field_t	dir_blkinfo_flds[] = {
	{ "forw", FLDT_DIRBLOCK, OI(BOFF(forw)), C1, 0, TYP_INODATA },
예제 #5
0
파일: regexec.c 프로젝트: qiuyesuifeng/gpdb
/*
 * 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;
}
예제 #6
0
파일: regexec.c 프로젝트: qiuyesuifeng/gpdb
/*
 * condissect - determine concatenation subexpression matches (uncomplicated)
 */
static int						/* regexec return code */
condissect(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);
}
예제 #7
0
파일: regexec.c 프로젝트: qiuyesuifeng/gpdb
/*
 * 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;
}
예제 #8
0
파일: regexec.c 프로젝트: qiuyesuifeng/gpdb
/*
 * 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);
}
예제 #9
0
파일: regexec.c 프로젝트: nawawi/tcl
/*
 - citerdissect - dissect match for iteration node
 ^ static int citerdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
citerdissect(struct vars * v,
	     struct subre * t,
	     chr *begin,	/* beginning of relevant substring */
	     chr *end)		/* end of same */
{
    struct dfa *d;
    chr	  **endpts;
    chr	   *limit;
    int		min_matches;
    size_t	max_matches;
    int		nverified;
    int		k;
    int		i;
    int		er;

    assert(t->op == '*');
    assert(t->left != NULL && t->left->cnfa.nstates > 0);
    assert(!(t->left->flags & SHORTER));
    assert(begin <= end);

    /*
     * If zero matches are allowed, and target string is empty, just declare
     * victory.  OTOH, if target string isn't empty, zero matches can't work
     * so we pretend the min is 1.
     */
    min_matches = t->min;
    if (min_matches <= 0) {
	if (begin == end)
	    return REG_OKAY;
	min_matches = 1;
    }

    /*
     * We need workspace to track the endpoints of each sub-match.  Normally
     * we consider only nonzero-length sub-matches, so there can be at most
     * end-begin of them.  However, if min is larger than that, we will also
     * consider zero-length sub-matches in order to find enough matches.
     *
     * For convenience, endpts[0] contains the "begin" pointer and we store
     * sub-match endpoints in endpts[1..max_matches].
     */
    max_matches = end - begin;
    if (max_matches > (size_t)t->max && t->max != DUPINF)
	max_matches = t->max;
    if (max_matches < (size_t)min_matches)
	max_matches = min_matches;
    endpts = (chr **) MALLOC((max_matches + 1) * sizeof(chr *));
    if (endpts == NULL)
	return REG_ESPACE;
    endpts[0] = begin;

    d = getsubdfa(v, t->left);
    if (ISERR()) {
	FREE(endpts);
	return v->err;
    }
    MDEBUG(("citer %d\n", t->id));

    /*
     * Our strategy is to first find a set of sub-match endpoints that are
     * valid according to the child node's DFA, and then recursively dissect
     * each sub-match to confirm validity.  If any validity check fails,
     * backtrack the last sub-match and try again.  And, when we next try for
     * a validity check, we need not recheck any successfully verified
     * sub-matches that we didn't move the endpoints of.  nverified remembers
     * how many sub-matches are currently known okay.
     */

    /* initialize to consider first sub-match */
    nverified = 0;
    k = 1;
    limit = end;

    /* iterate until satisfaction or failure */
    while (k > 0) {
	/* try to find an endpoint for the k'th sub-match */
	endpts[k] = longest(v, d, endpts[k - 1], limit, (int *) NULL);
	if (endpts[k] == NULL) {
	    /* no match possible, so see if we can shorten previous one */
	    k--;
	    goto backtrack;
	}
	MDEBUG(("%d: working endpoint %d: %ld\n",
		t->id, k, LOFF(endpts[k])));

	/* k'th sub-match can no longer be considered verified */
	if (nverified >= k)
	    nverified = k - 1;

	if (endpts[k] != end) {
	    /* haven't reached end yet, try another iteration if allowed */
	    if ((size_t)k >= max_matches) {
		/* must try to shorten some previous match */
		k--;
		goto backtrack;
	    }

	    /* reject zero-length match unless necessary to achieve min */
	    if (endpts[k] == endpts[k - 1] &&
		(k >= min_matches || min_matches - k < end - endpts[k]))
		goto backtrack;

	    k++;
	    limit = end;
	    continue;
	}

	/*
	 * We've identified a way to divide the string into k sub-matches
	 * that works so far as the child DFA can tell.  If k is an allowed
	 * number of matches, start the slow part: recurse to verify each
	 * sub-match.  We always have k <= max_matches, needn't check that.
	 */
	if (k < min_matches)
	    goto backtrack;

	MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));

	for (i = nverified + 1; i <= k; i++) {
	    zaptreesubs(v, t->left);
	    er = cdissect(v, t->left, endpts[i - 1], endpts[i]);
	    if (er == REG_OKAY) {
		nverified = i;
		continue;
	    }
	    if (er == REG_NOMATCH)
		break;
	    /* oops, something failed */
	    FREE(endpts);
	    return er;
	}

	if (i > k) {
	    /* satisfaction */
	    MDEBUG(("%d successful\n", t->id));
	    FREE(endpts);
	    return REG_OKAY;
	}

	/* match failed to verify, so backtrack */

    backtrack:
	/*
	 * Must consider shorter versions of the current sub-match.  However,
	 * we'll only ask for a zero-length match if necessary.
	 */
	while (k > 0) {
	    chr	   *prev_end = endpts[k - 1];

	    if (endpts[k] > prev_end) {
		limit = endpts[k] - 1;
		if (limit > prev_end ||
		    (k < min_matches && min_matches - k >= end - prev_end)) {
		    /* break out of backtrack loop, continue the outer one */
		    break;
		}
	    }
	    /* can't shorten k'th sub-match any more, consider previous one */
	    k--;
	}
    }

    /* all possibilities exhausted */
    MDEBUG(("%d failed\n", t->id));
    FREE(endpts);
    return REG_NOMATCH;
}
예제 #10
0
파일: regexec.c 프로젝트: nawawi/tcl
/*
 - crevcondissect - dissect match for concatenation node, shortest-first
 ^ static int crevcondissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
crevcondissect(
    struct vars *v,
    struct subre *t,
    chr *begin,		/* beginning of relevant substring */
    chr *end)		/* end of same */
{
    struct dfa *d, *d2;
    chr *mid;

    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);

    d = getsubdfa(v, t->left);
    NOERR();
    d2 = getsubdfa(v, t->right);
    NOERR();

    MDEBUG(("crevcon %d\n", t->id));

    /*
     * Pick a tentative midpoint.
     */

    mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
    if (mid == NULL) {
	return REG_NOMATCH;
    }
    MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));

    /*
     * Iterate until satisfaction or failure.
     */

    for (;;) {
	/*
	 * Try this midpoint on for size.
	 */

	if (longest(v, d2, mid, end, NULL) == end) {
	    int er = cdissect(v, t->left, begin, mid);

	    if (er == REG_OKAY) {
		er = cdissect(v, t->right, mid, end);
		if (er == REG_OKAY) {
		    /*
		     * Satisfaction.
		     */

		    MDEBUG(("successful\n"));
		    return REG_OKAY;
		}
	    }
	    if (er != REG_NOMATCH) {
		return er;
	    }
	}

	/*
	 * That midpoint didn't work, find a new one.
	 */

	if (mid == end) {
	    /*
	     * All possibilities exhausted.
	     */

	    MDEBUG(("%d no midpoint\n", t->id));
	    return REG_NOMATCH;
	}
	mid = shortest(v, d, begin, mid+1, end, NULL, NULL);
	if (mid == NULL) {
	    /*
	     * Failed to find a new one.
	     */

	    MDEBUG(("%d failed midpoint\n", t->id));
	    return REG_NOMATCH;
	}
	MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
	zaptreesubs(v, t->left);
	zaptreesubs(v, t->right);
    }
}
예제 #11
0
파일: regexec.c 프로젝트: nawawi/tcl
/*
 - cdissect - check backrefs and determine subexpression matches
 * cdissect recursively processes a subre tree to check matching of backrefs
 * and/or identify submatch boundaries for capture nodes.  The proposed match
 * runs from "begin" to "end" (not including "end"), and we are basically
 * "dissecting" it to see where the submatches are.
 * Before calling any level of cdissect, the caller must have run the node's
 * DFA and found that the proposed substring satisfies the DFA.  (We make
 * the caller do that because in concatenation and iteration nodes, it's
 * much faster to check all the substrings against the child DFAs before we
 * recurse.)  Also, caller must have cleared subexpression match data via
 * zaptreesubs (or zapallsubs at the top level).
 ^ static int cdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
cdissect(
    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);
	er = REG_OKAY;		/* no action, parent did the work */
	break;
    case 'b':			/* back reference */
	assert(t->left == NULL && t->right == NULL);
	er = cbrdissect(v, t, begin, end);
	break;
    case '.':			/* concatenation */
	assert(t->left != NULL && t->right != NULL);
	if (t->left->flags & SHORTER) /* reverse scan */
	    er = crevcondissect(v, t, begin, end);
	else
	    er = ccondissect(v, t, begin, end);
	break;
    case '|':			/* alternation */
	assert(t->left != NULL);
	er = caltdissect(v, t, begin, end);
	break;
    case '*':			/* iteration */
	assert(t->left != NULL);
	if (t->left->flags & SHORTER) /* reverse scan */
	    er = creviterdissect(v, t, begin, end);
	else
	    er = citerdissect(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);
	}
	break;
    default:
	er = REG_ASSERT;
	break;
    }

    /*
     * We should never have a match failure unless backrefs lurk below;
     * otherwise, either caller failed to check the DFA, or there's some
     * inconsistency between the DFA and the node's innards.
     */
    assert(er != REG_NOMATCH || (t->flags & BACKR));

    return er;
}
예제 #12
0
파일: regexec.c 프로젝트: 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;
}
예제 #13
0
파일: regexec.c 프로젝트: 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);
}
예제 #14
0
파일: regexec.c 프로젝트: dgsb/tcl
/*
 - complicatedReversedDissect - 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 complicatedReversedDissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
complicatedReversedDissect(
    struct vars *const v,
    struct subre *const t,
    chr *const begin,		/* beginning of relevant substring */
    chr *const end)		/* end of same */
{
    struct dfa *d, *d2;
    chr *mid;

    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, NULL, 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.
	 */

	if (longest(v, d2, mid, end, NULL) == end) {
	    int er = complicatedDissect(v, t->left, begin, mid);

	    if (er == REG_OKAY) {
		er = complicatedDissect(v, t->right, mid, end);
		if (er == REG_OKAY) {
		    /*
		     * Satisfaction.
		     */

		    MDEBUG(("successful\n"));
		    freeDFA(d);
		    freeDFA(d2);
		    return REG_OKAY;
		}
	    }
	    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, NULL, 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;
	zapSubtree(v, t->left);
	zapSubtree(v, t->right);
    }
}
예제 #15
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;
}
예제 #16
0
파일: regexec.c 프로젝트: samuelan/postgres
/*
 * ccondissect - dissect match for concatenation node
 */
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);
	assert(!(t->left->flags & SHORTER));

	d = getsubdfa(v, t->left);
	NOERR();
	d2 = getsubdfa(v, t->right);
	NOERR();
	MDEBUG(("cconcat %d\n", t->id));

	/* pick a tentative midpoint */
	mid = longest(v, d, begin, end, (int *) NULL);
	if (mid == NULL)
		return REG_NOMATCH;
	MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));

	/* iterate until satisfaction or failure */
	for (;;)
	{
		/* try this midpoint on for size */
		if (longest(v, d2, mid, end, (int *) NULL) == end)
		{
			er = cdissect(v, t->left, begin, mid);
			if (er == REG_OKAY)
			{
				er = cdissect(v, t->right, mid, end);
				if (er == REG_OKAY)
				{
					/* satisfaction */
					MDEBUG(("successful\n"));
					return REG_OKAY;
				}
			}
			if (er != REG_NOMATCH)
				return er;
		}

		/* that midpoint didn't work, find a new one */
		if (mid == begin)
		{
			/* all possibilities exhausted */
			MDEBUG(("%d no midpoint\n", t->id));
			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->id));
			return REG_NOMATCH;
		}
		MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
		zaptreesubs(v, t->left);
		zaptreesubs(v, t->right);
	}

	/* can't get here */
	return REG_ASSERT;
}