From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/cmd/grep/comp.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100755 sys/src/cmd/grep/comp.c (limited to 'sys/src/cmd/grep/comp.c') diff --git a/sys/src/cmd/grep/comp.c b/sys/src/cmd/grep/comp.c new file mode 100755 index 000000000..7f807e87c --- /dev/null +++ b/sys/src/cmd/grep/comp.c @@ -0,0 +1,285 @@ +#include "grep.h" + +/* + * incremental compiler. + * add the branch c to the + * state s. + */ +void +increment(State *s, int c) +{ + int i; + State *t, **tt; + Re *re1, *re2; + + nfollow = 0; + gen++; + matched = 0; + for(i=0; icount; i++) + fol1(s->re[i], c); + qsort(follow, nfollow, sizeof(*follow), fcmp); + for(tt=&state0; t = *tt;) { + if(t->count > nfollow) { + tt = &t->linkleft; + goto cont; + } + if(t->count < nfollow) { + tt = &t->linkright; + goto cont; + } + for(i=0; ire[i]; + re2 = follow[i]; + if(re1 > re2) { + tt = &t->linkleft; + goto cont; + } + if(re1 < re2) { + tt = &t->linkright; + goto cont; + } + } + if(!!matched && !t->match) { + tt = &t->linkleft; + goto cont; + } + if(!matched && !!t->match) { + tt = &t->linkright; + goto cont; + } + s->next[c] = t; + return; + cont:; + } + + t = sal(nfollow); + *tt = t; + for(i=0; ire[i] = re1; + } + s->next[c] = t; + t->match = matched; +} + +int +fcmp(void *va, void *vb) +{ + Re **aa, **bb; + Re *a, *b; + + aa = va; + bb = vb; + a = *aa; + b = *bb; + if(a > b) + return 1; + if(a < b) + return -1; + return 0; +} + +void +fol1(Re *r, int c) +{ + Re *r1; + +loop: + if(r->gen == gen) + return; + if(nfollow >= maxfollow) + error("nfollow"); + r->gen = gen; + switch(r->type) { + default: + error("fol1"); + + case Tcase: + if(c >= 0 && c < 256) + if(r1 = r->cases[c]) + follow[nfollow++] = r1; + if(r = r->next) + goto loop; + break; + + case Talt: + case Tor: + fol1(r->alt, c); + r = r->next; + goto loop; + + case Tbegin: + if(c == '\n' || c == Cbegin) + follow[nfollow++] = r->next; + break; + + case Tend: + if(c == '\n') { + if(r->next == 0) { + matched = 1; + break; + } + r = r->next; + goto loop; + } + break; + + case Tclass: + if(c >= r->lo && c <= r->hi) + follow[nfollow++] = r->next; + break; + } +} + +Rune tab1[] = +{ + 0x007f, + 0x07ff, +}; +Rune tab2[] = +{ + 0x003f, + 0x0fff, +}; + +Re2 +rclass(Rune p0, Rune p1) +{ + char xc0[6], xc1[6]; + int i, n, m; + Re2 x; + + if(p0 > p1) + return re2char(0xff, 0xff); // no match + + /* + * bust range into same length + * character sequences + */ + for(i=0; i m) + return re2or(rclass(p0, m), rclass(m+1, p1)); + } + + /* + * bust range into part of a single page + * or into full pages + */ + for(i=0; i= pairs + nelem(pairs) - 2) + error("class too big"); + s += chartorune(p, s); + if(*p != '-') + continue; + s += chartorune(p, s); + if(*p == '\\') + s += chartorune(p, s); + if(*p == 0) + break; + p[-1] = *p; + s += chartorune(p, s); + } + *p = 0; + qsort(pairs, (p-pairs)/2, 2*sizeof(*pairs), pcmp); + + q = pairs; + for(p=pairs+2; *p; p+=2) { + if(p[0] > p[1]) + continue; + if(p[0] > q[1] || p[1] < q[0]) { + q[2] = p[0]; + q[3] = p[1]; + q += 2; + continue; + } + if(p[0] < q[0]) + q[0] = p[0]; + if(p[1] > q[1]) + q[1] = p[1]; + } + q[2] = 0; + + p = pairs; + if(nc) { + x = rclass(0, p[0]-1); + ov = p[1]+1; + for(p+=2; *p; p+=2) { + x = re2or(x, rclass(ov, p[0]-1)); + ov = p[1]+1; + } + x = re2or(x, rclass(ov, 0xffff)); + } else { + x = rclass(p[0], p[1]); + for(p+=2; *p; p+=2) + x = re2or(x, rclass(p[0], p[1])); + } + return x; +} -- cgit v1.2.3