1 #include <stdlib.h> 2 #include <unistd.h> 3 #include <stdio.h> 4 #include "sed.h" 5 6 struct label *labtab = ltab; 7 char CGMES[] = "sed: Command garbled: %s\n"; 8 char TMMES[] = "sed: Too much text: %s\n"; 9 char LTL[] = "sed: Label too long: %s\n"; 10 char AD0MES[] = "sed: No addresses allowed: %s\n"; 11 char AD1MES[] = "sed: Only one address allowed: %s\n"; 12 uchar bittab[] = { 13 1, 14 2, 15 4, 16 8, 17 16, 18 32, 19 64, 20 128 21 }; 22 23 main(int argc, char **argv) 24 { 25 26 eargc = argc; 27 eargv = (uchar**)argv; 28 29 badp = &bad; 30 aptr = abuf; 31 hspend = holdsp; 32 lab = labtab + 1; /* 0 reserved for end-pointer */ 33 rep = ptrspace; 34 rep->r1.ad1 = respace; 35 lbend = &linebuf[LBSIZE]; 36 hend = &holdsp[LBSIZE]; 37 lcomend = &genbuf[64]; 38 ptrend = &ptrspace[PTRSIZE]; 39 reend = &respace[RESIZE]; 40 labend = &labtab[LABSIZE]; 41 lnum = 0; 42 pending = 0; 43 depth = 0; 44 spend = linebuf; 45 hspend = holdsp; 46 fcode[0] = stdout; 47 nfiles = 1; 48 lastre = NULL; 49 50 if(eargc == 1) 51 exit(0); 52 53 54 while (--eargc > 0 && (++eargv)[0][0] == '-') 55 switch (eargv[0][1]) { 56 57 case 'n': 58 nflag++; 59 continue; 60 61 case 'f': 62 if(eargc-- <= 0) exit(2); 63 64 if((fin = fopen((char*)(*++eargv), "r")) == NULL) { 65 fprintf(stderr, "sed: Cannot open pattern-file: %s\n", *eargv); 66 exit(2); 67 } 68 69 fcomp(); 70 fclose(fin); 71 continue; 72 73 case 'e': 74 eflag++; 75 fcomp(); 76 eflag = 0; 77 continue; 78 79 case 'g': 80 gflag++; 81 continue; 82 83 default: 84 fprintf(stderr, "sed: Unknown flag: %c\n", eargv[0][1]); 85 continue; 86 } 87 88 89 if(compfl == 0) { 90 eargv--; 91 eargc++; 92 eflag++; 93 fcomp(); 94 eargv++; 95 eargc--; 96 eflag = 0; 97 } 98 99 if(depth) { 100 fprintf(stderr, "sed: Too many {'s\n"); 101 exit(2); 102 } 103 104 labtab->address = rep; 105 106 dechain(); 107 108 /* abort(); /*DEBUG*/ 109 110 if(eargc <= 0) 111 execute((uchar *)NULL); 112 else while(--eargc >= 0) { 113 execute(*eargv++); 114 } 115 fclose(stdout); 116 exit(0); 117 } 118 void 119 fcomp(void) 120 { 121 122 uchar *p, *op, *tp; 123 uchar *address(uchar*); 124 union reptr *pt, *pt1; 125 int i; 126 struct label *lpt; 127 128 compfl = 1; 129 op = lastre; 130 131 if(rline(linebuf) < 0) { 132 lastre = op; 133 return; 134 } 135 if(*linebuf == '#') { 136 if(linebuf[1] == 'n') 137 nflag = 1; 138 } 139 else { 140 cp = linebuf; 141 goto comploop; 142 } 143 144 for(;;) { 145 if(rline(linebuf) < 0) break; 146 147 cp = linebuf; 148 149 comploop: 150 /* fprintf(stdout, "cp: %s\n", cp); /*DEBUG*/ 151 while(*cp == ' ' || *cp == '\t') cp++; 152 if(*cp == '\0' || *cp == '#') continue; 153 if(*cp == ';') { 154 cp++; 155 goto comploop; 156 } 157 158 p = address(rep->r1.ad1); 159 if(p == badp) { 160 fprintf(stderr, CGMES, linebuf); 161 exit(2); 162 } 163 164 if(p == 0) { 165 p = rep->r1.ad1; 166 rep->r1.ad1 = 0; 167 } else { 168 if(p == rep->r1.ad1) { 169 if(op) 170 rep->r1.ad1 = op; 171 else { 172 fprintf(stderr, "sed: First RE may not be null\n"); 173 exit(2); 174 } 175 } 176 if(*rep->r1.ad1 != CLNUM && *rep->r1.ad1 != CEND) 177 op = rep->r1.ad1; 178 if(*cp == ',' || *cp == ';') { 179 cp++; 180 if((rep->r1.ad2 = p) > reend) { 181 fprintf(stderr, TMMES, linebuf); 182 exit(2); 183 } 184 p = address(rep->r1.ad2); 185 if(p == badp || p == 0) { 186 fprintf(stderr, CGMES, linebuf); 187 exit(2); 188 } 189 if(p == rep->r1.ad2) 190 rep->r1.ad2 = op; 191 else{ 192 if(*rep->r1.ad2 != CLNUM && *rep->r1.ad2 != CEND) 193 op = rep->r1.ad2; 194 } 195 196 } else 197 rep->r1.ad2 = 0; 198 } 199 200 if(p > reend) { 201 fprintf(stderr, "sed: Too much text: %s\n", linebuf); 202 exit(2); 203 } 204 205 while(*cp == ' ' || *cp == '\t') cp++; 206 207 swit: 208 switch(*cp++) { 209 210 default: 211 /*fprintf(stderr, "cp = %d; *cp = %o\n", cp - linebuf, *cp);*/ 212 fprintf(stderr, "sed: Unrecognized command: %s\n", linebuf); 213 exit(2); 214 215 case '!': 216 rep->r1.negfl = 1; 217 goto swit; 218 219 case '{': 220 rep->r1.command = BCOM; 221 rep->r1.negfl = !(rep->r1.negfl); 222 cmpend[depth++] = &rep->r2.lb1; 223 if(++rep >= ptrend) { 224 fprintf(stderr, "sed: Too many commands: %s\n", linebuf); 225 exit(2); 226 } 227 rep->r1.ad1 = p; 228 if(*cp == '\0') continue; 229 230 goto comploop; 231 232 case '}': 233 if(rep->r1.ad1) { 234 fprintf(stderr, AD0MES, linebuf); 235 exit(2); 236 } 237 238 if(--depth < 0) { 239 fprintf(stderr, "sed: Too many }'s\n"); 240 exit(2); 241 } 242 *cmpend[depth] = rep; 243 244 rep->r1.ad1 = p; 245 if(*cp == 0) continue; 246 goto comploop; 247 248 case '=': 249 rep->r1.command = EQCOM; 250 if(rep->r1.ad2) { 251 fprintf(stderr, AD1MES, linebuf); 252 exit(2); 253 } 254 break; 255 256 case ':': 257 if(rep->r1.ad1) { 258 fprintf(stderr, AD0MES, linebuf); 259 exit(2); 260 } 261 262 while(*cp++ == ' '); 263 cp--; 264 265 266 tp = lab->asc; 267 while((*tp = *cp++) && *tp != ';') 268 if(++tp >= &(lab->asc[8])) { 269 fprintf(stderr, LTL, linebuf); 270 exit(2); 271 } 272 *tp = '\0'; 273 if(*lab->asc == 0) { 274 fprintf(stderr, CGMES, linebuf); 275 exit(2); 276 } 277 278 if(lpt = search(lab)) { 279 if(lpt->address) { 280 fprintf(stderr, "sed: Duplicate labels: %s\n", linebuf); 281 exit(2); 282 } 283 } else { 284 lab->chain = 0; 285 lpt = lab; 286 if(++lab >= labend) { 287 fprintf(stderr, "sed: Too many labels: %s\n", linebuf); 288 exit(2); 289 } 290 } 291 lpt->address = rep; 292 rep->r1.ad1 = p; 293 294 continue; 295 296 case 'a': 297 rep->r1.command = ACOM; 298 if(rep->r1.ad2) { 299 fprintf(stderr, AD1MES, linebuf); 300 exit(2); 301 } 302 if(*cp == '\\') cp++; 303 if(*cp++ != '\n') { 304 fprintf(stderr, CGMES, linebuf); 305 exit(2); 306 } 307 rep->r1.re1 = p; 308 p = text(rep->r1.re1); 309 break; 310 case 'c': 311 rep->r1.command = CCOM; 312 if(*cp == '\\') cp++; 313 if(*cp++ != ('\n')) { 314 fprintf(stderr, CGMES, linebuf); 315 exit(2); 316 } 317 rep->r1.re1 = p; 318 p = text(rep->r1.re1); 319 break; 320 case 'i': 321 rep->r1.command = ICOM; 322 if(rep->r1.ad2) { 323 fprintf(stderr, AD1MES, linebuf); 324 exit(2); 325 } 326 if(*cp == '\\') cp++; 327 if(*cp++ != ('\n')) { 328 fprintf(stderr, CGMES, linebuf); 329 exit(2); 330 } 331 rep->r1.re1 = p; 332 p = text(rep->r1.re1); 333 break; 334 335 case 'g': 336 rep->r1.command = GCOM; 337 break; 338 339 case 'G': 340 rep->r1.command = CGCOM; 341 break; 342 343 case 'h': 344 rep->r1.command = HCOM; 345 break; 346 347 case 'H': 348 rep->r1.command = CHCOM; 349 break; 350 351 case 't': 352 rep->r1.command = TCOM; 353 goto jtcommon; 354 355 case 'b': 356 rep->r1.command = BCOM; 357 jtcommon: 358 while(*cp++ == ' '); 359 cp--; 360 361 if(*cp == '\0') { 362 if(pt = labtab->chain) { 363 while(pt1 = pt->r2.lb1) 364 pt = pt1; 365 pt->r2.lb1 = rep; 366 } else 367 labtab->chain = rep; 368 break; 369 } 370 tp = lab->asc; 371 while((*tp = *cp++) && *tp != ';') 372 if(++tp >= &(lab->asc[8])) { 373 fprintf(stderr, LTL, linebuf); 374 exit(2); 375 } 376 cp--; 377 *tp = '\0'; 378 if(*lab->asc == 0) { 379 fprintf(stderr, CGMES, linebuf); 380 exit(2); 381 } 382 383 if(lpt = search(lab)) { 384 if(lpt->address) { 385 rep->r2.lb1 = lpt->address; 386 } else { 387 pt = lpt->chain; 388 while(pt1 = pt->r2.lb1) 389 pt = pt1; 390 pt->r2.lb1 = rep; 391 } 392 } else { 393 lab->chain = rep; 394 lab->address = 0; 395 if(++lab >= labend) { 396 fprintf(stderr, "sed: Too many labels: %s\n", linebuf); 397 exit(2); 398 } 399 } 400 break; 401 402 case 'n': 403 rep->r1.command = NCOM; 404 break; 405 406 case 'N': 407 rep->r1.command = CNCOM; 408 break; 409 410 case 'p': 411 rep->r1.command = PCOM; 412 break; 413 414 case 'P': 415 rep->r1.command = CPCOM; 416 break; 417 418 case 'r': 419 rep->r1.command = RCOM; 420 if(rep->r1.ad2) { 421 fprintf(stderr, AD1MES, linebuf); 422 exit(2); 423 } 424 if(*cp++ != ' ') { 425 fprintf(stderr, CGMES, linebuf); 426 exit(2); 427 } 428 rep->r1.re1 = p; 429 p = text(rep->r1.re1); 430 break; 431 432 case 'd': 433 rep->r1.command = DCOM; 434 break; 435 436 case 'D': 437 rep->r1.command = CDCOM; 438 rep->r2.lb1 = ptrspace; 439 break; 440 441 case 'q': 442 rep->r1.command = QCOM; 443 if(rep->r1.ad2) { 444 fprintf(stderr, AD1MES, linebuf); 445 exit(2); 446 } 447 break; 448 449 case 'l': 450 rep->r1.command = LCOM; 451 break; 452 453 case 's': 454 rep->r1.command = SCOM; 455 seof = *cp++; 456 rep->r1.re1 = p; 457 p = compile(rep->r1.re1); 458 if(p == badp) { 459 fprintf(stderr, CGMES, linebuf); 460 exit(2); 461 } 462 if(p == rep->r1.re1) { 463 if(op == NULL) { 464 fprintf(stderr, "sed: First RE may not be null.\n"); 465 exit(2); 466 } 467 rep->r1.re1 = op; 468 } else { 469 op = rep->r1.re1; 470 } 471 472 if((rep->r1.rhs = p) > reend) { 473 fprintf(stderr, TMMES, linebuf); 474 exit(2); 475 } 476 477 if((p = compsub(rep->r1.rhs)) == badp) { 478 fprintf(stderr, CGMES, linebuf); 479 exit(2); 480 } 481 if(*cp == 'g') { 482 cp++; 483 rep->r1.gfl++; 484 } else if(gflag) 485 rep->r1.gfl++; 486 487 if(*cp == 'p') { 488 cp++; 489 rep->r1.pfl = 1; 490 } 491 492 if(*cp == 'P') { 493 cp++; 494 rep->r1.pfl = 2; 495 } 496 497 if(*cp == 'w') { 498 cp++; 499 if(*cp++ != ' ') { 500 fprintf(stderr, CGMES, linebuf); 501 exit(2); 502 } 503 if(nfiles >= MAXFILES) { 504 fprintf(stderr, "sed: Too many files in w commands 1 \n"); 505 exit(2); 506 } 507 508 text((uchar*)fname[nfiles]); 509 for(i = nfiles - 1; i >= 0; i--) 510 if(cmp((uchar*)fname[nfiles],(uchar*)fname[i]) == 0) { 511 rep->r1.fcode = fcode[i]; 512 goto done; 513 } 514 if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) { 515 fprintf(stderr, "sed: Cannot open %s\n", fname[nfiles]); 516 exit(2); 517 } 518 fcode[nfiles++] = rep->r1.fcode; 519 } 520 break; 521 522 case 'w': 523 rep->r1.command = WCOM; 524 if(*cp++ != ' ') { 525 fprintf(stderr, CGMES, linebuf); 526 exit(2); 527 } 528 if(nfiles >= MAXFILES){ 529 fprintf(stderr, "sed: Too many files in w commands 2 \n"); 530 fprintf(stderr, "nfiles = %d; MAXF = %d\n", nfiles, MAXFILES); 531 exit(2); 532 } 533 534 text((uchar*)fname[nfiles]); 535 for(i = nfiles - 1; i >= 0; i--) 536 if(cmp((uchar*)fname[nfiles], (uchar*)fname[i]) == 0) { 537 rep->r1.fcode = fcode[i]; 538 goto done; 539 } 540 541 if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) { 542 fprintf(stderr, "sed: Cannot create %s\n", fname[nfiles]); 543 exit(2); 544 } 545 fcode[nfiles++] = rep->r1.fcode; 546 break; 547 548 case 'x': 549 rep->r1.command = XCOM; 550 break; 551 552 case 'y': 553 rep->r1.command = YCOM; 554 seof = *cp++; 555 rep->r1.re1 = p; 556 p = ycomp(rep->r1.re1); 557 if(p == badp) { 558 fprintf(stderr, CGMES, linebuf); 559 exit(2); 560 } 561 if(p > reend) { 562 fprintf(stderr, TMMES, linebuf); 563 exit(2); 564 } 565 break; 566 567 } 568 done: 569 if(++rep >= ptrend) { 570 fprintf(stderr, "sed: Too many commands, last: %s\n", linebuf); 571 exit(2); 572 } 573 574 rep->r1.ad1 = p; 575 576 if(*cp++ != '\0') { 577 if(cp[-1] == ';') 578 goto comploop; 579 fprintf(stderr, CGMES, linebuf); 580 exit(2); 581 } 582 583 } 584 } 585 586 uchar * 587 compsub(uchar *rhsbuf) 588 { 589 uchar *p, *q, *r; 590 p = rhsbuf; 591 q = cp; 592 for(;;) { 593 if((*p = *q++) == '\\') { 594 *++p = *q++; 595 if(*p >= '1' && *p <= '9' && *p > numbra + '0') 596 return(badp); 597 if(*p == 'n') 598 *--p = '\n'; 599 } else if(*p == seof) { 600 *p++ = '\0'; 601 cp = q; 602 return(p); 603 } 604 if(*p++ == '\0') { 605 return(badp); 606 } 607 608 } 609 } 610 611 uchar * 612 compile(uchar *expbuf) 613 { 614 int c; 615 uchar *ep, *sp; 616 uchar neg; 617 uchar *lastep, *cstart; 618 int cclcnt; 619 int closed; 620 uchar bracket[NBRA], *bracketp; 621 622 if(*cp == seof) { 623 cp++; 624 return(expbuf); 625 } 626 627 ep = expbuf; 628 lastep = 0; 629 bracketp = bracket; 630 closed = numbra = 0; 631 sp = cp; 632 if (*sp == '^') { 633 *ep++ = 1; 634 sp++; 635 } else { 636 *ep++ = 0; 637 } 638 for (;;) { 639 if (ep >= reend) { 640 cp = sp; 641 return(badp); 642 } 643 if((c = *sp++) == seof) { 644 if(bracketp != bracket) { 645 cp = sp; 646 return(badp); 647 } 648 cp = sp; 649 *ep++ = CEOF; 650 return(ep); 651 } 652 if(c != '*') 653 lastep = ep; 654 switch (c) { 655 656 case '\\': 657 if((c = *sp++) == '(') { 658 if(numbra >= NBRA) { 659 cp = sp; 660 return(badp); 661 } 662 *bracketp++ = numbra; 663 *ep++ = CBRA; 664 *ep++ = numbra++; 665 continue; 666 } 667 if(c == ')') { 668 if(bracketp <= bracket) { 669 cp = sp; 670 return(badp); 671 } 672 *ep++ = CKET; 673 *ep++ = *--bracketp; 674 closed++; 675 continue; 676 } 677 678 if(c >= '1' && c <= '9') { 679 if((c -= '1') >= closed) 680 return(badp); 681 682 *ep++ = CBACK; 683 *ep++ = c; 684 continue; 685 } 686 if(c == '\n') { 687 cp = sp; 688 return(badp); 689 } 690 if(c == 'n') { 691 c = '\n'; 692 } 693 goto defchar; 694 695 case '\0': 696 case '\n': 697 cp = sp; 698 return(badp); 699 700 case '.': 701 *ep++ = CDOT; 702 continue; 703 704 case '*': 705 if (lastep == 0) 706 goto defchar; 707 if(*lastep == CKET) { 708 cp = sp; 709 return(badp); 710 } 711 *lastep |= STAR; 712 continue; 713 714 case '$': 715 if (*sp != seof) 716 goto defchar; 717 *ep++ = CDOL; 718 continue; 719 720 case '[': 721 if(&ep[33] >= reend) { 722 fprintf(stderr, "sed: RE too long: %s\n", linebuf); 723 exit(2); 724 } 725 726 *ep++ = CCL; 727 728 neg = 0; 729 if((c = *sp++) == '^') { 730 neg = 1; 731 c = *sp++; 732 } 733 734 cstart = sp; 735 do { 736 if(c == '\0') { 737 fprintf(stderr, CGMES, linebuf); 738 exit(2); 739 } 740 if (c=='-' && sp>cstart && *sp!=']') { 741 for (c = sp[-2]; c<*sp; c++) 742 ep[c>>3] |= bittab[c&07]; 743 } 744 if(c == '\\') { 745 switch(c = *sp++) { 746 case 'n': 747 c = '\n'; 748 break; 749 } 750 } 751 752 ep[c >> 3] |= bittab[c & 07]; 753 } while((c = *sp++) != ']'); 754 755 if(neg) 756 for(cclcnt = 0; cclcnt < 32; cclcnt++) 757 ep[cclcnt] ^= -1; 758 ep[0] &= 0376; 759 760 ep += 32; 761 762 continue; 763 764 defchar: 765 default: 766 *ep++ = CCHR; 767 *ep++ = c; 768 } 769 } 770 } 771 int 772 rline(uchar *lbuf) 773 { 774 uchar *p, *q; 775 int t; 776 static uchar *saveq; 777 778 p = lbuf - 1; 779 780 if(eflag) { 781 if(eflag > 0) { 782 eflag = -1; 783 if(eargc-- <= 0) 784 exit(2); 785 q = *++eargv; 786 while(*++p = *q++) { 787 if(*p == '\\') { 788 if((*++p = *q++) == '\0') { 789 saveq = 0; 790 return(-1); 791 } else 792 continue; 793 } 794 if(*p == '\n') { 795 *p = '\0'; 796 saveq = q; 797 return(1); 798 } 799 } 800 saveq = 0; 801 return(1); 802 } 803 if((q = saveq) == 0) return(-1); 804 805 while(*++p = *q++) { 806 if(*p == '\\') { 807 if((*++p = *q++) == '0') { 808 saveq = 0; 809 return(-1); 810 } else 811 continue; 812 } 813 if(*p == '\n') { 814 *p = '\0'; 815 saveq = q; 816 return(1); 817 } 818 } 819 saveq = 0; 820 return(1); 821 } 822 823 while((t = getc(fin)) != EOF) { 824 *++p = t; 825 if(*p == '\\') { 826 t = getc(fin); 827 *++p = t; 828 } 829 else if(*p == '\n') { 830 *p = '\0'; 831 return(1); 832 } 833 } 834 *++p = '\0'; 835 return(-1); 836 } 837 838 uchar * 839 address(uchar *expbuf) 840 { 841 uchar *rcp; 842 long lno; 843 844 if(*cp == '$') { 845 cp++; 846 *expbuf++ = CEND; 847 *expbuf++ = CEOF; 848 return(expbuf); 849 } 850 851 if(*cp == '/') { 852 seof = '/'; 853 cp++; 854 return(compile(expbuf)); 855 } 856 857 rcp = cp; 858 lno = 0; 859 860 while(*rcp >= '0' && *rcp <= '9') 861 lno = lno*10 + *rcp++ - '0'; 862 863 if(rcp > cp) { 864 if(!lno){ 865 fprintf(stderr, "sed: line number 0 is illegal\n"); 866 exit(2); 867 } 868 *expbuf++ = CLNUM; 869 *expbuf++ = lno; 870 *expbuf++ = lno >> 8; 871 *expbuf++ = lno >> 16; 872 *expbuf++ = lno >> 24; 873 *expbuf++ = CEOF; 874 cp = rcp; 875 return(expbuf); 876 } 877 return(0); 878 } 879 int 880 cmp(uchar *a, uchar *b) 881 { 882 uchar *ra, *rb; 883 884 ra = a - 1; 885 rb = b - 1; 886 887 while(*++ra == *++rb) 888 if(*ra == '\0') return(0); 889 return(1); 890 } 891 892 uchar * 893 text(uchar *textbuf) 894 { 895 uchar *p, *q; 896 897 p = textbuf; 898 q = cp; 899 while(*q == '\t' || *q == ' ') q++; 900 for(;;) { 901 902 if((*p = *q++) == '\\') 903 *p = *q++; 904 if(*p == '\0') { 905 cp = --q; 906 return(++p); 907 } 908 if(*p == '\n') { 909 while(*q == '\t' || *q == ' ') q++; 910 } 911 p++; 912 } 913 } 914 915 916 struct label * 917 search(struct label *ptr) 918 { 919 struct label *rp; 920 921 rp = labtab; 922 while(rp < ptr) { 923 if(cmp(rp->asc, ptr->asc) == 0) 924 return(rp); 925 rp++; 926 } 927 928 return(0); 929 } 930 931 void 932 dechain(void) 933 { 934 struct label *lptr; 935 union reptr *rptr, *trptr; 936 937 for(lptr = labtab; lptr < lab; lptr++) { 938 939 if(lptr->address == 0) { 940 fprintf(stderr, "sed: Undefined label: %s\n", lptr->asc); 941 exit(2); 942 } 943 944 if(lptr->chain) { 945 rptr = lptr->chain; 946 while(trptr = rptr->r2.lb1) { 947 rptr->r2.lb1 = lptr->address; 948 rptr = trptr; 949 } 950 rptr->r2.lb1 = lptr->address; 951 } 952 } 953 } 954 955 uchar * 956 ycomp(uchar *expbuf) 957 { 958 uchar *ep, *tsp; 959 int c; 960 uchar *sp; 961 962 ep = expbuf; 963 sp = cp; 964 for(tsp = cp; *tsp != seof; tsp++) { 965 if(*tsp == '\\') 966 tsp++; 967 if(*tsp == '\n' || *tsp == '\0') 968 return(badp); 969 } 970 tsp++; 971 972 while((c = *sp++) != seof) { 973 if(c == '\\' && *sp == 'n') { 974 sp++; 975 c = '\n'; 976 } 977 if((ep[c] = *tsp++) == '\\' && *tsp == 'n') { 978 ep[c] = '\n'; 979 tsp++; 980 } 981 if(ep[c] == seof || ep[c] == '\0') 982 return(badp); 983 } 984 if(*tsp != seof) 985 return(badp); 986 cp = ++tsp; 987 988 for(c = 0; c<0400; c++) 989 if(ep[c] == 0) 990 ep[c] = c; 991 992 return(ep + 0400); 993 } 994 995