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

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

unix.superglobalmegacorp.com

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