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

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