Annotation of 42BSD/ucb/ex/ex_cmds2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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