1 /* sed1.c 4.3 87/12/21 */ 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 struct 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 struct 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 struct 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 } 720 721