diff options
Diffstat (limited to 'src/backend/regex/engine.c')
-rw-r--r-- | src/backend/regex/engine.c | 1032 |
1 files changed, 516 insertions, 516 deletions
diff --git a/src/backend/regex/engine.c b/src/backend/regex/engine.c index 6e0e7012140..1d86dcc7bd9 100644 --- a/src/backend/regex/engine.c +++ b/src/backend/regex/engine.c @@ -71,43 +71,43 @@ struct match { struct re_guts *g; - int eflags; - regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ - char *offp; /* offsets work from here */ - char *beginp; /* start of string -- virtual NUL precedes */ - char *endp; /* end of string -- virtual NUL here */ - char *coldp; /* can be no match starting before here */ - char **lastpos; /* [nplus+1] */ - STATEVARS; - states st; /* current states */ - states fresh; /* states for a fresh start */ - states tmp; /* temporary */ - states empty; /* empty set of states */ + int eflags; + regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ + char *offp; /* offsets work from here */ + char *beginp; /* start of string -- virtual NUL precedes */ + char *endp; /* end of string -- virtual NUL here */ + char *coldp; /* can be no match starting before here */ + char **lastpos; /* [nplus+1] */ + STATEVARS; + states st; /* current states */ + states fresh; /* states for a fresh start */ + states tmp; /* temporary */ + states empty; /* empty set of states */ }; /* ========= begin header generated by ./mkh ========= */ #ifdef __cplusplus -extern "C" +extern "C" { #endif /* === engine.c === */ static int - matcher(struct re_guts * g, char *string, size_t nmatch, - regmatch_t pmatch[], int eflags); - static char * - dissect(struct match * m, char *start, char *stop, - sopno startst, sopno stopst); - static char * - backref(struct match * m, char *start, char *stop, + matcher(struct re_guts * g, char *string, size_t nmatch, + regmatch_t pmatch[], int eflags); + static char * + dissect(struct match * m, char *start, char *stop, + sopno startst, sopno stopst); + static char * + backref(struct match * m, char *start, char *stop, sopno startst, sopno stopst, sopno lev); - static char * - fast(struct match * m, char *start, char *stop, - sopno startst, sopno stopst); - static char * - slow(struct match * m, char *start, char *stop, sopno startst, sopno stopst); - static states - step(struct re_guts * g, sopno start, + static char * + fast(struct match * m, char *start, char *stop, + sopno startst, sopno stopst); + static char * + slow(struct match * m, char *start, char *stop, sopno startst, sopno stopst); + static states + step(struct re_guts * g, sopno start, sopno stop, states bef, int ch, states aft); #define BOL (OUT+1) #define EOL (BOL+1) @@ -120,16 +120,16 @@ extern "C" #define NNONCHAR (CODEMAX-CHAR_MAX) #ifdef REDEBUG static void - print(struct match * m, char *caption, states st, int ch, FILE * d); + print(struct match * m, char *caption, states st, int ch, FILE * d); #endif #ifdef REDEBUG static void - at(struct match * m, char *title, char *start, char *stop, - sopno startst, sopno stopst); + at(struct match * m, char *title, char *start, char *stop, + sopno startst, sopno stopst); #endif #ifdef REDEBUG - static char * - pchar(int ch); + static char * + pchar(int ch); #endif #ifdef __cplusplus @@ -156,20 +156,20 @@ extern "C" static int /* 0 success, REG_NOMATCH failure */ matcher(g, string, nmatch, pmatch, eflags) register struct re_guts *g; -char *string; -size_t nmatch; -regmatch_t pmatch[]; -int eflags; +char *string; +size_t nmatch; +regmatch_t pmatch[]; +int eflags; { - register char *endp; - register int i; - struct match mv; + register char *endp; + register int i; + struct match mv; register struct match *m = &mv; - register char *dp; + register char *dp; register const sopno gf = g->firststate + 1; /* +1 for OEND */ register const sopno gl = g->laststate; - char *start; - char *stop; + char *start; + char *stop; /* simplify the situation where possible */ if (g->cflags & REG_NOSUB) @@ -336,27 +336,27 @@ int eflags; == static char *dissect(register struct match *m, char *start, \ == char *stop, sopno startst, sopno stopst); */ -static char * /* == stop (success) always */ +static char * /* == stop (success) always */ dissect(m, start, stop, startst, stopst) register struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +char *start; +char *stop; +sopno startst; +sopno stopst; { - register int i; - register sopno ss; /* start sop of current subRE */ - register sopno es; /* end sop of current subRE */ - register char *sp; /* start of string matched by it */ - register char *stp; /* string matched by it cannot pass here */ - register char *rest; /* start of rest of string */ - register char *tail; /* string unmatched by rest of RE */ - register sopno ssub; /* start sop of subsubRE */ - register sopno esub; /* end sop of subsubRE */ - register char *ssp; /* start of string matched by subsubRE */ - register char *sep; /* end of string matched by subsubRE */ - register char *oldssp; /* previous ssp */ - register char *dp; + register int i; + register sopno ss; /* start sop of current subRE */ + register sopno es; /* end sop of current subRE */ + register char *sp; /* start of string matched by it */ + register char *stp; /* string matched by it cannot pass here */ + register char *rest; /* start of rest of string */ + register char *tail; /* string unmatched by rest of RE */ + register sopno ssub; /* start sop of subsubRE */ + register sopno esub; /* end sop of subsubRE */ + register char *ssp; /* start of string matched by subsubRE */ + register char *sep; /* end of string matched by subsubRE */ + register char *oldssp; /* previous ssp */ + register char *dp; AT("diss", start, stop, startst, stopst); sp = start; @@ -366,164 +366,164 @@ sopno stopst; es = ss; switch (OP(m->g->strip[es])) { - case OPLUS_: - case OQUEST_: - es += OPND(m->g->strip[es]); - break; - case OCH_: - while (OP(m->g->strip[es]) != O_CH) + case OPLUS_: + case OQUEST_: es += OPND(m->g->strip[es]); - break; + break; + case OCH_: + while (OP(m->g->strip[es]) != O_CH) + es += OPND(m->g->strip[es]); + break; } es++; /* figure out what it matched */ switch (OP(m->g->strip[ss])) { - case OEND: - assert(nope); - break; - case OCHAR: - sp++; - break; - case OBOL: - case OEOL: - case OBOW: - case OEOW: - break; - case OANY: - case OANYOF: - sp++; - break; - case OBACK_: - case O_BACK: - assert(nope); - break; - /* cases where length of match is hard to find */ - case OQUEST_: - stp = stop; - for (;;) - { - /* how long could this one be? */ - rest = slow(m, sp, stp, ss, es); - assert(rest != NULL); /* it did match */ - /* could the rest match the rest? */ - tail = slow(m, rest, stop, es, stopst); - if (tail == stop) - break; /* yes! */ - /* no -- try a shorter match for this one */ - stp = rest - 1; - assert(stp >= sp); /* it did work */ - } - ssub = ss + 1; - esub = es - 1; - /* did innards match? */ - if (slow(m, sp, rest, ssub, esub) != NULL) - { - dp = dissect(m, sp, rest, ssub, esub); - assert(dp == rest); - } - else + case OEND: + assert(nope); + break; + case OCHAR: + sp++; + break; + case OBOL: + case OEOL: + case OBOW: + case OEOW: + break; + case OANY: + case OANYOF: + sp++; + break; + case OBACK_: + case O_BACK: + assert(nope); + break; + /* cases where length of match is hard to find */ + case OQUEST_: + stp = stop; + for (;;) + { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + /* did innards match? */ + if (slow(m, sp, rest, ssub, esub) != NULL) + { + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + } + else /* no */ - assert(sp == rest); - sp = rest; - break; - case OPLUS_: - stp = stop; - for (;;) - { - /* how long could this one be? */ - rest = slow(m, sp, stp, ss, es); - assert(rest != NULL); /* it did match */ - /* could the rest match the rest? */ - tail = slow(m, rest, stop, es, stopst); - if (tail == stop) - break; /* yes! */ - /* no -- try a shorter match for this one */ - stp = rest - 1; - assert(stp >= sp); /* it did work */ - } - ssub = ss + 1; - esub = es - 1; - ssp = sp; - oldssp = ssp; - for (;;) - { /* find last match of innards */ - sep = slow(m, ssp, rest, ssub, esub); - if (sep == NULL || sep == ssp) - break; /* failed or matched null */ - oldssp = ssp; /* on to next try */ - ssp = sep; - } - if (sep == NULL) - { - /* last successful match */ - sep = ssp; - ssp = oldssp; - } - assert(sep == rest);/* must exhaust substring */ - assert(slow(m, ssp, sep, ssub, esub) == rest); - dp = dissect(m, ssp, sep, ssub, esub); - assert(dp == sep); - sp = rest; - break; - case OCH_: - stp = stop; - for (;;) - { - /* how long could this one be? */ - rest = slow(m, sp, stp, ss, es); - assert(rest != NULL); /* it did match */ - /* could the rest match the rest? */ - tail = slow(m, rest, stop, es, stopst); - if (tail == stop) - break; /* yes! */ - /* no -- try a shorter match for this one */ - stp = rest - 1; - assert(stp >= sp); /* it did work */ - } - ssub = ss + 1; - esub = ss + OPND(m->g->strip[ss]) - 1; - assert(OP(m->g->strip[esub]) == OOR1); - for (;;) - { /* find first matching branch */ - if (slow(m, sp, rest, ssub, esub) == rest) - break; /* it matched all of it */ - /* that one missed, try next one */ + assert(sp == rest); + sp = rest; + break; + case OPLUS_: + stp = stop; + for (;;) + { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + ssp = sp; + oldssp = ssp; + for (;;) + { /* find last match of innards */ + sep = slow(m, ssp, rest, ssub, esub); + if (sep == NULL || sep == ssp) + break; /* failed or matched null */ + oldssp = ssp; /* on to next try */ + ssp = sep; + } + if (sep == NULL) + { + /* last successful match */ + sep = ssp; + ssp = oldssp; + } + assert(sep == rest); /* must exhaust substring */ + assert(slow(m, ssp, sep, ssub, esub) == rest); + dp = dissect(m, ssp, sep, ssub, esub); + assert(dp == sep); + sp = rest; + break; + case OCH_: + stp = stop; + for (;;) + { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = ss + OPND(m->g->strip[ss]) - 1; assert(OP(m->g->strip[esub]) == OOR1); - esub++; - assert(OP(m->g->strip[esub]) == OOR2); - ssub = esub + 1; - esub += OPND(m->g->strip[esub]); - if (OP(m->g->strip[esub]) == OOR2) - esub--; - else - assert(OP(m->g->strip[esub]) == O_CH); - } - dp = dissect(m, sp, rest, ssub, esub); - assert(dp == rest); - sp = rest; - break; - case O_PLUS: - case O_QUEST: - case OOR1: - case OOR2: - case O_CH: - assert(nope); - break; - case OLPAREN: - i = OPND(m->g->strip[ss]); - assert(0 < i && i <= m->g->nsub); - m->pmatch[i].rm_so = sp - m->offp; - break; - case ORPAREN: - i = OPND(m->g->strip[ss]); - assert(0 < i && i <= m->g->nsub); - m->pmatch[i].rm_eo = sp - m->offp; - break; - default: /* uh oh */ - assert(nope); - break; + for (;;) + { /* find first matching branch */ + if (slow(m, sp, rest, ssub, esub) == rest) + break; /* it matched all of it */ + /* that one missed, try next one */ + assert(OP(m->g->strip[esub]) == OOR1); + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + sp = rest; + break; + case O_PLUS: + case O_QUEST: + case OOR1: + case OOR2: + case O_CH: + assert(nope); + break; + case OLPAREN: + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_so = sp - m->offp; + break; + case ORPAREN: + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_eo = sp - m->offp; + break; + default: /* uh oh */ + assert(nope); + break; } } @@ -536,27 +536,27 @@ sopno stopst; == static char *backref(register struct match *m, char *start, \ == char *stop, sopno startst, sopno stopst, sopno lev); */ -static char * /* == stop (success) or NULL (failure) */ +static char * /* == stop (success) or NULL (failure) */ backref(m, start, stop, startst, stopst, lev) register struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; -sopno lev; /* PLUS nesting level */ +char *start; +char *stop; +sopno startst; +sopno stopst; +sopno lev; /* PLUS nesting level */ { - register int i; - register sopno ss; /* start sop of current subRE */ - register char *sp; /* start of string matched by it */ - register sopno ssub; /* start sop of subsubRE */ - register sopno esub; /* end sop of subsubRE */ - register char *ssp; /* start of string matched by subsubRE */ - register char *dp; + register int i; + register sopno ss; /* start sop of current subRE */ + register char *sp; /* start of string matched by it */ + register sopno ssub; /* start sop of subsubRE */ + register sopno esub; /* end sop of subsubRE */ + register char *ssp; /* start of string matched by subsubRE */ + register char *dp; register size_t len; - register int hard; - register sop s; + register int hard; + register sop s; register regoff_t offsave; - register cset *cs; + register cset *cs; AT("back", start, stop, startst, stopst); sp = start; @@ -566,76 +566,76 @@ sopno lev; /* PLUS nesting level */ for (ss = startst; !hard && ss < stopst; ss++) switch (OP(s = m->g->strip[ss])) { - case OCHAR: - if (sp == stop || *sp++ != (char) OPND(s)) - return (NULL); - break; - case OANY: - if (sp == stop) - return (NULL); - sp++; - break; - case OANYOF: - cs = &m->g->sets[OPND(s)]; - if (sp == stop || !CHIN(cs, *sp++)) - return (NULL); - break; - case OBOL: - if ((sp == m->beginp && !(m->eflags & REG_NOTBOL)) || - (sp < m->endp && *(sp - 1) == '\n' && - (m->g->cflags & REG_NEWLINE))) - { /* yes */ - } - else - return (NULL); - break; - case OEOL: - if ((sp == m->endp && !(m->eflags & REG_NOTEOL)) || - (sp < m->endp && *sp == '\n' && - (m->g->cflags & REG_NEWLINE))) - { /* yes */ - } - else - return (NULL); - break; - case OBOW: - if (((sp == m->beginp && !(m->eflags & REG_NOTBOL)) || - (sp < m->endp && *(sp - 1) == '\n' && - (m->g->cflags & REG_NEWLINE)) || - (sp > m->beginp && - !ISWORD(*(sp - 1)))) && - (sp < m->endp && ISWORD(*sp))) - { /* yes */ - } - else - return (NULL); - break; - case OEOW: - if (((sp == m->endp && !(m->eflags & REG_NOTEOL)) || - (sp < m->endp && *sp == '\n' && - (m->g->cflags & REG_NEWLINE)) || - (sp < m->endp && !ISWORD(*sp))) && - (sp > m->beginp && ISWORD(*(sp - 1)))) - { /* yes */ - } - else - return (NULL); - break; - case O_QUEST: - break; - case OOR1: /* matches null but needs to skip */ - ss++; - s = m->g->strip[ss]; - do - { - assert(OP(s) == OOR2); - ss += OPND(s); - } while (OP(s = m->g->strip[ss]) != O_CH); - /* note that the ss++ gets us past the O_CH */ - break; - default: /* have to make a choice */ - hard = 1; - break; + case OCHAR: + if (sp == stop || *sp++ != (char) OPND(s)) + return (NULL); + break; + case OANY: + if (sp == stop) + return (NULL); + sp++; + break; + case OANYOF: + cs = &m->g->sets[OPND(s)]; + if (sp == stop || !CHIN(cs, *sp++)) + return (NULL); + break; + case OBOL: + if ((sp == m->beginp && !(m->eflags & REG_NOTBOL)) || + (sp < m->endp && *(sp - 1) == '\n' && + (m->g->cflags & REG_NEWLINE))) + { /* yes */ + } + else + return (NULL); + break; + case OEOL: + if ((sp == m->endp && !(m->eflags & REG_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags & REG_NEWLINE))) + { /* yes */ + } + else + return (NULL); + break; + case OBOW: + if (((sp == m->beginp && !(m->eflags & REG_NOTBOL)) || + (sp < m->endp && *(sp - 1) == '\n' && + (m->g->cflags & REG_NEWLINE)) || + (sp > m->beginp && + !ISWORD(*(sp - 1)))) && + (sp < m->endp && ISWORD(*sp))) + { /* yes */ + } + else + return (NULL); + break; + case OEOW: + if (((sp == m->endp && !(m->eflags & REG_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags & REG_NEWLINE)) || + (sp < m->endp && !ISWORD(*sp))) && + (sp > m->beginp && ISWORD(*(sp - 1)))) + { /* yes */ + } + else + return (NULL); + break; + case O_QUEST: + break; + case OOR1: /* matches null but needs to skip */ + ss++; + s = m->g->strip[ss]; + do + { + assert(OP(s) == OOR2); + ss += OPND(s); + } while (OP(s = m->g->strip[ss]) != O_CH); + /* note that the ss++ gets us past the O_CH */ + break; + default: /* have to make a choice */ + hard = 1; + break; } if (!hard) { /* that was it! */ @@ -650,93 +650,93 @@ sopno lev; /* PLUS nesting level */ s = m->g->strip[ss]; switch (OP(s)) { - case OBACK_: /* the vilest depths */ - i = OPND(s); - assert(0 < i && i <= m->g->nsub); - if (m->pmatch[i].rm_eo == -1) - return (NULL); - assert(m->pmatch[i].rm_so != -1); - len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; - assert(stop - m->beginp >= len); - if (sp > stop - len) - return (NULL); /* not enough left to match */ - ssp = m->offp + m->pmatch[i].rm_so; - if (memcmp(sp, ssp, len) != 0) + case OBACK_: /* the vilest depths */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + if (m->pmatch[i].rm_eo == -1) + return (NULL); + assert(m->pmatch[i].rm_so != -1); + len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; + assert(stop - m->beginp >= len); + if (sp > stop - len) + return (NULL); /* not enough left to match */ + ssp = m->offp + m->pmatch[i].rm_so; + if (memcmp(sp, ssp, len) != 0) + return (NULL); + while (m->g->strip[ss] != SOP(O_BACK, i)) + ss++; + return (backref(m, sp + len, stop, ss + 1, stopst, lev)); + break; + case OQUEST_: /* to null or not */ + dp = backref(m, sp, stop, ss + 1, stopst, lev); + if (dp != NULL) + return (dp); /* not */ + return (backref(m, sp, stop, ss + OPND(s) + 1, stopst, lev)); + break; + case OPLUS_: + assert(m->lastpos != NULL); + assert(lev + 1 <= m->g->nplus); + m->lastpos[lev + 1] = sp; + return (backref(m, sp, stop, ss + 1, stopst, lev + 1)); + break; + case O_PLUS: + if (sp == m->lastpos[lev]) /* last pass matched null */ + return (backref(m, sp, stop, ss + 1, stopst, lev - 1)); + /* try another pass */ + m->lastpos[lev] = sp; + dp = backref(m, sp, stop, ss - OPND(s) + 1, stopst, lev); + if (dp == NULL) + return (backref(m, sp, stop, ss + 1, stopst, lev - 1)); + else + return (dp); + break; + case OCH_: /* find the right one, if any */ + ssub = ss + 1; + esub = ss + OPND(s) - 1; + assert(OP(m->g->strip[esub]) == OOR1); + for (;;) + { /* find first matching branch */ + dp = backref(m, sp, stop, ssub, esub, lev); + if (dp != NULL) + return (dp); + /* that one missed, try next one */ + if (OP(m->g->strip[esub]) == O_CH) + return (NULL); /* there is none */ + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + break; + case OLPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + offsave = m->pmatch[i].rm_so; + m->pmatch[i].rm_so = sp - m->offp; + dp = backref(m, sp, stop, ss + 1, stopst, lev); + if (dp != NULL) + return (dp); + m->pmatch[i].rm_so = offsave; return (NULL); - while (m->g->strip[ss] != SOP(O_BACK, i)) - ss++; - return (backref(m, sp + len, stop, ss + 1, stopst, lev)); - break; - case OQUEST_: /* to null or not */ - dp = backref(m, sp, stop, ss + 1, stopst, lev); - if (dp != NULL) - return (dp); /* not */ - return (backref(m, sp, stop, ss + OPND(s) + 1, stopst, lev)); - break; - case OPLUS_: - assert(m->lastpos != NULL); - assert(lev + 1 <= m->g->nplus); - m->lastpos[lev + 1] = sp; - return (backref(m, sp, stop, ss + 1, stopst, lev + 1)); - break; - case O_PLUS: - if (sp == m->lastpos[lev]) /* last pass matched null */ - return (backref(m, sp, stop, ss + 1, stopst, lev - 1)); - /* try another pass */ - m->lastpos[lev] = sp; - dp = backref(m, sp, stop, ss - OPND(s) + 1, stopst, lev); - if (dp == NULL) - return (backref(m, sp, stop, ss + 1, stopst, lev - 1)); - else - return (dp); - break; - case OCH_: /* find the right one, if any */ - ssub = ss + 1; - esub = ss + OPND(s) - 1; - assert(OP(m->g->strip[esub]) == OOR1); - for (;;) - { /* find first matching branch */ - dp = backref(m, sp, stop, ssub, esub, lev); + break; + case ORPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + offsave = m->pmatch[i].rm_eo; + m->pmatch[i].rm_eo = sp - m->offp; + dp = backref(m, sp, stop, ss + 1, stopst, lev); if (dp != NULL) return (dp); - /* that one missed, try next one */ - if (OP(m->g->strip[esub]) == O_CH) - return (NULL); /* there is none */ - esub++; - assert(OP(m->g->strip[esub]) == OOR2); - ssub = esub + 1; - esub += OPND(m->g->strip[esub]); - if (OP(m->g->strip[esub]) == OOR2) - esub--; - else - assert(OP(m->g->strip[esub]) == O_CH); - } - break; - case OLPAREN: /* must undo assignment if rest fails */ - i = OPND(s); - assert(0 < i && i <= m->g->nsub); - offsave = m->pmatch[i].rm_so; - m->pmatch[i].rm_so = sp - m->offp; - dp = backref(m, sp, stop, ss + 1, stopst, lev); - if (dp != NULL) - return (dp); - m->pmatch[i].rm_so = offsave; - return (NULL); - break; - case ORPAREN: /* must undo assignment if rest fails */ - i = OPND(s); - assert(0 < i && i <= m->g->nsub); - offsave = m->pmatch[i].rm_eo; - m->pmatch[i].rm_eo = sp - m->offp; - dp = backref(m, sp, stop, ss + 1, stopst, lev); - if (dp != NULL) - return (dp); - m->pmatch[i].rm_eo = offsave; - return (NULL); - break; - default: /* uh oh */ - assert(nope); - break; + m->pmatch[i].rm_eo = offsave; + return (NULL); + break; + default: /* uh oh */ + assert(nope); + break; } /* "can't happen" */ @@ -750,23 +750,23 @@ sopno lev; /* PLUS nesting level */ == static char *fast(register struct match *m, char *start, \ == char *stop, sopno startst, sopno stopst); */ -static char * /* where tentative match ended, or NULL */ +static char * /* where tentative match ended, or NULL */ fast(m, start, stop, startst, stopst) register struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +char *start; +char *stop; +sopno startst; +sopno stopst; { register states st = m->st; register states fresh = m->fresh; register states tmp = m->tmp; - register char *p = start; - register int c = (start == m->beginp) ? OUT : *(start - 1); - register int lastc; /* previous c */ - register int flagch; - register int i; - register char *coldp; /* last p after which no match was + register char *p = start; + register int c = (start == m->beginp) ? OUT : *(start - 1); + register int lastc; /* previous c */ + register int flagch; + register int i; + register char *coldp; /* last p after which no match was * underway */ CLEAR(st); @@ -849,23 +849,23 @@ sopno stopst; == static char *slow(register struct match *m, char *start, \ == char *stop, sopno startst, sopno stopst); */ -static char * /* where it ended */ +static char * /* where it ended */ slow(m, start, stop, startst, stopst) register struct match *m; -char *start; -char *stop; -sopno startst; -sopno stopst; +char *start; +char *stop; +sopno startst; +sopno stopst; { register states st = m->st; register states empty = m->empty; register states tmp = m->tmp; - register char *p = start; - register int c = (start == m->beginp) ? OUT : *(start - 1); - register int lastc; /* previous c */ - register int flagch; - register int i; - register char *matchp; /* last p at which a match ended */ + register char *p = start; + register int c = (start == m->beginp) ? OUT : *(start - 1); + register int lastc; /* previous c */ + register int flagch; + register int i; + register char *matchp; /* last p at which a match ended */ AT("slow", start, stop, startst, stopst); CLEAR(st); @@ -952,119 +952,119 @@ sopno stopst; == #define NONCHAR(c) ((c) > CHAR_MAX) == #define NNONCHAR (CODEMAX-CHAR_MAX) */ -static states +static states step(g, start, stop, bef, ch, aft) register struct re_guts *g; -sopno start; /* start state within strip */ -sopno stop; /* state after stop state within strip */ +sopno start; /* start state within strip */ +sopno stop; /* state after stop state within strip */ register states bef; /* states reachable before */ -int ch; /* character or NONCHAR code */ +int ch; /* character or NONCHAR code */ register states aft; /* states already known reachable after */ { - register cset *cs; - register sop s; - register sopno pc; + register cset *cs; + register sop s; + register sopno pc; register onestate here; /* note, macros know this name */ - register sopno look; - register int i; + register sopno look; + register int i; for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { s = g->strip[pc]; switch (OP(s)) { - case OEND: - assert(pc == stop - 1); - break; - case OCHAR: - /* only characters can match */ - assert(!NONCHAR(ch) || ch != (char) OPND(s)); - if (ch == (char) OPND(s)) - FWD(aft, bef, 1); - break; - case OBOL: - if (ch == BOL || ch == BOLEOL) - FWD(aft, bef, 1); - break; - case OEOL: - if (ch == EOL || ch == BOLEOL) - FWD(aft, bef, 1); - break; - case OBOW: - if (ch == BOW) - FWD(aft, bef, 1); - break; - case OEOW: - if (ch == EOW) - FWD(aft, bef, 1); - break; - case OANY: - if (!NONCHAR(ch)) - FWD(aft, bef, 1); - break; - case OANYOF: - cs = &g->sets[OPND(s)]; - if (!NONCHAR(ch) && CHIN(cs, ch)) - FWD(aft, bef, 1); - break; - case OBACK_: /* ignored here */ - case O_BACK: - FWD(aft, aft, 1); - break; - case OPLUS_: /* forward, this is just an empty */ - FWD(aft, aft, 1); - break; - case O_PLUS: /* both forward and back */ - FWD(aft, aft, 1); - i = ISSETBACK(aft, OPND(s)); - BACK(aft, aft, OPND(s)); - if (!i && ISSETBACK(aft, OPND(s))) - { - /* oho, must reconsider loop body */ - pc -= OPND(s) + 1; - INIT(here, pc); - } - break; - case OQUEST_: /* two branches, both forward */ - FWD(aft, aft, 1); - FWD(aft, aft, OPND(s)); - break; - case O_QUEST: /* just an empty */ - FWD(aft, aft, 1); - break; - case OLPAREN: /* not significant here */ - case ORPAREN: - FWD(aft, aft, 1); - break; - case OCH_: /* mark the first two branches */ - FWD(aft, aft, 1); - assert(OP(g->strip[pc + OPND(s)]) == OOR2); - FWD(aft, aft, OPND(s)); - break; - case OOR1: /* done a branch, find the O_CH */ - if (ISSTATEIN(aft, here)) - { - for (look = 1; - OP(s = g->strip[pc + look]) != O_CH; - look += OPND(s)) - assert(OP(s) == OOR2); - FWD(aft, aft, look); - } - break; - case OOR2: /* propagate OCH_'s marking */ - FWD(aft, aft, 1); - if (OP(g->strip[pc + OPND(s)]) != O_CH) - { + case OEND: + assert(pc == stop - 1); + break; + case OCHAR: + /* only characters can match */ + assert(!NONCHAR(ch) || ch != (char) OPND(s)); + if (ch == (char) OPND(s)) + FWD(aft, bef, 1); + break; + case OBOL: + if (ch == BOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OEOL: + if (ch == EOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OBOW: + if (ch == BOW) + FWD(aft, bef, 1); + break; + case OEOW: + if (ch == EOW) + FWD(aft, bef, 1); + break; + case OANY: + if (!NONCHAR(ch)) + FWD(aft, bef, 1); + break; + case OANYOF: + cs = &g->sets[OPND(s)]; + if (!NONCHAR(ch) && CHIN(cs, ch)) + FWD(aft, bef, 1); + break; + case OBACK_: /* ignored here */ + case O_BACK: + FWD(aft, aft, 1); + break; + case OPLUS_: /* forward, this is just an empty */ + FWD(aft, aft, 1); + break; + case O_PLUS: /* both forward and back */ + FWD(aft, aft, 1); + i = ISSETBACK(aft, OPND(s)); + BACK(aft, aft, OPND(s)); + if (!i && ISSETBACK(aft, OPND(s))) + { + /* oho, must reconsider loop body */ + pc -= OPND(s) + 1; + INIT(here, pc); + } + break; + case OQUEST_: /* two branches, both forward */ + FWD(aft, aft, 1); + FWD(aft, aft, OPND(s)); + break; + case O_QUEST: /* just an empty */ + FWD(aft, aft, 1); + break; + case OLPAREN: /* not significant here */ + case ORPAREN: + FWD(aft, aft, 1); + break; + case OCH_: /* mark the first two branches */ + FWD(aft, aft, 1); assert(OP(g->strip[pc + OPND(s)]) == OOR2); FWD(aft, aft, OPND(s)); - } - break; - case O_CH: /* just empty */ - FWD(aft, aft, 1); - break; - default: /* ooooops... */ - assert(nope); - break; + break; + case OOR1: /* done a branch, find the O_CH */ + if (ISSTATEIN(aft, here)) + { + for (look = 1; + OP(s = g->strip[pc + look]) != O_CH; + look += OPND(s)) + assert(OP(s) == OOR2); + FWD(aft, aft, look); + } + break; + case OOR2: /* propagate OCH_'s marking */ + FWD(aft, aft, 1); + if (OP(g->strip[pc + OPND(s)]) != O_CH) + { + assert(OP(g->strip[pc + OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + } + break; + case O_CH: /* just empty */ + FWD(aft, aft, 1); + break; + default: /* ooooops... */ + assert(nope); + break; } } @@ -1081,15 +1081,15 @@ register states aft; /* states already known reachable after */ */ static void print(m, caption, st, ch, d) -struct match *m; -char *caption; -states st; -int ch; -FILE *d; +struct match *m; +char *caption; +states st; +int ch; +FILE *d; { register struct re_guts *g = m->g; - register int i; - register int first = 1; + register int i; + register int first = 1; if (!(m->eflags & REG_TRACE)) return; @@ -1115,12 +1115,12 @@ FILE *d; */ static void at(m, title, start, stop, startst, stopst) -struct match *m; -char *title; -char *start; -char *stop; -sopno startst; -sopno stopst; +struct match *m; +char *title; +char *start; +char *stop; +sopno startst; +sopno stopst; { if (!(m->eflags & REG_TRACE)) return; @@ -1143,11 +1143,11 @@ sopno stopst; * a matching debug.o, and this is convenient. It all disappears in * the non-debug compilation anyway, so it doesn't matter much. */ -static char * /* -> representation */ +static char * /* -> representation */ pchar(ch) -int ch; +int ch; { - static char pbuf[10]; + static char pbuf[10]; if (isprint(ch) || ch == ' ') sprintf(pbuf, "%c", ch); |