[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.3

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')
1.3     ! deraadt   124:        while (--argc > 0 && (isoptstring(argv[0]) || isoptpending())) {
        !           125:                if (strcmp(argv[0], "--") == 0) {
        !           126:                        argv++;
        !           127:                        argc--;
        !           128:                        break;
        !           129:                }
1.1       etheisen  130:                scan_option(*argv++);
1.3     ! deraadt   131:        }
1.1       etheisen  132: #undef isoptstring
                    133:
                    134:        if (isoptpending())
                    135:        {
                    136:                /*
                    137:                 * Last command line option was a flag requiring a
                    138:                 * following string, but there was no following string.
                    139:                 */
                    140:                nopendopt();
                    141:                quit(QUIT_OK);
                    142:        }
                    143:
                    144: #if EDITOR
                    145:        editor = getenv("VISUAL");
                    146:        if (editor == NULL || *editor == '\0')
                    147:        {
                    148:                editor = getenv("EDITOR");
                    149:                if (editor == NULL || *editor == '\0')
                    150:                        editor = EDIT_PGM;
                    151:        }
                    152:        editproto = getenv("LESSEDIT");
                    153:        if (editproto == NULL || *editproto == '\0')
                    154:                editproto = "%E ?lm+%lm. %f";
                    155: #endif
                    156:
                    157:        /*
                    158:         * Call get_ifile with all the command line filenames
                    159:         * to "register" them with the ifile system.
                    160:         */
                    161:        ifile = NULL_IFILE;
                    162:        while (--argc >= 0)
                    163:        {
                    164: #if MSOFTC || OS2
                    165:                /*
                    166:                 * Because the "shell" doesn't expand filename patterns,
                    167:                 * treat each argument as a filename pattern rather than
                    168:                 * a single filename.
                    169:                 * Expand the pattern and iterate over the expanded list.
                    170:                 */
                    171:                struct textlist tlist;
                    172:                char *gfilename;
                    173:                char *filename;
                    174:
                    175:                gfilename = glob(*argv++);
                    176:                init_textlist(&tlist, gfilename);
                    177:                filename = NULL;
                    178:                while ((filename = forw_textlist(&tlist, filename)) != NULL)
                    179:                        ifile = get_ifile(filename, ifile);
                    180:                free(gfilename);
                    181: #else
                    182:                ifile = get_ifile(*argv++, ifile);
                    183: #endif
                    184:        }
                    185:        /*
                    186:         * Set up terminal, etc.
                    187:         */
                    188:        is_tty = isatty(1);
                    189:        if (!is_tty)
                    190:        {
                    191:                /*
                    192:                 * Output is not a tty.
                    193:                 * Just copy the input file(s) to output.
                    194:                 */
                    195:                if (nifile() == 0)
                    196:                {
                    197:                        if (edit_stdin() == 0)
                    198:                                cat_file();
                    199:                } else if (edit_first() == 0)
                    200:                {
                    201:                        do {
                    202:                                cat_file();
                    203:                        } while (edit_next(1) == 0);
                    204:                }
                    205:                quit(QUIT_OK);
                    206:        }
                    207:
                    208:        init_mark();
                    209:        raw_mode(1);
                    210:        open_getchr();
                    211:        init_signals(1);
                    212:
                    213:        /*
                    214:         * Select the first file to examine.
                    215:         */
                    216: #if TAGS
                    217:        if (tagoption != NULL)
                    218:        {
                    219:                /*
                    220:                 * A -t option was given.
                    221:                 * Verify that no filenames were also given.
                    222:                 * Edit the file selected by the "tags" search,
                    223:                 * and search for the proper line in the file.
                    224:                 */
                    225:                if (nifile() > 0)
                    226:                {
                    227:                        error("No filenames allowed with -t option", NULL_PARG);
                    228:                        quit(QUIT_ERROR);
                    229:                }
                    230:                findtag(tagoption);
                    231:                if (tagfile == NULL)
                    232:                        quit(QUIT_ERROR);
                    233:                if (edit(tagfile))  /* Edit file which contains the tag */
                    234:                        quit(QUIT_ERROR);
                    235:                /*
                    236:                 * Search for the line which contains the tag.
                    237:                 * Set up initial_scrpos so we display that line.
                    238:                 */
                    239:                initial_scrpos.pos = tagsearch();
                    240:                if (initial_scrpos.pos == NULL_POSITION)
                    241:                        quit(QUIT_ERROR);
                    242:                initial_scrpos.ln = jump_sline;
                    243:        } else
                    244: #endif
                    245:        if (nifile() == 0)
                    246:        {
                    247:                if (edit_stdin())  /* Edit standard input */
                    248:                        quit(QUIT_ERROR);
                    249:        } else
                    250:        {
                    251:                if (edit_first())  /* Edit first valid file in cmd line */
                    252:                        quit(QUIT_ERROR);
                    253:        }
                    254:
                    255:        init();
                    256:        commands();
                    257:        quit(QUIT_OK);
                    258:        /*NOTREACHED*/
                    259: }
                    260:
                    261: /*
                    262:  * Copy a string, truncating to the specified length if necessary.
                    263:  * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
                    264:  */
                    265:        public void
                    266: strtcpy(to, from, len)
                    267:        char *to;
                    268:        char *from;
                    269:        unsigned int len;
                    270: {
                    271:        strncpy(to, from, len);
                    272:        to[len-1] = '\0';
                    273: }
                    274:
                    275: /*
                    276:  * Copy a string to a "safe" place
                    277:  * (that is, to a buffer allocated by calloc).
                    278:  */
                    279:        public char *
                    280: save(s)
                    281:        char *s;
                    282: {
                    283:        register char *p;
                    284:
                    285:        p = (char *) ecalloc(strlen(s)+1, sizeof(char));
                    286:        strcpy(p, s);
                    287:        return (p);
                    288: }
                    289:
                    290: /*
                    291:  * Allocate memory.
                    292:  * Like calloc(), but never returns an error (NULL).
                    293:  */
                    294:        public VOID_POINTER
                    295: ecalloc(count, size)
                    296:        int count;
                    297:        unsigned int size;
                    298: {
                    299:        register VOID_POINTER p;
                    300:
                    301:        p = (VOID_POINTER) calloc(count, size);
                    302:        if (p != NULL)
                    303:                return (p);
                    304:        error("Cannot allocate memory", NULL_PARG);
                    305:        quit(QUIT_ERROR);
                    306:        /*NOTREACHED*/
                    307: }
                    308:
                    309: /*
                    310:  * Skip leading spaces in a string.
                    311:  */
                    312:        public char *
                    313: skipsp(s)
                    314:        register char *s;
                    315: {
                    316:        while (*s == ' ' || *s == '\t')
                    317:                s++;
                    318:        return (s);
                    319: }
                    320:
                    321: /*
                    322:  * Exit the program.
                    323:  */
                    324:        public void
                    325: quit(status)
                    326:        int status;
                    327: {
                    328:        static int save_status;
                    329:
                    330:        /*
                    331:         * Put cursor at bottom left corner, clear the line,
                    332:         * reset the terminal modes, and exit.
                    333:         */
                    334:        if (status < 0)
                    335:                status = save_status;
                    336:        else
                    337:                save_status = status;
                    338:        quitting = 1;
                    339:        edit((char*)NULL);
1.2       etheisen  340:        if (is_tty && any_display)
1.1       etheisen  341:                clear_bot();
                    342:        deinit();
                    343:        flush();
                    344:        raw_mode(0);
                    345: #if MSOFTC
                    346:        /*
                    347:         * If we don't close 2, we get some garbage from
                    348:         * 2's buffer when it flushes automatically.
                    349:         * I cannot track this one down  RB
                    350:         * The same bug shows up if we use ^C^C to abort.
                    351:         */
                    352:        close(2);
                    353: #endif
                    354:        exit(status);
                    355: }