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