diff options
Diffstat (limited to 'usr.bin/awk/b.c')
-rw-r--r-- | usr.bin/awk/b.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/usr.bin/awk/b.c b/usr.bin/awk/b.c index 9c1e96f166b..03018c10012 100644 --- a/usr.bin/awk/b.c +++ b/usr.bin/awk/b.c @@ -1,4 +1,4 @@ -/* $OpenBSD: b.c,v 1.14 2007/09/02 15:19:31 deraadt Exp $ */ +/* $OpenBSD: b.c,v 1.15 2008/10/06 20:38:33 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -23,7 +23,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -/* lasciate ogne speranza, voi ch'entrate. */ +/* lasciate ogne speranza, voi ch'intrate. */ #define DEBUG @@ -45,10 +45,11 @@ THIS SOFTWARE. #define parent(v) (v)->nnext #define LEAF case CCL: case NCCL: case CHAR: case DOT: case FINAL: case ALL: +#define ELEAF case EMPTYRE: /* empty string in regexp */ #define UNARY case STAR: case PLUS: case QUEST: /* encoding in tree Nodes: - leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL): + leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL, EMPTYRE): left is index, right contains value or pointer to value unary (STAR, PLUS, QUEST): left is child, right is null binary (CAT, OR): left and right are children @@ -183,6 +184,7 @@ int makeinit(fa *f, int anchor) void penter(Node *p) /* set up parent pointers and leaf indices */ { switch (type(p)) { + ELEAF LEAF info(p) = poscnt; poscnt++; @@ -207,6 +209,7 @@ void penter(Node *p) /* set up parent pointers and leaf indices */ void freetr(Node *p) /* free parse tree */ { switch (type(p)) { + ELEAF LEAF xfree(p); break; @@ -310,7 +313,7 @@ char *cclenter(const char *argp) /* add a character class */ continue; } while (c < c2) { - if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1")) FATAL("out of space for character class [%.10s...] 2", p); *bp++ = ++c; i++; @@ -318,7 +321,7 @@ char *cclenter(const char *argp) /* add a character class */ continue; } } - if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2")) FATAL("out of space for character class [%.10s...] 3", p); *bp++ = c; i++; @@ -340,6 +343,7 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo int *p; switch (type(v)) { + ELEAF LEAF f->re[info(v)].ltype = type(v); f->re[info(v)].lval.np = right(v); @@ -376,11 +380,12 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo } int first(Node *p) /* collects initially active leaves of p into setvec */ - /* returns 1 if p matches empty string */ + /* returns 0 if p matches empty string */ { int b, lp; switch (type(p)) { + ELEAF LEAF lp = info(p); /* look for high-water mark of subscripts */ while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */ @@ -390,6 +395,10 @@ int first(Node *p) /* collects initially active leaves of p into setvec */ if (setvec == 0 || tmpset == 0) overflo("out of space in first()"); } + if (type(p) == EMPTYRE) { + setvec[lp] = 0; + return(0); + } if (setvec[lp] != 1) { setvec[lp] = 1; setcnt++; @@ -466,7 +475,7 @@ int match(fa *f, const char *p0) /* shortest match ? */ if (f->out[s]) return(1); do { - assert(*p < NCHARS); + /* assert(*p < NCHARS); */ if ((ns = f->gototab[s][*p]) != 0) s = ns; else @@ -497,7 +506,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */ do { if (f->out[s]) /* final state */ patlen = q-p; - assert(*q < NCHARS); + /* assert(*q < NCHARS); */ if ((ns = f->gototab[s][*q]) != 0) s = ns; else @@ -555,7 +564,7 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */ do { if (f->out[s]) /* final state */ patlen = q-p; - assert(*q < NCHARS); + /* assert(*q < NCHARS); */ if ((ns = f->gototab[s][*q]) != 0) s = ns; else @@ -602,9 +611,10 @@ Node *reparse(const char *p) /* parses regular expression pointed to by p */ lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */ rtok = relex(); /* GNU compatibility: an empty regexp matches anything */ - if (rtok == '\0') + if (rtok == '\0') { /* FATAL("empty regular expression"); previous */ - return(op2(ALL, NIL, NIL)); + return(op2(EMPTYRE, NIL, NIL)); + } np = regexp(); if (rtok != '\0') FATAL("syntax error in regular expression %s at %s", lastre, prestr); @@ -628,6 +638,9 @@ Node *primary(void) case ALL: rtok = relex(); return (unary(op2(ALL, NIL, NIL))); + case EMPTYRE: + rtok = relex(); + return (unary(op2(ALL, NIL, NIL))); case DOT: rtok = relex(); return (unary(op2(DOT, NIL, NIL))); @@ -667,7 +680,7 @@ Node *primary(void) Node *concat(Node *np) { switch (rtok) { - case CHAR: case DOT: case ALL: case CCL: case NCCL: case '$': case '(': + case CHAR: case DOT: case ALL: case EMPTYRE: case CCL: case NCCL: case '$': case '(': return (concat(op2(CAT, np, primary()))); } return (np); @@ -788,7 +801,7 @@ int relex(void) /* lexical analyzer for reparse */ else cflag = 0; n = 2 * strlen((const char *) prestr)+1; - if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1")) FATAL("out of space for reg expr %.10s...", lastre); for (; ; ) { if ((c = *prestr++) == '\\') { @@ -807,7 +820,7 @@ int relex(void) /* lexical analyzer for reparse */ prestr[2 + cc->cc_namelen] == ']') { prestr += cc->cc_namelen + 3; for (i = 0; i < NCHARS; i++) { - if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2")) FATAL("out of space for reg expr %.10s...", lastre); if (cc->cc_func(i)) { *bp++ = i; @@ -856,6 +869,7 @@ int cgoto(fa *f, int s, int c) if ((k == CHAR && c == ptoi(f->re[p[i]].lval.np)) || (k == DOT && c != 0 && c != HAT) || (k == ALL && c != 0) + || (k == EMPTYRE && c != 0) || (k == CCL && member(c, (char *) f->re[p[i]].lval.up)) || (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) { q = f->re[p[i]].lfollow; |