Annotation of researchv10no/cmd/ed.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.