Annotation of 40BSD/cmd/ex/ex_cmds2.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1980 Regents of the University of California */
                      2: static char *sccsid = "@(#)ex_cmds2.c  6.1 10/18/80";
                      3: #include "ex.h"
                      4: #include "ex_argv.h"
                      5: #include "ex_temp.h"
                      6: #include "ex_tty.h"
                      7: #include "ex_vis.h"
                      8: 
                      9: bool   pflag, nflag;
                     10: int    poffset;
                     11: 
                     12: /*
                     13:  * Subroutines for major command loop.
                     14:  */
                     15: 
                     16: /*
                     17:  * Is there a single letter indicating a named buffer next?
                     18:  */
                     19: cmdreg()
                     20: {
                     21:        register int c = 0;
                     22:        register int wh = skipwh();
                     23: 
                     24:        if (wh && isalpha(peekchar()))
                     25:                c = getchar();
                     26:        return (c);
                     27: }
                     28: 
                     29: /*
                     30:  * Tell whether the character ends a command
                     31:  */
                     32: endcmd(ch)
                     33:        int ch;
                     34: {
                     35:        switch (ch) {
                     36:        
                     37:        case '\n':
                     38:        case EOF:
                     39:                endline = 1;
                     40:                return (1);
                     41:        
                     42:        case '|':
                     43:        case '"':
                     44:                endline = 0;
                     45:                return (1);
                     46:        }
                     47:        return (0);
                     48: }
                     49: 
                     50: /*
                     51:  * Insist on the end of the command.
                     52:  */
                     53: eol()
                     54: {
                     55: 
                     56:        if (!skipend())
                     57:                error("Extra chars|Extra characters at end of command");
                     58:        ignnEOF();
                     59: }
                     60: 
                     61: /*
                     62:  * Print out the message in the error message file at str,
                     63:  * with i an integer argument to printf.
                     64:  */
                     65: /*VARARGS2*/
                     66: error(str, i)
                     67: #ifdef lint
                     68:        register char *str;
                     69: #else
                     70:        register int str;
                     71: #endif
                     72:        int i;
                     73: {
                     74: 
                     75:        error0();
                     76:        merror(str, i);
                     77:        if (writing) {
                     78:                serror(" [Warning - %s is incomplete]", file);
                     79:                writing = 0;
                     80:        }
                     81:        error1(str);
                     82: }
                     83: 
                     84: /*
                     85:  * Rewind the argument list.
                     86:  */
                     87: erewind()
                     88: {
                     89: 
                     90:        argc = argc0;
                     91:        argv = argv0;
                     92:        args = args0;
                     93:        if (argc > 1 && !hush) {
                     94:                printf(mesg("%d files@to edit"), argc);
                     95:                if (inopen)
                     96:                        putchar(' ');
                     97:                else
                     98:                        putNFL();
                     99:        }
                    100: }
                    101: 
                    102: /*
                    103:  * Guts of the pre-printing error processing.
                    104:  * If in visual and catching errors, then we dont mung up the internals,
                    105:  * just fixing up the echo area for the print.
                    106:  * Otherwise we reset a number of externals, and discard unused input.
                    107:  */
                    108: error0()
                    109: {
                    110: 
                    111:        if (laste) {
                    112: #ifdef VMUNIX
                    113:                tlaste();
                    114: #endif
                    115:                laste = 0;
                    116:                sync();
                    117:        }
                    118:        if (vcatch) {
                    119:                if (splitw == 0)
                    120:                        fixech();
                    121:                if (!SO || !SE)
                    122:                        dingdong();
                    123:                return;
                    124:        }
                    125:        if (input) {
                    126:                input = strend(input) - 1;
                    127:                if (*input == '\n')
                    128:                        setlastchar('\n');
                    129:                input = 0;
                    130:        }
                    131:        setoutt();
                    132:        flush();
                    133:        resetflav();
                    134:        if (!SO || !SE)
                    135:                dingdong();
                    136:        if (inopen) {
                    137:                /*
                    138:                 * We are coming out of open/visual ungracefully.
                    139:                 * Restore COLUMNS, undo, and fix tty mode.
                    140:                 */
                    141:                COLUMNS = OCOLUMNS;
                    142:                undvis();
                    143:                ostop(normf);
                    144:                /* ostop should be doing this
                    145:                putpad(VE);
                    146:                putpad(KE);
                    147:                */
                    148:                putnl();
                    149:        }
                    150:        inopen = 0;
                    151:        holdcm = 0;
                    152: }
                    153: 
                    154: /*
                    155:  * Post error printing processing.
                    156:  * Close the i/o file if left open.
                    157:  * If catching in visual then throw to the visual catch,
                    158:  * else if a child after a fork, then exit.
                    159:  * Otherwise, in the normal command mode error case,
                    160:  * finish state reset, and throw to top.
                    161:  */
                    162: error1(str)
                    163:        char *str;
                    164: {
                    165:        bool die;
                    166: 
                    167:        if (io > 0) {
                    168:                close(io);
                    169:                io = -1;
                    170:        }
                    171:        die = (getpid() != ppid);       /* Only children die */
                    172:        inappend = inglobal = 0;
                    173:        globp = vglobp = vmacp = 0;
                    174:        if (vcatch && !die) {
                    175:                inopen = 1;
                    176:                vcatch = 0;
                    177:                if (str)
                    178:                        noonl();
                    179:                fixol();
                    180:                longjmp(vreslab,1);
                    181:        }
                    182:        if (str && !vcatch)
                    183:                putNFL();
                    184:        if (die)
                    185:                exit(1);
                    186:        lseek(0, 0L, 2);
                    187:        if (inglobal)
                    188:                setlastchar('\n');
                    189:        while (lastchar() != '\n' && lastchar() != EOF)
                    190:                ignchar();
                    191:        ungetchar(0);
                    192:        endline = 1;
                    193:        reset();
                    194: }
                    195: 
                    196: fixol()
                    197: {
                    198:        if (Outchar != vputchar) {
                    199:                flush();
                    200:                if (state == ONEOPEN || state == HARDOPEN)
                    201:                        outline = destline = 0;
                    202:                Outchar = vputchar;
                    203:                vcontin(1);
                    204:        } else {
                    205:                if (destcol)
                    206:                        vclreol();
                    207:                vclean();
                    208:        }
                    209: }
                    210: 
                    211: /*
                    212:  * Does an ! character follow in the command stream?
                    213:  */
                    214: exclam()
                    215: {
                    216: 
                    217:        if (peekchar() == '!') {
                    218:                ignchar();
                    219:                return (1);
                    220:        }
                    221:        return (0);
                    222: }
                    223: 
                    224: /*
                    225:  * Make an argument list for e.g. next.
                    226:  */
                    227: makargs()
                    228: {
                    229: 
                    230:        glob(&frob);
                    231:        argc0 = frob.argc0;
                    232:        argv0 = frob.argv;
                    233:        args0 = argv0[0];
                    234:        erewind();
                    235: }
                    236: 
                    237: /*
                    238:  * Advance to next file in argument list.
                    239:  */
                    240: next()
                    241: {
                    242:        extern short isalt;     /* defined in ex_io.c */
                    243: 
                    244:        if (argc == 0)
                    245:                error("No more files@to edit");
                    246:        morargc = argc;
                    247:        isalt = (strcmp(altfile, args)==0) + 1;
                    248:        if (savedfile[0])
                    249:                CP(altfile, savedfile);
                    250:        CP(savedfile, args);
                    251:        argc--;
                    252:        args = argv ? *++argv : strend(args) + 1;
                    253: }
                    254: 
                    255: /*
                    256:  * Eat trailing flags and offsets after a command,
                    257:  * saving for possible later post-command prints.
                    258:  */
                    259: newline()
                    260: {
                    261:        register int c;
                    262: 
                    263:        resetflav();
                    264:        for (;;) {
                    265:                c = getchar();
                    266:                switch (c) {
                    267: 
                    268:                case '^':
                    269:                case '-':
                    270:                        poffset--;
                    271:                        break;
                    272: 
                    273:                case '+':
                    274:                        poffset++;
                    275:                        break;
                    276: 
                    277:                case 'l':
                    278:                        listf++;
                    279:                        break;
                    280: 
                    281:                case '#':
                    282:                        nflag++;
                    283:                        break;
                    284: 
                    285:                case 'p':
                    286:                        listf = 0;
                    287:                        break;
                    288: 
                    289:                case ' ':
                    290:                case '\t':
                    291:                        continue;
                    292: 
                    293:                case '"':
                    294:                        comment();
                    295:                        setflav();
                    296:                        return;
                    297: 
                    298:                default:
                    299:                        if (!endcmd(c))
                    300: serror("Extra chars|Extra characters at end of \"%s\" command", Command);
                    301:                        if (c == EOF)
                    302:                                ungetchar(c);
                    303:                        setflav();
                    304:                        return;
                    305:                }
                    306:                pflag++;
                    307:        }
                    308: }
                    309: 
                    310: /*
                    311:  * Before quit or respec of arg list, check that there are
                    312:  * no more files in the arg list.
                    313:  */
                    314: nomore()
                    315: {
                    316: 
                    317:        if (argc == 0 || morargc == argc)
                    318:                return;
                    319:        morargc = argc;
                    320:        merror("%d more file", argc);
                    321:        serror("%s@to edit", plural((long) argc));
                    322: }
                    323: 
                    324: /*
                    325:  * Before edit of new file check that either an ! follows
                    326:  * or the file has not been changed.
                    327:  */
                    328: quickly()
                    329: {
                    330: 
                    331:        if (exclam())
                    332:                return (1);
                    333:        if (chng && dol > zero) {
                    334: /*
                    335:                chng = 0;
                    336: */
                    337:                xchng = 0;
                    338:                error("No write@since last change (:%s! overrides)", Command);
                    339:        }
                    340:        return (0);
                    341: }
                    342: 
                    343: /*
                    344:  * Reset the flavor of the output to print mode with no numbering.
                    345:  */
                    346: resetflav()
                    347: {
                    348: 
                    349:        if (inopen)
                    350:                return;
                    351:        listf = 0;
                    352:        nflag = 0;
                    353:        pflag = 0;
                    354:        poffset = 0;
                    355:        setflav();
                    356: }
                    357: 
                    358: /*
                    359:  * Print an error message with a %s type argument to printf.
                    360:  * Message text comes from error message file.
                    361:  */
                    362: serror(str, cp)
                    363: #ifdef lint
                    364:        register char *str;
                    365: #else
                    366:        register int str;
                    367: #endif
                    368:        char *cp;
                    369: {
                    370: 
                    371:        error0();
                    372:        smerror(str, cp);
                    373:        error1(str);
                    374: }
                    375: 
                    376: /*
                    377:  * Set the flavor of the output based on the flags given
                    378:  * and the number and list options to either number or not number lines
                    379:  * and either use normally decoded (ARPAnet standard) characters or list mode,
                    380:  * where end of lines are marked and tabs print as ^I.
                    381:  */
                    382: setflav()
                    383: {
                    384: 
                    385:        if (inopen)
                    386:                return;
                    387:        setnumb(nflag || value(NUMBER));
                    388:        setlist(listf || value(LIST));
                    389:        setoutt();
                    390: }
                    391: 
                    392: /*
                    393:  * Skip white space and tell whether command ends then.
                    394:  */
                    395: skipend()
                    396: {
                    397: 
                    398:        pastwh();
                    399:        return (endcmd(peekchar()) && peekchar() != '"');
                    400: }
                    401: 
                    402: /*
                    403:  * Set the command name for non-word commands.
                    404:  */
                    405: tailspec(c)
                    406:        int c;
                    407: {
                    408:        static char foocmd[2];
                    409: 
                    410:        foocmd[0] = c;
                    411:        Command = foocmd;
                    412: }
                    413: 
                    414: /*
                    415:  * Try to read off the rest of the command word.
                    416:  * If alphabetics follow, then this is not the command we seek.
                    417:  */
                    418: tail(comm)
                    419:        char *comm;
                    420: {
                    421: 
                    422:        tailprim(comm, 1, 0);
                    423: }
                    424: 
                    425: tail2of(comm)
                    426:        char *comm;
                    427: {
                    428: 
                    429:        tailprim(comm, 2, 0);
                    430: }
                    431: 
                    432: char   tcommand[20];
                    433: 
                    434: tailprim(comm, i, notinvis)
                    435:        register char *comm;
                    436:        int i;
                    437:        bool notinvis;
                    438: {
                    439:        register char *cp;
                    440:        register int c;
                    441: 
                    442:        Command = comm;
                    443:        for (cp = tcommand; i > 0; i--)
                    444:                *cp++ = *comm++;
                    445:        while (*comm && peekchar() == *comm)
                    446:                *cp++ = getchar(), comm++;
                    447:        c = peekchar();
                    448:        if (notinvis || isalpha(c)) {
                    449:                /*
                    450:                 * Of the trailing lp funny business, only dl and dp
                    451:                 * survive the move from ed to ex.
                    452:                 */
                    453:                if (tcommand[0] == 'd' && any(c, "lp"))
                    454:                        goto ret;
                    455:                if (tcommand[0] == 's' && any(c, "gcr"))
                    456:                        goto ret;
                    457:                while (cp < &tcommand[19] && isalpha(peekchar()))
                    458:                        *cp++ = getchar();
                    459:                *cp = 0;
                    460:                if (notinvis)
                    461:                        serror("What?|%s: No such command from open/visual", tcommand);
                    462:                else
                    463:                        serror("What?|%s: Not an editor command", tcommand);
                    464:        }
                    465: ret:
                    466:        *cp = 0;
                    467: }
                    468: 
                    469: /*
                    470:  * Continue after a : command from open/visual.
                    471:  */
                    472: vcontin(ask)
                    473:        bool ask;
                    474: {
                    475: 
                    476:        if (vcnt > 0)
                    477:                vcnt = -vcnt;
                    478:        if (inopen) {
                    479:                if (state != VISUAL) {
                    480:                        /*
                    481:                         * We don't know what a shell command may have left on
                    482:                         * the screen, so we move the cursor to the right place
                    483:                         * and then put out a newline.  But this makes an extra
                    484:                         * blank line most of the time so we only do it for :sh
                    485:                         * since the prompt gets left on the screen.
                    486:                         *
                    487:                         * BUG: :!echo longer than current line \\c
                    488:                         * will screw it up, but be reasonable!
                    489:                         */
                    490:                        if (state == CRTOPEN) {
                    491:                                termreset();
                    492:                                vgoto(WECHO, 0);
                    493:                        }
                    494:                        if (!ask) {
                    495:                                putch('\r');
                    496:                                putch('\n');
                    497:                        }
                    498:                        return;
                    499:                }
                    500:                if (ask) {
                    501:                        merror("[Hit return to continue] ");
                    502:                        flush();
                    503:                }
                    504: #ifndef CBREAK
                    505:                vraw();
                    506: #endif
                    507:                if (ask) {
                    508: #ifdef EATQS
                    509:                        /*
                    510:                         * Gobble ^Q/^S since the tty driver should be eating
                    511:                         * them (as far as the user can see)
                    512:                         */
                    513:                        while (peekkey() == CTRL(Q) || peekkey() == CTRL(S))
                    514:                                ignore(getkey());
                    515: #endif
                    516:                        if(getkey() == ':') {
                    517:                                /* Ugh. Extra newlines, but no other way */
                    518:                                putch('\n');
                    519:                                outline = WECHO;
                    520:                                ungetkey(':');
                    521:                        }
                    522:                }
                    523:                vclrech(1);
                    524:                if (Peekkey != ':') {
                    525:                        putpad(TI);
                    526:                        tostart();
                    527:                        /* replaced by ostart.
                    528:                        putpad(VS);
                    529:                        putpad(KS);
                    530:                        */
                    531:                }
                    532:        }
                    533: }
                    534: 
                    535: /*
                    536:  * Put out a newline (before a shell escape)
                    537:  * if in open/visual.
                    538:  */
                    539: vnfl()
                    540: {
                    541: 
                    542:        if (inopen) {
                    543:                if (state != VISUAL && state != CRTOPEN && destline <= WECHO)
                    544:                        vclean();
                    545:                else
                    546:                        vmoveitup(1, 0);
                    547:                vgoto(WECHO, 0);
                    548:                vclrbyte(vtube[WECHO], WCOLS);
                    549:                tostop();
                    550:                /* replaced by the ostop above
                    551:                putpad(VE);
                    552:                putpad(KE);
                    553:                */
                    554:        }
                    555:        flush();
                    556: }

unix.superglobalmegacorp.com

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