summaryrefslogtreecommitdiffstats
path: root/generic/regexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/regexec.c')
-rw-r--r--generic/regexec.c1913
1 files changed, 865 insertions, 1048 deletions
diff --git a/generic/regexec.c b/generic/regexec.c
index 9b6a693..be459d3 100644
--- a/generic/regexec.c
+++ b/generic/regexec.c
@@ -2,20 +2,20 @@
* re_*exec and friends - match REs
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation of
- * software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation
+ * of software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -26,1198 +26,1015 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
*/
#include "regguts.h"
-/*
- * Lazy-DFA representation.
- */
+
+/* lazy-DFA representation */
struct arcp { /* "pointer" to an outarc */
- struct sset *ss;
- color co;
+ struct sset *ss;
+ color co;
};
struct sset { /* state set */
- unsigned *states; /* pointer to bitvector */
- unsigned hash; /* hash of bitvector */
-#define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
-#define HIT(h,bv,ss,nw) ((ss)->hash == (h) && ((nw) == 1 || \
- memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
- int flags;
-#define STARTER 01 /* the initial state set */
-#define POSTSTATE 02 /* includes the goal state */
-#define LOCKED 04 /* locked in cache */
-#define NOPROGRESS 010 /* zero-progress state set */
- struct arcp ins; /* chain of inarcs pointing here */
- chr *lastseen; /* last entered on arrival here */
- struct sset **outs; /* outarc vector indexed by color */
- struct arcp *inchain; /* chain-pointer vector for outarcs */
+ unsigned *states; /* pointer to bitvector */
+ unsigned hash; /* hash of bitvector */
+# define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
+# define HIT(h,bv,ss,nw) ((ss)->hash == (h) && ((nw) == 1 || \
+ memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
+ int flags;
+# define STARTER 01 /* the initial state set */
+# define POSTSTATE 02 /* includes the goal state */
+# define LOCKED 04 /* locked in cache */
+# define NOPROGRESS 010 /* zero-progress state set */
+ struct arcp ins; /* chain of inarcs pointing here */
+ chr *lastseen; /* last entered on arrival here */
+ struct sset **outs; /* outarc vector indexed by color */
+ struct arcp *inchain; /* chain-pointer vector for outarcs */
};
struct dfa {
- int nssets; /* size of cache */
- int nssused; /* how many entries occupied yet */
- int nstates; /* number of states */
- int ncolors; /* length of outarc and inchain vectors */
- int wordsper; /* length of state-set bitvectors */
- struct sset *ssets; /* state-set cache */
- unsigned *statesarea; /* bitvector storage */
- unsigned *work; /* pointer to work area within statesarea */
- struct sset **outsarea; /* outarc-vector storage */
- struct arcp *incarea; /* inchain storage */
- struct cnfa *cnfa;
- struct colormap *cm;
- chr *lastpost; /* location of last cache-flushed success */
- chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
- struct sset *search; /* replacement-search-pointer memory */
- int cptsmalloced; /* were the areas individually malloced? */
- char *mallocarea; /* self, or master malloced area, or NULL */
+ int nssets; /* size of cache */
+ int nssused; /* how many entries occupied yet */
+ int nstates; /* number of states */
+ int ncolors; /* length of outarc and inchain vectors */
+ int wordsper; /* length of state-set bitvectors */
+ struct sset *ssets; /* state-set cache */
+ unsigned *statesarea; /* bitvector storage */
+ unsigned *work; /* pointer to work area within statesarea */
+ struct sset **outsarea; /* outarc-vector storage */
+ struct arcp *incarea; /* inchain storage */
+ struct cnfa *cnfa;
+ struct colormap *cm;
+ chr *lastpost; /* location of last cache-flushed success */
+ chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
+ struct sset *search; /* replacement-search-pointer memory */
+ int cptsmalloced; /* were the areas individually malloced? */
+ char *mallocarea; /* self, or master malloced area, or NULL */
};
#define WORK 1 /* number of work bitvectors needed */
-/*
- * Setup for non-malloc allocation for small cases.
- */
-
+/* setup for non-malloc allocation for small cases */
#define FEWSTATES 20 /* must be less than UBITS */
#define FEWCOLORS 15
struct smalldfa {
- struct dfa dfa;
- struct sset ssets[FEWSTATES*2];
- unsigned statesarea[FEWSTATES*2 + WORK];
- struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
- struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
+ struct dfa dfa;
+ struct sset ssets[FEWSTATES*2];
+ unsigned statesarea[FEWSTATES*2 + WORK];
+ struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
+ struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
};
#define DOMALLOC ((struct smalldfa *)NULL) /* force malloc */
-/*
- * Internal variables, bundled for easy passing around.
- */
+
+/* internal variables, bundled for easy passing around */
struct vars {
- regex_t *re;
- struct guts *g;
- int eflags; /* copies of arguments */
- size_t nmatch;
- regmatch_t *pmatch;
- rm_detail_t *details;
- chr *start; /* start of string */
- chr *stop; /* just past end of string */
- int err; /* error code if any (0 none) */
- regoff_t *mem; /* memory vector for backtracking */
- struct smalldfa dfa1;
- struct smalldfa dfa2;
+ regex_t *re;
+ struct guts *g;
+ int eflags; /* copies of arguments */
+ size_t nmatch;
+ regmatch_t *pmatch;
+ rm_detail_t *details;
+ chr *start; /* start of string */
+ chr *stop; /* just past end of string */
+ int err; /* error code if any (0 none) */
+ regoff_t *mem; /* memory vector for backtracking */
+ struct smalldfa dfa1;
+ struct smalldfa dfa2;
};
-#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
+#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
#define ISERR() VISERR(v)
-#define VERR(vv,e) (((vv)->err) ? (vv)->err : ((vv)->err = (e)))
-#define ERR(e) VERR(v, e) /* record an error */
+#define VERR(vv,e) (((vv)->err) ? (vv)->err : ((vv)->err = (e)))
+#define ERR(e) VERR(v, e) /* record an error */
#define NOERR() {if (ISERR()) return v->err;} /* if error seen, return it */
#define OFF(p) ((p) - v->start)
#define LOFF(p) ((long)OFF(p))
-
+
+
+
/*
* forward declarations
*/
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regexec.c === */
-int exec(regex_t *, const chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
-static int simpleFind(struct vars *const, struct cnfa *const, struct colormap *const);
-static int complicatedFind(struct vars *const, struct cnfa *const, struct colormap *const);
-static int complicatedFindLoop(struct vars *const, struct cnfa *const, struct colormap *const, struct dfa *const, struct dfa *const, chr **const);
-static void zapSubexpressions(regmatch_t *const, const size_t);
-static void zapSubtree(struct vars *const, struct subre *const);
-static void subset(struct vars *const, struct subre *const, chr *const, chr *const);
-static int dissect(struct vars *const, struct subre *, chr *const, chr *const);
-static int concatenationDissect(struct vars *const, struct subre *const, chr *const, chr *const);
-static int alternationDissect(struct vars *const, struct subre *, chr *const, chr *const);
-static inline int complicatedDissect(struct vars *const, struct subre *const, chr *const, chr *const);
-static int complicatedCapturingDissect(struct vars *const, struct subre *const, chr *const, chr *const);
-static int complicatedConcatenationDissect(struct vars *const, struct subre *const, chr *const, chr *const);
-static int complicatedReversedDissect(struct vars *const, struct subre *const, chr *const, chr *const);
-static int complicatedBackrefDissect(struct vars *const, struct subre *const, chr *const, chr *const);
-static int complicatedAlternationDissect(struct vars *const, struct subre *, chr *const, chr *const);
+int exec _ANSI_ARGS_((regex_t *, CONST chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
+static int find _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
+static int cfind _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
+static int cfindloop _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **));
+static VOID zapsubs _ANSI_ARGS_((regmatch_t *, size_t));
+static VOID zapmem _ANSI_ARGS_((struct vars *, struct subre *));
+static VOID subset _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int dissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int condissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int altdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int cdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int ccondissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int crevdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int cbrdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+static int caltdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
/* === rege_dfa.c === */
-static chr *longest(struct vars *const, struct dfa *const, chr *const, chr *const, int *const);
-static chr *shortest(struct vars *const, struct dfa *const, chr *const, chr *const, chr *const, chr **const, int *const);
-static chr *lastCold(struct vars *const, struct dfa *const);
-static struct dfa *newDFA(struct vars *const, struct cnfa *const, struct colormap *const, struct smalldfa *);
-static void freeDFA(struct dfa *const);
-static unsigned hash(unsigned *const, const int);
-static struct sset *initialize(struct vars *const, struct dfa *const, chr *const);
-static struct sset *miss(struct vars *const, struct dfa *const, struct sset *const, const pcolor, chr *const, chr *const);
-static int checkLAConstraint(struct vars *const, struct cnfa *const, chr *const, const pcolor);
-static struct sset *getVacantSS(struct vars *const, struct dfa *const, chr *const, chr *const);
-static struct sset *pickNextSS(struct vars *const, struct dfa *const, chr *const, chr *const);
+static chr *longest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, int *));
+static chr *shortest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *));
+static chr *lastcold _ANSI_ARGS_((struct vars *, struct dfa *));
+static struct dfa *newdfa _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct smalldfa *));
+static VOID freedfa _ANSI_ARGS_((struct dfa *));
+static unsigned hash _ANSI_ARGS_((unsigned *, int));
+static struct sset *initialize _ANSI_ARGS_((struct vars *, struct dfa *, chr *));
+static struct sset *miss _ANSI_ARGS_((struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *));
+static int lacon _ANSI_ARGS_((struct vars *, struct cnfa *, chr *, pcolor));
+static struct sset *getvacant _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
+static struct sset *pickss _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
-
+
+
+
/*
- exec - match regular expression
- ^ int exec(regex_t *, const chr *, size_t, rm_detail_t *,
+ ^ 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)
+exec(re, string, len, details, nmatch, pmatch, flags)
+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;
-#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));
+ 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->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));
}
- if (v->mem == NULL) {
- if (v->pmatch != pmatch && v->pmatch != mat) {
+
+ /* clean up */
+ 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 = 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) {
- zapSubexpressions(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;
+ if (v->mem != NULL && v->mem != mem)
+ FREE(v->mem);
+ return st;
}
-
+
/*
- - simpleFind - find a match for the main NFA (no-complications case)
- ^ static int simpleFind(struct vars *, struct cnfa *, struct colormap *);
+ - find - find a match for the main NFA (no-complications case)
+ ^ static int find(struct vars *, struct cnfa *, struct colormap *);
*/
static int
-simpleFind(
- struct vars *const v,
- struct cnfa *const cnfa,
- struct colormap *const cm)
+find(v, cnfa, cm)
+struct vars *v;
+struct cnfa *cnfa;
+struct colormap *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);
- }
+ 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->start, v->start, v->stop, &cold, (int *)NULL);
+ freedfa(s);
NOERR();
- if (hitend && cold == NULL) {
- cold = begin;
+ 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 (end != NULL) {
- break; /* NOTE BREAK OUT */
+ 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);
+ 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 */
}
- v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
- }
- if (v->nmatch == 1) { /* no need for submatches */
- return REG_OKAY;
- }
-
- /*
- * Submatches.
- */
-
- zapSubexpressions(v->pmatch, v->nmatch);
- return dissect(v, v->g->tree, begin, end);
+ 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);
}
-
+
/*
- - complicatedFind - find a match for the main NFA (with complications)
- ^ static int complicatedFind(struct vars *, struct cnfa *, struct colormap *);
+ - cfind - find a match for the main NFA (with complications)
+ ^ static int cfind(struct vars *, struct cnfa *, struct colormap *);
*/
static int
-complicatedFind(
- struct vars *const v,
- struct cnfa *const cnfa,
- struct colormap *const cm)
+cfind(v, cnfa, cm)
+struct vars *v;
+struct cnfa *cnfa;
+struct colormap *cm;
{
- struct dfa *s, *d;
- chr *cold = NULL; /* silence gcc 4 warning */
- int ret;
-
- s = newDFA(v, &v->g->search, cm, &v->dfa1);
- NOERR();
- d = newDFA(v, cnfa, cm, &v->dfa2);
- if (ISERR()) {
- assert(d == NULL);
- freeDFA(s);
- return v->err;
- }
-
- ret = complicatedFindLoop(v, cnfa, cm, d, s, &cold);
-
- freeDFA(d);
- 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);
+ struct dfa *s;
+ struct dfa *d;
+ chr *cold = NULL; /* silence gcc 4 warning */
+ int ret;
+
+ s = newdfa(v, &v->g->search, cm, &v->dfa1);
+ NOERR();
+ d = newdfa(v, cnfa, cm, &v->dfa2);
+ if (ISERR()) {
+ assert(d == NULL);
+ freedfa(s);
+ return v->err;
}
- v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
- }
- return ret;
+
+ ret = cfindloop(v, cnfa, cm, d, s, &cold);
+
+ freedfa(d);
+ 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 */
+ }
+ return ret;
}
-
+
/*
- - complicatedFindLoop - the heart of complicatedFind
- ^ static int complicatedFindLoop(struct vars *, struct cnfa *, struct colormap *,
+ - cfindloop - the heart of cfind
+ ^ static int cfindloop(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 */
+cfindloop(v, cnfa, cm, d, s, coldp)
+struct vars *v;
+struct cnfa *cnfa;
+struct colormap *cm;
+struct dfa *d;
+struct dfa *s;
+chr **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;
+ 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;
- 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)));
- zapSubexpressions(v->pmatch, v->nmatch);
- zapSubtree(v, v->g->tree);
- er = complicatedDissect(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);
- return er;
- }
- if ((shorter) ? end == estop : end == begin) {
- /*
- * No point in trying again.
- */
-
- *coldp = cold;
- return REG_NOMATCH;
+ close = v->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);
+ 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);
- /*
- * Go around and try again
- */
-
- if (shorter) {
- estart = end + 1;
- } else {
- estop = end - 1;
- }
- }
- }
- } while (close < v->stop);
-
- *coldp = cold;
- return REG_NOMATCH;
+ *coldp = cold;
+ return REG_NOMATCH;
}
-
+
/*
- - zapSubexpressions - initialize the subexpression matches to "no match"
- ^ static void zapSubexpressions(regmatch_t *, size_t);
+ - zapsubs - initialize the subexpression matches to "no match"
+ ^ static VOID zapsubs(regmatch_t *, size_t);
*/
-static void
-zapSubexpressions(
- regmatch_t *const p,
- const size_t n)
+static VOID
+zapsubs(p, n)
+regmatch_t *p;
+size_t n;
{
- size_t i;
+ size_t i;
- for (i = n-1; i > 0; i--) {
- p[i].rm_so = -1;
- p[i].rm_eo = -1;
- }
+ for (i = n-1; i > 0; i--) {
+ p[i].rm_so = -1;
+ p[i].rm_eo = -1;
+ }
}
-
+
/*
- - zapSubtree - initialize the retry memory of a subtree to zeros
- ^ static void zapSubtree(struct vars *, struct subre *);
+ - zapmem - initialize the retry memory of a subtree to zeros
+ ^ static VOID zapmem(struct vars *, struct subre *);
*/
-static void
-zapSubtree(
- struct vars *const v,
- struct subre *const t)
+static VOID
+zapmem(v, t)
+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) {
- zapSubtree(v, t->left);
- }
- if (t->right != NULL) {
- zapSubtree(v, t->right);
- }
+ 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);
}
-
+
/*
- subset - set any subexpression relevant to a successful subre
- ^ static void subset(struct vars *, struct subre *, chr *, chr *);
+ ^ static VOID subset(struct vars *, struct subre *, chr *, chr *);
*/
-static void
-subset(
- struct vars *const v,
- struct subre *const sub,
- chr *const begin,
- chr *const end)
+static VOID
+subset(v, sub, begin, end)
+struct vars *v;
+struct subre *sub;
+chr *begin;
+chr *end;
{
- int n = sub->subno;
+ int n = sub->subno;
- assert(n > 0);
- if ((size_t)n >= v->nmatch) {
- return;
- }
+ assert(n > 0);
+ if ((size_t)n >= v->nmatch)
+ return;
- MDEBUG(("setting %d\n", n));
- v->pmatch[n].rm_so = OFF(begin);
- v->pmatch[n].rm_eo = OFF(end);
+ MDEBUG(("setting %d\n", n));
+ v->pmatch[n].rm_so = OFF(begin);
+ v->pmatch[n].rm_eo = OFF(end);
}
-
+
/*
- 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 */
+dissect(v, t, begin, end)
+struct vars *v;
+struct subre *t;
+chr *begin; /* beginning of relevant substring */
+chr *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;
- }
-}
-
-/*
- - concatenationDissect - determine concatenation subexpression matches
- - (uncomplicated)
- ^ static int concatenationDissect(struct vars *, struct subre *, chr *, chr *);
- */
-static int /* regexec return code */
-concatenationDissect(
- 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;
- 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, NULL, NULL);
- } else {
- mid = longest(v, d, begin, end, 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, 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, NULL, NULL);
- } else {
- mid = longest(v, d, begin, mid-1, NULL);
- }
- if (mid == NULL) {
- /*
- * Failed to find a new one!
- */
-
- MDEBUG(("failed midpoint!\n"));
- freeDFA(d);
- freeDFA(d2);
- return REG_ASSERT;
+ 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 */
+ break;
+ case '|': /* alternation */
+ assert(t->left != NULL);
+ return altdissect(v, t, begin, end);
+ break;
+ case 'b': /* back ref -- shouldn't be calling us! */
+ return REG_ASSERT;
+ break;
+ case '.': /* concatenation */
+ assert(t->left != NULL && t->right != NULL);
+ return condissect(v, t, begin, end);
+ break;
+ case '(': /* capturing */
+ assert(t->left != NULL && t->right == NULL);
+ assert(t->subno > 0);
+ subset(v, t, begin, end);
+ return dissect(v, t->left, begin, end);
+ break;
+ default:
+ return REG_ASSERT;
+ break;
}
- 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);
}
-
+
/*
- - alternationDissect - determine alternative subexpression matches (uncomplicated)
- ^ static int alternationDissect(struct vars *, struct subre *, chr *, chr *);
+ - condissect - determine concatenation subexpression matches (uncomplicated)
+ ^ static int condissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-alternationDissect(
- struct vars *const v,
- struct subre *t,
- chr *const begin, /* beginning of relevant substring */
- chr *const end) /* end of same */
+condissect(v, t, begin, end)
+struct vars *v;
+struct subre *t;
+chr *begin; /* beginning of relevant substring */
+chr *end; /* end of same */
{
- int i;
-
- assert(t != NULL);
- assert(t->op == '|');
-
- for (i = 0; t != NULL; t = t->right, i++) {
struct dfa *d;
+ struct dfa *d2;
+ chr *mid;
+ int i;
+ int shorter = (t->left->flags&SHORTER) ? 1 : 0;
+ chr *stop = (shorter) ? end : begin;
- MDEBUG(("trying %dth\n", i));
+ assert(t->op == '.');
assert(t->left != NULL && t->left->cnfa.nstates > 0);
- d = newDFA(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
+ 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()) {
- return v->err;
+ assert(d2 == NULL);
+ freedfa(d);
+ return v->err;
}
- if (longest(v, d, begin, end, NULL) == end) {
- MDEBUG(("success\n"));
- freeDFA(d);
- return dissect(v, t->left, begin, end);
+
+ /* 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)));
}
- freeDFA(d);
- }
- return REG_ASSERT; /* none of them matched?!? */
+
+ /* 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);
}
-
+
/*
- - 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 *);
+ - altdissect - determine alternative subexpression matches (uncomplicated)
+ ^ static int altdissect(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 */
+static int /* regexec return code */
+altdissect(v, t, begin, end)
+struct vars *v;
+struct subre *t;
+chr *begin; /* beginning of relevant substring */
+chr *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;
- }
+ struct dfa *d;
+ int i;
+
+ assert(t != NULL);
+ assert(t->op == '|');
+
+ for (i = 0; t != NULL; t = t->right, i++) {
+ MDEBUG(("trying %dth\n", i));
+ assert(t->left != NULL && t->left->cnfa.nstates > 0);
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
+ if (ISERR())
+ return v->err;
+ if (longest(v, d, begin, end, (int *)NULL) == end) {
+ MDEBUG(("success\n"));
+ freedfa(d);
+ return dissect(v, t->left, begin, end);
+ }
+ freedfa(d);
+ }
+ return REG_ASSERT; /* none of them matched?!? */
}
+/*
+ - 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 */
-complicatedCapturingDissect(
- struct vars *const v,
- struct subre *const t,
- chr *const begin, /* beginning of relevant substring */
- chr *const end) /* end of same */
+cdissect(v, t, begin, end)
+struct vars *v;
+struct subre *t;
+chr *begin; /* beginning of relevant substring */
+chr *end; /* end of same */
{
- int er = complicatedDissect(v, t->left, begin, end);
-
- if (er == REG_OKAY) {
- subset(v, t, begin, end);
- }
- return er;
+ 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;
+ }
}
-
+
/*
- - complicatedConcatenationDissect - 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 complicatedConcatenationDissect(struct vars *, struct subre *, chr *, chr *);
+ - 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 */
-complicatedConcatenationDissect(
- struct vars *const v,
- struct subre *const t,
- chr *const begin, /* beginning of relevant substring */
- chr *const end) /* end of same */
+ccondissect(v, t, begin, end)
+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);
-
- if (t->left->flags&SHORTER) { /* reverse scan */
- return complicatedReversedDissect(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;
+ 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(("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;
+ MDEBUG(("cconcat %d\n", t->retry));
+
+ /* pick a tentative midpoint */
+ if (v->mem[t->retry] == 0) {
+ mid = longest(v, d, begin, end, (int *)NULL);
+ if (mid == NULL) {
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
- }
- if ((er != REG_OKAY) && (er != REG_NOMATCH)) {
- freeDFA(d);
- freeDFA(d2);
- return er;
- }
+ 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)));
}
- /*
- * That midpoint didn't work, find a new one.
- */
-
- if (mid == begin) {
- /*
- * All possibilities exhausted.
- */
+ /* iterate until satisfaction or failure */
+ for (;;) {
+ /* try this midpoint on for size */
+ if (longest(v, d2, mid, end, 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"));
+ freedfa(d);
+ freedfa(d2);
+ return REG_OKAY;
+ }
+ }
+ if ((er != REG_OKAY) && (er != REG_NOMATCH)) {
+ freedfa(d);
+ freedfa(d2);
+ return er;
+ }
+ }
- 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;
+ /* 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, (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);
}
- 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);
- }
}
-
+
/*
- - 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 *);
+ - 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 crevdissect(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 */
+crevdissect(v, t, begin, end)
+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);
-
- /*
- * 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;
+ 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(("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;
+ 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;
}
- }
- if (er != REG_OKAY && er != REG_NOMATCH) {
- freeDFA(d);
- freeDFA(d2);
- return er;
- }
+ 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)));
}
- /*
- * That midpoint didn't work, find a new one.
- */
-
- if (mid == end) {
- /*
- * All possibilities exhausted.
- */
+ /* iterate until satisfaction or failure */
+ for (;;) {
+ /* try this midpoint on for size */
+ if (longest(v, d2, mid, end, 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"));
+ freedfa(d);
+ freedfa(d2);
+ return REG_OKAY;
+ }
+ }
+ if (er != REG_OKAY && er != REG_NOMATCH) {
+ freedfa(d);
+ freedfa(d2);
+ return er;
+ }
+ }
- 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;
+ /* 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);
}
- 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);
- }
}
-
+
/*
- - complicatedBackrefDissect - determine backref subexpression matches
- ^ static int complicatedBackrefDissect(struct vars *, struct subre *, chr *, chr *);
+ - cbrdissect - determine backref subexpression matches
+ ^ static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-complicatedBackrefDissect(
- struct vars *const v,
- struct subre *const t,
- chr *const begin, /* beginning of relevant substring */
- chr *const end) /* end of same */
+cbrdissect(v, t, begin, end)
+struct vars *v;
+struct subre *t;
+chr *begin; /* beginning of relevant substring */
+chr *end; /* end of same */
{
- int i, n = t->subno, min = t->min, max = t->max;
- chr *paren, *p, *stop;
- size_t len;
-
- assert(t != NULL);
- assert(t->op == 'b');
- assert(n >= 0);
- assert((size_t)n < v->nmatch);
-
- MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
-
- if (v->pmatch[n].rm_so == -1) {
- return REG_NOMATCH;
- }
- paren = v->start + v->pmatch[n].rm_so;
- len = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
-
- /*
- * No room to maneuver -- retries are pointless.
- */
-
- if (v->mem[t->retry]) {
- return REG_NOMATCH;
- }
- v->mem[t->retry] = 1;
-
- /*
- * Special-case zero-length string.
- */
-
- if (len == 0) {
- if (begin == end) {
- return REG_OKAY;
+ int i;
+ int n = t->subno;
+ size_t len;
+ chr *paren;
+ chr *p;
+ chr *stop;
+ int min = t->min;
+ int max = t->max;
+
+ assert(t != NULL);
+ assert(t->op == 'b');
+ assert(n >= 0);
+ assert((size_t)n < v->nmatch);
+
+ MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
+
+ if (v->pmatch[n].rm_so == -1)
+ return REG_NOMATCH;
+ paren = v->start + v->pmatch[n].rm_so;
+ len = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
+
+ /* no room to maneuver -- retries are pointless */
+ if (v->mem[t->retry])
+ return REG_NOMATCH;
+ v->mem[t->retry] = 1;
+
+ /* special-case zero-length string */
+ if (len == 0) {
+ if (begin == end)
+ return REG_OKAY;
+ return REG_NOMATCH;
}
- return REG_NOMATCH;
- }
-
- /*
- * And too-short string.
- */
-
- assert(end >= begin);
- if ((size_t)(end - begin) < len) {
- return REG_NOMATCH;
- }
- stop = end - len;
-
- /*
- * Count occurrences.
- */
- i = 0;
- for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
- if (v->g->compare(paren, p, len) != 0) {
- break;
+ /* and too-short string */
+ assert(end >= begin);
+ if ((size_t)(end - begin) < len)
+ return REG_NOMATCH;
+ stop = end - len;
+
+ /* count occurrences */
+ i = 0;
+ for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
+ if ((*v->g->compare)(paren, p, len) != 0)
+ break;
+ i++;
}
- i++;
- }
- MDEBUG(("cbackref found %d\n", i));
-
- /*
- * And sort it out.
- */
-
- if (p != end) { /* didn't consume all of it */
- return REG_NOMATCH;
- }
- if (min <= i && (i <= max || max == INFINITY)) {
- return REG_OKAY;
- }
- return REG_NOMATCH; /* out of range */
+ MDEBUG(("cbackref found %d\n", i));
+
+ /* and sort it out */
+ if (p != end) /* didn't consume all of it */
+ return REG_NOMATCH;
+ if (min <= i && (i <= max || max == INFINITY))
+ return REG_OKAY;
+ return REG_NOMATCH; /* out of range */
}
-
+
/*
- - complicatedAlternationDissect - determine alternative subexpression matches (w.
- - complications)
- ^ static int complicatedAlternationDissect(struct vars *, struct subre *, chr *, chr *);
+ - caltdissect - determine alternative subexpression matches (w. complications)
+ ^ static int caltdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-complicatedAlternationDissect(
- struct vars *const v,
- struct subre *t,
- chr *const begin, /* beginning of relevant substring */
- chr *const end) /* end of same */
+caltdissect(v, t, begin, end)
+struct vars *v;
+struct subre *t;
+chr *begin; /* beginning of relevant substring */
+chr *end; /* end of same */
{
- int er;
-#define UNTRIED 0 /* not yet tried at all */
-#define TRYING 1 /* top matched, trying submatches */
-#define TRIED 2 /* top didn't match or submatches exhausted */
-
-#ifndef COMPILER_DOES_TAILCALL_OPTIMIZATION
- if (0) {
- doRight:
- t = t->right;
- }
-#endif
- if (t == NULL) {
- return REG_NOMATCH;
- }
- assert(t->op == '|');
- if (v->mem[t->retry] == TRIED) {
- goto doRight;
- }
+ struct dfa *d;
+ int er;
+# define UNTRIED 0 /* not yet tried at all */
+# define TRYING 1 /* top matched, trying submatches */
+# define TRIED 2 /* top didn't match or submatches exhausted */
+
+ if (t == NULL)
+ return REG_NOMATCH;
+ assert(t->op == '|');
+ if (v->mem[t->retry] == TRIED)
+ return caltdissect(v, t->right, begin, end);
+
+ MDEBUG(("calt n%d\n", t->retry));
+ assert(t->left != NULL);
- MDEBUG(("cAlt n%d\n", t->retry));
- assert(t->left != NULL);
+ if (v->mem[t->retry] == UNTRIED) {
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR())
+ return v->err;
+ if (longest(v, d, begin, end, (int *)NULL) != end) {
+ freedfa(d);
+ v->mem[t->retry] = TRIED;
+ return caltdissect(v, t->right, begin, end);
+ }
+ freedfa(d);
+ MDEBUG(("calt matched\n"));
+ v->mem[t->retry] = TRYING;
+ }
- if (v->mem[t->retry] == UNTRIED) {
- struct dfa *d = newDFA(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
+ er = cdissect(v, t->left, begin, end);
+ if (er != REG_NOMATCH)
+ return er;
- if (ISERR()) {
- return v->err;
- }
- if (longest(v, d, begin, end, NULL) != end) {
- freeDFA(d);
- v->mem[t->retry] = TRIED;
- goto doRight;
- }
- freeDFA(d);
- MDEBUG(("cAlt matched\n"));
- v->mem[t->retry] = TRYING;
- }
-
- er = complicatedDissect(v, t->left, begin, end);
- if (er != REG_NOMATCH) {
- return er;
- }
-
- v->mem[t->retry] = TRIED;
-#ifndef COMPILER_DOES_TAILCALL_OPTIMIZATION
- goto doRight;
-#else
- doRight:
- return complicatedAlternationDissect(v, t->right, begin, end);
-#endif
+ v->mem[t->retry] = TRIED;
+ return caltdissect(v, t->right, begin, end);
}
+
+
#include "rege_dfa.c"
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */