|
|
1.1 ! root 1: /*% cc -c -O % ! 2: */ ! 3: #include "vars.h" ! 4: #define ESIZE 128 /* ESIZE-1 must fit in a signed byte */ ! 5: char expbuf[ESIZE+4]; ! 6: int expgood /*0*/; /* flag indicating if compiled exp is good */ ! 7: #define CCHR 2 ! 8: #define CDOT 4 ! 9: #define CCL 6 ! 10: #define NCCL 8 ! 11: #define CFUNNY 10 ! 12: #define CALT 12 ! 13: #define CBACK 14 ! 14: ! 15: #define STAR 01 ! 16: #define STARABLE CBACK ! 17: ! 18: #define CKET 16 ! 19: #define CDOL 17 ! 20: #define CEOF 18 ! 21: #define CBRA 19 ! 22: #define CBOI 20 ! 23: #define CEOI 21 ! 24: #define CSPACE 22 ! 25: int circfl; ! 26: char pmagic[] = "/.$^*+\\()<|>{}[!_123456789"; ! 27: compile(eof) ! 28: char eof; ! 29: { ! 30: register c; ! 31: register char *ep, *penultep; ! 32: char *lastep, *bracketp, bracket[NBRA]; ! 33: int getsvc(); ! 34: int getchar(); ! 35: struct{ ! 36: char *althd; /* start of code for < ... > */ ! 37: char *altlast; /* start of code for last < or | */ ! 38: char *bpstart; /* bracketp at start of < and | */ ! 39: char *bpend; /* bracketp at end of > or | */ ! 40: int nbstart; /* nbra at start of < and | */ ! 41: int nbend; /* nbra at end of > or | */ ! 42: int firstalt; /* is this the first alternative? */ ! 43: } *asp, altstk[NBRA]; ! 44: ! 45: if(eof == '\n') ! 46: error('x'); ! 47: pmagic[0] = eof; ! 48: if ((c=nextchar()) == eof || c=='\n') { ! 49: if (!expgood) ! 50: goto cerror; ! 51: if(c!='\n') ! 52: getchar(); /* eat the eof character */ ! 53: return; ! 54: } ! 55: expgood = FALSE; ! 56: ep = expbuf; ! 57: lastep = 0; ! 58: bracketp = bracket; ! 59: nbra = 0; ! 60: asp = &altstk[-1]; ! 61: startstring(); /* for the saved pattern register */ ! 62: circfl = 0; ! 63: if (c=='^') { ! 64: getsvc(); /* save the caret */ ! 65: circfl++; ! 66: } ! 67: for (;;) { ! 68: c = getquote(pmagic, getsvc); ! 69: if (c==eof || c=='\n') { ! 70: if (bracketp!=bracket || asp>=altstk) ! 71: goto cerror; ! 72: *ep++ = CEOF; ! 73: expgood = TRUE; ! 74: dropstring(); /* lose the eof character */ ! 75: setstring(SAVPAT); ! 76: if(c=='\n') ! 77: ungetchar(c); ! 78: return; ! 79: } ! 80: if (ep >= &expbuf[ESIZE-5]) ! 81: goto cerror; ! 82: penultep = lastep; ! 83: lastep = ep; ! 84: ! 85: if(c != (eof|0200)) switch (c) { ! 86: case '('|0200: ! 87: if (nbra >= NBRA) ! 88: goto cerror; ! 89: *bracketp++ = nbra; ! 90: *ep++ = CBRA; ! 91: *ep++ = nbra++; ! 92: continue; ! 93: case ')'|0200: ! 94: if (bracketp <= bracket) ! 95: goto cerror; ! 96: *ep++ = CKET; ! 97: *ep++ = *--bracketp; ! 98: continue; ! 99: case '{'|0200: ! 100: *ep++ = CBOI; ! 101: continue; ! 102: case '}'|0200: ! 103: *ep++ = CEOI; ! 104: continue; ! 105: case '_'|0200: ! 106: *ep++ = CSPACE; ! 107: continue; ! 108: case '!'|0200: ! 109: *ep++ = CFUNNY; ! 110: continue; ! 111: case '<': ! 112: if (++asp >= &altstk[NBRA]) ! 113: goto cerror; ! 114: *ep++ = CALT; ! 115: asp->althd = ep; ! 116: ep++; ! 117: asp->bpstart = bracketp; ! 118: asp->nbstart = nbra; ! 119: asp->firstalt = TRUE; ! 120: asp->altlast = ep++; ! 121: lastep = 0; ! 122: continue; ! 123: case '|': ! 124: if (asp<altstk) ! 125: break; ! 126: if (asp->firstalt) { ! 127: asp->bpend = bracketp; ! 128: asp->nbend = nbra; ! 129: } ! 130: if (bracketp!=asp->bpend || nbra!=asp->nbend) ! 131: goto cerror; ! 132: *ep++ = CEOF; ! 133: asp->altlast[0] = ep-asp->altlast; ! 134: asp->firstalt = FALSE; ! 135: bracketp = asp->bpstart; ! 136: nbra = asp->nbstart; ! 137: asp->altlast = ep++; ! 138: lastep = 0; ! 139: continue; ! 140: case '>': ! 141: if (asp<altstk) ! 142: break; ! 143: if (!asp->firstalt && ! 144: (bracketp!=asp->bpend || nbra!=asp->nbend)) ! 145: goto cerror; ! 146: *ep++ = CEOF; ! 147: asp->altlast[0] = ep-asp->altlast; ! 148: lastep = asp->althd; ! 149: *lastep = ep-lastep; ! 150: lastep--; ! 151: if (bracketp!=asp->bpstart || nbra!=asp->nbstart) ! 152: lastep = 0; ! 153: asp--; ! 154: continue; ! 155: case '*': ! 156: case '+': ! 157: if (penultep==0){ ! 158: *ep++ = CCHR; ! 159: *ep++ = c; ! 160: } else { ! 161: if(*penultep>STARABLE) ! 162: goto cerror; ! 163: if(c == '+'){ ! 164: if((ep-penultep)+ep >= &expbuf[ESIZE-1]) ! 165: goto cerror; ! 166: do ! 167: *ep++ = *penultep++; ! 168: while (penultep!=lastep); ! 169: } ! 170: *penultep |= STAR; ! 171: lastep = 0; ! 172: } ! 173: continue; ! 174: case '.': ! 175: *ep++ = CDOT; ! 176: continue; ! 177: ! 178: case '[': ! 179: penultep = ep; ! 180: *ep++ = CCL; ! 181: *ep++ = 0; ! 182: if ((c=getsvc()) == '^') { ! 183: c = getsvc(); ! 184: ep[-2] = NCCL; ! 185: } ! 186: do { ! 187: if (c == EOF || c == '\n') ! 188: goto cerror; ! 189: *ep++ = c; ! 190: if ((lastc=getsvc()) == '-') { ! 191: c=getsvc(); ! 192: if (c == EOF || c == '\n' || c<=ep[-1]) ! 193: goto cerror; ! 194: ep[-1] |= 0200; ! 195: *ep++ = c; ! 196: lastc = getsvc(); /* prime lastc */ ! 197: } else if (dflag&&'a'<=(c|' ')&&(c|' ')<='z') ! 198: *ep++ = c^' '; ! 199: if (ep >= &expbuf[ESIZE-1]) ! 200: goto cerror; ! 201: } while ((c=lastc) != ']'); ! 202: penultep[1] = ep-penultep-1; ! 203: continue; ! 204: ! 205: ! 206: case '$': ! 207: if (nextchar() == eof || peekc=='\n') { ! 208: *ep++ = CDOL; ! 209: continue; ! 210: } ! 211: /* fall through */ ! 212: default: ! 213: break; ! 214: } ! 215: /* if fell through switch, match literal character */ ! 216: /* Goddamned sign extension! */ ! 217: if ((c&0200) && (c&0177)>='1' && (c&0177)<='9') { ! 218: *ep++ = CBACK; ! 219: *ep++ = c-('1'|0200); ! 220: continue; ! 221: } ! 222: c &= ~0200; ! 223: if(dflag && c|' '>='a' && c|' '<='z'){ ! 224: *ep++ = CCL; ! 225: *ep++ = 3; ! 226: *ep++ = c; ! 227: *ep++ = c^' '; ! 228: } ! 229: else{ ! 230: *ep++ = CCHR; ! 231: *ep++ = c; ! 232: } ! 233: } ! 234: cerror: ! 235: error('p'); ! 236: } ! 237: getsvc(){ ! 238: register c; ! 239: addstring(c=getchar()); ! 240: return(c); ! 241: } ! 242: int ! 243: execute(addr) ! 244: int *addr; ! 245: { ! 246: register char *p1, *p2; ! 247: ! 248: if (addr==0) { ! 249: if((p1=loc2) == 0) /* G command */ ! 250: p1 = linebuf; ! 251: else if (circfl) /* not first search in substitute */ ! 252: return(FALSE); ! 253: } else { ! 254: if (addr==zero) ! 255: return(FALSE); ! 256: p1 = getline(*addr, linebuf); ! 257: } ! 258: p2 = expbuf; ! 259: if (circfl) { ! 260: loc1 = p1; ! 261: return(advance(p1, p2)); ! 262: } ! 263: do { ! 264: if (*p2 != CCHR || p2[1] == *p1) { ! 265: if (advance(p1, p2)) { ! 266: loc1 = p1; ! 267: return(TRUE); ! 268: } ! 269: } ! 270: } while (*p1++); ! 271: return(FALSE); ! 272: } ! 273: ! 274: int ! 275: advance(lp, ep) ! 276: register char *lp, *ep; ! 277: { ! 278: register char *curlp; ! 279: char *althd, *altend; ! 280: ! 281: for (;;) { ! 282: curlp = lp; ! 283: switch (*ep++) { ! 284: ! 285: case CCHR: ! 286: if (*ep++ == *lp++) ! 287: continue; ! 288: return(FALSE); ! 289: ! 290: case CCHR|STAR: ! 291: do ; while (*lp++ == *ep); ! 292: ep++; ! 293: break; ! 294: ! 295: case CDOT: ! 296: if (*lp++) ! 297: continue; ! 298: return(FALSE); ! 299: ! 300: case CDOT|STAR: ! 301: do ; while (*lp++); ! 302: break; ! 303: ! 304: case CCL: ! 305: case NCCL: ! 306: if (cclass(ep, *lp++, ep[-1]==CCL)) { ! 307: ep += *ep; ! 308: continue; ! 309: } ! 310: return(FALSE); ! 311: ! 312: case CCL|STAR: ! 313: case NCCL|STAR: ! 314: do ; while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); ! 315: ep += *ep; ! 316: break; ! 317: ! 318: case CFUNNY: ! 319: if (*lp>=' ' && *lp!='\177' || *lp=='\t' || *lp=='\0') ! 320: return(FALSE); ! 321: lp++; ! 322: continue; ! 323: ! 324: case CFUNNY|STAR: ! 325: while (*lp<' ' && *lp && *lp!='\t' || *lp=='\177') ! 326: lp++; ! 327: lp++; ! 328: break; ! 329: ! 330: case CBACK: ! 331: if (braelist[*ep]==0) ! 332: error('p'); ! 333: if (backref(*ep++, lp)) { ! 334: lp += braelist[ep[-1]] - braslist[ep[-1]]; ! 335: continue; ! 336: } ! 337: return(FALSE); ! 338: ! 339: case CBACK|STAR: ! 340: if (braelist[*ep] == 0) ! 341: error('p'); ! 342: curlp = lp; ! 343: while (backref(*ep, lp)) ! 344: lp += braelist[*ep] - braslist[*ep]; ! 345: while (lp >= curlp) { ! 346: if (advance(lp, ep+1)) ! 347: return(TRUE); ! 348: lp -= braelist[*ep] - braslist[*ep]; ! 349: } ! 350: ep++; ! 351: continue; ! 352: ! 353: case CBRA: ! 354: braslist[*ep++] = lp; ! 355: continue; ! 356: ! 357: case CKET: ! 358: braelist[*ep++] = lp; ! 359: continue; ! 360: ! 361: case CDOL: ! 362: if (*lp==0) ! 363: continue; ! 364: return(FALSE); ! 365: ! 366: case CEOF: ! 367: loc2 = lp; ! 368: return(TRUE); ! 369: ! 370: case CBOI: ! 371: if (alfmatch(*lp,0) ! 372: && (lp==linebuf || !alfmatch(lp[-1],1))) ! 373: continue; ! 374: return(FALSE); ! 375: ! 376: case CEOI: ! 377: if (!alfmatch(*lp,1) ! 378: && lp!=linebuf && alfmatch(lp[-1],1)) ! 379: continue; ! 380: return(FALSE); ! 381: ! 382: case CSPACE: ! 383: if (*lp==' ' || *lp=='\t') { ! 384: while (*lp == ' ' || *lp=='\t') ! 385: lp++; ! 386: continue; ! 387: } ! 388: return(FALSE); ! 389: ! 390: case CALT: ! 391: althd = ep-1; ! 392: altend = ep + *ep; ! 393: for(ep++; ; ep+= *ep) { ! 394: if(ep == altend) ! 395: return(FALSE); ! 396: if(advance(lp,ep+1) && advance(loc2,altend)) ! 397: return(TRUE); ! 398: } ! 399: ! 400: case CALT|STAR: ! 401: althd = ep-1; ! 402: altend = ep + *ep; ! 403: for(ep++; ep!=altend; ep+= *ep){ ! 404: if(advance(lp, ep+1)){ ! 405: if(loc2 == lp) ! 406: break; ! 407: if(advance(loc2, althd)) ! 408: return(TRUE); ! 409: } ! 410: } ! 411: /* return (advance(lp,altend)) */ ! 412: continue; ! 413: ! 414: default: ! 415: error('!'); ! 416: } ! 417: /* star logic: executed by falling out of switch */ ! 418: do { ! 419: lp--; ! 420: if (advance(lp, ep)) ! 421: return(TRUE); ! 422: } while (lp > curlp); ! 423: return(FALSE); ! 424: } ! 425: } ! 426: ! 427: backref(i, lp) ! 428: register i; ! 429: register char *lp; ! 430: { ! 431: register char *bp; ! 432: ! 433: bp = braslist[i]; ! 434: while (*bp++ == *lp++) ! 435: if (bp >= braelist[i]) ! 436: return(TRUE); ! 437: return(FALSE); ! 438: } ! 439: int alfmatch(c,tail) ! 440: register char c; ! 441: { ! 442: return (('a' <= c && c <= 'z') || ! 443: ('A' <= c && c <= 'Z') || ! 444: (c == '_') || ! 445: (tail && '0' <= c && c<= '9')); ! 446: } ! 447: ! 448: ! 449: cclass(set, c, f) ! 450: register char *set; ! 451: register c; ! 452: { ! 453: register n; ! 454: if (c == 0) ! 455: return(0); ! 456: n = *set++; ! 457: while (--n) { ! 458: if (*set&0200) { ! 459: if ((*set++ & 0177) <= c) { ! 460: if (c <= *set++) ! 461: return(f); ! 462: } else ! 463: set++; ! 464: --n; ! 465: } else if (*set++ == c) ! 466: return(f); ! 467: } ! 468: return(!f); ! 469: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.