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