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

Annotation of src/usr.bin/less/main.c, Revision 1.2

1.1       etheisen    1: /*
                      2:  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice in the documentation and/or other materials provided with
                     12:  *    the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
                     15:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     17:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
                     18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     19:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
                     20:  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
                     21:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     22:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
                     23:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
                     24:  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27:
                     28: /*
                     29:  * Entry point, initialization, miscellaneous routines.
                     30:  */
                     31:
                     32: #include "less.h"
                     33: #include "position.h"
                     34:
                     35: public char *  every_first_cmd = NULL;
                     36: public int     new_file;
                     37: public int     is_tty;
                     38: public IFILE   curr_ifile = NULL_IFILE;
                     39: public IFILE   old_ifile = NULL_IFILE;
                     40: public struct scrpos initial_scrpos;
                     41: public int     any_display = FALSE;
                     42: public int     wscroll;
                     43: public char *  progname;
                     44: public int     quitting;
1.2     ! etheisen   45: public int     more_mode = 0;
1.1       etheisen   46:
                     47: extern int     quit_at_eof;
                     48: extern int     cbufs;
                     49: extern int     errmsgs;
                     50: extern int     screen_trashed;
                     51: extern int     force_open;
                     52:
                     53: #if LOGFILE
                     54: public int     logfile = -1;
                     55: public int     force_logfile = FALSE;
                     56: public char *  namelogfile = NULL;
                     57: #endif
                     58:
                     59: #if EDITOR
                     60: public char *  editor;
                     61: public char *  editproto;
                     62: #endif
                     63:
                     64: #if TAGS
                     65: extern char *  tagfile;
                     66: extern char *  tagoption;
                     67: extern int     jump_sline;
                     68: #endif
                     69:
                     70:
                     71:
                     72: /*
                     73:  * Entry point.
                     74:  */
                     75: int
                     76: main(argc, argv)
                     77:        int argc;
                     78:        char *argv[];
                     79: {
                     80:        IFILE ifile;
1.2     ! etheisen   81:        extern char *__progname;
1.1       etheisen   82:
                     83: #ifdef __EMX__
                     84:        _response(&argc, &argv);
                     85:        _wildcard(&argc, &argv);
                     86: #endif
                     87:
                     88:        progname = *argv++;
                     89:
                     90:        /*
                     91:         * Process command line arguments and LESS environment arguments.
                     92:         * Command line arguments override environment arguments.
                     93:         */
1.2     ! etheisen   94:        if (strcmp(__progname, "more") == 0)
        !            95:                more_mode = 1;
        !            96:
1.1       etheisen   97:        get_term();
                     98:        init_cmds();
                     99:        init_prompt();
                    100:        init_charset();
                    101:        init_option();
1.2     ! etheisen  102:
        !           103:        if (more_mode) {
        !           104:                scan_option("-E");
        !           105:                scan_option("-m");
        !           106:                scan_option("-G");
        !           107:                scan_option(getenv("MORE"));
        !           108:        } else
        !           109:                scan_option(getenv("LESS"));
1.1       etheisen  110:
                    111: #if GNU_OPTIONS
                    112:        /*
                    113:         * Special case for "less --help" and "less --version".
                    114:         */
                    115:        if (argc == 2)
                    116:        {
                    117:                if (strcmp(argv[0], "--help") == 0)
                    118:                        scan_option("-?");
                    119:                if (strcmp(argv[0], "--version") == 0)
                    120:                        scan_option("-V");
                    121:        }
                    122: #endif
                    123: #define        isoptstring(s)  (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
                    124:        while (--argc > 0 && (isoptstring(argv[0]) || isoptpending()))
                    125:                scan_option(*argv++);
                    126: #undef isoptstring
                    127:
                    128:        if (isoptpending())
                    129:        {
                    130:                /*
                    131:                 * Last command line option was a flag requiring a
                    132:                 * following string, but there was no following string.
                    133:                 */
                    134:                nopendopt();
                    135:                quit(QUIT_OK);
                    136:        }
                    137:
                    138: #if EDITOR
                    139:        editor = getenv("VISUAL");
                    140:        if (editor == NULL || *editor == '\0')
                    141:        {
                    142:                editor = getenv("EDITOR");
                    143:                if (editor == NULL || *editor == '\0')
                    144:                        editor = EDIT_PGM;
                    145:        }
                    146:        editproto = getenv("LESSEDIT");
                    147:        if (editproto == NULL || *editproto == '\0')
                    148:                editproto = "%E ?lm+%lm. %f";
                    149: #endif
                    150:
                    151:        /*
                    152:         * Call get_ifile with all the command line filenames
                    153:         * to "register" them with the ifile system.
                    154:         */
                    155:        ifile = NULL_IFILE;
                    156:        while (--argc >= 0)
                    157:        {
                    158: #if MSOFTC || OS2
                    159:                /*
                    160:                 * Because the "shell" doesn't expand filename patterns,
                    161:                 * treat each argument as a filename pattern rather than
                    162:                 * a single filename.
                    163:                 * Expand the pattern and iterate over the expanded list.
                    164:                 */
                    165:                struct textlist tlist;
                    166:                char *gfilename;
                    167:                char *filename;
                    168:
                    169:                gfilename = glob(*argv++);
                    170:                init_textlist(&tlist, gfilename);
                    171:                filename = NULL;
                    172:                while ((filename = forw_textlist(&tlist, filename)) != NULL)
                    173:                        ifile = get_ifile(filename, ifile);
                    174:                free(gfilename);
                    175: #else
                    176:                ifile = get_ifile(*argv++, ifile);
                    177: #endif
                    178:        }
                    179:        /*
                    180:         * Set up terminal, etc.
                    181:         */
                    182:        is_tty = isatty(1);
                    183:        if (!is_tty)
                    184:        {
                    185:                /*
                    186:                 * Output is not a tty.
                    187:                 * Just copy the input file(s) to output.
                    188:                 */
                    189:                if (nifile() == 0)
                    190:                {
                    191:                        if (edit_stdin() == 0)
                    192:                                cat_file();
                    193:                } else if (edit_first() == 0)
                    194:                {
                    195:                        do {
                    196:                                cat_file();
                    197:                        } while (edit_next(1) == 0);
                    198:                }
                    199:                quit(QUIT_OK);
                    200:        }
                    201:
                    202:        init_mark();
                    203:        raw_mode(1);
                    204:        open_getchr();
                    205:        init_signals(1);
                    206:
                    207:        /*
                    208:         * Select the first file to examine.
                    209:         */
                    210: #if TAGS
                    211:        if (tagoption != NULL)
                    212:        {
                    213:                /*
                    214:                 * A -t option was given.
                    215:                 * Verify that no filenames were also given.
                    216:                 * Edit the file selected by the "tags" search,
                    217:                 * and search for the proper line in the file.
                    218:                 */
                    219:                if (nifile() > 0)
                    220:                {
                    221:                        error("No filenames allowed with -t option", NULL_PARG);
                    222:                        quit(QUIT_ERROR);
                    223:                }
                    224:                findtag(tagoption);
                    225:                if (tagfile == NULL)
                    226:                        quit(QUIT_ERROR);
                    227:                if (edit(tagfile))  /* Edit file which contains the tag */
                    228:                        quit(QUIT_ERROR);
                    229:                /*
                    230:                 * Search for the line which contains the tag.
                    231:                 * Set up initial_scrpos so we display that line.
                    232:                 */
                    233:                initial_scrpos.pos = tagsearch();
                    234:                if (initial_scrpos.pos == NULL_POSITION)
                    235:                        quit(QUIT_ERROR);
                    236:                initial_scrpos.ln = jump_sline;
                    237:        } else
                    238: #endif
                    239:        if (nifile() == 0)
                    240:        {
                    241:                if (edit_stdin())  /* Edit standard input */
                    242:                        quit(QUIT_ERROR);
                    243:        } else
                    244:        {
                    245:                if (edit_first())  /* Edit first valid file in cmd line */
                    246:                        quit(QUIT_ERROR);
                    247:        }
                    248:
                    249:        init();
                    250:        commands();
                    251:        quit(QUIT_OK);
                    252:        /*NOTREACHED*/
                    253: }
                    254:
                    255: /*
                    256:  * Copy a string, truncating to the specified length if necessary.
                    257:  * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
                    258:  */
                    259:        public void
                    260: strtcpy(to, from, len)
                    261:        char *to;
                    262:        char *from;
                    263:        unsigned int len;
                    264: {
                    265:        strncpy(to, from, len);
                    266:        to[len-1] = '\0';
                    267: }
                    268:
                    269: /*
                    270:  * Copy a string to a "safe" place
                    271:  * (that is, to a buffer allocated by calloc).
                    272:  */
                    273:        public char *
                    274: save(s)
                    275:        char *s;
                    276: {
                    277:        register char *p;
                    278:
                    279:        p = (char *) ecalloc(strlen(s)+1, sizeof(char));
                    280:        strcpy(p, s);
                    281:        return (p);
                    282: }
                    283:
                    284: /*
                    285:  * Allocate memory.
                    286:  * Like calloc(), but never returns an error (NULL).
                    287:  */
                    288:        public VOID_POINTER
                    289: ecalloc(count, size)
                    290:        int count;
                    291:        unsigned int size;
                    292: {
                    293:        register VOID_POINTER p;
                    294:
                    295:        p = (VOID_POINTER) calloc(count, size);
                    296:        if (p != NULL)
                    297:                return (p);
                    298:        error("Cannot allocate memory", NULL_PARG);
                    299:        quit(QUIT_ERROR);
                    300:        /*NOTREACHED*/
                    301: }
                    302:
                    303: /*
                    304:  * Skip leading spaces in a string.
                    305:  */
                    306:        public char *
                    307: skipsp(s)
                    308:        register char *s;
                    309: {
                    310:        while (*s == ' ' || *s == '\t')
                    311:                s++;
                    312:        return (s);
                    313: }
                    314:
                    315: /*
                    316:  * Exit the program.
                    317:  */
                    318:        public void
                    319: quit(status)
                    320:        int status;
                    321: {
                    322:        static int save_status;
                    323:
                    324:        /*
                    325:         * Put cursor at bottom left corner, clear the line,
                    326:         * reset the terminal modes, and exit.
                    327:         */
                    328:        if (status < 0)
                    329:                status = save_status;
                    330:        else
                    331:                save_status = status;
                    332:        quitting = 1;
                    333:        edit((char*)NULL);
1.2     ! etheisen  334:        if (is_tty && any_display)
1.1       etheisen  335:                clear_bot();
                    336:        deinit();
                    337:        flush();
                    338:        raw_mode(0);
                    339: #if MSOFTC
                    340:        /*
                    341:         * If we don't close 2, we get some garbage from
                    342:         * 2's buffer when it flushes automatically.
                    343:         * I cannot track this one down  RB
                    344:         * The same bug shows up if we use ^C^C to abort.
                    345:         */
                    346:        close(2);
                    347: #endif
                    348:        exit(status);
                    349: }