version 1.9, 1998/11/14 16:43:49 |
version 1.15, 2003/08/07 16:43:19 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c) 1992, 1993, 1994 Henry Spencer. |
|
* Copyright (c) 1992, 1993, 1994 |
* Copyright (c) 1992, 1993, 1994 |
* The Regents of the University of California. All rights reserved. |
* The Regents of the University of California. All rights reserved. |
* |
* |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
|
* 3. Neither the name of the University nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 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. |
|
* |
|
* @(#)engine.c 8.5 (Berkeley) 3/20/94 |
|
*/ |
|
|
|
/*- |
|
* Copyright (c) 1992, 1993, 1994 Henry Spencer. |
|
* |
|
* This code is derived from software contributed to Berkeley by |
|
* Henry Spencer. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* This product includes software developed by the University of |
|
|
#define print sprint |
#define print sprint |
#define at sat |
#define at sat |
#define match smat |
#define match smat |
|
#define nope snope |
#endif |
#endif |
#ifdef LNAMES |
#ifdef LNAMES |
#define matcher lmatcher |
#define matcher lmatcher |
|
|
#define print lprint |
#define print lprint |
#define at lat |
#define at lat |
#define match lmat |
#define match lmat |
|
#define nope lnope |
#endif |
#endif |
|
|
/* another structure passed up and down to avoid zillions of parameters */ |
/* another structure passed up and down to avoid zillions of parameters */ |
Line 126 static char *pchar __P((int ch)); |
|
Line 160 static char *pchar __P((int ch)); |
|
#define SP(t, s, c) print(m, t, s, c, stdout) |
#define SP(t, s, c) print(m, t, s, c, stdout) |
#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) |
#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) |
#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } |
#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } |
|
static int nope = 0; |
#else |
#else |
#define SP(t, s, c) /* nothing */ |
#define SP(t, s, c) /* nothing */ |
#define AT(t, p1, p2, s1, s2) /* nothing */ |
#define AT(t, p1, p2, s1, s2) /* nothing */ |
|
|
const sopno gl = g->laststate; |
const sopno gl = g->laststate; |
char *start; |
char *start; |
char *stop; |
char *stop; |
|
int error = 0; |
|
|
|
_DIAGASSERT(g != NULL); |
|
_DIAGASSERT(string != NULL); |
|
/* pmatch checked below */ |
|
|
/* simplify the situation where possible */ |
/* simplify the situation where possible */ |
if (g->cflags®_NOSUB) |
if (g->cflags®_NOSUB) |
nmatch = 0; |
nmatch = 0; |
if (eflags®_STARTEND) { |
if (eflags®_STARTEND) { |
|
_DIAGASSERT(pmatch != NULL); |
start = string + (size_t)pmatch[0].rm_so; |
start = string + (size_t)pmatch[0].rm_so; |
stop = string + (size_t)pmatch[0].rm_eo; |
stop = string + (size_t)pmatch[0].rm_eo; |
} else { |
} else { |
|
|
for (;;) { |
for (;;) { |
endp = fast(m, start, stop, gf, gl); |
endp = fast(m, start, stop, gf, gl); |
if (endp == NULL) { /* a miss */ |
if (endp == NULL) { /* a miss */ |
STATETEARDOWN(m); |
error = REG_NOMATCH; |
return(REG_NOMATCH); |
goto done; |
} |
} |
if (nmatch == 0 && !g->backrefs) |
if (nmatch == 0 && !g->backrefs) |
break; /* no further info needed */ |
break; /* no further info needed */ |
|
|
m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * |
m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * |
sizeof(regmatch_t)); |
sizeof(regmatch_t)); |
if (m->pmatch == NULL) { |
if (m->pmatch == NULL) { |
STATETEARDOWN(m); |
error = REG_ESPACE; |
return(REG_ESPACE); |
goto done; |
} |
} |
for (i = 1; i <= m->g->nsub; i++) |
for (i = 1; i <= m->g->nsub; i++) |
m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; |
m->pmatch[i].rm_so = m->pmatch[i].rm_eo = (regoff_t)-1; |
if (!g->backrefs && !(m->eflags®_BACKR)) { |
if (!g->backrefs && !(m->eflags®_BACKR)) { |
NOTE("dissecting"); |
NOTE("dissecting"); |
dp = dissect(m, m->coldp, endp, gf, gl); |
dp = dissect(m, m->coldp, endp, gf, gl); |
|
|
m->lastpos = (char **)malloc((g->nplus+1) * |
m->lastpos = (char **)malloc((g->nplus+1) * |
sizeof(char *)); |
sizeof(char *)); |
if (g->nplus > 0 && m->lastpos == NULL) { |
if (g->nplus > 0 && m->lastpos == NULL) { |
free(m->pmatch); |
error = REG_ESPACE; |
STATETEARDOWN(m); |
goto done; |
return(REG_ESPACE); |
|
} |
} |
NOTE("backref dissect"); |
NOTE("backref dissect"); |
dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); |
dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); |
|
|
/* try it on a shorter possibility */ |
/* try it on a shorter possibility */ |
#ifndef NDEBUG |
#ifndef NDEBUG |
for (i = 1; i <= m->g->nsub; i++) { |
for (i = 1; i <= m->g->nsub; i++) { |
assert(m->pmatch[i].rm_so == -1); |
assert(m->pmatch[i].rm_so == (regoff_t)-1); |
assert(m->pmatch[i].rm_eo == -1); |
assert(m->pmatch[i].rm_eo == (regoff_t)-1); |
} |
} |
#endif |
#endif |
NOTE("backoff dissect"); |
NOTE("backoff dissect"); |
|
|
|
|
/* fill in the details if requested */ |
/* fill in the details if requested */ |
if (nmatch > 0) { |
if (nmatch > 0) { |
|
_DIAGASSERT(pmatch != NULL); |
pmatch[0].rm_so = m->coldp - m->offp; |
pmatch[0].rm_so = m->coldp - m->offp; |
pmatch[0].rm_eo = endp - m->offp; |
pmatch[0].rm_eo = endp - m->offp; |
} |
} |
|
|
if (i <= m->g->nsub) |
if (i <= m->g->nsub) |
pmatch[i] = m->pmatch[i]; |
pmatch[i] = m->pmatch[i]; |
else { |
else { |
pmatch[i].rm_so = -1; |
pmatch[i].rm_so = (regoff_t)-1; |
pmatch[i].rm_eo = -1; |
pmatch[i].rm_eo = (regoff_t)-1; |
} |
} |
} |
} |
|
|
if (m->pmatch != NULL) |
done: |
|
if (m->pmatch != NULL) { |
free(m->pmatch); |
free(m->pmatch); |
if (m->lastpos != NULL) |
m->pmatch = NULL; |
|
} |
|
if (m->lastpos != NULL) { |
free(m->lastpos); |
free(m->lastpos); |
|
m->lastpos = NULL; |
|
} |
STATETEARDOWN(m); |
STATETEARDOWN(m); |
return(0); |
return error; |
} |
} |
|
|
/* |
/* |
|
|
char *dp; |
char *dp; |
#endif |
#endif |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
AT("diss", start, stop, startst, stopst); |
AT("diss", start, stop, startst, stopst); |
sp = start; |
sp = start; |
for (ss = startst; ss < stopst; ss = es) { |
for (ss = startst; ss < stopst; ss = es) { |
Line 530 sopno lev; /* PLUS nesting level */ |
|
Line 580 sopno lev; /* PLUS nesting level */ |
|
regoff_t offsave; |
regoff_t offsave; |
cset *cs; |
cset *cs; |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
AT("back", start, stop, startst, stopst); |
AT("back", start, stop, startst, stopst); |
sp = start; |
sp = start; |
|
|
Line 617 sopno lev; /* PLUS nesting level */ |
|
Line 671 sopno lev; /* PLUS nesting level */ |
|
case OBACK_: /* the vilest depths */ |
case OBACK_: /* the vilest depths */ |
i = OPND(s); |
i = OPND(s); |
assert(0 < i && i <= m->g->nsub); |
assert(0 < i && i <= m->g->nsub); |
if (m->pmatch[i].rm_eo == -1) |
if (m->pmatch[i].rm_eo == (regoff_t)-1) |
return(NULL); |
return(NULL); |
assert(m->pmatch[i].rm_so != -1); |
assert(m->pmatch[i].rm_so != (regoff_t)-1); |
len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so); |
len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so); |
assert(stop - m->beginp >= len); |
assert(stop - m->beginp >= len); |
if (sp > stop - len) |
if (sp > stop - len) |
|
|
int i; |
int i; |
char *coldp; /* last p after which no match was underway */ |
char *coldp; /* last p after which no match was underway */ |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
CLEAR(st); |
CLEAR(st); |
SET1(st, startst); |
SET1(st, startst); |
st = step(m->g, startst, stopst, st, NOTHING, st); |
st = step(m->g, startst, stopst, st, NOTHING, st); |
|
|
int i; |
int i; |
char *matchp; /* last p at which a match ended */ |
char *matchp; /* last p at which a match ended */ |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
AT("slow", start, stop, startst, stopst); |
AT("slow", start, stop, startst, stopst); |
CLEAR(st); |
CLEAR(st); |
SET1(st, startst); |
SET1(st, startst); |
Line 915 states aft; /* states already known rea |
|
Line 977 states aft; /* states already known rea |
|
sopno look; |
sopno look; |
int i; |
int i; |
|
|
|
_DIAGASSERT(g != NULL); |
|
|
for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { |
for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { |
s = g->strip[pc]; |
s = g->strip[pc]; |
switch (OP(s)) { |
switch (OP(s)) { |
|
|
int i; |
int i; |
int first = 1; |
int first = 1; |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(caption != NULL); |
|
|
if (!(m->eflags®_TRACE)) |
if (!(m->eflags®_TRACE)) |
return; |
return; |
|
|
|
_DIAGASSERT(d != NULL); |
|
|
fprintf(d, "%s", caption); |
fprintf(d, "%s", caption); |
if (ch != '\0') |
if (ch != '\0') |
fprintf(d, " %s", pchar(ch)); |
fprintf(d, " %s", pchar(ch)); |
|
|
sopno startst; |
sopno startst; |
sopno stopst; |
sopno stopst; |
{ |
{ |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(title != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
if (!(m->eflags®_TRACE)) |
if (!(m->eflags®_TRACE)) |
return; |
return; |
|
|
|
|
#undef print |
#undef print |
#undef at |
#undef at |
#undef match |
#undef match |
|
#undef nope |