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

Annotation of src/usr.bin/less/optfunc.c, Revision 1.5

1.1       etheisen    1: /*
1.4       millert     2:  * Copyright (C) 1984-2002  Mark Nudelman
1.1       etheisen    3:  *
1.4       millert     4:  * You may distribute under the terms of either the GNU General Public
                      5:  * License or the Less License, as specified in the README file.
1.1       etheisen    6:  *
1.4       millert     7:  * For more information about less, or for information on how to
                      8:  * contact the author, see the README file.
1.1       etheisen    9:  */
                     10:
                     11:
                     12: /*
                     13:  * Handling functions for command line options.
                     14:  *
                     15:  * Most options are handled by the generic code in option.c.
                     16:  * But all string options, and a few non-string options, require
                     17:  * special handling specific to the particular option.
                     18:  * This special processing is done by the "handling functions" in this file.
                     19:  *
                     20:  * Each handling function is passed a "type" and, if it is a string
                     21:  * option, the string which should be "assigned" to the option.
                     22:  * The type may be one of:
                     23:  *     INIT    The option is being initialized from the command line.
                     24:  *     TOGGLE  The option is being changed from within the program.
                     25:  *     QUERY   The setting of the option is merely being queried.
                     26:  */
                     27:
                     28: #include "less.h"
                     29: #include "option.h"
                     30:
                     31: extern int nbufs;
1.4       millert    32: extern int bufspace;
1.1       etheisen   33: extern int pr_type;
1.5     ! millert    34: extern int nohelp;
1.1       etheisen   35: extern int plusoption;
                     36: extern int swindow;
                     37: extern int sc_height;
1.4       millert    38: extern int secure;
1.1       etheisen   39: extern int any_display;
1.4       millert    40: extern char openquote;
                     41: extern char closequote;
1.1       etheisen   42: extern char *prproto[];
                     43: extern char *eqproto;
1.4       millert    44: extern char *hproto;
                     45: extern char *wproto;
1.1       etheisen   46: extern IFILE curr_ifile;
1.4       millert    47: extern char version[];
1.1       etheisen   48: #if LOGFILE
                     49: extern char *namelogfile;
                     50: extern int force_logfile;
                     51: extern int logfile;
                     52: #endif
                     53: #if TAGS
                     54: public char *tagoption = NULL;
                     55: extern char *tags;
                     56: extern int jump_sline;
                     57: #endif
1.4       millert    58: #if MSDOS_COMPILER
1.1       etheisen   59: extern int nm_fg_color, nm_bg_color;
                     60: extern int bo_fg_color, bo_bg_color;
                     61: extern int ul_fg_color, ul_bg_color;
                     62: extern int so_fg_color, so_bg_color;
                     63: extern int bl_fg_color, bl_bg_color;
                     64: #endif
                     65:
                     66:
                     67: #if LOGFILE
                     68: /*
                     69:  * Handler for -o option.
                     70:  */
                     71:        public void
                     72: opt_o(type, s)
                     73:        int type;
                     74:        char *s;
                     75: {
                     76:        PARG parg;
                     77:
1.4       millert    78:        if (secure)
                     79:        {
                     80:                error("log file support is not available", NULL_PARG);
                     81:                return;
                     82:        }
1.1       etheisen   83:        switch (type)
                     84:        {
                     85:        case INIT:
                     86:                namelogfile = s;
                     87:                break;
                     88:        case TOGGLE:
                     89:                if (ch_getflags() & CH_CANSEEK)
                     90:                {
                     91:                        error("Input is not a pipe", NULL_PARG);
                     92:                        return;
                     93:                }
                     94:                if (logfile >= 0)
                     95:                {
                     96:                        error("Log file is already in use", NULL_PARG);
                     97:                        return;
                     98:                }
                     99:                s = skipsp(s);
1.4       millert   100:                namelogfile = lglob(s);
1.1       etheisen  101:                use_logfile(namelogfile);
                    102:                sync_logfile();
                    103:                break;
                    104:        case QUERY:
                    105:                if (logfile < 0)
                    106:                        error("No log file", NULL_PARG);
                    107:                else
                    108:                {
                    109:                        parg.p_string = namelogfile;
                    110:                        error("Log file \"%s\"", &parg);
                    111:                }
                    112:                break;
                    113:        }
                    114: }
                    115:
                    116: /*
                    117:  * Handler for -O option.
                    118:  */
                    119:        public void
                    120: opt__O(type, s)
                    121:        int type;
                    122:        char *s;
                    123: {
                    124:        force_logfile = TRUE;
                    125:        opt_o(type, s);
                    126: }
                    127: #endif
                    128:
                    129: /*
                    130:  * Handlers for -l option.
                    131:  */
                    132:        public void
                    133: opt_l(type, s)
                    134:        int type;
                    135:        char *s;
                    136: {
                    137:        int err;
                    138:        int n;
                    139:        char *t;
                    140:
                    141:        switch (type)
                    142:        {
                    143:        case INIT:
                    144:                t = s;
1.4       millert   145:                n = getnum(&t, "l", &err);
1.1       etheisen  146:                if (err || n <= 0)
                    147:                {
                    148:                        error("Line number is required after -l", NULL_PARG);
                    149:                        return;
                    150:                }
                    151:                plusoption = TRUE;
                    152:                ungetsc(s);
                    153:                break;
                    154:        }
                    155: }
                    156:
                    157: #if USERFILE
                    158:        public void
                    159: opt_k(type, s)
                    160:        int type;
                    161:        char *s;
                    162: {
                    163:        PARG parg;
                    164:
                    165:        switch (type)
                    166:        {
                    167:        case INIT:
1.4       millert   168:                if (lesskey(s, 0))
1.1       etheisen  169:                {
                    170:                        parg.p_string = s;
                    171:                        error("Cannot use lesskey file \"%s\"", &parg);
                    172:                }
                    173:                break;
                    174:        }
                    175: }
                    176: #endif
                    177:
                    178: #if TAGS
                    179: /*
                    180:  * Handler for -t option.
                    181:  */
                    182:        public void
                    183: opt_t(type, s)
                    184:        int type;
                    185:        char *s;
                    186: {
                    187:        IFILE save_ifile;
                    188:        POSITION pos;
                    189:
                    190:        switch (type)
                    191:        {
                    192:        case INIT:
                    193:                tagoption = s;
                    194:                /* Do the rest in main() */
                    195:                break;
                    196:        case TOGGLE:
1.4       millert   197:                if (secure)
                    198:                {
                    199:                        error("tags support is not available", NULL_PARG);
                    200:                        break;
                    201:                }
1.1       etheisen  202:                findtag(skipsp(s));
1.4       millert   203:                save_ifile = save_curr_ifile();
                    204:                if (edit_tagfile())
1.1       etheisen  205:                        break;
                    206:                if ((pos = tagsearch()) == NULL_POSITION)
                    207:                {
1.4       millert   208:                        reedit_ifile(save_ifile);
1.1       etheisen  209:                        break;
                    210:                }
1.4       millert   211:                unsave_ifile(save_ifile);
1.1       etheisen  212:                jump_loc(pos, jump_sline);
                    213:                break;
                    214:        }
                    215: }
                    216:
                    217: /*
                    218:  * Handler for -T option.
                    219:  */
                    220:        public void
                    221: opt__T(type, s)
                    222:        int type;
                    223:        char *s;
                    224: {
                    225:        PARG parg;
                    226:
                    227:        switch (type)
                    228:        {
                    229:        case INIT:
                    230:                tags = s;
                    231:                break;
                    232:        case TOGGLE:
                    233:                s = skipsp(s);
1.4       millert   234:                tags = lglob(s);
1.1       etheisen  235:                break;
                    236:        case QUERY:
                    237:                parg.p_string = tags;
                    238:                error("Tags file \"%s\"", &parg);
                    239:                break;
                    240:        }
                    241: }
                    242: #endif
                    243:
                    244: /*
                    245:  * Handler for -p option.
                    246:  */
                    247:        public void
                    248: opt_p(type, s)
                    249:        int type;
1.4       millert   250:        register char *s;
1.1       etheisen  251: {
                    252:        switch (type)
                    253:        {
                    254:        case INIT:
                    255:                /*
                    256:                 * Unget a search command for the specified string.
                    257:                 * {{ This won't work if the "/" command is
                    258:                 *    changed or invalidated by a .lesskey file. }}
                    259:                 */
                    260:                plusoption = TRUE;
                    261:                ungetsc(s);
                    262:                ungetsc("/");
                    263:                break;
                    264:        }
                    265: }
                    266:
                    267: /*
                    268:  * Handler for -P option.
                    269:  */
                    270:        public void
                    271: opt__P(type, s)
                    272:        int type;
1.4       millert   273:        register char *s;
1.1       etheisen  274: {
1.4       millert   275:        register char **proto;
1.1       etheisen  276:        PARG parg;
                    277:
                    278:        switch (type)
                    279:        {
                    280:        case INIT:
                    281:        case TOGGLE:
                    282:                /*
                    283:                 * Figure out which prototype string should be changed.
                    284:                 */
                    285:                switch (*s)
                    286:                {
1.4       millert   287:                case 's':  proto = &prproto[PR_SHORT];  s++;    break;
1.1       etheisen  288:                case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
                    289:                case 'M':  proto = &prproto[PR_LONG];   s++;    break;
                    290:                case '=':  proto = &eqproto;            s++;    break;
1.4       millert   291:                case 'h':  proto = &hproto;             s++;    break;
                    292:                case 'w':  proto = &wproto;             s++;    break;
1.1       etheisen  293:                default:   proto = &prproto[PR_SHORT];          break;
                    294:                }
                    295:                free(*proto);
                    296:                *proto = save(s);
                    297:                break;
                    298:        case QUERY:
                    299:                parg.p_string = prproto[pr_type];
                    300:                error("%s", &parg);
                    301:                break;
                    302:        }
                    303: }
                    304:
                    305: /*
                    306:  * Handler for the -b option.
                    307:  */
                    308:        /*ARGSUSED*/
                    309:        public void
                    310: opt_b(type, s)
                    311:        int type;
                    312:        char *s;
                    313: {
                    314:        switch (type)
                    315:        {
1.4       millert   316:        case INIT:
1.1       etheisen  317:        case TOGGLE:
                    318:                /*
1.4       millert   319:                 * Set the new number of buffers.
1.1       etheisen  320:                 */
1.4       millert   321:                ch_setbufspace(bufspace);
1.1       etheisen  322:                break;
1.4       millert   323:        case QUERY:
1.1       etheisen  324:                break;
                    325:        }
                    326: }
                    327:
                    328: /*
                    329:  * Handler for the -i option.
                    330:  */
                    331:        /*ARGSUSED*/
                    332:        public void
                    333: opt_i(type, s)
                    334:        int type;
                    335:        char *s;
                    336: {
                    337:        switch (type)
                    338:        {
                    339:        case TOGGLE:
                    340:                chg_caseless();
                    341:                break;
                    342:        case QUERY:
                    343:        case INIT:
                    344:                break;
                    345:        }
                    346: }
                    347:
                    348: /*
                    349:  * Handler for the -V option.
                    350:  */
                    351:        /*ARGSUSED*/
                    352:        public void
                    353: opt__V(type, s)
                    354:        int type;
                    355:        char *s;
                    356: {
                    357:        switch (type)
                    358:        {
                    359:        case TOGGLE:
                    360:        case QUERY:
1.4       millert   361:                dispversion();
                    362:                break;
1.1       etheisen  363:        case INIT:
1.4       millert   364:                /*
                    365:                 * Force output to stdout per GNU standard for --version output.
                    366:                 */
                    367:                any_display = 1;
                    368:                putstr("less ");
                    369:                putstr(version);
                    370:                putstr("\nCopyright (C) 2002 Mark Nudelman\n\n");
                    371:                putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
                    372:                putstr("For information about the terms of redistribution,\n");
                    373:                putstr("see the file named README in the less distribution.\n");
                    374:                putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
                    375:                quit(QUIT_OK);
1.1       etheisen  376:                break;
                    377:        }
                    378: }
                    379:
1.4       millert   380: #if MSDOS_COMPILER
1.1       etheisen  381: /*
1.4       millert   382:  * Parse an MSDOS color descriptor.
1.1       etheisen  383:  */
                    384:        static void
                    385: colordesc(s, fg_color, bg_color)
                    386:        char *s;
                    387:        int *fg_color;
                    388:        int *bg_color;
                    389: {
                    390:        int fg, bg;
                    391:        int err;
                    392:
1.4       millert   393:        fg = getnum(&s, "D", &err);
1.1       etheisen  394:        if (err)
                    395:        {
                    396:                error("Missing fg color in -D", NULL_PARG);
                    397:                return;
                    398:        }
                    399:        if (*s != '.')
                    400:                bg = 0;
                    401:        else
                    402:        {
                    403:                s++;
1.4       millert   404:                bg = getnum(&s, "D", &err);
1.1       etheisen  405:                if (err)
                    406:                {
                    407:                        error("Missing fg color in -D", NULL_PARG);
                    408:                        return;
                    409:                }
                    410:        }
1.4       millert   411:        if (*s != '\0')
                    412:                error("Extra characters at end of -D option", NULL_PARG);
1.1       etheisen  413:        *fg_color = fg;
                    414:        *bg_color = bg;
                    415: }
                    416:
                    417: /*
                    418:  * Handler for the -D option.
                    419:  */
                    420:        /*ARGSUSED*/
                    421:        public void
                    422: opt_D(type, s)
                    423:        int type;
                    424:        char *s;
                    425: {
                    426:        switch (type)
                    427:        {
                    428:        case INIT:
                    429:        case TOGGLE:
                    430:                switch (*s++)
                    431:                {
                    432:                case 'n':
                    433:                        colordesc(s, &nm_fg_color, &nm_bg_color);
                    434:                        break;
                    435:                case 'd':
                    436:                        colordesc(s, &bo_fg_color, &bo_bg_color);
                    437:                        break;
                    438:                case 'u':
                    439:                        colordesc(s, &ul_fg_color, &ul_bg_color);
                    440:                        break;
                    441:                case 'k':
                    442:                        colordesc(s, &bl_fg_color, &bl_bg_color);
                    443:                        break;
                    444:                case 's':
                    445:                        colordesc(s, &so_fg_color, &so_bg_color);
                    446:                        break;
                    447:                default:
                    448:                        error("-D must be followed by n, d, u, k or s", NULL_PARG);
                    449:                        break;
                    450:                }
                    451:                if (type == TOGGLE)
                    452:                {
                    453:                        so_enter();
                    454:                        so_exit();
                    455:                }
                    456:                break;
                    457:        case QUERY:
                    458:                break;
                    459:        }
                    460: }
                    461: #endif
                    462:
                    463: /*
1.4       millert   464:  * Handler for the -x option.
                    465:  */
                    466:        public void
                    467: opt_x(type, s)
                    468:        int type;
                    469:        register char *s;
                    470: {
                    471:        extern int tabstops[];
                    472:        extern int ntabstops;
                    473:        extern int tabdefault;
                    474:        char msg[60+(4*TABSTOP_MAX)];
                    475:        int i;
                    476:        PARG p;
                    477:
                    478:        switch (type)
                    479:        {
                    480:        case INIT:
                    481:        case TOGGLE:
                    482:                /* Start at 1 because tabstops[0] is always zero. */
                    483:                for (i = 1;  i < TABSTOP_MAX;  )
                    484:                {
                    485:                        int n = 0;
                    486:                        s = skipsp(s);
                    487:                        while (*s >= '0' && *s <= '9')
                    488:                                n = (10 * n) + (*s++ - '0');
                    489:                        if (n > tabstops[i-1])
                    490:                                tabstops[i++] = n;
                    491:                        s = skipsp(s);
                    492:                        if (*s++ != ',')
                    493:                                break;
                    494:                }
                    495:                if (i < 2)
                    496:                        return;
                    497:                ntabstops = i;
                    498:                tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
                    499:                break;
                    500:        case QUERY:
                    501:                strlcpy(msg, "Tab stops ", sizeof(msg));
                    502:                if (ntabstops > 2)
                    503:                {
                    504:                        for (i = 1;  i < ntabstops;  i++)
                    505:                        {
                    506:                                if (i > 1)
                    507:                                        strlcat(msg, ",", sizeof(msg));
                    508:                                snprintf(msg+strlen(msg),
                    509:                                    sizeof(msg)-strlen(msg), "%d", tabstops[i]);
                    510:                        }
                    511:                        snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
                    512:                            " and then ");
                    513:                }
                    514:                snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
                    515:                    "every %d spaces",
                    516:                        tabdefault);
                    517:                p.p_string = msg;
                    518:                error("%s", &p);
                    519:                break;
                    520:        }
                    521: }
                    522:
                    523:
                    524: /*
                    525:  * Handler for the -" option.
                    526:  */
                    527:        public void
                    528: opt_quote(type, s)
                    529:        int type;
                    530:        register char *s;
                    531: {
                    532:        char buf[3];
                    533:        PARG parg;
                    534:
                    535:        switch (type)
                    536:        {
                    537:        case INIT:
                    538:        case TOGGLE:
                    539:                if (s[0] == '\0')
                    540:                {
                    541:                        openquote = closequote = '\0';
                    542:                        break;
                    543:                }
                    544:                if (s[1] != '\0' && s[2] != '\0')
                    545:                {
                    546:                        error("-\" must be followed by 1 or 2 chars", NULL_PARG);
                    547:                        return;
                    548:                }
                    549:                openquote = s[0];
                    550:                if (s[1] == '\0')
                    551:                        closequote = openquote;
                    552:                else
                    553:                        closequote = s[1];
                    554:                break;
                    555:        case QUERY:
                    556:                buf[0] = openquote;
                    557:                buf[1] = closequote;
                    558:                buf[2] = '\0';
                    559:                parg.p_string = buf;
                    560:                error("quotes %s", &parg);
                    561:                break;
                    562:        }
                    563: }
                    564:
                    565: /*
1.1       etheisen  566:  * "-?" means display a help message.
                    567:  * If from the command line, exit immediately.
                    568:  */
                    569:        /*ARGSUSED*/
                    570:        public void
                    571: opt_query(type, s)
                    572:        int type;
                    573:        char *s;
                    574: {
1.5     ! millert   575:        if (nohelp)
        !           576:                return;
1.1       etheisen  577:        switch (type)
                    578:        {
                    579:        case QUERY:
                    580:        case TOGGLE:
                    581:                error("Use \"h\" for help", NULL_PARG);
                    582:                break;
                    583:        case INIT:
1.5     ! millert   584:                /*
        !           585:                 * This is "less -?".
        !           586:                 * It rather ungracefully grabs control,
        !           587:                 * does the initializations normally done in main,
        !           588:                 * shows the help file and exits.
        !           589:                 */
        !           590:                raw_mode(1);
        !           591:                get_term();
        !           592:                open_getchr();
        !           593:                init();
        !           594:                any_display = TRUE;
        !           595:                help(1);
        !           596:                quit(QUIT_OK);
        !           597:                /*NOTREACHED*/
1.1       etheisen  598:        }
                    599: }
                    600:
                    601: /*
                    602:  * Get the "screen window" size.
                    603:  */
                    604:        public int
                    605: get_swindow()
                    606: {
                    607:        if (swindow > 0)
                    608:                return (swindow);
                    609:        return (sc_height + swindow);
                    610: }
                    611: