Annotation of 43BSDTahoe/ucb/ex/ex_cmds2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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