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

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

unix.superglobalmegacorp.com

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