|
|
1.1 ! root 1: /* ! 2: * Editor ! 3: */ ! 4: ! 5: #include <signal.h> ! 6: #include <setjmp.h> ! 7: ! 8: /* make BLKSIZE and LBSIZE 512 for smaller machines */ ! 9: #define BLKSIZE 4096 ! 10: #define NBLK 2047 ! 11: ! 12: #define NULL 0 ! 13: #define FNSIZE 128 ! 14: #define LBSIZE 4096 ! 15: #define ESIZE 256 ! 16: #define GBSIZE 256 ! 17: #define NBRA 5 ! 18: #define EOF -1 ! 19: #define KSIZE 9 ! 20: ! 21: #define CBRA 1 ! 22: #define CCHR 2 ! 23: #define CDOT 4 ! 24: #define CCL 6 ! 25: #define NCCL 8 ! 26: #define CDOL 10 ! 27: #define CEOF 11 ! 28: #define CKET 12 ! 29: #define CBACK 14 ! 30: #define CCIRC 15 ! 31: ! 32: #define STAR 01 ! 33: ! 34: char Q[] = ""; ! 35: char T[] = "TMP"; ! 36: #define READ 0 ! 37: #define WRITE 1 ! 38: ! 39: int peekc; ! 40: int lastc; ! 41: char savedfile[FNSIZE]; ! 42: char file[FNSIZE]; ! 43: char linebuf[LBSIZE]; ! 44: char rhsbuf[LBSIZE/2]; ! 45: char expbuf[ESIZE+4]; ! 46: int given; ! 47: unsigned int *addr1, *addr2; ! 48: unsigned int *dot, *dol, *zero; ! 49: char genbuf[LBSIZE]; ! 50: long count; ! 51: char *nextip; ! 52: char *linebp; ! 53: int ninbuf; ! 54: int io; ! 55: int pflag; ! 56: long lseek(); ! 57: SIG_TYP oldhup; ! 58: SIG_TYP oldquit; ! 59: int vflag = 1; ! 60: int oflag; ! 61: int listf; ! 62: int listn; ! 63: int col; ! 64: char *globp; ! 65: int tfile = -1; ! 66: int tline; ! 67: char *tfname; ! 68: char *loc1; ! 69: char *loc2; ! 70: char ibuff[BLKSIZE]; ! 71: int iblock = -1; ! 72: char obuff[BLKSIZE]; ! 73: int oblock = -1; ! 74: int ichanged; ! 75: int nleft; ! 76: char WRERR[] = "WRITE ERROR"; ! 77: int names[26]; ! 78: int anymarks; ! 79: char *braslist[NBRA]; ! 80: char *braelist[NBRA]; ! 81: int nbra; ! 82: int subnewa; ! 83: int subolda; ! 84: int fchange; ! 85: int wrapp; ! 86: int bpagesize = 20; ! 87: unsigned nlall = 128; ! 88: ! 89: unsigned int *address(); ! 90: char *getline(); ! 91: char *getblock(); ! 92: char *place(); ! 93: char *mktemp(); ! 94: char *malloc(); ! 95: char *realloc(); ! 96: jmp_buf savej; ! 97: ! 98: main(argc, argv) ! 99: char **argv; ! 100: { ! 101: register char *p1, *p2; ! 102: extern int onintr(), quit(), onhup(); ! 103: SIG_TYP oldintr; ! 104: ! 105: oldquit = signal(SIGQUIT, SIG_IGN); ! 106: oldhup = signal(SIGHUP, SIG_IGN); ! 107: oldintr = signal(SIGINT, SIG_IGN); ! 108: if (signal(SIGTERM, SIG_IGN) == SIG_DFL) ! 109: signal(SIGTERM, quit); ! 110: argv++; ! 111: while (argc > 1 && **argv=='-') { ! 112: switch((*argv)[1]) { ! 113: ! 114: case '\0': ! 115: vflag = 0; ! 116: break; ! 117: ! 118: case 'q': ! 119: signal(SIGQUIT, SIG_DFL); ! 120: vflag = 1; ! 121: break; ! 122: ! 123: case 'o': ! 124: oflag = 1; ! 125: break; ! 126: } ! 127: argv++; ! 128: argc--; ! 129: } ! 130: if (oflag) { ! 131: p1 = "/dev/stdout"; ! 132: p2 = savedfile; ! 133: while (*p2++ = *p1++) ! 134: ; ! 135: } ! 136: if (argc>1) { ! 137: p1 = *argv; ! 138: p2 = savedfile; ! 139: while (*p2++ = *p1++) ! 140: if (p2 >= &savedfile[sizeof(savedfile)]) ! 141: p2--; ! 142: globp = "r"; ! 143: } ! 144: zero = (unsigned *)malloc(nlall*sizeof(unsigned)); ! 145: tfname = mktemp("/tmp/eXXXXX"); ! 146: init(); ! 147: if (oldintr!=SIG_IGN) ! 148: signal(SIGINT, onintr); ! 149: if (oldhup!=SIG_IGN) ! 150: signal(SIGHUP, onhup); ! 151: setjmp(savej); ! 152: commands(); ! 153: quit(); ! 154: } ! 155: ! 156: commands() ! 157: { ! 158: int getfile(), gettty(); ! 159: register unsigned *a1; ! 160: register c; ! 161: register int temp; ! 162: char lastsep; ! 163: ! 164: for (;;) { ! 165: if (pflag) { ! 166: pflag = 0; ! 167: addr1 = addr2 = dot; ! 168: print(); ! 169: } ! 170: c = '\n'; ! 171: for (addr1 = 0;;) { ! 172: lastsep = c; ! 173: a1 = address(); ! 174: c = getchr(); ! 175: if (c!=',' && c!=';') ! 176: break; ! 177: if (lastsep==',') ! 178: error(Q); ! 179: if (a1==0) { ! 180: a1 = zero+1; ! 181: if (a1>dol) ! 182: a1--; ! 183: } ! 184: addr1 = a1; ! 185: if (c==';') ! 186: dot = a1; ! 187: } ! 188: if (lastsep!='\n' && a1==0) ! 189: a1 = dol; ! 190: if ((addr2=a1)==0) { ! 191: given = 0; ! 192: addr2 = dot; ! 193: } ! 194: else ! 195: given = 1; ! 196: if (addr1==0) ! 197: addr1 = addr2; ! 198: switch(c) { ! 199: ! 200: case 'a': ! 201: add(0); ! 202: continue; ! 203: ! 204: case 'b': ! 205: nonzero(); ! 206: browse(); ! 207: continue; ! 208: ! 209: case 'c': ! 210: nonzero(); ! 211: newline(); ! 212: rdelete(addr1, addr2); ! 213: append(gettty, addr1-1); ! 214: continue; ! 215: ! 216: case 'd': ! 217: nonzero(); ! 218: newline(); ! 219: rdelete(addr1, addr2); ! 220: continue; ! 221: ! 222: case 'E': ! 223: fchange = 0; ! 224: c = 'e'; ! 225: case 'e': ! 226: setnoaddr(); ! 227: if (vflag && fchange) { ! 228: fchange = 0; ! 229: error(Q); ! 230: } ! 231: filename(c); ! 232: init(); ! 233: addr2 = zero; ! 234: goto caseread; ! 235: ! 236: case 'f': ! 237: setnoaddr(); ! 238: filename(c); ! 239: puts(savedfile); ! 240: continue; ! 241: ! 242: case 'g': ! 243: global(1); ! 244: continue; ! 245: ! 246: case 'i': ! 247: add(-1); ! 248: continue; ! 249: ! 250: ! 251: case 'j': ! 252: if (!given) ! 253: addr2++; ! 254: newline(); ! 255: join(); ! 256: continue; ! 257: ! 258: case 'k': ! 259: nonzero(); ! 260: if ((c = getchr()) < 'a' || c > 'z') ! 261: error(Q); ! 262: newline(); ! 263: names[c-'a'] = *addr2 & ~01; ! 264: anymarks |= 01; ! 265: continue; ! 266: ! 267: case 'm': ! 268: move(0); ! 269: continue; ! 270: ! 271: case 'n': ! 272: listn++; ! 273: newline(); ! 274: print(); ! 275: continue; ! 276: ! 277: case '\n': ! 278: if (a1==0) { ! 279: a1 = dot+1; ! 280: addr2 = a1; ! 281: addr1 = a1; ! 282: } ! 283: if (lastsep==';') ! 284: addr1 = a1; ! 285: print(); ! 286: continue; ! 287: ! 288: case 'l': ! 289: listf++; ! 290: case 'p': ! 291: case 'P': ! 292: newline(); ! 293: print(); ! 294: continue; ! 295: ! 296: case 'Q': ! 297: fchange = 0; ! 298: case 'q': ! 299: setnoaddr(); ! 300: newline(); ! 301: quit(); ! 302: ! 303: case 'r': ! 304: filename(c); ! 305: caseread: ! 306: if ((io = open(file, 0)) < 0) { ! 307: lastc = '\n'; ! 308: error(file); ! 309: } ! 310: setwide(); ! 311: squeeze(0); ! 312: ninbuf = 0; ! 313: c = zero != dol; ! 314: append(getfile, addr2); ! 315: exfile(); ! 316: fchange = c; ! 317: continue; ! 318: ! 319: case 's': ! 320: nonzero(); ! 321: substitute(globp!=0); ! 322: continue; ! 323: ! 324: case 't': ! 325: move(1); ! 326: continue; ! 327: ! 328: case 'u': ! 329: nonzero(); ! 330: newline(); ! 331: if ((*addr2&~01) != subnewa) ! 332: error(Q); ! 333: *addr2 = subolda; ! 334: dot = addr2; ! 335: continue; ! 336: ! 337: case 'v': ! 338: global(0); ! 339: continue; ! 340: ! 341: case 'W': ! 342: wrapp++; ! 343: case 'w': ! 344: setwide(); ! 345: squeeze(dol>zero); ! 346: if ((temp = getchr()) != 'q' && temp != 'Q') { ! 347: peekc = temp; ! 348: temp = 0; ! 349: } ! 350: filename(c); ! 351: if(!wrapp || ! 352: ((io = open(file,1)) == -1) || ! 353: ((lseek(io, 0L, 2)) == -1)) ! 354: if ((io = creat(file, 0666)) < 0) ! 355: error(file); ! 356: wrapp = 0; ! 357: if (dol > zero) ! 358: putfile(); ! 359: exfile(); ! 360: if (addr1<=zero+1 && addr2==dol) ! 361: fchange = 0; ! 362: if (temp == 'Q') ! 363: fchange = 0; ! 364: if (temp) ! 365: quit(); ! 366: continue; ! 367: ! 368: case '=': ! 369: setwide(); ! 370: squeeze(0); ! 371: newline(); ! 372: count = addr2 - zero; ! 373: putd(); ! 374: putchr('\n'); ! 375: continue; ! 376: ! 377: case '!': ! 378: callunix(); ! 379: continue; ! 380: ! 381: case EOF: ! 382: return; ! 383: ! 384: } ! 385: error(Q); ! 386: } ! 387: } ! 388: ! 389: print() ! 390: { ! 391: register unsigned *a1; ! 392: ! 393: nonzero(); ! 394: a1 = addr1; ! 395: do { ! 396: if (listn) { ! 397: count = a1-zero; ! 398: putd(); ! 399: putchr('\t'); ! 400: } ! 401: puts(getline(*a1++)); ! 402: } while (a1 <= addr2); ! 403: dot = addr2; ! 404: listf = 0; ! 405: listn = 0; ! 406: pflag = 0; ! 407: } ! 408: ! 409: unsigned * ! 410: address() ! 411: { ! 412: register int sign; ! 413: register unsigned *a, *b; ! 414: int opcnt, nextopand; ! 415: register int c; ! 416: ! 417: nextopand = -1; ! 418: sign = 1; ! 419: opcnt = 0; ! 420: a = dot; ! 421: do { ! 422: do c = getchr(); while (c==' ' || c=='\t'); ! 423: if ('0'<=c && c<='9') { ! 424: peekc = c; ! 425: if (!opcnt) ! 426: a = zero; ! 427: a += sign*getnum(); ! 428: } else switch (c) { ! 429: case '$': ! 430: a = dol; ! 431: /* fall through */ ! 432: case '.': ! 433: if (opcnt) ! 434: error(Q); ! 435: break; ! 436: case '\'': ! 437: c = getchr(); ! 438: if (opcnt || c<'a' || 'z'<c) ! 439: error(Q); ! 440: a = zero; ! 441: do a++; while (a<=dol && names[c-'a']!=(*a&~01)); ! 442: break; ! 443: case '?': ! 444: sign = -sign; ! 445: /* fall through */ ! 446: case '/': ! 447: compile(c); ! 448: b = a; ! 449: for (;;) { ! 450: a += sign; ! 451: if (a<=zero) ! 452: a = dol; ! 453: if (a>dol) ! 454: a = zero; ! 455: if (execute(a)) ! 456: break; ! 457: if (a==b) ! 458: error(Q); ! 459: } ! 460: break; ! 461: default: ! 462: if (nextopand == opcnt) { ! 463: a += sign; ! 464: if (a<zero || dol<a) ! 465: continue; /* error(Q); */ ! 466: } ! 467: if (c!='+' && c!='-' && c!='^') { ! 468: peekc = c; ! 469: if (opcnt==0) ! 470: a = 0; ! 471: return (a); ! 472: } ! 473: sign = 1; ! 474: if (c!='+') ! 475: sign = -sign; ! 476: nextopand = ++opcnt; ! 477: continue; ! 478: } ! 479: sign = 1; ! 480: opcnt++; ! 481: } while (zero<=a && a<=dol); ! 482: error(Q); ! 483: /*NOTREACHED*/ ! 484: } ! 485: ! 486: int getnum() ! 487: { ! 488: register int r, c; ! 489: ! 490: r = 0; ! 491: while ((c=getchr())>='0' && c<='9') ! 492: r = r*10 + c - '0'; ! 493: peekc = c; ! 494: return (r); ! 495: } ! 496: ! 497: setwide() ! 498: { ! 499: if (!given) { ! 500: addr1 = zero + (dol>zero); ! 501: addr2 = dol; ! 502: } ! 503: } ! 504: ! 505: setnoaddr() ! 506: { ! 507: if (given) ! 508: error(Q); ! 509: } ! 510: ! 511: nonzero() ! 512: { ! 513: squeeze(1); ! 514: } ! 515: ! 516: squeeze(i) ! 517: int i; ! 518: { ! 519: if (addr1<zero+i || addr2>dol || addr1>addr2) ! 520: error(Q); ! 521: } ! 522: ! 523: newline() ! 524: { ! 525: register c; ! 526: ! 527: if ((c = getchr()) == '\n' || c == EOF) ! 528: return; ! 529: if (c=='p' || c=='l' || c=='n') { ! 530: pflag++; ! 531: if (c=='l') ! 532: listf++; ! 533: else if (c=='n') ! 534: listn++; ! 535: if ((c=getchr())=='\n') ! 536: return; ! 537: } ! 538: error(Q); ! 539: } ! 540: ! 541: filename(comm) ! 542: { ! 543: register char *p1, *p2; ! 544: register c; ! 545: ! 546: count = 0; ! 547: c = getchr(); ! 548: if (c=='\n' || c==EOF) { ! 549: p1 = savedfile; ! 550: if (*p1==0 && comm!='f') ! 551: error(Q); ! 552: p2 = file; ! 553: while (*p2++ = *p1++) ! 554: ; ! 555: return; ! 556: } ! 557: if (c!=' ') ! 558: error(Q); ! 559: while ((c = getchr()) == ' ') ! 560: ; ! 561: if (c=='\n') ! 562: error(Q); ! 563: p1 = file; ! 564: do { ! 565: if (p1 >= &file[sizeof(file)-1] || c==' ' || c==EOF) ! 566: error(Q); ! 567: *p1++ = c; ! 568: } while ((c = getchr()) != '\n'); ! 569: *p1++ = 0; ! 570: if (savedfile[0]==0 || comm=='e' || comm=='f') { ! 571: p1 = savedfile; ! 572: p2 = file; ! 573: while (*p1++ = *p2++) ! 574: ; ! 575: } ! 576: } ! 577: ! 578: exfile() ! 579: { ! 580: close(io); ! 581: io = -1; ! 582: if (vflag) { ! 583: putd(); ! 584: putchr('\n'); ! 585: } ! 586: } ! 587: ! 588: onintr() ! 589: { ! 590: signal(SIGINT, onintr); ! 591: putchr('\n'); ! 592: lastc = '\n'; ! 593: error(Q); ! 594: } ! 595: ! 596: onhup() ! 597: { ! 598: signal(SIGINT, SIG_IGN); ! 599: signal(SIGHUP, SIG_IGN); ! 600: if (dol > zero) { ! 601: addr1 = zero+1; ! 602: addr2 = dol; ! 603: io = creat("ed.hup", 0600); ! 604: if (io > 0) ! 605: putfile(); ! 606: } ! 607: fchange = 0; ! 608: quit(); ! 609: } ! 610: ! 611: error(s) ! 612: char *s; ! 613: { ! 614: register c; ! 615: ! 616: wrapp = 0; ! 617: listf = 0; ! 618: listn = 0; ! 619: putchr('?'); ! 620: puts(s); ! 621: count = 0; ! 622: lseek(0, (long)0, 2); ! 623: pflag = 0; ! 624: if (globp) ! 625: lastc = '\n'; ! 626: globp = 0; ! 627: peekc = lastc; ! 628: if(lastc) ! 629: while ((c = getchr()) != '\n' && c != EOF) ! 630: ; ! 631: if (io > 0) { ! 632: close(io); ! 633: io = -1; ! 634: } ! 635: longjmp(savej, 1); ! 636: } ! 637: ! 638: getchr() ! 639: { ! 640: char c; ! 641: if (lastc=peekc) { ! 642: peekc = 0; ! 643: return(lastc); ! 644: } ! 645: if (globp) { ! 646: if ((lastc = *globp++) != 0) ! 647: return(lastc); ! 648: globp = 0; ! 649: return(EOF); ! 650: } ! 651: if (read(0, &c, 1) <= 0) ! 652: return(lastc = EOF); ! 653: lastc = c&0177; ! 654: return(lastc); ! 655: } ! 656: ! 657: gettty() ! 658: { ! 659: register int rc; ! 660: ! 661: if (rc = gety()) ! 662: return(rc); ! 663: if (linebuf[0]=='.' && linebuf[1]==0) ! 664: return(EOF); ! 665: return(0); ! 666: } ! 667: ! 668: gety() ! 669: { ! 670: register int c; ! 671: register char *gf; ! 672: register char *p; ! 673: ! 674: p = linebuf; ! 675: gf = globp; ! 676: while ((c = getchr()) != '\n') { ! 677: if (c==EOF) { ! 678: if (gf) ! 679: peekc = c; ! 680: return(c); ! 681: } ! 682: if ((c &= 0177) == 0) ! 683: continue; ! 684: *p++ = c; ! 685: if (p >= &linebuf[LBSIZE-2]) ! 686: error(Q); ! 687: } ! 688: ! 689: *p++ = 0; ! 690: return(0); ! 691: } ! 692: ! 693: getfile() ! 694: { ! 695: register c; ! 696: register char *lp, *fp; ! 697: ! 698: lp = linebuf; ! 699: fp = nextip; ! 700: do { ! 701: if (--ninbuf < 0) { ! 702: if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) ! 703: if (lp>linebuf) { ! 704: puts("'\\n' appended"); ! 705: *genbuf = '\n'; ! 706: } ! 707: else return(EOF); ! 708: fp = genbuf; ! 709: while(fp < &genbuf[ninbuf]) { ! 710: if (*fp++ & 0200) ! 711: break; ! 712: } ! 713: fp = genbuf; ! 714: } ! 715: c = *fp++; ! 716: if (c=='\0') ! 717: continue; ! 718: if (c&0200 || lp >= &linebuf[LBSIZE]) { ! 719: lastc = '\n'; ! 720: error(Q); ! 721: } ! 722: *lp++ = c; ! 723: count++; ! 724: } while (c != '\n'); ! 725: *--lp = 0; ! 726: nextip = fp; ! 727: return(0); ! 728: } ! 729: ! 730: putfile() ! 731: { ! 732: register unsigned *a1; ! 733: register int n; ! 734: register char *fp, *lp; ! 735: register nib; ! 736: ! 737: nib = BLKSIZE; ! 738: fp = genbuf; ! 739: a1 = addr1; ! 740: do { ! 741: lp = getline(*a1++); ! 742: for (;;) { ! 743: if (--nib < 0) { ! 744: n = fp-genbuf; ! 745: if(write(io, genbuf, n) != n) { ! 746: puts(WRERR); ! 747: error(Q); ! 748: } ! 749: nib = BLKSIZE-1; ! 750: fp = genbuf; ! 751: } ! 752: count++; ! 753: if ((*fp++ = *lp++) == 0) { ! 754: fp[-1] = '\n'; ! 755: break; ! 756: } ! 757: } ! 758: } while (a1 <= addr2); ! 759: n = fp-genbuf; ! 760: if(write(io, genbuf, n) != n) { ! 761: puts(WRERR); ! 762: error(Q); ! 763: } ! 764: } ! 765: ! 766: append(f, a) ! 767: unsigned *a; ! 768: int (*f)(); ! 769: { ! 770: register unsigned *a1, *a2, *rdot; ! 771: int nline, tl; ! 772: ! 773: nline = 0; ! 774: dot = a; ! 775: while ((*f)() == 0) { ! 776: if ((dol-zero)+1 >= nlall) { ! 777: unsigned *ozero = zero; ! 778: ! 779: nlall += 1024; ! 780: if ((zero = (unsigned *)realloc((char *)zero, nlall*sizeof(unsigned)))==NULL) { ! 781: error("MEM?"); ! 782: onhup(); ! 783: } ! 784: dot += zero - ozero; ! 785: dol += zero - ozero; ! 786: } ! 787: tl = putline(); ! 788: nline++; ! 789: a1 = ++dol; ! 790: a2 = a1+1; ! 791: rdot = ++dot; ! 792: while (a1 > rdot) ! 793: *--a2 = *--a1; ! 794: *rdot = tl; ! 795: } ! 796: return(nline); ! 797: } ! 798: ! 799: add(i) ! 800: int i; ! 801: { ! 802: if (i && (given || dol>zero)) { ! 803: addr1--; ! 804: addr2--; ! 805: } ! 806: squeeze(0); ! 807: newline(); ! 808: append(gettty, addr2); ! 809: } ! 810: ! 811: browse() ! 812: { ! 813: register forward, n; ! 814: static bformat; /*0*/ ! 815: static bnum; /*0*/ ! 816: ! 817: forward = 1; ! 818: if((peekc=getchr()) != '\n'){ ! 819: if (peekc=='-' || peekc=='+') { ! 820: if(peekc=='-') ! 821: forward=0; ! 822: getchr(); ! 823: } ! 824: if((n=getnum()) > 0) ! 825: bpagesize = n; ! 826: } ! 827: newline(); ! 828: if (pflag) { ! 829: bformat = listf; ! 830: bnum = listn; ! 831: } else { ! 832: listf = bformat; ! 833: listn = bnum; ! 834: } ! 835: if (forward) { ! 836: addr1 = addr2; ! 837: if((addr2 += bpagesize)>dol) ! 838: addr2 = dol; ! 839: } else { ! 840: if((addr1=addr2-bpagesize) <= zero) ! 841: addr1 = zero+1; ! 842: } ! 843: print(); ! 844: } ! 845: ! 846: callunix() ! 847: { ! 848: SIG_TYP savint; ! 849: register pid, rpid; ! 850: int retcode; ! 851: ! 852: setnoaddr(); ! 853: if ((pid = fork()) == 0) { ! 854: signal(SIGHUP, oldhup); ! 855: signal(SIGQUIT, oldquit); ! 856: execl("/bin/sh", "sh", "-t", 0); ! 857: exit(0100); ! 858: } ! 859: savint = signal(SIGINT, SIG_IGN); ! 860: while ((rpid = wait(&retcode)) != pid && rpid != -1) ! 861: ; ! 862: signal(SIGINT, savint); ! 863: if (vflag) { ! 864: puts("!"); ! 865: } ! 866: } ! 867: ! 868: quit() ! 869: { ! 870: if (vflag && fchange && dol!=zero) { ! 871: fchange = 0; ! 872: error(Q); ! 873: } ! 874: unlink(tfname); ! 875: exit(0); ! 876: } ! 877: ! 878: rdelete(ad1, ad2) ! 879: unsigned *ad1, *ad2; ! 880: { ! 881: register unsigned *a1, *a2, *a3; ! 882: ! 883: a1 = ad1; ! 884: a2 = ad2+1; ! 885: a3 = dol; ! 886: dol -= a2 - a1; ! 887: do { ! 888: *a1++ = *a2++; ! 889: } while (a2 <= a3); ! 890: a1 = ad1; ! 891: if (a1 > dol) ! 892: a1 = dol; ! 893: dot = a1; ! 894: fchange = 1; ! 895: } ! 896: ! 897: gdelete() ! 898: { ! 899: register unsigned *a1, *a2, *a3; ! 900: ! 901: a3 = dol; ! 902: for (a1=zero; (*a1&01)==0; a1++) ! 903: if (a1>=a3) ! 904: return; ! 905: for (a2=a1+1; a2<=a3;) { ! 906: if (*a2&01) { ! 907: a2++; ! 908: dot = a1; ! 909: } else ! 910: *a1++ = *a2++; ! 911: } ! 912: dol = a1-1; ! 913: if (dot>dol) ! 914: dot = dol; ! 915: fchange = 1; ! 916: } ! 917: ! 918: char * ! 919: getline(tl) ! 920: unsigned tl; ! 921: { ! 922: register char *bp, *lp; ! 923: register nl; ! 924: ! 925: lp = linebuf; ! 926: bp = getblock(tl, READ); ! 927: nl = nleft; ! 928: tl &= ~((BLKSIZE/2)-1); ! 929: while (*lp++ = *bp++) ! 930: if (--nl == 0) { ! 931: bp = getblock(tl+=(BLKSIZE/2), READ); ! 932: nl = nleft; ! 933: } ! 934: return(linebuf); ! 935: } ! 936: ! 937: putline() ! 938: { ! 939: register char *bp, *lp; ! 940: register nl; ! 941: register unsigned tl; ! 942: ! 943: fchange = 1; ! 944: lp = linebuf; ! 945: tl = tline; ! 946: bp = getblock(tl, WRITE); ! 947: nl = nleft; ! 948: tl &= ~((BLKSIZE/2)-1); ! 949: while (*bp = *lp++) { ! 950: if (*bp++ == '\n') { ! 951: *--bp = 0; ! 952: linebp = lp; ! 953: break; ! 954: } ! 955: if (--nl == 0) { ! 956: bp = getblock(tl+=(BLKSIZE/2), WRITE); ! 957: nl = nleft; ! 958: } ! 959: } ! 960: nl = tline; ! 961: tline += (((lp-linebuf)+03)>>1)&077776; ! 962: return(nl); ! 963: } ! 964: ! 965: char * ! 966: getblock(atl, iof) ! 967: unsigned atl; ! 968: { ! 969: extern read(), write(); ! 970: register bno, off; ! 971: ! 972: bno = (atl/(BLKSIZE/2)); ! 973: off = (atl<<1) & (BLKSIZE-1) & ~03; ! 974: if (bno >= NBLK) { ! 975: lastc = '\n'; ! 976: error(T); ! 977: } ! 978: nleft = BLKSIZE - off; ! 979: if (bno==iblock) { ! 980: ichanged |= iof; ! 981: return(ibuff+off); ! 982: } ! 983: if (bno==oblock) ! 984: return(obuff+off); ! 985: if (iof==READ) { ! 986: if (ichanged) ! 987: blkio(iblock, ibuff, write); ! 988: ichanged = 0; ! 989: iblock = bno; ! 990: blkio(bno, ibuff, read); ! 991: return(ibuff+off); ! 992: } ! 993: if (oblock>=0) ! 994: blkio(oblock, obuff, write); ! 995: oblock = bno; ! 996: return(obuff+off); ! 997: } ! 998: ! 999: blkio(b, buf, iofcn) ! 1000: char *buf; ! 1001: int (*iofcn)(); ! 1002: { ! 1003: lseek(tfile, (long)b*BLKSIZE, 0); ! 1004: if ((*iofcn)(tfile, buf, BLKSIZE) != BLKSIZE) { ! 1005: error(T); ! 1006: } ! 1007: } ! 1008: ! 1009: init() ! 1010: { ! 1011: register *markp; ! 1012: ! 1013: close(tfile); ! 1014: tline = 2; ! 1015: for (markp = names; markp < &names[26]; ) ! 1016: *markp++ = 0; ! 1017: subnewa = 0; ! 1018: anymarks = 0; ! 1019: iblock = -1; ! 1020: oblock = -1; ! 1021: ichanged = 0; ! 1022: close(creat(tfname, 0600)); ! 1023: tfile = open(tfname, 2); ! 1024: dot = dol = zero; ! 1025: } ! 1026: ! 1027: global(k) ! 1028: { ! 1029: register char *gp; ! 1030: register c; ! 1031: register unsigned *a1; ! 1032: char globuf[GBSIZE]; ! 1033: ! 1034: if (globp) ! 1035: error(Q); ! 1036: setwide(); ! 1037: squeeze(dol>zero); ! 1038: if ((c=getchr())=='\n') ! 1039: error(Q); ! 1040: compile(c); ! 1041: gp = globuf; ! 1042: while ((c = getchr()) != '\n') { ! 1043: if (c==EOF) ! 1044: error(Q); ! 1045: if (c=='\\') { ! 1046: c = getchr(); ! 1047: if (c!='\n') ! 1048: *gp++ = '\\'; ! 1049: } ! 1050: *gp++ = c; ! 1051: if (gp >= &globuf[GBSIZE-2]) ! 1052: error(Q); ! 1053: } ! 1054: if (gp == globuf) ! 1055: *gp++ = 'p'; ! 1056: *gp++ = '\n'; ! 1057: *gp++ = 0; ! 1058: for (a1=zero; a1<=dol; a1++) { ! 1059: *a1 &= ~01; ! 1060: if (a1>=addr1 && a1<=addr2 && execute(a1)==k) ! 1061: *a1 |= 01; ! 1062: } ! 1063: /* ! 1064: * Special case: g/.../d (avoid n^2 algorithm) ! 1065: */ ! 1066: if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') { ! 1067: gdelete(); ! 1068: return; ! 1069: } ! 1070: for (a1=zero; a1<=dol; a1++) { ! 1071: if (*a1 & 01) { ! 1072: *a1 &= ~01; ! 1073: dot = a1; ! 1074: globp = globuf; ! 1075: commands(); ! 1076: a1 = zero; ! 1077: } ! 1078: } ! 1079: } ! 1080: ! 1081: join() ! 1082: { ! 1083: register char *gp, *lp; ! 1084: register unsigned *a1; ! 1085: ! 1086: nonzero(); ! 1087: gp = genbuf; ! 1088: for (a1=addr1; a1<=addr2; a1++) { ! 1089: lp = getline(*a1); ! 1090: while (*gp = *lp++) ! 1091: if (gp++ >= &genbuf[LBSIZE-2]) ! 1092: error(Q); ! 1093: } ! 1094: lp = linebuf; ! 1095: gp = genbuf; ! 1096: while (*lp++ = *gp++) ! 1097: ; ! 1098: *addr1 = putline(); ! 1099: if (addr1<addr2) ! 1100: rdelete(addr1+1, addr2); ! 1101: dot = addr1; ! 1102: } ! 1103: ! 1104: substitute(inglob) ! 1105: { ! 1106: register *mp, nl; ! 1107: register unsigned *a1; ! 1108: int gsubf; ! 1109: int getsub(); ! 1110: int n; ! 1111: ! 1112: n = getnum(); /* OK even if n==0 */ ! 1113: gsubf = compsub(); ! 1114: for (a1 = addr1; a1 <= addr2; a1++) { ! 1115: if (execute(a1)){ ! 1116: unsigned *ozero; ! 1117: int m = n; ! 1118: do { ! 1119: int span = loc2-loc1; ! 1120: if (--m <= 0) { ! 1121: dosub(); ! 1122: if (!gsubf) ! 1123: break; ! 1124: if (span==0) { /* null RE match */ ! 1125: if (*loc2=='\0') ! 1126: break; ! 1127: loc2++; ! 1128: } ! 1129: } ! 1130: } while (execute((unsigned *)0)); ! 1131: if (m <= 0) { ! 1132: inglob |= 01; ! 1133: subnewa = putline(); ! 1134: *a1 &= ~01; ! 1135: if (anymarks) { ! 1136: for (mp = names; mp < &names[26]; mp++) ! 1137: if (*mp == *a1) ! 1138: *mp = subnewa; ! 1139: } ! 1140: subolda = *a1; ! 1141: *a1 = subnewa; ! 1142: ozero = zero; ! 1143: nl = append(getsub, a1); ! 1144: nl += zero-ozero; ! 1145: a1 += nl; ! 1146: addr2 += nl; ! 1147: } ! 1148: } ! 1149: } ! 1150: if (inglob==0) ! 1151: error(Q); ! 1152: } ! 1153: ! 1154: compsub() ! 1155: { ! 1156: register seof, c; ! 1157: register char *p; ! 1158: ! 1159: if ((seof = getchr()) == '\n' || seof == ' ') ! 1160: error(Q); ! 1161: compile(seof); ! 1162: p = rhsbuf; ! 1163: for (;;) { ! 1164: c = getchr(); ! 1165: if (c=='\\') ! 1166: c = getchr() | 0200; ! 1167: if (c=='\n') { ! 1168: if (globp && globp[0]) /* last '\n' does not count */ ! 1169: c |= 0200; ! 1170: else { ! 1171: peekc = c; ! 1172: pflag++; ! 1173: break; ! 1174: } ! 1175: } ! 1176: if (c==seof) ! 1177: break; ! 1178: *p++ = c; ! 1179: if (p >= &rhsbuf[LBSIZE/2]) ! 1180: error(Q); ! 1181: } ! 1182: *p++ = 0; ! 1183: if ((peekc = getchr()) == 'g') { ! 1184: peekc = 0; ! 1185: newline(); ! 1186: return(1); ! 1187: } ! 1188: newline(); ! 1189: return(0); ! 1190: } ! 1191: ! 1192: getsub() ! 1193: { ! 1194: register char *p1, *p2; ! 1195: ! 1196: p1 = linebuf; ! 1197: if ((p2 = linebp) == 0) ! 1198: return(EOF); ! 1199: while (*p1++ = *p2++) ! 1200: ; ! 1201: linebp = 0; ! 1202: return(0); ! 1203: } ! 1204: ! 1205: dosub() ! 1206: { ! 1207: register char *lp, *sp, *rp; ! 1208: int c; ! 1209: ! 1210: lp = linebuf; ! 1211: sp = genbuf; ! 1212: rp = rhsbuf; ! 1213: while (lp < loc1) ! 1214: *sp++ = *lp++; ! 1215: while (c = *rp++&0377) { ! 1216: if (c=='&') { ! 1217: sp = place(sp, loc1, loc2); ! 1218: continue; ! 1219: } else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') { ! 1220: sp = place(sp, braslist[c-'1'], braelist[c-'1']); ! 1221: continue; ! 1222: } ! 1223: *sp++ = c&0177; ! 1224: if (sp >= &genbuf[LBSIZE]) ! 1225: error(Q); ! 1226: } ! 1227: lp = loc2; ! 1228: loc2 = sp - genbuf + linebuf; ! 1229: while (*sp++ = *lp++) ! 1230: if (sp >= &genbuf[LBSIZE]) ! 1231: error(Q); ! 1232: lp = linebuf; ! 1233: sp = genbuf; ! 1234: while (*lp++ = *sp++) ! 1235: ; ! 1236: } ! 1237: ! 1238: char * ! 1239: place(sp, l1, l2) ! 1240: register char *sp, *l1, *l2; ! 1241: { ! 1242: ! 1243: while (l1 < l2) { ! 1244: *sp++ = *l1++; ! 1245: if (sp >= &genbuf[LBSIZE]) ! 1246: error(Q); ! 1247: } ! 1248: return(sp); ! 1249: } ! 1250: ! 1251: move(cflag) ! 1252: { ! 1253: register unsigned *adt, *ad1, *ad2; ! 1254: int getcopy(); ! 1255: ! 1256: nonzero(); ! 1257: if ((adt = address())==0) /* address() guarantees addr is in range */ ! 1258: error(Q); ! 1259: newline(); ! 1260: if (cflag) { ! 1261: register unsigned *ozero; ! 1262: int delta; ! 1263: ! 1264: ad1 = dol; ! 1265: ozero = zero; ! 1266: append(getcopy, ad1++); ! 1267: ad2 = dol; ! 1268: delta = zero - ozero; ! 1269: ad1 += delta; ! 1270: adt += delta; ! 1271: } else { ! 1272: ad2 = addr2; ! 1273: for (ad1 = addr1; ad1 <= ad2;) ! 1274: *ad1++ &= ~01; ! 1275: ad1 = addr1; ! 1276: } ! 1277: ad2++; ! 1278: if (adt<ad1) { ! 1279: dot = adt + (ad2-ad1); ! 1280: if ((++adt)==ad1) ! 1281: return; ! 1282: reverse(adt, ad1); ! 1283: reverse(ad1, ad2); ! 1284: reverse(adt, ad2); ! 1285: } else if (adt >= ad2) { ! 1286: dot = adt++; ! 1287: reverse(ad1, ad2); ! 1288: reverse(ad2, adt); ! 1289: reverse(ad1, adt); ! 1290: } else ! 1291: error(Q); ! 1292: fchange = 1; ! 1293: } ! 1294: ! 1295: reverse(a1, a2) ! 1296: register unsigned *a1, *a2; ! 1297: { ! 1298: register int t; ! 1299: ! 1300: for (;;) { ! 1301: t = *--a2; ! 1302: if (a2 <= a1) ! 1303: return; ! 1304: *a2 = *a1; ! 1305: *a1++ = t; ! 1306: } ! 1307: } ! 1308: ! 1309: getcopy() ! 1310: { ! 1311: if (addr1 > addr2) ! 1312: return(EOF); ! 1313: getline(*addr1++); ! 1314: return(0); ! 1315: } ! 1316: ! 1317: compile(eof) ! 1318: register eof; ! 1319: { ! 1320: register c; ! 1321: register char *ep; ! 1322: char *lastep; ! 1323: char bracket[NBRA], *bracketp; ! 1324: int cclcnt; ! 1325: ! 1326: ep = expbuf; ! 1327: bracketp = bracket; ! 1328: if ((c = getchr()) == '\n') { ! 1329: peekc = c; ! 1330: c = eof; ! 1331: } ! 1332: if (c == eof) { ! 1333: if (*ep==0) ! 1334: error(Q); ! 1335: return; ! 1336: } ! 1337: nbra = 0; ! 1338: if (c=='^') { ! 1339: c = getchr(); ! 1340: *ep++ = CCIRC; ! 1341: } ! 1342: peekc = c; ! 1343: lastep = 0; ! 1344: for (;;) { ! 1345: if (ep >= &expbuf[ESIZE]) ! 1346: goto cerror; ! 1347: c = getchr(); ! 1348: if (c == '\n') { ! 1349: peekc = c; ! 1350: c = eof; ! 1351: } ! 1352: if (c==eof) { ! 1353: if (bracketp != bracket) ! 1354: goto cerror; ! 1355: *ep++ = CEOF; ! 1356: return; ! 1357: } ! 1358: if (c!='*') ! 1359: lastep = ep; ! 1360: switch (c) { ! 1361: ! 1362: case '\\': ! 1363: if ((c = getchr())=='(') { ! 1364: if (nbra >= NBRA) ! 1365: goto cerror; ! 1366: *bracketp++ = nbra; ! 1367: *ep++ = CBRA; ! 1368: *ep++ = nbra++; ! 1369: continue; ! 1370: } ! 1371: if (c == ')') { ! 1372: if (bracketp <= bracket) ! 1373: goto cerror; ! 1374: *ep++ = CKET; ! 1375: *ep++ = *--bracketp; ! 1376: continue; ! 1377: } ! 1378: if (c>='1' && c<'1'+NBRA) { ! 1379: *ep++ = CBACK; ! 1380: *ep++ = c-'1'; ! 1381: continue; ! 1382: } ! 1383: *ep++ = CCHR; ! 1384: if (c=='\n') ! 1385: goto cerror; ! 1386: *ep++ = c; ! 1387: continue; ! 1388: ! 1389: case '.': ! 1390: *ep++ = CDOT; ! 1391: continue; ! 1392: ! 1393: case '\n': ! 1394: goto cerror; ! 1395: ! 1396: case '*': ! 1397: if (lastep==0 || *lastep==CBRA || *lastep==CKET) ! 1398: goto defchar; ! 1399: *lastep |= STAR; ! 1400: continue; ! 1401: ! 1402: case '$': ! 1403: if ((peekc=getchr()) != eof && peekc!='\n') ! 1404: goto defchar; ! 1405: *ep++ = CDOL; ! 1406: continue; ! 1407: ! 1408: case '[': ! 1409: *ep++ = CCL; ! 1410: *ep++ = 0; ! 1411: cclcnt = 1; ! 1412: if ((c=getchr()) == '^') { ! 1413: c = getchr(); ! 1414: ep[-2] = NCCL; ! 1415: } ! 1416: do { ! 1417: if (c=='\n') ! 1418: goto cerror; ! 1419: if (c=='-' && ep[-1]!=0) { ! 1420: if ((c=getchr())==']') { ! 1421: *ep++ = '-'; ! 1422: cclcnt++; ! 1423: break; ! 1424: } ! 1425: while (ep[-1]<c) { ! 1426: *ep = ep[-1]+1; ! 1427: ep++; ! 1428: cclcnt++; ! 1429: if (ep>=&expbuf[ESIZE]) ! 1430: goto cerror; ! 1431: } ! 1432: } ! 1433: *ep++ = c; ! 1434: cclcnt++; ! 1435: if (ep >= &expbuf[ESIZE]) ! 1436: goto cerror; ! 1437: } while ((c = getchr()) != ']'); ! 1438: lastep[1] = cclcnt; ! 1439: continue; ! 1440: ! 1441: defchar: ! 1442: default: ! 1443: *ep++ = CCHR; ! 1444: *ep++ = c; ! 1445: } ! 1446: } ! 1447: cerror: ! 1448: expbuf[0] = 0; ! 1449: nbra = 0; ! 1450: error(Q); ! 1451: } ! 1452: ! 1453: execute(addr) ! 1454: unsigned register *addr; ! 1455: { ! 1456: register char *p1, *p2; ! 1457: register c; ! 1458: ! 1459: for (c=0; c<NBRA; c++) { ! 1460: braslist[c] = 0; ! 1461: braelist[c] = 0; ! 1462: } ! 1463: p2 = expbuf; ! 1464: if (addr == (unsigned *)0) { ! 1465: if (*p2==CCIRC) ! 1466: return(0); ! 1467: p1 = loc2; ! 1468: } else if (addr==zero) ! 1469: return(0); ! 1470: else ! 1471: p1 = getline(*addr); ! 1472: if (*p2==CCIRC) { ! 1473: loc1 = p1; ! 1474: return(advance(p1, p2+1)); ! 1475: } ! 1476: /* fast check for first character */ ! 1477: if (*p2==CCHR) { ! 1478: c = p2[1]; ! 1479: do { ! 1480: if (*p1!=c) ! 1481: continue; ! 1482: if (advance(p1, p2)) { ! 1483: loc1 = p1; ! 1484: return(1); ! 1485: } ! 1486: } while (*p1++); ! 1487: return(0); ! 1488: } ! 1489: /* regular algorithm */ ! 1490: do { ! 1491: if (advance(p1, p2)) { ! 1492: loc1 = p1; ! 1493: return(1); ! 1494: } ! 1495: } while (*p1++); ! 1496: return(0); ! 1497: } ! 1498: ! 1499: advance(lp, ep) ! 1500: register char *ep, *lp; ! 1501: { ! 1502: register char *curlp; ! 1503: int i; ! 1504: ! 1505: for (;;) switch (*ep++) { ! 1506: ! 1507: case CCHR: ! 1508: if (*ep++ == *lp++) ! 1509: continue; ! 1510: return(0); ! 1511: ! 1512: case CDOT: ! 1513: if (*lp++) ! 1514: continue; ! 1515: return(0); ! 1516: ! 1517: case CDOL: ! 1518: if (*lp==0) ! 1519: continue; ! 1520: return(0); ! 1521: ! 1522: case CEOF: ! 1523: loc2 = lp; ! 1524: return(1); ! 1525: ! 1526: case CCL: ! 1527: if (cclass(ep, *lp++, 1)) { ! 1528: ep += *ep; ! 1529: continue; ! 1530: } ! 1531: return(0); ! 1532: ! 1533: case NCCL: ! 1534: if (cclass(ep, *lp++, 0)) { ! 1535: ep += *ep; ! 1536: continue; ! 1537: } ! 1538: return(0); ! 1539: ! 1540: case CBRA: ! 1541: braslist[*ep++] = lp; ! 1542: continue; ! 1543: ! 1544: case CKET: ! 1545: braelist[*ep++] = lp; ! 1546: continue; ! 1547: ! 1548: case CBACK: ! 1549: if (braelist[i = *ep++]==0) ! 1550: error(Q); ! 1551: if (backref(i, lp)) { ! 1552: lp += braelist[i] - braslist[i]; ! 1553: continue; ! 1554: } ! 1555: return(0); ! 1556: ! 1557: case CBACK|STAR: ! 1558: if (braelist[i = *ep++] == 0) ! 1559: error(Q); ! 1560: curlp = lp; ! 1561: if (braelist[i] - braslist[i] == 0) ! 1562: continue; ! 1563: while (backref(i, lp)) ! 1564: lp += braelist[i] - braslist[i]; ! 1565: while (lp >= curlp) { ! 1566: if (advance(lp, ep)) ! 1567: return(1); ! 1568: lp -= braelist[i] - braslist[i]; ! 1569: } ! 1570: continue; ! 1571: ! 1572: case CDOT|STAR: ! 1573: curlp = lp; ! 1574: while (*lp++) ! 1575: ; ! 1576: goto star; ! 1577: ! 1578: case CCHR|STAR: ! 1579: curlp = lp; ! 1580: while (*lp++ == *ep) ! 1581: ; ! 1582: ep++; ! 1583: goto star; ! 1584: ! 1585: case CCL|STAR: ! 1586: case NCCL|STAR: ! 1587: curlp = lp; ! 1588: while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))) ! 1589: ; ! 1590: ep += *ep; ! 1591: goto star; ! 1592: ! 1593: star: ! 1594: do { ! 1595: lp--; ! 1596: if (advance(lp, ep)) ! 1597: return(1); ! 1598: } while (lp > curlp); ! 1599: return(0); ! 1600: ! 1601: default: ! 1602: error(Q); ! 1603: } ! 1604: } ! 1605: ! 1606: backref(i, lp) ! 1607: register i; ! 1608: register char *lp; ! 1609: { ! 1610: register char *bp; ! 1611: ! 1612: bp = braslist[i]; ! 1613: while (*bp++ == *lp++) ! 1614: if (bp >= braelist[i]) ! 1615: return(1); ! 1616: return(0); ! 1617: } ! 1618: ! 1619: cclass(set, c, af) ! 1620: register char *set; ! 1621: register c; ! 1622: { ! 1623: register n; ! 1624: ! 1625: if (c==0) ! 1626: return(0); ! 1627: n = *set++; ! 1628: while (--n) ! 1629: if (*set++ == c) ! 1630: return(af); ! 1631: return(!af); ! 1632: } ! 1633: ! 1634: putd() ! 1635: { ! 1636: register r; ! 1637: ! 1638: r = count%10; ! 1639: count /= 10; ! 1640: if (count) ! 1641: putd(); ! 1642: putchr(r + '0'); ! 1643: } ! 1644: ! 1645: puts(sp) ! 1646: register char *sp; ! 1647: { ! 1648: col = 0; ! 1649: while (*sp) ! 1650: putchr(*sp++); ! 1651: putchr('\n'); ! 1652: } ! 1653: ! 1654: char line[70]; ! 1655: char *linp = line; ! 1656: ! 1657: putchr(ac) ! 1658: { ! 1659: register char *lp; ! 1660: register c; ! 1661: ! 1662: lp = linp; ! 1663: c = ac; ! 1664: if (listf) { ! 1665: if (c=='\n') { ! 1666: if (linp!=line && linp[-1]==' ') { ! 1667: *lp++ = '\\'; ! 1668: *lp++ = 'n'; ! 1669: } ! 1670: } else { ! 1671: if (col > (72-4-2)) { ! 1672: col = 8; ! 1673: *lp++ = '\\'; ! 1674: *lp++ = '\n'; ! 1675: *lp++ = '\t'; ! 1676: } ! 1677: col++; ! 1678: if (c=='\b' || c=='\t' || c=='\\') { ! 1679: *lp++ = '\\'; ! 1680: if (c=='\b') ! 1681: c = 'b'; ! 1682: else if (c=='\t') ! 1683: c = 't'; ! 1684: col++; ! 1685: } else if (c<' ' || c=='\177') { ! 1686: *lp++ = '\\'; ! 1687: *lp++ = (c>>6) +'0'; ! 1688: *lp++ = ((c>>3)&07)+'0'; ! 1689: c = ( c &07)+'0'; ! 1690: col += 3; ! 1691: } ! 1692: } ! 1693: } ! 1694: *lp++ = c; ! 1695: if(c == '\n' || lp >= &line[64]) { ! 1696: linp = line; ! 1697: write(oflag?2:1, line, lp-line); ! 1698: return; ! 1699: } ! 1700: linp = lp; ! 1701: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.