[BACK]Return to command.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / more

Annotation of src/usr.bin/more/command.c, Revision 1.1

1.1     ! deraadt     1: /*
        !             2:  * Copyright (c) 1988 Mark Nudleman
        !             3:  * Copyright (c) 1988 Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. All advertising materials mentioning features or use of this software
        !            15:  *    must display the following acknowledgement:
        !            16:  *     This product includes software developed by the University of
        !            17:  *     California, Berkeley and its contributors.
        !            18:  * 4. Neither the name of the University nor the names of its contributors
        !            19:  *    may be used to endorse or promote products derived from this software
        !            20:  *    without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            32:  * SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: #ifndef lint
        !            36: /* from: static char sccsid[] = "@(#)command.c 5.22 (Berkeley) 6/21/92"; */
        !            37: static char *rcsid = "$Id: command.c,v 1.6 1995/08/06 09:22:30 ghudson Exp $";
        !            38: #endif /* not lint */
        !            39:
        !            40: #include <sys/param.h>
        !            41: #include <stdio.h>
        !            42: #include <string.h>
        !            43: #include <ctype.h>
        !            44: #include <less.h>
        !            45: #include "pathnames.h"
        !            46:
        !            47: #define        NO_MCA          0
        !            48: #define        MCA_DONE        1
        !            49: #define        MCA_MORE        2
        !            50:
        !            51: extern int erase_char, kill_char, werase_char;
        !            52: extern int ispipe;
        !            53: extern int sigs;
        !            54: extern int quit_at_eof;
        !            55: extern int hit_eof;
        !            56: extern int sc_width;
        !            57: extern int sc_height;
        !            58: extern int sc_window;
        !            59: extern int curr_ac;
        !            60: extern int ac;
        !            61: extern int quitting;
        !            62: extern int scroll;
        !            63: extern int screen_trashed;     /* The screen has been overwritten */
        !            64: extern int novice;
        !            65:
        !            66: static char cmdbuf[120];       /* Buffer for holding a multi-char command */
        !            67: static char *cp;               /* Pointer into cmdbuf */
        !            68: static int cmd_col;            /* Current column of the multi-char command */
        !            69: static int longprompt;         /* if stat command instead of prompt */
        !            70: static int helpprompt;         /* If help directions instead of prompt */
        !            71: static int mca;                        /* The multicharacter command (action) */
        !            72: static int last_mca;           /* The previous mca */
        !            73: static int number;             /* The number typed by the user */
        !            74: static char *shellcmd = NULL;  /* Pointer to a shell command */
        !            75: static int wsearch;            /* Search for matches (1) or non-matches (0) */
        !            76:
        !            77: #define        CMD_RESET       cp = cmdbuf     /* reset command buffer to empty */
        !            78: #define        CMD_EXEC        lower_left(); flush()
        !            79:
        !            80: /* backspace in command buffer. */
        !            81: static
        !            82: cmd_erase()
        !            83: {
        !            84:        /*
        !            85:         * backspace past beginning of the string: this usually means
        !            86:         * abort the command.
        !            87:         */
        !            88:        if (cp == cmdbuf)
        !            89:                return(1);
        !            90:
        !            91:        /* erase an extra character, for the carat. */
        !            92:        if (CONTROL_CHAR(*--cp)) {
        !            93:                backspace();
        !            94:                --cmd_col;
        !            95:        }
        !            96:
        !            97:        backspace();
        !            98:        --cmd_col;
        !            99:        return(0);
        !           100: }
        !           101:
        !           102: /* set up the display to start a new multi-character command. */
        !           103: start_mca(action, prompt)
        !           104:        int action;
        !           105:        char *prompt;
        !           106: {
        !           107:        lower_left();
        !           108:        clear_eol();
        !           109:        putstr(prompt);
        !           110:        cmd_col = strlen(prompt);
        !           111:        mca = action;
        !           112: }
        !           113:
        !           114: /*
        !           115:  * process a single character of a multi-character command, such as
        !           116:  * a number, or the pattern of a search command.
        !           117:  */
        !           118: static
        !           119: cmd_char(c)
        !           120:        int c;
        !           121: {
        !           122:        if (c == erase_char)
        !           123:                return(cmd_erase());
        !           124:        /* in this order, in case werase == erase_char */
        !           125:        if (c == werase_char) {
        !           126:                if (cp > cmdbuf) {
        !           127:                        while (isspace(cp[-1]) && !cmd_erase());
        !           128:                        while (!isspace(cp[-1]) && !cmd_erase());
        !           129:                        while (isspace(cp[-1]) && !cmd_erase());
        !           130:                }
        !           131:                return(cp == cmdbuf);
        !           132:        }
        !           133:        if (c == kill_char) {
        !           134:                while (!cmd_erase());
        !           135:                return(1);
        !           136:        }
        !           137:        /*
        !           138:         * No room in the command buffer, or no room on the screen;
        !           139:         * {{ Could get fancy here; maybe shift the displayed line
        !           140:         * and make room for more chars, like ksh. }}
        !           141:         */
        !           142:        if (cp >= &cmdbuf[sizeof(cmdbuf)-1] || cmd_col >= sc_width-3)
        !           143:                bell();
        !           144:        else {
        !           145:                *cp++ = c;
        !           146:                if (CONTROL_CHAR(c)) {
        !           147:                        putchr('^');
        !           148:                        cmd_col++;
        !           149:                        c = CARAT_CHAR(c);
        !           150:                }
        !           151:                putchr(c);
        !           152:                cmd_col++;
        !           153:        }
        !           154:        return(0);
        !           155: }
        !           156:
        !           157: off_t position();
        !           158:
        !           159: prompt()
        !           160: {
        !           161:        extern int linenums, short_file;
        !           162:        extern char *current_name, *firstsearch, *next_name;
        !           163:        off_t len, pos, ch_length(), forw_line();
        !           164:        char pbuf[40];
        !           165:
        !           166:        /*
        !           167:         * if nothing is displayed yet, display starting from line 1;
        !           168:         * if search string provided, go there instead.
        !           169:         */
        !           170:        if (position(TOP) == NULL_POSITION) {
        !           171:                if (forw_line((off_t)0) == NULL_POSITION)
        !           172:                        return(0);
        !           173:                if (!firstsearch || !search(1, firstsearch, 1, 1))
        !           174:                        jump_back(1);
        !           175:        }
        !           176:        else if (screen_trashed)
        !           177:                repaint();
        !           178:
        !           179:        /* if no -e flag and we've hit EOF on the last file, quit. */
        !           180:        if ((!quit_at_eof || short_file) && hit_eof && curr_ac + 1 >= ac)
        !           181:                quit();
        !           182:
        !           183:        /* select the proper prompt and display it. */
        !           184:        lower_left();
        !           185:        clear_eol();
        !           186:        if (longprompt) {
        !           187:                so_enter();
        !           188:                putstr(current_name);
        !           189:                putstr(":");
        !           190:                if (!ispipe) {
        !           191:                        (void)sprintf(pbuf, " file %d/%d", curr_ac + 1, ac);
        !           192:                        putstr(pbuf);
        !           193:                }
        !           194:                if (linenums) {
        !           195:                        (void)sprintf(pbuf, " line %d", currline(BOTTOM));
        !           196:                        putstr(pbuf);
        !           197:                }
        !           198:                if ((pos = position(BOTTOM)) != NULL_POSITION) {
        !           199:                        (void)sprintf(pbuf, " byte %qd", pos);
        !           200:                        putstr(pbuf);
        !           201:                        if (!ispipe && (len = ch_length())) {
        !           202:                                (void)sprintf(pbuf, "/%qd pct %qd%%",
        !           203:                                    len, ((100 * pos) / len));
        !           204:                                putstr(pbuf);
        !           205:                        }
        !           206:                }
        !           207:                so_exit();
        !           208:                longprompt = 0;
        !           209:        }
        !           210:        else if (helpprompt) {
        !           211:                so_enter();
        !           212:                putstr("[Press 'h' for instructions.]");
        !           213:                so_exit();
        !           214:                helpprompt = 0;
        !           215:        }
        !           216:        else {
        !           217:                so_enter();
        !           218:                putstr(current_name);
        !           219:                if (hit_eof)
        !           220:                        if (next_name) {
        !           221:                                putstr(": END (next file: ");
        !           222:                                putstr(next_name);
        !           223:                                putstr(")");
        !           224:                        }
        !           225:                        else
        !           226:                                putstr(": END");
        !           227:                else if (!ispipe &&
        !           228:                    (pos = position(BOTTOM)) != NULL_POSITION &&
        !           229:                    (len = ch_length())) {
        !           230:                        (void)sprintf(pbuf, " (%qd%%)", ((100 * pos) / len));
        !           231:                        putstr(pbuf);
        !           232:                }
        !           233:                if (novice)
        !           234:                        putstr(" [Press space to continue, 'q' to quit.]");
        !           235:                so_exit();
        !           236:        }
        !           237:        return(1);
        !           238: }
        !           239:
        !           240: /* get command character. */
        !           241: static
        !           242: getcc()
        !           243: {
        !           244:        extern int cmdstack;
        !           245:        int ch;
        !           246:
        !           247:        /* left over from error() routine. */
        !           248:        if (cmdstack) {
        !           249:                ch = cmdstack;
        !           250:                cmdstack = NULL;
        !           251:                return(ch);
        !           252:        }
        !           253:        if (cp > cmdbuf && position(TOP) == NULL_POSITION) {
        !           254:                /*
        !           255:                 * Command is incomplete, so try to complete it.
        !           256:                 * There are only two cases:
        !           257:                 * 1. We have "/string" but no newline.  Add the \n.
        !           258:                 * 2. We have a number but no command.  Treat as #g.
        !           259:                 * (This is all pretty hokey.)
        !           260:                 */
        !           261:                if (mca != A_DIGIT)
        !           262:                        /* Not a number; must be search string */
        !           263:                        return('\n');
        !           264:                else
        !           265:                        /* A number; append a 'g' */
        !           266:                        return('g');
        !           267:        }
        !           268:        return(getchr());
        !           269: }
        !           270:
        !           271: /* execute a multicharacter command. */
        !           272: static
        !           273: exec_mca()
        !           274: {
        !           275:        extern int file;
        !           276:        extern char *tagfile;
        !           277:        register char *p;
        !           278:        char *glob(), *fexpand();
        !           279:
        !           280:        *cp = '\0';
        !           281:        CMD_EXEC;
        !           282:        switch (mca) {
        !           283:        case A_F_SEARCH:
        !           284:                (void)search(1, cmdbuf, number, wsearch);
        !           285:                break;
        !           286:        case A_B_SEARCH:
        !           287:                (void)search(0, cmdbuf, number, wsearch);
        !           288:                break;
        !           289:        case A_EXAMINE:
        !           290:                for (p = cmdbuf; isspace(*p); ++p);
        !           291:                (void)edit(glob(p));
        !           292:                break;
        !           293:        case A_SHELL:
        !           294:                /*
        !           295:                 * Copy cmdbuf to shellcmd,
        !           296:                 * expanding any special characters ("%" or "#"
        !           297:                 * or an initial !).
        !           298:                 */
        !           299:                if ((p = fexpand(cmdbuf, shellcmd)) == NULL)
        !           300:                        break;
        !           301:                else if (shellcmd != NULL)
        !           302:                        free(shellcmd);
        !           303:                lsystem(shellcmd = p);
        !           304:                error("!done");
        !           305:                break;
        !           306:        case A_TAGFILE:
        !           307:                for (p = cmdbuf; isspace(*p); ++p);
        !           308:                findtag(p);
        !           309:                if (tagfile == NULL)
        !           310:                        break;
        !           311:                if (edit(tagfile))
        !           312:                        (void)tagsearch();
        !           313:                break;
        !           314:        }
        !           315: }
        !           316:
        !           317: /* add a character to a multi-character command. */
        !           318: static
        !           319: mca_char(c)
        !           320:        int c;
        !           321: {
        !           322:        switch (mca) {
        !           323:        case 0:                 /* not in a multicharacter command. */
        !           324:        case A_PREFIX:          /* in the prefix of a command. */
        !           325:                return(NO_MCA);
        !           326:        case A_DIGIT:
        !           327:                /*
        !           328:                 * Entering digits of a number.
        !           329:                 * Terminated by a non-digit.
        !           330:                 */
        !           331:                if (!isascii(c) || !isdigit(c) &&
        !           332:                    c != erase_char && c != kill_char && c != werase_char) {
        !           333:                        /*
        !           334:                         * Not part of the number.
        !           335:                         * Treat as a normal command character.
        !           336:                         */
        !           337:                        *cp = '\0';
        !           338:                        number = atoi(cmdbuf);
        !           339:                        CMD_RESET;
        !           340:                        mca = 0;
        !           341:                        return(NO_MCA);
        !           342:                }
        !           343:                break;
        !           344:        }
        !           345:
        !           346:        /*
        !           347:         * Any other multicharacter command
        !           348:         * is terminated by a newline.
        !           349:         */
        !           350:        if (c == '\n' || c == '\r') {
        !           351:                exec_mca();
        !           352:                return(MCA_DONE);
        !           353:        }
        !           354:
        !           355:        /* append the char to the command buffer. */
        !           356:        if (cmd_char(c))
        !           357:                return(MCA_DONE);
        !           358:
        !           359:        return(MCA_MORE);
        !           360: }
        !           361:
        !           362: /*
        !           363:  * Main command processor.
        !           364:  * Accept and execute commands until a quit command, then return.
        !           365:  */
        !           366: commands()
        !           367: {
        !           368:        register int c;
        !           369:        register int action;
        !           370:
        !           371:        last_mca = 0;
        !           372:        scroll = (sc_height + 1) / 2;
        !           373:
        !           374:        for (;;) {
        !           375:                mca = 0;
        !           376:                number = 0;
        !           377:
        !           378:                /*
        !           379:                 * See if any signals need processing.
        !           380:                 */
        !           381:                if (sigs) {
        !           382:                        psignals();
        !           383:                        if (quitting)
        !           384:                                quit();
        !           385:                }
        !           386:                /*
        !           387:                 * Display prompt and accept a character.
        !           388:                 */
        !           389:                CMD_RESET;
        !           390:                if (!prompt()) {
        !           391:                        next_file(1);
        !           392:                        continue;
        !           393:                }
        !           394:                noprefix();
        !           395:                c = getcc();
        !           396:
        !           397: again:         if (sigs)
        !           398:                        continue;
        !           399:
        !           400:                /*
        !           401:                 * If we are in a multicharacter command, call mca_char.
        !           402:                 * Otherwise we call cmd_decode to determine the
        !           403:                 * action to be performed.
        !           404:                 */
        !           405:                if (mca)
        !           406:                        switch (mca_char(c)) {
        !           407:                        case MCA_MORE:
        !           408:                                /*
        !           409:                                 * Need another character.
        !           410:                                 */
        !           411:                                c = getcc();
        !           412:                                goto again;
        !           413:                        case MCA_DONE:
        !           414:                                /*
        !           415:                                 * Command has been handled by mca_char.
        !           416:                                 * Start clean with a prompt.
        !           417:                                 */
        !           418:                                continue;
        !           419:                        case NO_MCA:
        !           420:                                /*
        !           421:                                 * Not a multi-char command
        !           422:                                 * (at least, not anymore).
        !           423:                                 */
        !           424:                                break;
        !           425:                        }
        !           426:
        !           427:                /* decode the command character and decide what to do. */
        !           428:                switch (action = cmd_decode(c)) {
        !           429:                case A_DIGIT:           /* first digit of a number */
        !           430:                        start_mca(A_DIGIT, ":");
        !           431:                        goto again;
        !           432:                case A_F_SCREEN:        /* forward one screen */
        !           433:                        CMD_EXEC;
        !           434:                        if (number <= 0 && (number = sc_window) <= 0)
        !           435:                                number = sc_height - 1;
        !           436:                        forward(number, 1);
        !           437:                        break;
        !           438:                case A_B_SCREEN:        /* backward one screen */
        !           439:                        CMD_EXEC;
        !           440:                        if (number <= 0 && (number = sc_window) <= 0)
        !           441:                                number = sc_height - 1;
        !           442:                        backward(number, 1);
        !           443:                        break;
        !           444:                case A_F_LINE:          /* forward N (default 1) line */
        !           445:                        CMD_EXEC;
        !           446:                        forward(number <= 0 ? 1 : number, 0);
        !           447:                        break;
        !           448:                case A_B_LINE:          /* backward N (default 1) line */
        !           449:                        CMD_EXEC;
        !           450:                        backward(number <= 0 ? 1 : number, 0);
        !           451:                        break;
        !           452:                case A_F_SCROLL:        /* forward N lines */
        !           453:                        CMD_EXEC;
        !           454:                        if (number > 0)
        !           455:                                scroll = number;
        !           456:                        forward(scroll, 0);
        !           457:                        break;
        !           458:                case A_B_SCROLL:        /* backward N lines */
        !           459:                        CMD_EXEC;
        !           460:                        if (number > 0)
        !           461:                                scroll = number;
        !           462:                        backward(scroll, 0);
        !           463:                        break;
        !           464:                case A_FREPAINT:        /* flush buffers and repaint */
        !           465:                        if (!ispipe) {
        !           466:                                ch_init(0, 0);
        !           467:                                clr_linenum();
        !           468:                        }
        !           469:                        /* FALLTHROUGH */
        !           470:                case A_REPAINT:         /* repaint the screen */
        !           471:                        CMD_EXEC;
        !           472:                        repaint();
        !           473:                        break;
        !           474:                case A_GOLINE:          /* go to line N, default 1 */
        !           475:                        CMD_EXEC;
        !           476:                        if (number <= 0)
        !           477:                                number = 1;
        !           478:                        jump_back(number);
        !           479:                        break;
        !           480:                case A_PERCENT:         /* go to percent of file */
        !           481:                        CMD_EXEC;
        !           482:                        if (number < 0)
        !           483:                                number = 0;
        !           484:                        else if (number > 100)
        !           485:                                number = 100;
        !           486:                        jump_percent(number);
        !           487:                        break;
        !           488:                case A_GOEND:           /* go to line N, default end */
        !           489:                        CMD_EXEC;
        !           490:                        if (number <= 0)
        !           491:                                jump_forw();
        !           492:                        else
        !           493:                                jump_back(number);
        !           494:                        break;
        !           495:                case A_STAT:            /* print file name, etc. */
        !           496:                        longprompt = 1;
        !           497:                        continue;
        !           498:                case A_QUIT:            /* exit */
        !           499:                        quit();
        !           500:                case A_F_SEARCH:        /* search for a pattern */
        !           501:                case A_B_SEARCH:
        !           502:                        if (number <= 0)
        !           503:                                number = 1;
        !           504:                        start_mca(action, (action==A_F_SEARCH) ? "/" : "?");
        !           505:                        last_mca = mca;
        !           506:                        wsearch = 1;
        !           507:                        c = getcc();
        !           508:                        if (c == '!') {
        !           509:                                /*
        !           510:                                 * Invert the sense of the search; set wsearch
        !           511:                                 * to 0 and get a new character for the start
        !           512:                                 * of the pattern.
        !           513:                                 */
        !           514:                                start_mca(action,
        !           515:                                    (action == A_F_SEARCH) ? "!/" : "!?");
        !           516:                                wsearch = 0;
        !           517:                                c = getcc();
        !           518:                        }
        !           519:                        goto again;
        !           520:                case A_AGAIN_SEARCH:            /* repeat previous search */
        !           521:                        if (number <= 0)
        !           522:                                number = 1;
        !           523:                        if (wsearch)
        !           524:                                start_mca(last_mca,
        !           525:                                    (last_mca == A_F_SEARCH) ? "/" : "?");
        !           526:                        else
        !           527:                                start_mca(last_mca,
        !           528:                                    (last_mca == A_F_SEARCH) ? "!/" : "!?");
        !           529:                        CMD_EXEC;
        !           530:                        (void)search(mca == A_F_SEARCH, (char *)NULL,
        !           531:                            number, wsearch);
        !           532:                        break;
        !           533:                case A_HELP:                    /* help */
        !           534:                        lower_left();
        !           535:                        clear_eol();
        !           536:                        putstr("help");
        !           537:                        CMD_EXEC;
        !           538:                        help();
        !           539:                        break;
        !           540:                case A_TAGFILE:                 /* tag a new file */
        !           541:                        CMD_RESET;
        !           542:                        start_mca(A_TAGFILE, "Tag: ");
        !           543:                        c = getcc();
        !           544:                        goto again;
        !           545:                case A_FILE_LIST:               /* show list of file names */
        !           546:                        CMD_EXEC;
        !           547:                        showlist();
        !           548:                        repaint();
        !           549:                        break;
        !           550:                case A_EXAMINE:                 /* edit a new file */
        !           551:                        CMD_RESET;
        !           552:                        start_mca(A_EXAMINE, "Examine: ");
        !           553:                        c = getcc();
        !           554:                        goto again;
        !           555:                case A_VISUAL:                  /* invoke the editor */
        !           556:                        if (ispipe) {
        !           557:                                error("Cannot edit standard input");
        !           558:                                break;
        !           559:                        }
        !           560:                        CMD_EXEC;
        !           561:                        editfile();
        !           562:                        ch_init(0, 0);
        !           563:                        clr_linenum();
        !           564:                        break;
        !           565:                case A_NEXT_FILE:               /* examine next file */
        !           566:                        if (number <= 0)
        !           567:                                number = 1;
        !           568:                        next_file(number);
        !           569:                        break;
        !           570:                case A_PREV_FILE:               /* examine previous file */
        !           571:                        if (number <= 0)
        !           572:                                number = 1;
        !           573:                        prev_file(number);
        !           574:                        break;
        !           575:                case A_SETMARK:                 /* set a mark */
        !           576:                        lower_left();
        !           577:                        clear_eol();
        !           578:                        start_mca(A_SETMARK, "mark: ");
        !           579:                        c = getcc();
        !           580:                        if (c == erase_char || c == kill_char)
        !           581:                                break;
        !           582:                        setmark(c);
        !           583:                        break;
        !           584:                case A_GOMARK:                  /* go to mark */
        !           585:                        lower_left();
        !           586:                        clear_eol();
        !           587:                        start_mca(A_GOMARK, "goto mark: ");
        !           588:                        c = getcc();
        !           589:                        if (c == erase_char || c == kill_char)
        !           590:                                break;
        !           591:                        gomark(c);
        !           592:                        break;
        !           593:                case A_SHELL:
        !           594:                        /*
        !           595:                         * Shell escape.
        !           596:                         */
        !           597:                        start_mca(A_SHELL, "!");
        !           598:                        c = getcc();
        !           599:                        goto again;
        !           600:                case A_PREFIX:
        !           601:                        /*
        !           602:                         * The command is incomplete (more chars are needed).
        !           603:                         * Display the current char so the user knows what's
        !           604:                         * going on and get another character.
        !           605:                         */
        !           606:                        if (mca != A_PREFIX)
        !           607:                                start_mca(A_PREFIX, "");
        !           608:                        if (CONTROL_CHAR(c)) {
        !           609:                                putchr('^');
        !           610:                                c = CARAT_CHAR(c);
        !           611:                        }
        !           612:                        putchr(c);
        !           613:                        c = getcc();
        !           614:                        goto again;
        !           615:                default:
        !           616:                        if (novice)
        !           617:                                helpprompt = 1;
        !           618:                        else
        !           619:                                bell();
        !           620:                        break;
        !           621:                }
        !           622:        }
        !           623: }
        !           624:
        !           625: editfile()
        !           626: {
        !           627:        extern char *current_file;
        !           628:        static int dolinenumber;
        !           629:        static char *editor;
        !           630:        int c;
        !           631:        char buf[MAXPATHLEN * 2 + 20], *getenv();
        !           632:
        !           633:        if (editor == NULL) {
        !           634:                editor = getenv("EDITOR");
        !           635:                /* pass the line number to vi */
        !           636:                if (editor == NULL || *editor == '\0') {
        !           637:                        editor = _PATH_VI;
        !           638:                        dolinenumber = 1;
        !           639:                }
        !           640:                else
        !           641:                        dolinenumber = 0;
        !           642:        }
        !           643:        if (dolinenumber && (c = currline(MIDDLE)))
        !           644:                (void)sprintf(buf, "%s +%d %s", editor, c, current_file);
        !           645:        else
        !           646:                (void)sprintf(buf, "%s %s", editor, current_file);
        !           647:        lsystem(buf);
        !           648: }
        !           649:
        !           650: showlist()
        !           651: {
        !           652:        extern int sc_width;
        !           653:        extern char **av;
        !           654:        register int indx, width;
        !           655:        int len;
        !           656:        char *p;
        !           657:
        !           658:        if (ac <= 0) {
        !           659:                error("No files provided as arguments.");
        !           660:                return;
        !           661:        }
        !           662:        for (width = indx = 0; indx < ac;) {
        !           663:                p = strcmp(av[indx], "-") ? av[indx] : "stdin";
        !           664:                len = strlen(p) + 1;
        !           665:                if (curr_ac == indx)
        !           666:                        len += 2;
        !           667:                if (width + len + 1 >= sc_width) {
        !           668:                        if (!width) {
        !           669:                                if (curr_ac == indx)
        !           670:                                        putchr('[');
        !           671:                                putstr(p);
        !           672:                                if (curr_ac == indx)
        !           673:                                        putchr(']');
        !           674:                                ++indx;
        !           675:                        }
        !           676:                        width = 0;
        !           677:                        putchr('\n');
        !           678:                        continue;
        !           679:                }
        !           680:                if (width)
        !           681:                        putchr(' ');
        !           682:                if (curr_ac == indx)
        !           683:                        putchr('[');
        !           684:                putstr(p);
        !           685:                if (curr_ac == indx)
        !           686:                        putchr(']');
        !           687:                width += len;
        !           688:                ++indx;
        !           689:        }
        !           690:        putchr('\n');
        !           691:        error((char *)NULL);
        !           692: }