/* - exec - match regular expression ^ int exec(regex_t *, const chr *, size_t, rm_detail_t *, ^ size_t, regmatch_t [], int); */ int exec( regex_t *re, const chr *string, size_t len, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags) { AllocVars(v); int st, backref; size_t n; size_t i; #define LOCALMAT 20 regmatch_t mat[LOCALMAT]; #define LOCALDFAS 40 struct dfa *subdfas[LOCALDFAS]; /* * Sanity checks. */ if (re == NULL || string == NULL || re->re_magic != REMAGIC) { FreeVars(v); return REG_INVARG; } if (re->re_csize != sizeof(chr)) { FreeVars(v); return REG_MIXED; } /* * Setup. */ v->re = re; v->g = (struct guts *)re->re_guts; if ((v->g->cflags®_EXPECT) && details == NULL) { FreeVars(v); return REG_INVARG; } if (v->g->info®_UIMPOSSIBLE) { FreeVars(v); return REG_NOMATCH; } backref = (v->g->info®_UBACKREF) ? 1 : 0; v->eflags = flags; if (v->g->cflags®_NOSUB) { nmatch = 0; /* override client */ } v->nmatch = nmatch; if (backref) { /* * Need work area. */ if (v->g->nsub + 1 <= LOCALMAT) { v->pmatch = mat; } else { v->pmatch = (regmatch_t *) MALLOC((v->g->nsub + 1) * sizeof(regmatch_t)); } if (v->pmatch == NULL) { FreeVars(v); return REG_ESPACE; } v->nmatch = v->g->nsub + 1; } else { v->pmatch = pmatch; } v->details = details; v->start = (chr *)string; v->stop = (chr *)string + len; v->err = 0; assert(v->g->ntree >= 0); n = (size_t) v->g->ntree; if (n <= LOCALDFAS) v->subdfas = subdfas; else v->subdfas = (struct dfa **) MALLOC(n * sizeof(struct dfa *)); if (v->subdfas == NULL) { if (v->pmatch != pmatch && v->pmatch != mat) FREE(v->pmatch); FreeVars(v); return REG_ESPACE; } for (i = 0; i < n; i++) v->subdfas[i] = NULL; /* * Do it. */ assert(v->g->tree != NULL); if (backref) { st = complicatedFind(v, &v->g->tree->cnfa, &v->g->cmap); } else { st = simpleFind(v, &v->g->tree->cnfa, &v->g->cmap); } /* * Copy (portion of) match vector over if necessary. */ if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) { zapallsubs(pmatch, nmatch); n = (nmatch < v->nmatch) ? nmatch : v->nmatch; memcpy((void*)(pmatch), (void*)(v->pmatch), n*sizeof(regmatch_t)); } /* * Clean up. */ if (v->pmatch != pmatch && v->pmatch != mat) { FREE(v->pmatch); } n = (size_t) v->g->ntree; for (i = 0; i < n; i++) { if (v->subdfas[i] != NULL) freeDFA(v->subdfas[i]); } if (v->subdfas != subdfas) FREE(v->subdfas); FreeVars(v); return st; }
/* - exec - match regular expression ^ int exec(regex_t *, const chr *, size_t, rm_detail_t *, ^ size_t, regmatch_t [], int); */ int exec( regex_t *re, const chr *string, size_t len, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags) { AllocVars(v); int st; size_t n; int backref; #define LOCALMAT 20 regmatch_t mat[LOCALMAT]; #define LOCALMEM 40 regoff_t mem[LOCALMEM]; /* * Sanity checks. */ if (re == NULL || string == NULL || re->re_magic != REMAGIC) { FreeVars(v); return REG_INVARG; } if (re->re_csize != sizeof(chr)) { FreeVars(v); return REG_MIXED; } /* * Setup. */ v->re = re; v->g = (struct guts *)re->re_guts; if ((v->g->cflags®_EXPECT) && details == NULL) { FreeVars(v); return REG_INVARG; } if (v->g->info®_UIMPOSSIBLE) { FreeVars(v); return REG_NOMATCH; } backref = (v->g->info®_UBACKREF) ? 1 : 0; v->eflags = flags; if (v->g->cflags®_NOSUB) { nmatch = 0; /* override client */ } v->nmatch = nmatch; if (backref) { /* * Need work area. */ if (v->g->nsub + 1 <= LOCALMAT) { v->pmatch = mat; } else { v->pmatch = (regmatch_t *) MALLOC((v->g->nsub + 1) * sizeof(regmatch_t)); } if (v->pmatch == NULL) { FreeVars(v); return REG_ESPACE; } v->nmatch = v->g->nsub + 1; } else { v->pmatch = pmatch; } v->details = details; v->start = (chr *)string; v->stop = (chr *)string + len; v->err = 0; if (backref) { /* * Need retry memory. */ assert(v->g->ntree >= 0); n = (size_t)v->g->ntree; if (n <= LOCALMEM) { v->mem = mem; } else { v->mem = (regoff_t *) MALLOC(n*sizeof(regoff_t)); } if (v->mem == NULL) { if (v->pmatch != pmatch && v->pmatch != mat) { FREE(v->pmatch); } FreeVars(v); return REG_ESPACE; } } else { v->mem = NULL; } /* * Do it. */ assert(v->g->tree != NULL); if (backref) { st = cfind(v, &v->g->tree->cnfa, &v->g->cmap); } else { st = find(v, &v->g->tree->cnfa, &v->g->cmap); } /* * Copy (portion of) match vector over if necessary. */ if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) { zapsubs(pmatch, nmatch); n = (nmatch < v->nmatch) ? nmatch : v->nmatch; memcpy(VS(pmatch), VS(v->pmatch), n*sizeof(regmatch_t)); } /* * Clean up. */ if (v->pmatch != pmatch && v->pmatch != mat) { FREE(v->pmatch); } if (v->mem != NULL && v->mem != mem) { FREE(v->mem); } FreeVars(v); return st; }