1: #include <stdio.h> 2: #include "sed.h" 3: 4: char *trans[040] = { 5: "\\01", 6: "\\02", 7: "\\03", 8: "\\04", 9: "\\05", 10: "\\06", 11: "\\07", 12: "<-", 13: ">-", 14: "\n", 15: "\\13", 16: "\\14", 17: "\\15", 18: "\\16", 19: "\\17", 20: "\\20", 21: "\\21", 22: "\\22", 23: "\\23", 24: "\\24", 25: "\\25", 26: "\\26", 27: "\\27", 28: "\\30", 29: "\\31", 30: "\\32", 31: "\\33", 32: "\\34", 33: "\\35", 34: "\\36", 35: "\\37" 36: }; 37: char rub[] = {"\177"}; 38: 39: execute(file) 40: char *file; 41: { 42: register char *p1, *p2; 43: register union reptr *ipc; 44: int c; 45: char *execp; 46: 47: if (file) { 48: if ((f = open(file, 0)) < 0) { 49: fprintf(stderr, "Can't open %s\n", file); 50: } 51: } else 52: f = 0; 53: 54: ebp = ibuf; 55: cbp = ibuf; 56: 57: if(pending) { 58: ipc = pending; 59: pending = 0; 60: goto yes; 61: } 62: 63: for(;;) { 64: if((execp = gline(linebuf)) == badp) { 65: close(f); 66: return; 67: } 68: spend = execp; 69: 70: for(ipc = ptrspace; ipc->command; ) { 71: 72: p1 = ipc->ad1; 73: p2 = ipc->ad2; 74: 75: if(p1) { 76: 77: if(ipc->inar) { 78: if(*p2 == CEND) { 79: p1 = 0; 80: } else if(*p2 == CLNUM) { 81: c = p2[1]; 82: if(lnum > tlno[c]) { 83: ipc->inar = 0; 84: if(ipc->negfl) 85: goto yes; 86: ipc++; 87: continue; 88: } 89: if(lnum == tlno[c]) { 90: ipc->inar = 0; 91: } 92: } else if(match(p2, 0)) { 93: ipc->inar = 0; 94: } 95: } else if(*p1 == CEND) { 96: if(!dolflag) { 97: if(ipc->negfl) 98: goto yes; 99: ipc++; 100: continue; 101: } 102: 103: } else if(*p1 == CLNUM) { 104: c = p1[1]; 105: if(lnum != tlno[c]) { 106: if(ipc->negfl) 107: goto yes; 108: ipc++; 109: continue; 110: } 111: if(p2) 112: ipc->inar = 1; 113: } else if(match(p1, 0)) { 114: if(p2) 115: ipc->inar = 1; 116: } else { 117: if(ipc->negfl) 118: goto yes; 119: ipc++; 120: continue; 121: } 122: } 123: 124: if(ipc->negfl) { 125: ipc++; 126: continue; 127: } 128: yes: 129: command(ipc); 130: 131: if(delflag) 132: break; 133: 134: if(jflag) { 135: jflag = 0; 136: if((ipc = ipc->lb1) == 0) { 137: ipc = ptrspace; 138: break; 139: } 140: } else 141: ipc++; 142: 143: } 144: if(!nflag && !delflag) { 145: for(p1 = linebuf; p1 < spend; p1++) 146: putc(*p1, stdout); 147: putc('\n', stdout); 148: } 149: 150: if(aptr > abuf) { 151: arout(); 152: } 153: 154: delflag = 0; 155: 156: } 157: } 158: match(expbuf, gf) 159: char *expbuf; 160: { 161: register char *p1, *p2, c; 162: 163: if(gf) { 164: if(*expbuf) return(0); 165: p1 = linebuf; 166: p2 = genbuf; 167: while(*p1++ = *p2++); 168: locs = p1 = loc2; 169: } else { 170: p1 = linebuf; 171: locs = 0; 172: } 173: 174: p2 = expbuf; 175: if(*p2++) { 176: loc1 = p1; 177: if(*p2 == CCHR && p2[1] != *p1) 178: return(0); 179: return(advance(p1, p2)); 180: } 181: 182: /* fast check for first character */ 183: 184: if(*p2 == CCHR) { 185: c = p2[1]; 186: do { 187: if(*p1 != c) 188: continue; 189: if(advance(p1, p2)) { 190: loc1 = p1; 191: return(1); 192: } 193: } while(*p1++); 194: return(0); 195: } 196: 197: do { 198: if(advance(p1, p2)) { 199: loc1 = p1; 200: return(1); 201: } 202: } while(*p1++); 203: return(0); 204: } 205: advance(alp, aep) 206: char *alp, *aep; 207: { 208: register char *lp, *ep, *curlp; 209: char c; 210: char *bbeg; 211: int ct; 212: 213: /*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep); /*DEBUG*/ 214: 215: lp = alp; 216: ep = aep; 217: for (;;) switch (*ep++) { 218: 219: case CCHR: 220: if (*ep++ == *lp++) 221: continue; 222: return(0); 223: 224: case CDOT: 225: if (*lp++) 226: continue; 227: return(0); 228: 229: case CNL: 230: case CDOL: 231: if (*lp == 0) 232: continue; 233: return(0); 234: 235: case CEOF: 236: loc2 = lp; 237: return(1); 238: 239: case CCL: 240: c = *lp++ & 0177; 241: if(ep[c>>3] & bittab[c & 07]) { 242: ep += 16; 243: continue; 244: } 245: return(0); 246: 247: case CBRA: 248: braslist[*ep++] = lp; 249: continue; 250: 251: case CKET: 252: braelist[*ep++] = lp; 253: continue; 254: 255: case CBACK: 256: bbeg = braslist[*ep]; 257: ct = braelist[*ep++] - bbeg; 258: 259: if(ecmp(bbeg, lp, ct)) { 260: lp += ct; 261: continue; 262: } 263: return(0); 264: 265: case CBACK|STAR: 266: bbeg = braslist[*ep]; 267: ct = braelist[*ep++] - bbeg; 268: curlp = lp; 269: while(ecmp(bbeg, lp, ct)) 270: lp += ct; 271: 272: while(lp >= curlp) { 273: if(advance(lp, ep)) return(1); 274: lp -= ct; 275: } 276: return(0); 277: 278: 279: case CDOT|STAR: 280: curlp = lp; 281: while (*lp++); 282: goto star; 283: 284: case CCHR|STAR: 285: curlp = lp; 286: while (*lp++ == *ep); 287: ep++; 288: goto star; 289: 290: case CCL|STAR: 291: curlp = lp; 292: do { 293: c = *lp++ & 0177; 294: } while(ep[c>>3] & bittab[c & 07]); 295: ep += 16; 296: goto star; 297: 298: star: 299: if(--lp == curlp) { 300: continue; 301: } 302: 303: if(*ep == CCHR) { 304: c = ep[1]; 305: do { 306: if(*lp != c) 307: continue; 308: if(advance(lp, ep)) 309: return(1); 310: } while(lp-- > curlp); 311: return(0); 312: } 313: 314: if(*ep == CBACK) { 315: c = *(braslist[ep[1]]); 316: do { 317: if(*lp != c) 318: continue; 319: if(advance(lp, ep)) 320: return(1); 321: } while(lp-- > curlp); 322: return(0); 323: } 324: 325: do { 326: if(lp == locs) break; 327: if (advance(lp, ep)) 328: return(1); 329: } while (lp-- > curlp); 330: return(0); 331: 332: default: 333: fprintf(stderr, "RE botch, %o\n", *--ep); 334: } 335: } 336: substitute(ipc) 337: union reptr *ipc; 338: { 339: if(match(ipc->re1, 0) == 0) return(0); 340: 341: sflag = 1; 342: dosub(ipc->rhs); 343: 344: if(ipc->gfl) { 345: while(*loc2) { 346: if(match(ipc->re1, 1) == 0) break; 347: dosub(ipc->rhs); 348: } 349: } 350: return(1); 351: } 352: 353: dosub(rhsbuf) 354: char *rhsbuf; 355: { 356: register char *lp, *sp, *rp; 357: int c; 358: 359: lp = linebuf; 360: sp = genbuf; 361: rp = rhsbuf; 362: while (lp < loc1) 363: *sp++ = *lp++; 364: while(c = *rp++) { 365: if (c == '&') { 366: sp = place(sp, loc1, loc2); 367: continue; 368: } else if (c&0200 && (c &= 0177) >= '1' && c < NBRA+'1') { 369: sp = place(sp, braslist[c-'1'], braelist[c-'1']); 370: continue; 371: } 372: *sp++ = c&0177; 373: if (sp >= &genbuf[LBSIZE]) 374: fprintf(stderr, "output line too long.\n"); 375: } 376: lp = loc2; 377: loc2 = sp - genbuf + linebuf; 378: while (*sp++ = *lp++) 379: if (sp >= &genbuf[LBSIZE]) { 380: fprintf(stderr, "Output line too long.\n"); 381: } 382: lp = linebuf; 383: sp = genbuf; 384: while (*lp++ = *sp++); 385: spend = lp-1; 386: } 387: char *place(asp, al1, al2) 388: char *asp, *al1, *al2; 389: { 390: register char *sp, *l1, *l2; 391: 392: sp = asp; 393: l1 = al1; 394: l2 = al2; 395: while (l1 < l2) { 396: *sp++ = *l1++; 397: if (sp >= &genbuf[LBSIZE]) 398: fprintf(stderr, "Output line too long.\n"); 399: } 400: return(sp); 401: } 402: 403: command(ipc) 404: union reptr *ipc; 405: { 406: register int i; 407: register char *p1, *p2, *p3; 408: char *execp; 409: 410: 411: switch(ipc->command) { 412: 413: case ACOM: 414: *aptr++ = ipc; 415: if(aptr >= &abuf[ABUFSIZE]) { 416: fprintf(stderr, "Too many appends after line %ld\n", 417: lnum); 418: } 419: *aptr = 0; 420: break; 421: 422: case CCOM: 423: delflag = 1; 424: if(!ipc->inar || dolflag) { 425: for(p1 = ipc->re1; *p1; ) 426: putc(*p1++, stdout); 427: putc('\n', stdout); 428: } 429: break; 430: case DCOM: 431: delflag++; 432: break; 433: case CDCOM: 434: p1 = p2 = linebuf; 435: 436: while(*p1 != '\n') { 437: if(*p1++ == 0) { 438: delflag++; 439: return; 440: } 441: } 442: 443: p1++; 444: while(*p2++ = *p1++); 445: spend = p2-1; 446: jflag++; 447: break; 448: 449: case EQCOM: 450: fprintf(stdout, "%ld\n", lnum); 451: break; 452: 453: case GCOM: 454: p1 = linebuf; 455: p2 = holdsp; 456: while(*p1++ = *p2++); 457: spend = p1-1; 458: break; 459: 460: case CGCOM: 461: *spend++ = '\n'; 462: p1 = spend; 463: p2 = holdsp; 464: while(*p1++ = *p2++) 465: if(p1 >= lbend) 466: break; 467: spend = p1-1; 468: break; 469: 470: case HCOM: 471: p1 = holdsp; 472: p2 = linebuf; 473: while(*p1++ = *p2++); 474: hspend = p1-1; 475: break; 476: 477: case CHCOM: 478: *hspend++ = '\n'; 479: p1 = hspend; 480: p2 = linebuf; 481: while(*p1++ = *p2++) 482: if(p1 >= hend) 483: break; 484: hspend = p1-1; 485: break; 486: 487: case ICOM: 488: for(p1 = ipc->re1; *p1; ) 489: putc(*p1++, stdout); 490: putc('\n', stdout); 491: break; 492: 493: case BCOM: 494: jflag = 1; 495: break; 496: 497: case LCOM: 498: p1 = linebuf; 499: p2 = genbuf; 500: genbuf[72] = 0; 501: while(*p1) 502: if(*p1 >= 040) { 503: if(*p1 == 0177) { 504: p3 = rub; 505: while(*p2++ = *p3++) 506: if(p2 >= lcomend) { 507: *p2 = '\\'; 508: fprintf(stdout, "%s\n", genbuf); 509: p2 = genbuf; 510: } 511: p2--; 512: p1++; 513: continue; 514: } 515: *p2++ = *p1++; 516: if(p2 >= lcomend) { 517: *p2 = '\\'; 518: fprintf(stdout, "%s\n", genbuf); 519: p2 = genbuf; 520: } 521: } else { 522: p3 = trans[*p1-1]; 523: while(*p2++ = *p3++) 524: if(p2 >= lcomend) { 525: *p2 = '\\'; 526: fprintf(stdout, "%s\n", genbuf); 527: p2 = genbuf; 528: } 529: p2--; 530: p1++; 531: } 532: *p2 = 0; 533: fprintf(stdout, "%s\n", genbuf); 534: break; 535: 536: case NCOM: 537: if(!nflag) { 538: for(p1 = linebuf; p1 < spend; p1++) 539: putc(*p1, stdout); 540: putc('\n', stdout); 541: } 542: 543: if(aptr > abuf) 544: arout(); 545: if((execp = gline(linebuf)) == badp) { 546: pending = ipc; 547: delflag = 1; 548: break; 549: } 550: spend = execp; 551: 552: break; 553: case CNCOM: 554: if(aptr > abuf) 555: arout(); 556: *spend++ = '\n'; 557: if((execp = gline(spend)) == badp) { 558: pending = ipc; 559: delflag = 1; 560: break; 561: } 562: spend = execp; 563: break; 564: 565: case PCOM: 566: for(p1 = linebuf; p1 < spend; p1++) 567: putc(*p1, stdout); 568: putc('\n', stdout); 569: break; 570: case CPCOM: 571: cpcom: 572: for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; ) 573: putc(*p1++, stdout); 574: putc('\n', stdout); 575: break; 576: 577: case QCOM: 578: if(!nflag) { 579: for(p1 = linebuf; p1 < spend; p1++) 580: putc(*p1, stdout); 581: putc('\n', stdout); 582: } 583: if(aptr > abuf) arout(); 584: fclose(stdout); 585: exit(0); 586: case RCOM: 587: 588: *aptr++ = ipc; 589: if(aptr >= &abuf[ABUFSIZE]) 590: fprintf(stderr, "Too many reads after line%ld\n", 591: lnum); 592: 593: *aptr = 0; 594: 595: break; 596: 597: case SCOM: 598: i = substitute(ipc); 599: if(ipc->pfl && i) 600: if(ipc->pfl == 1) { 601: for(p1 = linebuf; p1 < spend; p1++) 602: putc(*p1, stdout); 603: putc('\n', stdout); 604: } 605: else 606: goto cpcom; 607: if(i && ipc->fcode) 608: goto wcom; 609: break; 610: 611: case TCOM: 612: if(sflag == 0) break; 613: sflag = 0; 614: jflag = 1; 615: break; 616: 617: wcom: 618: case WCOM: 619: fprintf(ipc->fcode, "%s\n", linebuf); 620: break; 621: case XCOM: 622: p1 = linebuf; 623: p2 = genbuf; 624: while(*p2++ = *p1++); 625: p1 = holdsp; 626: p2 = linebuf; 627: while(*p2++ = *p1++); 628: spend = p2 - 1; 629: p1 = genbuf; 630: p2 = holdsp; 631: while(*p2++ = *p1++); 632: hspend = p2 - 1; 633: break; 634: 635: case YCOM: 636: p1 = linebuf; 637: p2 = ipc->re1; 638: while(*p1 = p2[*p1]) p1++; 639: break; 640: } 641: 642: } 643: 644: char * 645: gline(addr) 646: char *addr; 647: { 648: register char *p1, *p2; 649: register c; 650: p1 = addr; 651: p2 = cbp; 652: for (;;) { 653: if (p2 >= ebp) { 654: if ((c = read(f, ibuf, 512)) <= 0) { 655: return(badp); 656: } 657: p2 = ibuf; 658: ebp = ibuf+c; 659: } 660: if ((c = *p2++) == '\n') { 661: if(p2 >= ebp) { 662: if((c = read(f, ibuf, 512)) <= 0) { 663: close(f); 664: if(eargc == 0) 665: dolflag = 1; 666: } 667: 668: p2 = ibuf; 669: ebp = ibuf + c; 670: } 671: break; 672: } 673: if(c) 674: if(p1 < lbend) 675: *p1++ = c; 676: } 677: lnum++; 678: *p1 = 0; 679: cbp = p2; 680: 681: return(p1); 682: } 683: ecmp(a, b, count) 684: char *a, *b; 685: { 686: while(count--) 687: if(*a++ != *b++) return(0); 688: return(1); 689: } 690: 691: arout() 692: { 693: register char *p1; 694: FILE *fi; 695: char c; 696: int t; 697: 698: aptr = abuf - 1; 699: while(*++aptr) { 700: if((*aptr)->command == ACOM) { 701: for(p1 = (*aptr)->re1; *p1; ) 702: putc(*p1++, stdout); 703: putc('\n', stdout); 704: } else { 705: if((fi = fopen((*aptr)->re1, "r")) == NULL) 706: continue; 707: while((t = getc(fi)) != EOF) { 708: c = t; 709: putc(c, stdout); 710: } 711: fclose(fi); 712: } 713: } 714: aptr = abuf; 715: *aptr = 0; 716: }