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

unix.superglobalmegacorp.com

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