Annotation of 3BSD/cmd/ex/ex_cmds.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include "ex.h"
                      3: #include "ex_argv.h"
                      4: #include "ex_temp.h"
                      5: #include "ex_tty.h"
                      6: 
                      7: bool   pflag, nflag;
                      8: int    poffset;
                      9: 
                     10: #define        nochng()        lchng = chng
                     11: 
                     12: /*
                     13:  * Main loop for command mode command decoding.
                     14:  * A few commands are executed here, but main function
                     15:  * is to strip command addresses, do a little address oriented
                     16:  * processing and call command routines to do the real work.
                     17:  */
                     18: commands(noprompt, exitoneof)
                     19:        bool noprompt, exitoneof;
                     20: {
                     21:        register line *addr;
                     22:        register int c;
                     23:        register int lchng;
                     24:        int given;
                     25:        int seensemi;
                     26:        int cnt;
                     27:        bool hadpr;
                     28: 
                     29:        resetflav();
                     30:        nochng();
                     31:        for (;;) {
                     32:                /*
                     33:                 * If dot at last command
                     34:                 * ended up at zero, advance to one if there is a such.
                     35:                 */
                     36:                if (dot <= zero) {
                     37:                        dot = zero;
                     38:                        if (dol > zero)
                     39:                                dot = one;
                     40:                }
                     41:                shudclob = 0;
                     42: 
                     43:                /*
                     44:                 * If autoprint or trailing print flags,
                     45:                 * print the line at the specified offset
                     46:                 * before the next command.
                     47:                 */
                     48:                if (pflag ||
                     49:                    lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) {
                     50:                        pflag = 0;
                     51:                        nochng();
                     52:                        if (dol != zero) {
                     53:                                addr1 = addr2 = dot + poffset;
                     54:                                if (addr1 < one || addr1 > dol)
                     55: error("Offset out-of-bounds|Offset after command too large");
                     56:                                setdot1();
                     57:                                goto print;
                     58:                        }
                     59:                }
                     60:                nochng();
                     61: 
                     62:                /*
                     63:                 * Print prompt if appropriate.
                     64:                 * If not in global flush output first to prevent
                     65:                 * going into pfast mode unreasonably.
                     66:                 */
                     67:                if (inglobal == 0) {
                     68:                        flush();
                     69:                        if (!hush && value(PROMPT) && !globp && !noprompt && endline) {
                     70:                                putchar(':');
                     71:                                hadpr = 1;
                     72:                        }
                     73:                        TSYNC();
                     74:                }
                     75: 
                     76:                /*
                     77:                 * Gobble up the address.
                     78:                 * Degenerate addresses yield ".".
                     79:                 */
                     80:                addr2 = 0;
                     81:                given = seensemi = 0;
                     82:                do {
                     83:                        addr1 = addr2;
                     84:                        addr = address(0);
                     85:                        c = getcd();
                     86:                        if (addr == 0)
                     87:                                if (c == ',')
                     88:                                        addr = dot;
                     89:                                else if (addr1 != 0) {
                     90:                                        addr2 = dot;
                     91:                                        break;
                     92:                                } else
                     93:                                        break;
                     94:                        addr2 = addr;
                     95:                        given++;
                     96:                        if (c == ';') {
                     97:                                c = ',';
                     98:                                dot = addr;
                     99:                                seensemi = 1;
                    100:                        }
                    101:                } while (c == ',');
                    102:                if (c == '%') {
                    103:                        /* %: same as 1,$ */
                    104:                        addr1 = one;
                    105:                        addr2 = dol;
                    106:                        given = 2;
                    107:                        c = getchar();
                    108:                }
                    109:                if (addr1 == 0)
                    110:                        addr1 = addr2;
                    111:                if (c == ':')
                    112:                        c = getchar();
                    113: 
                    114:                /*
                    115:                 * Set command name for special character commands.
                    116:                 */
                    117:                tailspec(c);
                    118: 
                    119:                /*
                    120:                 * If called via : escape from open or visual, limit
                    121:                 * the set of available commands here to save work below.
                    122:                 */
                    123:                if (inopen) {
                    124:                        if (c=='\n' || c=='\r' || c==CTRL(d) || c==EOF) {
                    125:                                if (addr2)
                    126:                                        dot = addr2;
                    127:                                if (c == EOF)
                    128:                                        return;
                    129:                                continue;
                    130:                        }
                    131:                        if (any(c, "o"))
                    132: notinvis:
                    133:                                tailprim(Command, 1, 1);
                    134:                }
                    135: choice:
                    136:                switch (c) {
                    137: 
                    138:                case 'a':
                    139: 
                    140:                        if (peekchar() == 'r') {
                    141: /* args */
                    142:                                tail("args");
                    143:                                setnoaddr();
                    144:                                eol();
                    145:                                pargs();
                    146:                                continue;
                    147:                        }
                    148: 
                    149: /* append */
                    150:                        if (inopen)
                    151:                                goto notinvis;
                    152:                        tail("append");
                    153:                        setdot();
                    154:                        aiflag = exclam();
                    155:                        newline();
                    156:                        deletenone();
                    157:                        setin(addr2);
                    158:                        ignore(append(gettty, addr2));
                    159:                        nochng();
                    160:                        continue;
                    161: 
                    162:                case 'c':
                    163:                        switch (peekchar()) {
                    164: 
                    165: /* copy */
                    166:                        case 'o':
                    167:                                tail("copy");
                    168:                                move();
                    169:                                continue;
                    170: 
                    171: #ifdef CHDIR
                    172: /* cd */
                    173:                        case 'd':
                    174:                                tail("cd");
                    175:                                goto changdir;
                    176: 
                    177: /* chdir */
                    178:                        case 'h':
                    179:                                ignchar();
                    180:                                if (peekchar() == 'd') {
                    181:                                        register char *p;
                    182:                                        tail2of("chdir");
                    183: changdir:
                    184:                                        if (savedfile[0] == '/' || !value(WARN))
                    185:                                                ignore(exclam());
                    186:                                        else
                    187:                                                ignore(quickly());
                    188:                                        if (skipend()) {
                    189:                                                p = getenv("HOME");
                    190:                                                if (p == NULL)
                    191:                                                        error("Home directory unknown");
                    192:                                        } else
                    193:                                                getone(), p = file;
                    194:                                        eol();
                    195:                                        if (chdir(p) < 0)
                    196:                                                filioerr(p);
                    197:                                        if (savedfile[0] != '/')
                    198:                                                edited = 0;
                    199:                                        continue;
                    200:                                }
                    201:                                if (inopen)
                    202:                                        tailprim("change", 2, 1);
                    203:                                tail2of("change");
                    204:                                break;
                    205: 
                    206: #endif
                    207:                        default:
                    208:                                if (inopen)
                    209:                                        goto notinvis;
                    210:                                tail("change");
                    211:                                break;
                    212:                        }
                    213: /* change */
                    214:                        aiflag = exclam();
                    215:                        setCNL();
                    216:                        setin(addr1);
                    217:                        delete(0);
                    218:                        ignore(append(gettty, addr1 - 1));
                    219:                        nochng();
                    220:                        continue;
                    221: 
                    222: /* delete */
                    223:                case 'd':
                    224:                        /*
                    225:                         * Caution: dp and dl have special meaning already.
                    226:                         */
                    227:                        tail("delete");
                    228:                        c = cmdreg();
                    229:                        setCNL();
                    230:                        if (c)
                    231:                                YANKreg(c);
                    232:                        delete(0);
                    233:                        appendnone();
                    234:                        continue;
                    235: 
                    236: /* edit */
                    237: /* ex */
                    238:                case 'e':
                    239:                        tail(peekchar() == 'x' ? "ex" : "edit");
                    240:                        if (!exclam() && chng)
                    241:                                c = 'E';
                    242:                        filename(c);
                    243:                        if (c == 'E') {
                    244:                                ungetchar(lastchar());
                    245:                                ignore(quickly());
                    246:                        }
                    247:                        setnoaddr();
                    248: doecmd:
                    249:                        init();
                    250:                        addr2 = zero;
                    251:                        laste++;
                    252:                        sync();
                    253:                        rop(c);
                    254:                        nochng();
                    255:                        continue;
                    256: 
                    257: /* file */
                    258:                case 'f':
                    259:                        tail("file");
                    260:                        setnoaddr();
                    261:                        filename(c);
                    262:                        noonl();
                    263: /*
                    264:                        synctmp();
                    265: */
                    266:                        continue;
                    267: 
                    268: /* global */
                    269:                case 'g':
                    270:                        tail("global");
                    271:                        global(!exclam());
                    272:                        nochng();
                    273:                        continue;
                    274: 
                    275: /* insert */
                    276:                case 'i':
                    277:                        if (inopen)
                    278:                                goto notinvis;
                    279:                        tail("insert");
                    280:                        setdot();
                    281:                        nonzero();
                    282:                        aiflag = exclam();
                    283:                        newline();
                    284:                        deletenone();
                    285:                        setin(addr2);
                    286:                        ignore(append(gettty, addr2 - 1));
                    287:                        if (dot == zero && dol > zero)
                    288:                                dot = one;
                    289:                        nochng();
                    290:                        continue;
                    291: 
                    292: /* join */
                    293:                case 'j':
                    294:                        tail("join");
                    295:                        c = exclam();
                    296:                        setcount();
                    297:                        nonzero();
                    298:                        newline();
                    299:                        if (given < 2 && addr2 != dol)
                    300:                                addr2++;
                    301:                        join(c);
                    302:                        continue;
                    303: 
                    304: /* k */
                    305:                case 'k':
                    306: casek:
                    307:                        pastwh();
                    308:                        c = getchar();
                    309:                        if (endcmd(c))
                    310:                                serror("Mark what?|%s requires following letter", Command);
                    311:                        newline();
                    312:                        if (!islower(c))
                    313:                                error("Bad mark|Mark must specify a letter");
                    314:                        setdot();
                    315:                        nonzero();
                    316:                        names[c - 'a'] = *addr2 &~ 01;
                    317:                        anymarks = 1;
                    318:                        continue;
                    319: 
                    320: /* list */
                    321:                case 'l':
                    322:                        tail("list");
                    323:                        setCNL();
                    324:                        ignorf(setlist(1));
                    325:                        pflag = 0;
                    326:                        goto print;
                    327: 
                    328:                case 'm':
                    329:                        if (peekchar() == 'a') {
                    330:                                ignchar();
                    331:                                if (peekchar() == 'p') {
                    332: /* map */
                    333:                                        tail2of("map");
                    334:                                        setnoaddr();
                    335:                                        mapcmd(0);
                    336:                                        continue;
                    337:                                }
                    338: /* mark */
                    339:                                tail2of("mark");
                    340:                                goto casek;
                    341:                        }
                    342: /* move */
                    343:                        tail("move");
                    344:                        move();
                    345:                        continue;
                    346: 
                    347:                case 'n':
                    348:                        if (peekchar() == 'u') {
                    349:                                tail("number");
                    350:                                goto numberit;
                    351:                        }
                    352: /* next */
                    353:                        tail("next");
                    354:                        setnoaddr();
                    355:                        ckaw();
                    356:                        ignore(quickly());
                    357:                        if (getargs())
                    358:                                makargs();
                    359:                        next();
                    360:                        c = 'e';
                    361:                        filename(c);
                    362:                        goto doecmd;
                    363: 
                    364: /* open */
                    365:                case 'o':
                    366:                        tail("open");
                    367:                        oop();
                    368:                        pflag = 0;
                    369:                        nochng();
                    370:                        continue;
                    371: 
                    372:                case 'p':
                    373:                case 'P':
                    374:                        switch (peekchar()) {
                    375: 
                    376: /* put */
                    377:                        case 'u':
                    378:                                tail("put");
                    379:                                setdot();
                    380:                                c = cmdreg();
                    381:                                eol();
                    382:                                if (c)
                    383:                                        putreg(c);
                    384:                                else
                    385:                                        put();
                    386:                                continue;
                    387: 
                    388:                        case 'r':
                    389:                                ignchar();
                    390:                                if (peekchar() == 'e') {
                    391: /* preserve */
                    392:                                        tail2of("preserve");
                    393:                                        eol();
                    394:                                        if (preserve() == 0)
                    395:                                                error("Preserve failed!");
                    396:                                        else
                    397:                                                error("File preserved.");
                    398:                                }
                    399:                                tail2of("print");
                    400:                                break;
                    401: 
                    402:                        default:
                    403:                                tail("print");
                    404:                                break;
                    405:                        }
                    406: /* print */
                    407:                        setCNL();
                    408:                        pflag = 0;
                    409: print:
                    410:                        nonzero();
                    411:                        if (CL && span() > LINES) {
                    412:                                flush1();
                    413:                                vclear();
                    414:                        }
                    415:                        plines(addr1, addr2, 1);
                    416:                        continue;
                    417: 
                    418: /* quit */
                    419:                case 'q':
                    420:                        tail("quit");
                    421:                        setnoaddr();
                    422:                        c = quickly();
                    423:                        eol();
                    424:                        if (!c)
                    425: quit:
                    426:                                nomore();
                    427:                        if (inopen) {
                    428:                                vgoto(WECHO, 0);
                    429:                                if (!ateopr())
                    430:                                        vnfl();
                    431:                                else {
                    432:                                        putpad(VE);
                    433:                                        putpad(KE);
                    434:                                }
                    435:                                flush();
                    436:                                setty(normf);
                    437:                        }
                    438:                        cleanup(1);
                    439:                        exit(0);
                    440: 
                    441:                case 'r':
                    442:                        if (peekchar() == 'e') {
                    443:                                ignchar();
                    444:                                switch (peekchar()) {
                    445: 
                    446: /* rewind */
                    447:                                case 'w':
                    448:                                        tail2of("rewind");
                    449:                                        setnoaddr();
                    450:                                        ignore(quickly());
                    451:                                        eol();
                    452:                                        erewind();
                    453:                                        next();
                    454:                                        c = 'e';
                    455:                                        ungetchar(lastchar());
                    456:                                        filename(c);
                    457:                                        goto doecmd;
                    458: 
                    459: /* recover */
                    460:                                case 'c':
                    461:                                        tail2of("recover");
                    462:                                        setnoaddr();
                    463:                                        c = 'e';
                    464:                                        if (!exclam() && chng)
                    465:                                                c = 'E';
                    466:                                        filename(c);
                    467:                                        if (c == 'E') {
                    468:                                                ungetchar(lastchar());
                    469:                                                ignore(quickly());
                    470:                                        }
                    471:                                        init();
                    472:                                        addr2 = zero;
                    473:                                        laste++;
                    474:                                        sync();
                    475:                                        recover();
                    476:                                        rop2();
                    477:                                        revocer();
                    478:                                        if (status == 0)
                    479:                                                rop3(c);
                    480:                                        if (dol != zero)
                    481:                                                change();
                    482:                                        nochng();
                    483:                                        continue;
                    484:                                }
                    485:                                tail2of("read");
                    486:                        } else
                    487:                                tail("read");
                    488: /* read */
                    489:                        if (savedfile[0] == 0 && dol == zero)
                    490:                                c = 'e';
                    491:                        pastwh();
                    492:                        if (peekchar() == '!') {
                    493:                                setdot();
                    494:                                ignchar();
                    495:                                unix0(0);
                    496:                                filter(0);
                    497:                                continue;
                    498:                        }
                    499:                        filename(c);
                    500:                        rop(c);
                    501:                        nochng();
                    502:                        if (inopen && endline && addr1 > zero && addr1 < dol)
                    503:                                dot = addr1 + 1;
                    504:                        continue;
                    505: 
                    506:                case 's':
                    507:                        switch (peekchar()) {
                    508:                        /*
                    509:                         * Caution: 2nd char cannot be c, g, or r
                    510:                         * because these have meaning to substitute.
                    511:                         */
                    512: 
                    513: /* set */
                    514:                        case 'e':
                    515:                                tail("set");
                    516:                                setnoaddr();
                    517:                                set();
                    518:                                continue;
                    519: 
                    520: /* shell */
                    521:                        case 'h':
                    522:                                tail("shell");
                    523:                                setNAEOL();
                    524:                                vnfl();
                    525:                                putpad(TE);
                    526:                                flush();
                    527:                                unixwt(1, unixex("-i", (char *) 0, 0, 0));
                    528:                                vcontin(0);
                    529:                                putpad(TI);
                    530:                                continue;
                    531: 
                    532: /* source */
                    533:                        case 'o':
                    534:                                if (inopen)
                    535:                                        goto notinvis;
                    536:                                tail("source");
                    537:                                setnoaddr();
                    538:                                getone();
                    539:                                eol();
                    540:                                source(file, 0);
                    541:                                continue;
                    542:                        }
                    543:                        /* fall into ... */
                    544: 
                    545: /* & */
                    546: /* ~ */
                    547: /* substitute */
                    548:                case '&':
                    549:                case '~':
                    550:                        Command = "substitute";
                    551:                        if (c == 's')
                    552:                                tail(Command);
                    553:                        if (!substitute(c))
                    554:                                pflag = 0;
                    555:                        continue;
                    556: 
                    557: /* t */
                    558:                case 't':
                    559:                        if (peekchar() == 'a') {
                    560:                                tail("tag");
                    561:                                tagfind(exclam());
                    562:                                if (!inopen)
                    563:                                        lchng = chng - 1;
                    564:                                else
                    565:                                        nochng();
                    566:                                continue;
                    567:                        }
                    568:                        tail("t");
                    569:                        move();
                    570:                        continue;
                    571: 
                    572:                case 'u':
                    573:                        if (peekchar() == 'n') {
                    574: /* unmap */
                    575:                                ignchar();
                    576:                                if (peekchar() == 'm') {
                    577:                                        tail2of("unmap");
                    578:                                        setnoaddr();
                    579:                                        mapcmd(1);
                    580:                                        continue;
                    581:                                }
                    582: /* undo */
                    583:                                tail2of("undo");
                    584:                        } else
                    585:                                tail("undo");
                    586:                        setnoaddr();
                    587:                        markDOT();
                    588:                        c = exclam();
                    589:                        newline();
                    590:                        undo(c);
                    591:                        continue;
                    592: 
                    593:                case 'v':
                    594:                        switch (peekchar()) {
                    595: 
                    596:                        case 'e':
                    597: /* version */
                    598:                                tail("version");
                    599:                                setNAEOL();
                    600:                                /* should use SCCS subst here */
                    601:                                printf("Version 3.2, January 4, 1980");
                    602:                                noonl();
                    603:                                continue;
                    604: 
                    605: /* visual */
                    606:                        case 'i':
                    607:                                tail("visual");
                    608:                                vop();
                    609:                                pflag = 0;
                    610:                                nochng();
                    611:                                continue;
                    612:                        }
                    613: /* v */
                    614:                        tail("v");
                    615:                        global(0);
                    616:                        nochng();
                    617:                        continue;
                    618: 
                    619: /* write */
                    620:                case 'w':
                    621:                        c = peekchar();
                    622:                        tail(c == 'q' ? "wq" : "write");
                    623:                        if (skipwh() && peekchar() == '!') {
                    624:                                ignchar();
                    625:                                setall();
                    626:                                unix0(0);
                    627:                                filter(1);
                    628:                        } else {
                    629:                                setall();
                    630:                                wop(1);
                    631:                                nochng();
                    632:                        }
                    633:                        if (c == 'q')
                    634:                                goto quit;
                    635:                        continue;
                    636: 
                    637: /* yank */
                    638:                case 'y':
                    639:                        tail("yank");
                    640:                        c = cmdreg();
                    641:                        setcount();
                    642:                        eol();
                    643:                        if (c)
                    644:                                YANKreg(c);
                    645:                        else
                    646:                                yank();
                    647:                        continue;
                    648: 
                    649: /* z */
                    650:                case 'z':
                    651:                        zop(0);
                    652:                        pflag = 0;
                    653:                        continue;
                    654: 
                    655: /* * */
                    656: /* @ */
                    657:                case '*':
                    658:                case '@':
                    659:                        c = getchar();
                    660:                        if (c=='\n' || c=='\r')
                    661:                                ungetchar(c);
                    662:                        if (any(c, "@*\n\r"))
                    663:                                c = lastmac;
                    664:                        if (isupper(c))
                    665:                                c = tolower(c);
                    666:                        if (!islower(c))
                    667:                                error("Bad register");
                    668:                        newline();
                    669:                        setdot();
                    670:                        cmdmac(c);
                    671:                        continue;
                    672: 
                    673: /* | */
                    674:                case '|':
                    675:                        endline = 0;
                    676:                        goto caseline;
                    677: 
                    678: /* \n */
                    679:                case '\n':
                    680:                        endline = 1;
                    681: caseline:
                    682:                        notempty();
                    683:                        if (addr2 == 0) {
                    684:                                if (dot == dol)
                    685:                                        error("At EOF|At end-of-file");
                    686:                                if (UP != NOSTR && c == '\n' && !inglobal)
                    687:                                        c = CTRL(k);
                    688:                                if (inglobal)
                    689:                                        addr1 = addr2 = dot;
                    690:                                else
                    691:                                        addr1 = addr2 = dot + 1;
                    692:                        }
                    693:                        setdot();
                    694:                        nonzero();
                    695:                        if (seensemi)
                    696:                                addr1 = addr2;
                    697:                        getline(*addr1);
                    698:                        if (c == CTRL(k)) {
                    699:                                flush1();
                    700:                                destline--;
                    701:                                if (hadpr)
                    702:                                        shudclob = 1;
                    703:                        }
                    704:                        plines(addr1, addr2, 1);
                    705:                        continue;
                    706: 
                    707: /* # */
                    708:                case '#':
                    709: numberit:
                    710:                        setCNL();
                    711:                        ignorf(setnumb(1));
                    712:                        pflag = 0;
                    713:                        goto print;
                    714: 
                    715: /* = */
                    716:                case '=':
                    717:                        newline();
                    718:                        setall();
                    719:                        printf("%d", lineno(addr2));
                    720:                        noonl();
                    721:                        continue;
                    722: 
                    723: /* ! */
                    724:                case '!':
                    725:                        if (addr2 != 0) {
                    726:                                unix0(0);
                    727:                                setdot();
                    728:                                filter(2);
                    729:                        } else {
                    730:                                unix0(1);
                    731:                                vnfl();
                    732:                                putpad(TE);
                    733:                                flush();
                    734:                                unixwt(1, unixex("-c", uxb, 0, 0));
                    735:                                vcontin(1);
                    736:                                putpad(TI);
                    737:                                nochng();
                    738:                        }
                    739:                        continue;
                    740: 
                    741: /* < */
                    742: /* > */
                    743:                case '<':
                    744:                case '>':
                    745:                        for (cnt = 1; peekchar() == c; cnt++)
                    746:                                ignchar();
                    747:                        setCNL();
                    748:                        shift(c, cnt);
                    749:                        continue;
                    750: 
                    751: /* ^D */
                    752: /* EOF */
                    753:                case CTRL(d):
                    754:                case EOF:
                    755:                        if (exitoneof) {
                    756:                                if (addr2 != 0)
                    757:                                        dot = addr2;
                    758:                                return;
                    759:                        }
                    760:                        if (!isatty(0)) {
                    761:                                if (intty)
                    762:                                        /*
                    763:                                         * Chtty sys call at UCB may cause a
                    764:                                         * input which was a tty to suddenly be
                    765:                                         * turned into /dev/null.
                    766:                                         */
                    767:                                        onhup();
                    768:                                return;
                    769:                        }
                    770:                        if (addr2 != 0) {
                    771:                                setlastchar('\n');
                    772:                                putnl();
                    773:                        }
                    774:                        if (dol == zero) {
                    775:                                if (addr2 == 0)
                    776:                                        putnl();
                    777:                                notempty();
                    778:                        }
                    779:                        ungetchar(EOF);
                    780:                        zop(hadpr);
                    781:                        continue;
                    782: 
                    783:                default:
                    784:                        if (!isalpha(c))
                    785:                                break;
                    786:                        ungetchar(c);
                    787:                        tailprim("", 0, 0);
                    788:                }
                    789:                error("What?|Unknown command character '%c'", c);
                    790:        }
                    791: }

unix.superglobalmegacorp.com

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