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