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