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