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