1*7dd7cddfSDavid du Colombier #include "grep.h" 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier /* 4*7dd7cddfSDavid du Colombier * incremental compiler. 5*7dd7cddfSDavid du Colombier * add the branch c to the 6*7dd7cddfSDavid du Colombier * state s. 7*7dd7cddfSDavid du Colombier */ 8*7dd7cddfSDavid du Colombier void 9*7dd7cddfSDavid du Colombier increment(State *s, int c) 10*7dd7cddfSDavid du Colombier { 11*7dd7cddfSDavid du Colombier int i; 12*7dd7cddfSDavid du Colombier State *t, **tt; 13*7dd7cddfSDavid du Colombier Re *re1, *re2; 14*7dd7cddfSDavid du Colombier 15*7dd7cddfSDavid du Colombier nfollow = 0; 16*7dd7cddfSDavid du Colombier gen++; 17*7dd7cddfSDavid du Colombier matched = 0; 18*7dd7cddfSDavid du Colombier for(i=0; i<s->count; i++) 19*7dd7cddfSDavid du Colombier fol1(s->re[i], c); 20*7dd7cddfSDavid du Colombier qsort(follow, nfollow, sizeof(*follow), fcmp); 21*7dd7cddfSDavid du Colombier for(tt=&state0; t = *tt;) { 22*7dd7cddfSDavid du Colombier if(t->count > nfollow) { 23*7dd7cddfSDavid du Colombier tt = &t->linkleft; 24*7dd7cddfSDavid du Colombier goto cont; 25*7dd7cddfSDavid du Colombier } 26*7dd7cddfSDavid du Colombier if(t->count < nfollow) { 27*7dd7cddfSDavid du Colombier tt = &t->linkright; 28*7dd7cddfSDavid du Colombier goto cont; 29*7dd7cddfSDavid du Colombier } 30*7dd7cddfSDavid du Colombier for(i=0; i<nfollow; i++) { 31*7dd7cddfSDavid du Colombier re1 = t->re[i]; 32*7dd7cddfSDavid du Colombier re2 = follow[i]; 33*7dd7cddfSDavid du Colombier if(re1 > re2) { 34*7dd7cddfSDavid du Colombier tt = &t->linkleft; 35*7dd7cddfSDavid du Colombier goto cont; 36*7dd7cddfSDavid du Colombier } 37*7dd7cddfSDavid du Colombier if(re1 < re2) { 38*7dd7cddfSDavid du Colombier tt = &t->linkright; 39*7dd7cddfSDavid du Colombier goto cont; 40*7dd7cddfSDavid du Colombier } 41*7dd7cddfSDavid du Colombier } 42*7dd7cddfSDavid du Colombier if(!!matched && !t->match) { 43*7dd7cddfSDavid du Colombier tt = &t->linkleft; 44*7dd7cddfSDavid du Colombier goto cont; 45*7dd7cddfSDavid du Colombier } 46*7dd7cddfSDavid du Colombier if(!matched && !!t->match) { 47*7dd7cddfSDavid du Colombier tt = &t->linkright; 48*7dd7cddfSDavid du Colombier goto cont; 49*7dd7cddfSDavid du Colombier } 50*7dd7cddfSDavid du Colombier s->next[c] = t; 51*7dd7cddfSDavid du Colombier return; 52*7dd7cddfSDavid du Colombier cont:; 53*7dd7cddfSDavid du Colombier } 54*7dd7cddfSDavid du Colombier 55*7dd7cddfSDavid du Colombier t = sal(nfollow); 56*7dd7cddfSDavid du Colombier *tt = t; 57*7dd7cddfSDavid du Colombier for(i=0; i<nfollow; i++) { 58*7dd7cddfSDavid du Colombier re1 = follow[i]; 59*7dd7cddfSDavid du Colombier t->re[i] = re1; 60*7dd7cddfSDavid du Colombier } 61*7dd7cddfSDavid du Colombier s->next[c] = t; 62*7dd7cddfSDavid du Colombier t->match = matched; 63*7dd7cddfSDavid du Colombier } 64*7dd7cddfSDavid du Colombier 65*7dd7cddfSDavid du Colombier int 66*7dd7cddfSDavid du Colombier fcmp(void *va, void *vb) 67*7dd7cddfSDavid du Colombier { 68*7dd7cddfSDavid du Colombier Re **aa, **bb; 69*7dd7cddfSDavid du Colombier Re *a, *b; 70*7dd7cddfSDavid du Colombier 71*7dd7cddfSDavid du Colombier aa = va; 72*7dd7cddfSDavid du Colombier bb = vb; 73*7dd7cddfSDavid du Colombier a = *aa; 74*7dd7cddfSDavid du Colombier b = *bb; 75*7dd7cddfSDavid du Colombier if(a > b) 76*7dd7cddfSDavid du Colombier return 1; 77*7dd7cddfSDavid du Colombier if(a < b) 78*7dd7cddfSDavid du Colombier return -1; 79*7dd7cddfSDavid du Colombier return 0; 80*7dd7cddfSDavid du Colombier } 81*7dd7cddfSDavid du Colombier 82*7dd7cddfSDavid du Colombier void 83*7dd7cddfSDavid du Colombier fol1(Re *r, int c) 84*7dd7cddfSDavid du Colombier { 85*7dd7cddfSDavid du Colombier Re *r1; 86*7dd7cddfSDavid du Colombier 87*7dd7cddfSDavid du Colombier loop: 88*7dd7cddfSDavid du Colombier if(r->gen == gen) 89*7dd7cddfSDavid du Colombier return; 90*7dd7cddfSDavid du Colombier if(nfollow >= maxfollow) 91*7dd7cddfSDavid du Colombier error("nfollow"); 92*7dd7cddfSDavid du Colombier r->gen = gen; 93*7dd7cddfSDavid du Colombier switch(r->type) { 94*7dd7cddfSDavid du Colombier default: 95*7dd7cddfSDavid du Colombier error("fol1"); 96*7dd7cddfSDavid du Colombier 97*7dd7cddfSDavid du Colombier case Tcase: 98*7dd7cddfSDavid du Colombier if(c >= 0 && c < 256) 99*7dd7cddfSDavid du Colombier if(r1 = r->cases[c]) 100*7dd7cddfSDavid du Colombier follow[nfollow++] = r1; 101*7dd7cddfSDavid du Colombier if(r = r->next) 102*7dd7cddfSDavid du Colombier goto loop; 103*7dd7cddfSDavid du Colombier break; 104*7dd7cddfSDavid du Colombier 105*7dd7cddfSDavid du Colombier case Talt: 106*7dd7cddfSDavid du Colombier case Tor: 107*7dd7cddfSDavid du Colombier fol1(r->alt, c); 108*7dd7cddfSDavid du Colombier r = r->next; 109*7dd7cddfSDavid du Colombier goto loop; 110*7dd7cddfSDavid du Colombier 111*7dd7cddfSDavid du Colombier case Tbegin: 112*7dd7cddfSDavid du Colombier if(c == '\n' || c == Cbegin) 113*7dd7cddfSDavid du Colombier follow[nfollow++] = r->next; 114*7dd7cddfSDavid du Colombier break; 115*7dd7cddfSDavid du Colombier 116*7dd7cddfSDavid du Colombier case Tend: 117*7dd7cddfSDavid du Colombier if(c == '\n') 118*7dd7cddfSDavid du Colombier matched = 1; 119*7dd7cddfSDavid du Colombier break; 120*7dd7cddfSDavid du Colombier 121*7dd7cddfSDavid du Colombier case Tclass: 122*7dd7cddfSDavid du Colombier if(c >= r->lo && c <= r->hi) 123*7dd7cddfSDavid du Colombier follow[nfollow++] = r->next; 124*7dd7cddfSDavid du Colombier break; 125*7dd7cddfSDavid du Colombier } 126*7dd7cddfSDavid du Colombier } 127*7dd7cddfSDavid du Colombier 128*7dd7cddfSDavid du Colombier Rune tab1[] = 129*7dd7cddfSDavid du Colombier { 130*7dd7cddfSDavid du Colombier 0x007f, 131*7dd7cddfSDavid du Colombier 0x07ff, 132*7dd7cddfSDavid du Colombier }; 133*7dd7cddfSDavid du Colombier Rune tab2[] = 134*7dd7cddfSDavid du Colombier { 135*7dd7cddfSDavid du Colombier 0x003f, 136*7dd7cddfSDavid du Colombier 0x0fff, 137*7dd7cddfSDavid du Colombier }; 138*7dd7cddfSDavid du Colombier 139*7dd7cddfSDavid du Colombier Re2 140*7dd7cddfSDavid du Colombier rclass(Rune p0, Rune p1) 141*7dd7cddfSDavid du Colombier { 142*7dd7cddfSDavid du Colombier char xc0[6], xc1[6]; 143*7dd7cddfSDavid du Colombier int i, n, m; 144*7dd7cddfSDavid du Colombier Re2 x; 145*7dd7cddfSDavid du Colombier 146*7dd7cddfSDavid du Colombier if(p0 > p1) 147*7dd7cddfSDavid du Colombier return re2char(0xff, 0xff); // no match 148*7dd7cddfSDavid du Colombier 149*7dd7cddfSDavid du Colombier /* 150*7dd7cddfSDavid du Colombier * bust range into same length 151*7dd7cddfSDavid du Colombier * character sequences 152*7dd7cddfSDavid du Colombier */ 153*7dd7cddfSDavid du Colombier for(i=0; i<nelem(tab1); i++) { 154*7dd7cddfSDavid du Colombier m = tab1[i]; 155*7dd7cddfSDavid du Colombier if(p0 <= m && p1 > m) 156*7dd7cddfSDavid du Colombier return re2or(rclass(p0, m), rclass(m+1, p1)); 157*7dd7cddfSDavid du Colombier } 158*7dd7cddfSDavid du Colombier 159*7dd7cddfSDavid du Colombier /* 160*7dd7cddfSDavid du Colombier * bust range into part of a single page 161*7dd7cddfSDavid du Colombier * or into full pages 162*7dd7cddfSDavid du Colombier */ 163*7dd7cddfSDavid du Colombier for(i=0; i<nelem(tab2); i++) { 164*7dd7cddfSDavid du Colombier m = tab2[i]; 165*7dd7cddfSDavid du Colombier if((p0 & ~m) != (p1 & ~m)) { 166*7dd7cddfSDavid du Colombier if((p0 & m) != 0) 167*7dd7cddfSDavid du Colombier return re2or(rclass(p0, p0|m), rclass((p0|m)+1, p1)); 168*7dd7cddfSDavid du Colombier if((p1 & m) != m) 169*7dd7cddfSDavid du Colombier return re2or(rclass(p0, (p1&~m)-1), rclass(p1&~m, p1)); 170*7dd7cddfSDavid du Colombier } 171*7dd7cddfSDavid du Colombier } 172*7dd7cddfSDavid du Colombier 173*7dd7cddfSDavid du Colombier n = runetochar(xc0, &p0); 174*7dd7cddfSDavid du Colombier i = runetochar(xc1, &p1); 175*7dd7cddfSDavid du Colombier if(i != n) 176*7dd7cddfSDavid du Colombier error("length"); 177*7dd7cddfSDavid du Colombier 178*7dd7cddfSDavid du Colombier x = re2char(xc0[0], xc1[0]); 179*7dd7cddfSDavid du Colombier for(i=1; i<n; i++) 180*7dd7cddfSDavid du Colombier x = re2cat(x, re2char(xc0[i], xc1[i])); 181*7dd7cddfSDavid du Colombier return x; 182*7dd7cddfSDavid du Colombier } 183*7dd7cddfSDavid du Colombier 184*7dd7cddfSDavid du Colombier int 185*7dd7cddfSDavid du Colombier pcmp(void *va, void *vb) 186*7dd7cddfSDavid du Colombier { 187*7dd7cddfSDavid du Colombier int n; 188*7dd7cddfSDavid du Colombier Rune *a, *b; 189*7dd7cddfSDavid du Colombier 190*7dd7cddfSDavid du Colombier a = va; 191*7dd7cddfSDavid du Colombier b = vb; 192*7dd7cddfSDavid du Colombier 193*7dd7cddfSDavid du Colombier n = a[0] - b[0]; 194*7dd7cddfSDavid du Colombier if(n) 195*7dd7cddfSDavid du Colombier return n; 196*7dd7cddfSDavid du Colombier return a[1] - b[1]; 197*7dd7cddfSDavid du Colombier } 198*7dd7cddfSDavid du Colombier 199*7dd7cddfSDavid du Colombier /* 200*7dd7cddfSDavid du Colombier * convert character chass into 201*7dd7cddfSDavid du Colombier * run-pair ranges of matches. 202*7dd7cddfSDavid du Colombier * this is 10646/utf specific and 203*7dd7cddfSDavid du Colombier * needs to be changed for some 204*7dd7cddfSDavid du Colombier * other input character set. 205*7dd7cddfSDavid du Colombier * this is the key to a fast 206*7dd7cddfSDavid du Colombier * regular search of characters 207*7dd7cddfSDavid du Colombier * by looking at sequential bytes. 208*7dd7cddfSDavid du Colombier */ 209*7dd7cddfSDavid du Colombier Re2 210*7dd7cddfSDavid du Colombier re2class(char *s) 211*7dd7cddfSDavid du Colombier { 212*7dd7cddfSDavid du Colombier Rune pairs[200], *p, *q, ov; 213*7dd7cddfSDavid du Colombier int nc; 214*7dd7cddfSDavid du Colombier Re2 x; 215*7dd7cddfSDavid du Colombier 216*7dd7cddfSDavid du Colombier nc = 0; 217*7dd7cddfSDavid du Colombier if(*s == '^') { 218*7dd7cddfSDavid du Colombier nc = 1; 219*7dd7cddfSDavid du Colombier s++; 220*7dd7cddfSDavid du Colombier } 221*7dd7cddfSDavid du Colombier 222*7dd7cddfSDavid du Colombier p = pairs; 223*7dd7cddfSDavid du Colombier s += chartorune(p, s); 224*7dd7cddfSDavid du Colombier for(;;) { 225*7dd7cddfSDavid du Colombier if(*p == '\\') 226*7dd7cddfSDavid du Colombier s += chartorune(p, s); 227*7dd7cddfSDavid du Colombier if(*p == 0) 228*7dd7cddfSDavid du Colombier break; 229*7dd7cddfSDavid du Colombier p[1] = *p; 230*7dd7cddfSDavid du Colombier p += 2; 231*7dd7cddfSDavid du Colombier s += chartorune(p, s); 232*7dd7cddfSDavid du Colombier if(*p != '-') 233*7dd7cddfSDavid du Colombier continue; 234*7dd7cddfSDavid du Colombier s += chartorune(p, s); 235*7dd7cddfSDavid du Colombier if(*p == '\\') 236*7dd7cddfSDavid du Colombier s += chartorune(p, s); 237*7dd7cddfSDavid du Colombier if(*p == 0) 238*7dd7cddfSDavid du Colombier break; 239*7dd7cddfSDavid du Colombier p[-1] = *p; 240*7dd7cddfSDavid du Colombier s += chartorune(p, s); 241*7dd7cddfSDavid du Colombier } 242*7dd7cddfSDavid du Colombier *p = 0; 243*7dd7cddfSDavid du Colombier qsort(pairs, (p-pairs)/2, 2*sizeof(*pairs), pcmp); 244*7dd7cddfSDavid du Colombier 245*7dd7cddfSDavid du Colombier q = pairs; 246*7dd7cddfSDavid du Colombier for(p=pairs+2; *p; p+=2) { 247*7dd7cddfSDavid du Colombier if(p[0] > p[1]) 248*7dd7cddfSDavid du Colombier continue; 249*7dd7cddfSDavid du Colombier if(p[0] > q[1] || p[1] < q[0]) { 250*7dd7cddfSDavid du Colombier q[2] = p[0]; 251*7dd7cddfSDavid du Colombier q[3] = p[1]; 252*7dd7cddfSDavid du Colombier q += 2; 253*7dd7cddfSDavid du Colombier continue; 254*7dd7cddfSDavid du Colombier } 255*7dd7cddfSDavid du Colombier if(p[0] < q[0]) 256*7dd7cddfSDavid du Colombier q[0] = p[0]; 257*7dd7cddfSDavid du Colombier if(p[1] > q[1]) 258*7dd7cddfSDavid du Colombier q[1] = p[1]; 259*7dd7cddfSDavid du Colombier } 260*7dd7cddfSDavid du Colombier q[2] = 0; 261*7dd7cddfSDavid du Colombier 262*7dd7cddfSDavid du Colombier p = pairs; 263*7dd7cddfSDavid du Colombier if(nc) { 264*7dd7cddfSDavid du Colombier x = rclass(0, p[0]-1); 265*7dd7cddfSDavid du Colombier ov = p[1]+1; 266*7dd7cddfSDavid du Colombier for(p+=2; *p; p+=2) { 267*7dd7cddfSDavid du Colombier x = re2or(x, rclass(ov, p[0]-1)); 268*7dd7cddfSDavid du Colombier ov = p[1]+1; 269*7dd7cddfSDavid du Colombier } 270*7dd7cddfSDavid du Colombier x = re2or(x, rclass(ov, 0xffff)); 271*7dd7cddfSDavid du Colombier } else { 272*7dd7cddfSDavid du Colombier x = rclass(p[0], p[1]); 273*7dd7cddfSDavid du Colombier for(p+=2; *p; p+=2) 274*7dd7cddfSDavid du Colombier x = re2or(x, rclass(p[0], p[1])); 275*7dd7cddfSDavid du Colombier } 276*7dd7cddfSDavid du Colombier return x; 277*7dd7cddfSDavid du Colombier } 278