1: # 2: 3: /* 4: * Editor 5: */ 6: 7: #define SIGHUP 1 8: #define SIGINTR 2 9: #define SIGQUIT 3 10: #define FNSIZE 64 11: #define LBSIZE 512 12: #define ESIZE 128 13: #define GBSIZE 256 14: #define NBRA 5 15: #define EOF -1 16: 17: #define CBRA 1 18: #define CCHR 2 19: #define CDOT 4 20: #define CCL 6 21: #define NCCL 8 22: #define CDOL 10 23: #define CEOF 11 24: #define CKET 12 25: 26: #define STAR 01 27: 28: #define error goto errlab 29: #define READ 0 30: #define WRITE 1 31: 32: int peekc; 33: int lastc; 34: char savedfile[FNSIZE]; 35: char file[FNSIZE]; 36: char linebuf[LBSIZE]; 37: char rhsbuf[LBSIZE/2]; 38: char expbuf[ESIZE+4]; 39: int circfl; 40: int *zero; 41: int *dot; 42: int *dol; 43: int *endcore; 44: int *fendcore; 45: int *addr1; 46: int *addr2; 47: char genbuf[LBSIZE]; 48: int count[2]; 49: char *nextip; 50: char *linebp; 51: int ninbuf; 52: int io; 53: int pflag; 54: int onhup; 55: int onquit; 56: int vflag 1; 57: int listf; 58: int col; 59: char *globp; 60: int tfile -1; 61: int tline; 62: char *tfname; 63: char *loc1; 64: char *loc2; 65: char *locs; 66: char ibuff[512]; 67: int iblock -1; 68: char obuff[512]; 69: int oblock -1; 70: int ichanged; 71: int nleft; 72: int errfunc(); 73: int *errlab errfunc; 74: char TMPERR[] "TMP"; 75: int names[26]; 76: char *braslist[NBRA]; 77: char *braelist[NBRA]; 78: 79: main(argc, argv) 80: char **argv; 81: { 82: register char *p1, *p2; 83: extern int onintr(); 84: 85: onquit = signal(SIGQUIT, 1); 86: onhup = signal(SIGHUP, 1); 87: argv++; 88: if (argc > 1 && **argv=='-') { 89: vflag = 0; 90: /* allow debugging quits? */ 91: if ((*argv)[1]=='q') { 92: signal(SIGQUIT, 0); 93: vflag++; 94: } 95: argv++; 96: argc--; 97: } 98: if (argc>1) { 99: p1 = *argv; 100: p2 = savedfile; 101: while (*p2++ = *p1++); 102: globp = "r"; 103: } 104: fendcore = sbrk(0); 105: init(); 106: if ((signal(SIGINTR, 1) & 01) == 0) 107: signal(SIGINTR, onintr); 108: setexit(); 109: commands(); 110: unlink(tfname); 111: } 112: 113: commands() 114: { 115: int getfile(), gettty(); 116: register *a1, c; 117: register char *p; 118: int r; 119: 120: for (;;) { 121: if (pflag) { 122: pflag = 0; 123: addr1 = addr2 = dot; 124: goto print; 125: } 126: addr1 = 0; 127: addr2 = 0; 128: do { 129: addr1 = addr2; 130: if ((a1 = address())==0) { 131: c = getchar(); 132: break; 133: } 134: addr2 = a1; 135: if ((c=getchar()) == ';') { 136: c = ','; 137: dot = a1; 138: } 139: } while (c==','); 140: if (addr1==0) 141: addr1 = addr2; 142: switch(c) { 143: 144: case 'a': 145: setdot(); 146: newline(); 147: append(gettty, addr2); 148: continue; 149: 150: case 'c': 151: delete(); 152: append(gettty, addr1-1); 153: continue; 154: 155: case 'd': 156: delete(); 157: continue; 158: 159: case 'e': 160: setnoaddr(); 161: if ((peekc = getchar()) != ' ') 162: error; 163: savedfile[0] = 0; 164: init(); 165: addr2 = zero; 166: goto caseread; 167: 168: case 'f': 169: setnoaddr(); 170: if ((c = getchar()) != '\n') { 171: peekc = c; 172: savedfile[0] = 0; 173: filename(); 174: } 175: puts(savedfile); 176: continue; 177: 178: case 'g': 179: global(1); 180: continue; 181: 182: case 'i': 183: setdot(); 184: nonzero(); 185: newline(); 186: append(gettty, addr2-1); 187: continue; 188: 189: case 'k': 190: if ((c = getchar()) < 'a' || c > 'z') 191: error; 192: newline(); 193: setdot(); 194: nonzero(); 195: names[c-'a'] = *addr2 | 01; 196: continue; 197: 198: case 'm': 199: move(0); 200: continue; 201: 202: case '\n': 203: if (addr2==0) 204: addr2 = dot+1; 205: addr1 = addr2; 206: goto print; 207: 208: case 'l': 209: listf++; 210: case 'p': 211: newline(); 212: print: 213: setdot(); 214: nonzero(); 215: a1 = addr1; 216: do 217: puts(getline(*a1++)); 218: while (a1 <= addr2); 219: dot = addr2; 220: listf = 0; 221: continue; 222: 223: case 'q': 224: setnoaddr(); 225: newline(); 226: unlink(tfname); 227: exit(); 228: 229: case 'r': 230: caseread: 231: filename(); 232: if ((io = open(file, 0)) < 0) { 233: lastc = '\n'; 234: error; 235: } 236: setall(); 237: ninbuf = 0; 238: append(getfile, addr2); 239: exfile(); 240: continue; 241: 242: case 's': 243: setdot(); 244: nonzero(); 245: substitute(globp); 246: continue; 247: 248: case 't': 249: move(1); 250: continue; 251: 252: case 'v': 253: global(0); 254: continue; 255: 256: case 'w': 257: setall(); 258: nonzero(); 259: filename(); 260: if ((io = creat(file, 0666)) < 0) 261: error; 262: putfile(); 263: exfile(); 264: continue; 265: 266: case '=': 267: setall(); 268: newline(); 269: count[1] = (addr2-zero)&077777; 270: putd(); 271: putchar('\n'); 272: continue; 273: 274: case '!': 275: unix(); 276: continue; 277: 278: case EOF: 279: return; 280: 281: } 282: error; 283: } 284: } 285: 286: address() 287: { 288: register *a1, minus, c; 289: int n, relerr; 290: 291: minus = 0; 292: a1 = 0; 293: for (;;) { 294: c = getchar(); 295: if ('0'<=c && c<='9') { 296: n = 0; 297: do { 298: n =* 10; 299: n =+ c - '0'; 300: } while ((c = getchar())>='0' && c<='9'); 301: peekc = c; 302: if (a1==0) 303: a1 = zero; 304: if (minus<0) 305: n = -n; 306: a1 =+ n; 307: minus = 0; 308: continue; 309: } 310: relerr = 0; 311: if (a1 || minus) 312: relerr++; 313: switch(c) { 314: case ' ': 315: case '\t': 316: continue; 317: 318: case '+': 319: minus++; 320: if (a1==0) 321: a1 = dot; 322: continue; 323: 324: case '-': 325: case '^': 326: minus--; 327: if (a1==0) 328: a1 = dot; 329: continue; 330: 331: case '?': 332: case '/': 333: compile(c); 334: a1 = dot; 335: for (;;) { 336: if (c=='/') { 337: a1++; 338: if (a1 > dol) 339: a1 = zero; 340: } else { 341: a1--; 342: if (a1 < zero) 343: a1 = dol; 344: } 345: if (execute(0, a1)) 346: break; 347: if (a1==dot) 348: error; 349: } 350: break; 351: 352: case '$': 353: a1 = dol; 354: break; 355: 356: case '.': 357: a1 = dot; 358: break; 359: 360: case '\'': 361: if ((c = getchar()) < 'a' || c > 'z') 362: error; 363: for (a1=zero; a1<=dol; a1++) 364: if (names[c-'a'] == (*a1|01)) 365: break; 366: break; 367: 368: default: 369: peekc = c; 370: if (a1==0) 371: return(0); 372: a1 =+ minus; 373: if (a1<zero || a1>dol) 374: error; 375: return(a1); 376: } 377: if (relerr) 378: error; 379: } 380: } 381: 382: setdot() 383: { 384: if (addr2 == 0) 385: addr1 = addr2 = dot; 386: if (addr1 > addr2) 387: error; 388: } 389: 390: setall() 391: { 392: if (addr2==0) { 393: addr1 = zero+1; 394: addr2 = dol; 395: if (dol==zero) 396: addr1 = zero; 397: } 398: setdot(); 399: } 400: 401: setnoaddr() 402: { 403: if (addr2) 404: error; 405: } 406: 407: nonzero() 408: { 409: if (addr1<=zero || addr2>dol) 410: error; 411: } 412: 413: newline() 414: { 415: register c; 416: 417: if ((c = getchar()) == '\n') 418: return; 419: if (c=='p' || c=='l') { 420: pflag++; 421: if (c=='l') 422: listf++; 423: if (getchar() == '\n') 424: return; 425: } 426: error; 427: } 428: 429: filename() 430: { 431: register char *p1, *p2; 432: register c; 433: 434: count[1] = 0; 435: c = getchar(); 436: if (c=='\n' || c==EOF) { 437: p1 = savedfile; 438: if (*p1==0) 439: error; 440: p2 = file; 441: while (*p2++ = *p1++); 442: return; 443: } 444: if (c!=' ') 445: error; 446: while ((c = getchar()) == ' '); 447: if (c=='\n') 448: error; 449: p1 = file; 450: do { 451: *p1++ = c; 452: } while ((c = getchar()) != '\n'); 453: *p1++ = 0; 454: if (savedfile[0]==0) { 455: p1 = savedfile; 456: p2 = file; 457: while (*p1++ = *p2++); 458: } 459: } 460: 461: exfile() 462: { 463: close(io); 464: io = -1; 465: if (vflag) { 466: putd(); 467: putchar('\n'); 468: } 469: } 470: 471: onintr() 472: { 473: signal(SIGINTR, onintr); 474: putchar('\n'); 475: lastc = '\n'; 476: error; 477: } 478: 479: errfunc() 480: { 481: register c; 482: 483: listf = 0; 484: puts("?"); 485: count[0] = 0; 486: seek(0, 0, 2); 487: pflag = 0; 488: if (globp) 489: lastc = '\n'; 490: globp = 0; 491: peekc = lastc; 492: while ((c = getchar()) != '\n' && c != EOF); 493: if (io > 0) { 494: close(io); 495: io = -1; 496: } 497: reset(); 498: } 499: 500: getchar() 501: { 502: if (lastc=peekc) { 503: peekc = 0; 504: return(lastc); 505: } 506: if (globp) { 507: if ((lastc = *globp++) != 0) 508: return(lastc); 509: globp = 0; 510: return(EOF); 511: } 512: if (read(0, &lastc, 1) <= 0) 513: return(lastc = EOF); 514: lastc =& 0177; 515: return(lastc); 516: } 517: 518: gettty() 519: { 520: register c, gf; 521: register char *p; 522: 523: p = linebuf; 524: gf = globp; 525: while ((c = getchar()) != '\n') { 526: if (c==EOF) { 527: if (gf) 528: peekc = c; 529: return(c); 530: } 531: if ((c =& 0177) == 0) 532: continue; 533: *p++ = c; 534: if (p >= &linebuf[LBSIZE-2]) 535: error; 536: } 537: *p++ = 0; 538: if (linebuf[0]=='.' && linebuf[1]==0) 539: return(EOF); 540: return(0); 541: } 542: 543: getfile() 544: { 545: register c; 546: register char *lp, *fp; 547: 548: lp = linebuf; 549: fp = nextip; 550: do { 551: if (--ninbuf < 0) { 552: if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) 553: return(EOF); 554: fp = genbuf; 555: } 556: if (lp >= &linebuf[LBSIZE]) 557: error; 558: if ((*lp++ = c = *fp++ & 0177) == 0) { 559: lp--; 560: continue; 561: } 562: if (++count[1] == 0) 563: ++count[0]; 564: } while (c != '\n'); 565: *--lp = 0; 566: nextip = fp; 567: return(0); 568: } 569: 570: putfile() 571: { 572: int *a1; 573: register char *fp, *lp; 574: register nib; 575: 576: nib = 512; 577: fp = genbuf; 578: a1 = addr1; 579: do { 580: lp = getline(*a1++); 581: for (;;) { 582: if (--nib < 0) { 583: write(io, genbuf, fp-genbuf); 584: nib = 511; 585: fp = genbuf; 586: } 587: if (++count[1] == 0) 588: ++count[0]; 589: if ((*fp++ = *lp++) == 0) { 590: fp[-1] = '\n'; 591: break; 592: } 593: } 594: } while (a1 <= addr2); 595: write(io, genbuf, fp-genbuf); 596: } 597: 598: append(f, a) 599: int (*f)(); 600: { 601: register *a1, *a2, *rdot; 602: int nline, tl; 603: struct { int integer; }; 604: 605: nline = 0; 606: dot = a; 607: while ((*f)() == 0) { 608: if (dol >= endcore) { 609: if (sbrk(1024) == -1) 610: error; 611: endcore.integer =+ 1024; 612: } 613: tl = putline(); 614: nline++; 615: a1 = ++dol; 616: a2 = a1+1; 617: rdot = ++dot; 618: while (a1 > rdot) 619: *--a2 = *--a1; 620: *rdot = tl; 621: } 622: return(nline); 623: } 624: 625: unix() 626: { 627: register savint, pid, rpid; 628: int retcode; 629: 630: setnoaddr(); 631: if ((pid = fork()) == 0) { 632: signal(SIGHUP, onhup); 633: signal(SIGQUIT, onquit); 634: execl("/bin/sh", "sh", "-t", 0); 635: exit(); 636: } 637: savint = signal(SIGINTR, 1); 638: while ((rpid = wait(&retcode)) != pid && rpid != -1); 639: signal(SIGINTR, savint); 640: puts("!"); 641: } 642: 643: delete() 644: { 645: register *a1, *a2, *a3; 646: 647: setdot(); 648: newline(); 649: nonzero(); 650: a1 = addr1; 651: a2 = addr2+1; 652: a3 = dol; 653: dol =- a2 - a1; 654: do 655: *a1++ = *a2++; 656: while (a2 <= a3); 657: a1 = addr1; 658: if (a1 > dol) 659: a1 = dol; 660: dot = a1; 661: } 662: 663: getline(tl) 664: { 665: register char *bp, *lp; 666: register nl; 667: 668: lp = linebuf; 669: bp = getblock(tl, READ); 670: nl = nleft; 671: tl =& ~0377; 672: while (*lp++ = *bp++) 673: if (--nl == 0) { 674: bp = getblock(tl=+0400, READ); 675: nl = nleft; 676: } 677: return(linebuf); 678: } 679: 680: putline() 681: { 682: register char *bp, *lp; 683: register nl; 684: int tl; 685: 686: lp = linebuf; 687: tl = tline; 688: bp = getblock(tl, WRITE); 689: nl = nleft; 690: tl =& ~0377; 691: while (*bp = *lp++) { 692: if (*bp++ == '\n') { 693: *--bp = 0; 694: linebp = lp; 695: break; 696: } 697: if (--nl == 0) { 698: bp = getblock(tl=+0400, WRITE); 699: nl = nleft; 700: } 701: } 702: nl = tline; 703: tline =+ (((lp-linebuf)+03)>>1)&077776; 704: return(nl); 705: } 706: 707: getblock(atl, iof) 708: { 709: extern read(), write(); 710: register bno, off; 711: 712: bno = (atl>>8)&0377; 713: off = (atl<<1)&0774; 714: if (bno >= 255) { 715: puts(TMPERR); 716: error; 717: } 718: nleft = 512 - off; 719: if (bno==iblock) { 720: ichanged =| iof; 721: return(ibuff+off); 722: } 723: if (bno==oblock) 724: return(obuff+off); 725: if (iof==READ) { 726: if (ichanged) 727: blkio(iblock, ibuff, write); 728: ichanged = 0; 729: iblock = bno; 730: blkio(bno, ibuff, read); 731: return(ibuff+off); 732: } 733: if (oblock>=0) 734: blkio(oblock, obuff, write); 735: oblock = bno; 736: return(obuff+off); 737: } 738: 739: blkio(b, buf, iofcn) 740: int (*iofcn)(); 741: { 742: seek(tfile, b, 3); 743: if ((*iofcn)(tfile, buf, 512) != 512) { 744: puts(TMPERR); 745: error; 746: } 747: } 748: 749: init() 750: { 751: register char *p; 752: register pid; 753: 754: close(tfile); 755: tline = 0; 756: iblock = -1; 757: oblock = -1; 758: tfname = "/tmp/exxxxx"; 759: ichanged = 0; 760: pid = getpid(); 761: for (p = &tfname[11]; p > &tfname[6];) { 762: *--p = (pid&07) + '0'; 763: pid =>> 3; 764: } 765: close(creat(tfname, 0600)); 766: tfile = open(tfname, 2); 767: brk(fendcore); 768: dot = zero = dol = fendcore; 769: endcore = fendcore - 2; 770: } 771: 772: global(k) 773: { 774: register char *gp; 775: register c; 776: register int *a1; 777: char globuf[GBSIZE]; 778: 779: if (globp) 780: error; 781: setall(); 782: nonzero(); 783: if ((c=getchar())=='\n') 784: error; 785: compile(c); 786: gp = globuf; 787: while ((c = getchar()) != '\n') { 788: if (c==EOF) 789: error; 790: if (c=='\\') { 791: c = getchar(); 792: if (c!='\n') 793: *gp++ = '\\'; 794: } 795: *gp++ = c; 796: if (gp >= &globuf[GBSIZE-2]) 797: error; 798: } 799: *gp++ = '\n'; 800: *gp++ = 0; 801: for (a1=zero; a1<=dol; a1++) { 802: *a1 =& ~01; 803: if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k) 804: *a1 =| 01; 805: } 806: for (a1=zero; a1<=dol; a1++) { 807: if (*a1 & 01) { 808: *a1 =& ~01; 809: dot = a1; 810: globp = globuf; 811: commands(); 812: a1 = zero; 813: } 814: } 815: } 816: 817: substitute(inglob) 818: { 819: register gsubf, *a1, nl; 820: int getsub(); 821: 822: gsubf = compsub(); 823: for (a1 = addr1; a1 <= addr2; a1++) { 824: if (execute(0, a1)==0) 825: continue; 826: inglob =| 01; 827: dosub(); 828: if (gsubf) { 829: while (*loc2) { 830: if (execute(1)==0) 831: break; 832: dosub(); 833: } 834: } 835: *a1 = putline(); 836: nl = append(getsub, a1); 837: a1 =+ nl; 838: addr2 =+ nl; 839: } 840: if (inglob==0) 841: error; 842: } 843: 844: compsub() 845: { 846: register seof, c; 847: register char *p; 848: int gsubf; 849: 850: if ((seof = getchar()) == '\n') 851: error; 852: compile(seof); 853: p = rhsbuf; 854: for (;;) { 855: c = getchar(); 856: if (c=='\\') 857: c = getchar() | 0200; 858: if (c=='\n') 859: error; 860: if (c==seof) 861: break; 862: *p++ = c; 863: if (p >= &rhsbuf[LBSIZE/2]) 864: error; 865: } 866: *p++ = 0; 867: if ((peekc = getchar()) == 'g') { 868: peekc = 0; 869: newline(); 870: return(1); 871: } 872: newline(); 873: return(0); 874: } 875: 876: getsub() 877: { 878: register char *p1, *p2; 879: 880: p1 = linebuf; 881: if ((p2 = linebp) == 0) 882: return(EOF); 883: while (*p1++ = *p2++); 884: linebp = 0; 885: return(0); 886: } 887: 888: dosub() 889: { 890: register char *lp, *sp, *rp; 891: int c; 892: 893: lp = linebuf; 894: sp = genbuf; 895: rp = rhsbuf; 896: while (lp < loc1) 897: *sp++ = *lp++; 898: while (c = *rp++) { 899: if (c=='&') { 900: sp = place(sp, loc1, loc2); 901: continue; 902: } else if (c<0 && (c =& 0177) >='1' && c < NBRA+'1') { 903: sp = place(sp, braslist[c-'1'], braelist[c-'1']); 904: continue; 905: } 906: *sp++ = c&0177; 907: if (sp >= &genbuf[LBSIZE]) 908: error; 909: } 910: lp = loc2; 911: loc2 = sp + linebuf - genbuf; 912: while (*sp++ = *lp++) 913: if (sp >= &genbuf[LBSIZE]) 914: error; 915: lp = linebuf; 916: sp = genbuf; 917: while (*lp++ = *sp++); 918: } 919: 920: place(asp, al1, al2) 921: { 922: register char *sp, *l1, *l2; 923: 924: sp = asp; 925: l1 = al1; 926: l2 = al2; 927: while (l1 < l2) { 928: *sp++ = *l1++; 929: if (sp >= &genbuf[LBSIZE]) 930: error; 931: } 932: return(sp); 933: } 934: 935: move(cflag) 936: { 937: register int *adt, *ad1, *ad2; 938: int getcopy(); 939: 940: setdot(); 941: nonzero(); 942: if ((adt = address())==0) 943: error; 944: newline(); 945: ad1 = addr1; 946: ad2 = addr2; 947: if (cflag) { 948: ad1 = dol; 949: append(getcopy, ad1++); 950: ad2 = dol; 951: } 952: ad2++; 953: if (adt<ad1) { 954: dot = adt + (ad2-ad1); 955: if ((++adt)==ad1) 956: return; 957: reverse(adt, ad1); 958: reverse(ad1, ad2); 959: reverse(adt, ad2); 960: } else if (adt >= ad2) { 961: dot = adt++; 962: reverse(ad1, ad2); 963: reverse(ad2, adt); 964: reverse(ad1, adt); 965: } else 966: error; 967: } 968: 969: reverse(aa1, aa2) 970: { 971: register int *a1, *a2, t; 972: 973: a1 = aa1; 974: a2 = aa2; 975: for (;;) { 976: t = *--a2; 977: if (a2 <= a1) 978: return; 979: *a2 = *a1; 980: *a1++ = t; 981: } 982: } 983: 984: getcopy() 985: { 986: if (addr1 > addr2) 987: return(EOF); 988: getline(*addr1++); 989: return(0); 990: } 991: 992: compile(aeof) 993: { 994: register eof, c; 995: register char *ep; 996: char *lastep; 997: char bracket[NBRA], *bracketp; 998: int nbra; 999: int cclcnt; 1000: 1001: ep = expbuf; 1002: eof = aeof; 1003: bracketp = bracket; 1004: nbra = 0; 1005: if ((c = getchar()) == eof) { 1006: if (*ep==0) 1007: error; 1008: return; 1009: } 1010: circfl = 0; 1011: if (c=='^') { 1012: c = getchar(); 1013: circfl++; 1014: } 1015: if (c=='*') 1016: goto cerror; 1017: peekc = c; 1018: for (;;) { 1019: if (ep >= &expbuf[ESIZE]) 1020: goto cerror; 1021: c = getchar(); 1022: if (c==eof) { 1023: *ep++ = CEOF; 1024: return; 1025: } 1026: if (c!='*') 1027: lastep = ep; 1028: switch (c) { 1029: 1030: case '\\': 1031: if ((c = getchar())=='(') { 1032: if (nbra >= NBRA) 1033: goto cerror; 1034: *bracketp++ = nbra; 1035: *ep++ = CBRA; 1036: *ep++ = nbra++; 1037: continue; 1038: } 1039: if (c == ')') { 1040: if (bracketp <= bracket) 1041: goto cerror; 1042: *ep++ = CKET; 1043: *ep++ = *--bracketp; 1044: continue; 1045: } 1046: *ep++ = CCHR; 1047: if (c=='\n') 1048: goto cerror; 1049: *ep++ = c; 1050: continue; 1051: 1052: case '.': 1053: *ep++ = CDOT; 1054: continue; 1055: 1056: case '\n': 1057: goto cerror; 1058: 1059: case '*': 1060: if (*lastep==CBRA || *lastep==CKET) 1061: error; 1062: *lastep =| STAR; 1063: continue; 1064: 1065: case '$': 1066: if ((peekc=getchar()) != eof) 1067: goto defchar; 1068: *ep++ = CDOL; 1069: continue; 1070: 1071: case '[': 1072: *ep++ = CCL; 1073: *ep++ = 0; 1074: cclcnt = 1; 1075: if ((c=getchar()) == '^') { 1076: c = getchar(); 1077: ep[-2] = NCCL; 1078: } 1079: do { 1080: if (c=='\n') 1081: goto cerror; 1082: *ep++ = c; 1083: cclcnt++; 1084: if (ep >= &expbuf[ESIZE]) 1085: goto cerror; 1086: } while ((c = getchar()) != ']'); 1087: lastep[1] = cclcnt; 1088: continue; 1089: 1090: defchar: 1091: default: 1092: *ep++ = CCHR; 1093: *ep++ = c; 1094: } 1095: } 1096: cerror: 1097: expbuf[0] = 0; 1098: error; 1099: } 1100: 1101: execute(gf, addr) 1102: int *addr; 1103: { 1104: register char *p1, *p2, c; 1105: 1106: if (gf) { 1107: if (circfl) 1108: return(0); 1109: p1 = linebuf; 1110: p2 = genbuf; 1111: while (*p1++ = *p2++); 1112: locs = p1 = loc2; 1113: } else { 1114: if (addr==zero) 1115: return(0); 1116: p1 = getline(*addr); 1117: locs = 0; 1118: } 1119: p2 = expbuf; 1120: if (circfl) { 1121: loc1 = p1; 1122: return(advance(p1, p2)); 1123: } 1124: /* fast check for first character */ 1125: if (*p2==CCHR) { 1126: c = p2[1]; 1127: do { 1128: if (*p1!=c) 1129: continue; 1130: if (advance(p1, p2)) { 1131: loc1 = p1; 1132: return(1); 1133: } 1134: } while (*p1++); 1135: return(0); 1136: } 1137: /* regular algorithm */ 1138: do { 1139: if (advance(p1, p2)) { 1140: loc1 = p1; 1141: return(1); 1142: } 1143: } while (*p1++); 1144: return(0); 1145: } 1146: 1147: advance(alp, aep) 1148: { 1149: register char *lp, *ep, *curlp; 1150: char *nextep; 1151: 1152: lp = alp; 1153: ep = aep; 1154: for (;;) switch (*ep++) { 1155: 1156: case CCHR: 1157: if (*ep++ == *lp++) 1158: continue; 1159: return(0); 1160: 1161: case CDOT: 1162: if (*lp++) 1163: continue; 1164: return(0); 1165: 1166: case CDOL: 1167: if (*lp==0) 1168: continue; 1169: return(0); 1170: 1171: case CEOF: 1172: loc2 = lp; 1173: return(1); 1174: 1175: case CCL: 1176: if (cclass(ep, *lp++, 1)) { 1177: ep =+ *ep; 1178: continue; 1179: } 1180: return(0); 1181: 1182: case NCCL: 1183: if (cclass(ep, *lp++, 0)) { 1184: ep =+ *ep; 1185: continue; 1186: } 1187: return(0); 1188: 1189: case CBRA: 1190: braslist[*ep++] = lp; 1191: continue; 1192: 1193: case CKET: 1194: braelist[*ep++] = lp; 1195: continue; 1196: 1197: case CDOT|STAR: 1198: curlp = lp; 1199: while (*lp++); 1200: goto star; 1201: 1202: case CCHR|STAR: 1203: curlp = lp; 1204: while (*lp++ == *ep); 1205: ep++; 1206: goto star; 1207: 1208: case CCL|STAR: 1209: case NCCL|STAR: 1210: curlp = lp; 1211: while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); 1212: ep =+ *ep; 1213: goto star; 1214: 1215: star: 1216: do { 1217: lp--; 1218: if (lp==locs) 1219: break; 1220: if (advance(lp, ep)) 1221: return(1); 1222: } while (lp > curlp); 1223: return(0); 1224: 1225: default: 1226: error; 1227: } 1228: } 1229: 1230: cclass(aset, ac, af) 1231: { 1232: register char *set, c; 1233: register n; 1234: 1235: set = aset; 1236: if ((c = ac) == 0) 1237: return(0); 1238: n = *set++; 1239: while (--n) 1240: if (*set++ == c) 1241: return(af); 1242: return(!af); 1243: } 1244: 1245: putd() 1246: { 1247: register r; 1248: extern ldivr; 1249: 1250: count[1] = ldiv(count[0], count[1], 10); 1251: count[0] = 0; 1252: r = ldivr; 1253: if (count[1]) 1254: putd(); 1255: putchar(r + '0'); 1256: } 1257: 1258: puts(as) 1259: { 1260: register char *sp; 1261: 1262: sp = as; 1263: col = 0; 1264: while (*sp) 1265: putchar(*sp++); 1266: putchar('\n'); 1267: } 1268: 1269: char line[70]; 1270: char *linp line; 1271: 1272: putchar(ac) 1273: { 1274: register char *lp; 1275: register c; 1276: 1277: lp = linp; 1278: c = ac; 1279: if (listf) { 1280: col++; 1281: if (col >= 72) { 1282: col = 0; 1283: *lp++ = '\\'; 1284: *lp++ = '\n'; 1285: } 1286: if (c=='\t') { 1287: c = '>'; 1288: goto esc; 1289: } 1290: if (c=='\b') { 1291: c = '<'; 1292: esc: 1293: *lp++ = '-'; 1294: *lp++ = '\b'; 1295: *lp++ = c; 1296: goto out; 1297: } 1298: if (c<' ' && c!= '\n') { 1299: *lp++ = '\\'; 1300: *lp++ = (c>>3)+'0'; 1301: *lp++ = (c&07)+'0'; 1302: col =+ 2; 1303: goto out; 1304: } 1305: } 1306: *lp++ = c; 1307: out: 1308: if(c == '\n' || lp >= &line[64]) { 1309: linp = line; 1310: write(1, line, lp-line); 1311: return; 1312: } 1313: linp = lp; 1314: } 1315: 1316: /* 1317: * Get process ID routine if system call is unavailable. 1318: getpid() 1319: { 1320: register f; 1321: int b[1]; 1322: 1323: f = open("/dev/kmem", 0); 1324: if(f < 0) 1325: return(-1); 1326: seek(f, 0140074, 0); 1327: read(f, b, 2); 1328: seek(f, b[0]+8, 0); 1329: read(f, b, 2); 1330: close(f); 1331: return(b[0]); 1332: } 1333: */