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:  */

Defined functions

address defined in line 286; used 2 times
advance defined in line 1147; used 4 times
append defined in line 598; used 6 times
blkio defined in line 739; used 3 times
cclass defined in line 1230; used 3 times
commands defined in line 113; used 2 times
compile defined in line 992; used 3 times
compsub defined in line 844; used 1 times
delete defined in line 643; used 2 times
dosub defined in line 888; used 2 times
errfunc defined in line 479; used 1 times
  • in line 72
execute defined in line 1101; used 4 times
exfile defined in line 461; used 2 times
filename defined in line 429; used 3 times
getblock defined in line 707; used 4 times
getchar defined in line 500; used 30 times
getcopy defined in line 984; used 2 times
getfile defined in line 543; used 2 times
getline defined in line 663; used 4 times
getsub defined in line 876; used 2 times
gettty defined in line 518; used 4 times
global defined in line 772; used 2 times
init defined in line 749; used 2 times
main defined in line 79; never used
move defined in line 935; used 2 times
newline defined in line 413; used 10 times
nonzero defined in line 407; used 8 times
onintr defined in line 471; used 3 times
place defined in line 920; used 2 times
putchar defined in line 1272; used 6 times
putd defined in line 1245; used 3 times
putfile defined in line 570; used 1 times
putline defined in line 680; used 2 times
puts defined in line 1258; used 6 times
reverse defined in line 969; used 6 times
setall defined in line 390; used 4 times
setdot defined in line 382; used 8 times
setnoaddr defined in line 401; used 4 times
substitute defined in line 817; used 1 times
unix defined in line 625; used 1 times

Defined variables

TMPERR defined in line 74; used 2 times
addr1 defined in line 45; used 21 times
addr2 defined in line 46; used 30 times
braelist defined in line 77; used 2 times
braslist defined in line 76; used 2 times
circfl defined in line 39; used 4 times
col defined in line 58; used 5 times
count defined in line 48; used 12 times
dol defined in line 42; used 19 times
dot defined in line 41; used 17 times
endcore defined in line 43; used 3 times
errlab defined in line 73; used 1 times
  • in line 28
expbuf defined in line 38; used 5 times
fendcore defined in line 44; used 4 times
file defined in line 35; used 5 times
genbuf defined in line 47; used 15 times
globp defined in line 59; used 10 times
iblock defined in line 67; used 4 times
ibuff defined in line 66; used 4 times
ichanged defined in line 70; used 4 times
io defined in line 52; used 10 times
lastc defined in line 33; used 12 times
line defined in line 1270; used 4 times
linebp defined in line 50; used 3 times
linebuf defined in line 36; used 15 times
linp defined in line 1270; used 3 times
listf defined in line 57; used 5 times
loc1 defined in line 63; used 5 times
loc2 defined in line 64; used 6 times
locs defined in line 65; used 3 times
names defined in line 75; used 2 times
nextip defined in line 49; used 2 times
ninbuf defined in line 51; used 3 times
nleft defined in line 71; used 5 times
oblock defined in line 69; used 5 times
obuff defined in line 68; used 3 times
onhup defined in line 54; used 2 times
onquit defined in line 55; used 2 times
peekc defined in line 32; used 12 times
pflag defined in line 53; used 4 times
rhsbuf defined in line 37; used 3 times
savedfile defined in line 34; used 7 times
tfile defined in line 60; used 4 times
tfname defined in line 62; used 7 times
tline defined in line 61; used 4 times
vflag defined in line 56; used 3 times
zero defined in line 40; used 16 times

Defined macros

CBRA defined in line 17; used 2 times
CCHR defined in line 18; used 4 times
CCL defined in line 20; used 3 times
CDOL defined in line 22; used 1 times
CDOT defined in line 19; used 2 times
CEOF defined in line 23; used 1 times
CKET defined in line 24; used 2 times
EOF defined in line 15; used 10 times
ESIZE defined in line 12; used 3 times
FNSIZE defined in line 10; used 2 times
GBSIZE defined in line 13; used 2 times
LBSIZE defined in line 11; used 10 times
NBRA defined in line 14; used 5 times
NCCL defined in line 21; used 2 times
READ defined in line 29; used 3 times
SIGHUP defined in line 7; used 2 times
SIGINTR defined in line 8; used 5 times
SIGQUIT defined in line 9; used 3 times
STAR defined in line 26; used 2 times
WRITE defined in line 30; used 2 times
error defined in line 28; used 39 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6612
Valid CSS Valid XHTML 1.0 Strict