1*1348Sbill static char sccsid[] = "@(#)re.c 4.1 10/09/80"; 2*1348Sbill #include "head.h" 3*1348Sbill #define CBRA 1 4*1348Sbill #define CCHR 2 5*1348Sbill #define CDOT 4 6*1348Sbill #define CCL 6 7*1348Sbill #define NCCL 8 8*1348Sbill #define CDOL 10 9*1348Sbill #define CEOF 11 10*1348Sbill #define CKET 12 11*1348Sbill #define CBACK 18 12*1348Sbill 13*1348Sbill #define CSTAR 01 14*1348Sbill 15*1348Sbill #define LBSIZE 512 16*1348Sbill #define ESIZE 256 17*1348Sbill #define NBRA 9 18*1348Sbill 19*1348Sbill char expbuf[ESIZE]; 20*1348Sbill int circf; 21*1348Sbill char *braslist[NBRA]; 22*1348Sbill char *braelist[NBRA]; 23*1348Sbill char bittab[] = { 24*1348Sbill 1, 25*1348Sbill 2, 26*1348Sbill 4, 27*1348Sbill 8, 28*1348Sbill 16, 29*1348Sbill 32, 30*1348Sbill 64, 31*1348Sbill 128 32*1348Sbill }; 33*1348Sbill 34*1348Sbill dore() { 35*1348Sbill register int line; 36*1348Sbill register char *p; 37*1348Sbill 38*1348Sbill circf = 0; 39*1348Sbill line = fline; 40*1348Sbill compile(re); 41*1348Sbill do { 42*1348Sbill if (redir) fnext(); 43*1348Sbill else fprev(); 44*1348Sbill p = fbuf; 45*1348Sbill while(*p++ != '\n') 46*1348Sbill ; 47*1348Sbill *--p = '\0'; 48*1348Sbill if (match(fbuf)) goto l1; 49*1348Sbill } while (fline != line); 50*1348Sbill error("No match"); 51*1348Sbill l1: *p = '\n'; 52*1348Sbill fprint(); 53*1348Sbill } 54*1348Sbill 55*1348Sbill 56*1348Sbill compile(astr) 57*1348Sbill char *astr; 58*1348Sbill { 59*1348Sbill register c; 60*1348Sbill register char *ep, *sp; 61*1348Sbill char *cstart; 62*1348Sbill char *lastep; 63*1348Sbill int cclcnt; 64*1348Sbill char bracket[NBRA], *bracketp; 65*1348Sbill int closed; 66*1348Sbill char numbra; 67*1348Sbill char neg; 68*1348Sbill 69*1348Sbill ep = expbuf; 70*1348Sbill sp = astr; 71*1348Sbill lastep = 0; 72*1348Sbill bracketp = bracket; 73*1348Sbill closed = numbra = 0; 74*1348Sbill if (*sp == '^') { 75*1348Sbill circf++; 76*1348Sbill sp++; 77*1348Sbill } 78*1348Sbill for (;;) { 79*1348Sbill if (ep >= &expbuf[ESIZE]) 80*1348Sbill goto cerror; 81*1348Sbill if ((c = *sp++) != '*') 82*1348Sbill lastep = ep; 83*1348Sbill switch (c) { 84*1348Sbill 85*1348Sbill case '\0': 86*1348Sbill *ep++ = CEOF; 87*1348Sbill return; 88*1348Sbill 89*1348Sbill case '.': 90*1348Sbill *ep++ = CDOT; 91*1348Sbill continue; 92*1348Sbill 93*1348Sbill case '*': 94*1348Sbill if (lastep==0 || *lastep==CBRA || *lastep==CKET) 95*1348Sbill goto defchar; 96*1348Sbill *lastep |= CSTAR; 97*1348Sbill continue; 98*1348Sbill 99*1348Sbill case '$': 100*1348Sbill if (*sp != '\0') 101*1348Sbill goto defchar; 102*1348Sbill *ep++ = CDOL; 103*1348Sbill continue; 104*1348Sbill 105*1348Sbill case '[': 106*1348Sbill if(&ep[17] >= &expbuf[ESIZE]) 107*1348Sbill goto cerror; 108*1348Sbill *ep++ = CCL; 109*1348Sbill neg = 0; 110*1348Sbill if((c = *sp++) == '^') { 111*1348Sbill neg = 1; 112*1348Sbill c = *sp++; 113*1348Sbill } 114*1348Sbill cstart = sp; 115*1348Sbill do { 116*1348Sbill if (c=='\0') 117*1348Sbill goto cerror; 118*1348Sbill if (c=='-' && sp>cstart && *sp!=']') { 119*1348Sbill for (c = sp[-2]; c<*sp; c++) 120*1348Sbill ep[c>>3] |= bittab[c&07]; 121*1348Sbill sp++; 122*1348Sbill } 123*1348Sbill ep[c>>3] |= bittab[c&07]; 124*1348Sbill } while((c = *sp++) != ']'); 125*1348Sbill if(neg) { 126*1348Sbill for(cclcnt = 0; cclcnt < 16; cclcnt++) 127*1348Sbill ep[cclcnt] ^= -1; 128*1348Sbill ep[0] &= 0376; 129*1348Sbill } 130*1348Sbill 131*1348Sbill ep += 16; 132*1348Sbill 133*1348Sbill continue; 134*1348Sbill 135*1348Sbill case '\\': 136*1348Sbill if((c = *sp++) == '(') { 137*1348Sbill if(numbra >= NBRA) { 138*1348Sbill goto cerror; 139*1348Sbill } 140*1348Sbill *bracketp++ = numbra; 141*1348Sbill *ep++ = CBRA; 142*1348Sbill *ep++ = numbra++; 143*1348Sbill continue; 144*1348Sbill } 145*1348Sbill if(c == ')') { 146*1348Sbill if(bracketp <= bracket) { 147*1348Sbill goto cerror; 148*1348Sbill } 149*1348Sbill *ep++ = CKET; 150*1348Sbill *ep++ = *--bracketp; 151*1348Sbill closed++; 152*1348Sbill continue; 153*1348Sbill } 154*1348Sbill 155*1348Sbill if(c >= '1' && c <= '9') { 156*1348Sbill if((c -= '1') >= closed) 157*1348Sbill goto cerror; 158*1348Sbill *ep++ = CBACK; 159*1348Sbill *ep++ = c; 160*1348Sbill continue; 161*1348Sbill } 162*1348Sbill 163*1348Sbill defchar: 164*1348Sbill default: 165*1348Sbill *ep++ = CCHR; 166*1348Sbill *ep++ = c; 167*1348Sbill } 168*1348Sbill } 169*1348Sbill cerror: 170*1348Sbill errexit("RE error\n", (char *)NULL); 171*1348Sbill } 172*1348Sbill 173*1348Sbill match(p1) 174*1348Sbill register char *p1; { 175*1348Sbill register char *p2; 176*1348Sbill register c; 177*1348Sbill p2 = expbuf; 178*1348Sbill if (circf) { 179*1348Sbill if (advance(p1, p2)) 180*1348Sbill goto found; 181*1348Sbill goto nfound; 182*1348Sbill } 183*1348Sbill /* fast check for first character */ 184*1348Sbill if (*p2==CCHR) { 185*1348Sbill c = p2[1]; 186*1348Sbill do { 187*1348Sbill if (*p1!=c) 188*1348Sbill continue; 189*1348Sbill if (advance(p1, p2)) 190*1348Sbill goto found; 191*1348Sbill } while (*p1++); 192*1348Sbill goto nfound; 193*1348Sbill } 194*1348Sbill /* regular algorithm */ 195*1348Sbill do { 196*1348Sbill if (advance(p1, p2)) 197*1348Sbill goto found; 198*1348Sbill } while (*p1++); 199*1348Sbill nfound: 200*1348Sbill return(0); 201*1348Sbill found: 202*1348Sbill return(1); 203*1348Sbill } 204*1348Sbill 205*1348Sbill advance(lp, ep) 206*1348Sbill register char *lp, *ep; 207*1348Sbill { 208*1348Sbill register char *curlp; 209*1348Sbill char c; 210*1348Sbill char *bbeg; 211*1348Sbill int ct; 212*1348Sbill 213*1348Sbill for (;;) switch (*ep++) { 214*1348Sbill 215*1348Sbill case CCHR: 216*1348Sbill if (*ep++ == *lp++) 217*1348Sbill continue; 218*1348Sbill return(0); 219*1348Sbill 220*1348Sbill case CDOT: 221*1348Sbill if (*lp++) 222*1348Sbill continue; 223*1348Sbill return(0); 224*1348Sbill 225*1348Sbill case CDOL: 226*1348Sbill if (*lp=='\0') 227*1348Sbill continue; 228*1348Sbill return(0); 229*1348Sbill 230*1348Sbill case CEOF: 231*1348Sbill return(1); 232*1348Sbill 233*1348Sbill case CCL: 234*1348Sbill c = *lp++ & 0177; 235*1348Sbill if(ep[c>>3] & bittab[c & 07]) { 236*1348Sbill ep += 16; 237*1348Sbill continue; 238*1348Sbill } 239*1348Sbill return(0); 240*1348Sbill case CBRA: 241*1348Sbill braslist[*ep++] = lp; 242*1348Sbill continue; 243*1348Sbill 244*1348Sbill case CKET: 245*1348Sbill braelist[*ep++] = lp; 246*1348Sbill continue; 247*1348Sbill 248*1348Sbill case CBACK: 249*1348Sbill bbeg = braslist[*ep]; 250*1348Sbill if (braelist[*ep]==0) 251*1348Sbill return(0); 252*1348Sbill ct = braelist[*ep++] - bbeg; 253*1348Sbill if(ecmp(bbeg, lp, ct)) { 254*1348Sbill lp += ct; 255*1348Sbill continue; 256*1348Sbill } 257*1348Sbill return(0); 258*1348Sbill 259*1348Sbill case CBACK|CSTAR: 260*1348Sbill bbeg = braslist[*ep]; 261*1348Sbill if (braelist[*ep]==0) 262*1348Sbill return(0); 263*1348Sbill ct = braelist[*ep++] - bbeg; 264*1348Sbill curlp = lp; 265*1348Sbill while(ecmp(bbeg, lp, ct)) 266*1348Sbill lp += ct; 267*1348Sbill while(lp >= curlp) { 268*1348Sbill if(advance(lp, ep)) return(1); 269*1348Sbill lp -= ct; 270*1348Sbill } 271*1348Sbill return(0); 272*1348Sbill 273*1348Sbill 274*1348Sbill case CDOT|CSTAR: 275*1348Sbill curlp = lp; 276*1348Sbill while (*lp++); 277*1348Sbill goto star; 278*1348Sbill 279*1348Sbill case CCHR|CSTAR: 280*1348Sbill curlp = lp; 281*1348Sbill while (*lp++ == *ep); 282*1348Sbill ep++; 283*1348Sbill goto star; 284*1348Sbill 285*1348Sbill case CCL|CSTAR: 286*1348Sbill curlp = lp; 287*1348Sbill do { 288*1348Sbill c = *lp++ & 0177; 289*1348Sbill } while(ep[c>>3] & bittab[c & 07]); 290*1348Sbill ep += 16; 291*1348Sbill goto star; 292*1348Sbill 293*1348Sbill star: 294*1348Sbill if(--lp == curlp) { 295*1348Sbill continue; 296*1348Sbill } 297*1348Sbill 298*1348Sbill if(*ep == CCHR) { 299*1348Sbill c = ep[1]; 300*1348Sbill do { 301*1348Sbill if(*lp != c) 302*1348Sbill continue; 303*1348Sbill if(advance(lp, ep)) 304*1348Sbill return(1); 305*1348Sbill } while(lp-- > curlp); 306*1348Sbill return(0); 307*1348Sbill } 308*1348Sbill 309*1348Sbill do { 310*1348Sbill if (advance(lp, ep)) 311*1348Sbill return(1); 312*1348Sbill } while (lp-- > curlp); 313*1348Sbill return(0); 314*1348Sbill 315*1348Sbill default: 316*1348Sbill errexit("RE botch\n", (char *)NULL); 317*1348Sbill } 318*1348Sbill } 319*1348Sbill ecmp(a, b, count) 320*1348Sbill char *a, *b; 321*1348Sbill { 322*1348Sbill register cc = count; 323*1348Sbill while(cc--) 324*1348Sbill if(*a++ != *b++) return(0); 325*1348Sbill return(1); 326*1348Sbill } 327*1348Sbill 328*1348Sbill 329*1348Sbill errexit(s) 330*1348Sbill char *s; { 331*1348Sbill error(s); 332*1348Sbill return; 333*1348Sbill } 334