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

1.1       etheisen    1: /*
1.7       shadchin    2:  * Copyright (C) 1984-2011  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;
                     34: extern int plusoption;
                     35: extern int swindow;
1.7       shadchin   36: extern int sc_width;
1.1       etheisen   37: extern int sc_height;
1.4       millert    38: extern int secure;
1.7       shadchin   39: extern int dohelp;
1.1       etheisen   40: extern int any_display;
1.4       millert    41: extern char openquote;
                     42: extern char closequote;
1.1       etheisen   43: extern char *prproto[];
                     44: extern char *eqproto;
1.4       millert    45: extern char *hproto;
                     46: extern char *wproto;
1.1       etheisen   47: extern IFILE curr_ifile;
1.4       millert    48: extern char version[];
1.7       shadchin   49: extern int jump_sline;
                     50: extern int jump_sline_fraction;
                     51: extern int shift_count;
                     52: extern int shift_count_fraction;
                     53: extern int less_is_more;
1.1       etheisen   54: #if LOGFILE
                     55: extern char *namelogfile;
                     56: extern int force_logfile;
                     57: extern int logfile;
                     58: #endif
                     59: #if TAGS
                     60: public char *tagoption = NULL;
                     61: extern char *tags;
                     62: #endif
1.4       millert    63: #if MSDOS_COMPILER
1.1       etheisen   64: extern int nm_fg_color, nm_bg_color;
                     65: extern int bo_fg_color, bo_bg_color;
                     66: extern int ul_fg_color, ul_bg_color;
                     67: extern int so_fg_color, so_bg_color;
                     68: extern int bl_fg_color, bl_bg_color;
                     69: #endif
1.8     ! millert    70: extern char *every_first_cmd;
1.1       etheisen   71:
                     72:
                     73: #if LOGFILE
                     74: /*
                     75:  * Handler for -o option.
                     76:  */
                     77:        public void
                     78: opt_o(type, s)
                     79:        int type;
                     80:        char *s;
                     81: {
                     82:        PARG parg;
                     83:
1.4       millert    84:        if (secure)
                     85:        {
                     86:                error("log file support is not available", NULL_PARG);
                     87:                return;
                     88:        }
1.1       etheisen   89:        switch (type)
                     90:        {
                     91:        case INIT:
                     92:                namelogfile = s;
                     93:                break;
                     94:        case TOGGLE:
                     95:                if (ch_getflags() & CH_CANSEEK)
                     96:                {
                     97:                        error("Input is not a pipe", NULL_PARG);
                     98:                        return;
                     99:                }
                    100:                if (logfile >= 0)
                    101:                {
                    102:                        error("Log file is already in use", NULL_PARG);
                    103:                        return;
                    104:                }
                    105:                s = skipsp(s);
1.4       millert   106:                namelogfile = lglob(s);
1.1       etheisen  107:                use_logfile(namelogfile);
                    108:                sync_logfile();
                    109:                break;
                    110:        case QUERY:
                    111:                if (logfile < 0)
                    112:                        error("No log file", NULL_PARG);
                    113:                else
                    114:                {
                    115:                        parg.p_string = namelogfile;
                    116:                        error("Log file \"%s\"", &parg);
                    117:                }
                    118:                break;
                    119:        }
                    120: }
                    121:
                    122: /*
                    123:  * Handler for -O option.
                    124:  */
                    125:        public void
                    126: opt__O(type, s)
                    127:        int type;
                    128:        char *s;
                    129: {
                    130:        force_logfile = TRUE;
                    131:        opt_o(type, s);
                    132: }
                    133: #endif
                    134:
                    135: /*
1.7       shadchin  136:  * Handlers for -j option.
1.1       etheisen  137:  */
                    138:        public void
1.7       shadchin  139: opt_j(type, s)
1.1       etheisen  140:        int type;
                    141:        char *s;
                    142: {
1.7       shadchin  143:        PARG parg;
                    144:        char buf[16];
                    145:        int len;
1.1       etheisen  146:        int err;
1.7       shadchin  147:
                    148:        switch (type)
                    149:        {
                    150:        case INIT:
                    151:        case TOGGLE:
                    152:                if (*s == '.')
                    153:                {
                    154:                        s++;
                    155:                        jump_sline_fraction = getfraction(&s, "j", &err);
                    156:                        if (err)
                    157:                                error("Invalid line fraction", NULL_PARG);
                    158:                        else
                    159:                                calc_jump_sline();
                    160:                } else
                    161:                {
                    162:                        int sline = getnum(&s, "j", &err);
                    163:                        if (err)
                    164:                                error("Invalid line number", NULL_PARG);
                    165:                        else
                    166:                        {
                    167:                                jump_sline = sline;
                    168:                                jump_sline_fraction = -1;
                    169:                        }
                    170:                }
                    171:                break;
                    172:        case QUERY:
                    173:                if (jump_sline_fraction < 0)
                    174:                {
                    175:                        parg.p_int =  jump_sline;
                    176:                        error("Position target at screen line %d", &parg);
                    177:                } else
                    178:                {
                    179:
                    180:                        snprintf(buf, sizeof(buf), ".%06d", jump_sline_fraction);
                    181:                        len = strlen(buf);
                    182:                        while (len > 2 && buf[len-1] == '0')
                    183:                                len--;
                    184:                        buf[len] = '\0';
                    185:                        parg.p_string = buf;
                    186:                        error("Position target at screen position %s", &parg);
                    187:                }
                    188:                break;
                    189:        }
                    190: }
                    191:
                    192:        public void
                    193: calc_jump_sline()
                    194: {
                    195:        if (jump_sline_fraction < 0)
                    196:                return;
                    197:        jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
                    198: }
                    199:
                    200: /*
                    201:  * Handlers for -# option.
                    202:  */
                    203:        public void
                    204: opt_shift(type, s)
                    205:        int type;
                    206:        char *s;
                    207: {
                    208:        PARG parg;
                    209:        char buf[16];
                    210:        int len;
                    211:        int err;
                    212:
1.1       etheisen  213:        switch (type)
                    214:        {
                    215:        case INIT:
1.7       shadchin  216:        case TOGGLE:
                    217:                if (*s == '.')
                    218:                {
                    219:                        s++;
                    220:                        shift_count_fraction = getfraction(&s, "#", &err);
                    221:                        if (err)
                    222:                                error("Invalid column fraction", NULL_PARG);
                    223:                        else
                    224:                                calc_shift_count();
                    225:                } else
                    226:                {
                    227:                        int hs = getnum(&s, "#", &err);
                    228:                        if (err)
                    229:                                error("Invalid column number", NULL_PARG);
                    230:                        else
                    231:                        {
                    232:                                shift_count = hs;
                    233:                                shift_count_fraction = -1;
                    234:                        }
                    235:                }
                    236:                break;
                    237:        case QUERY:
                    238:                if (shift_count_fraction < 0)
                    239:                {
                    240:                        parg.p_int = shift_count;
                    241:                        error("Horizontal shift %d columns", &parg);
                    242:                } else
1.1       etheisen  243:                {
1.7       shadchin  244:
                    245:                        snprintf(buf, sizeof(buf), ".%06d", shift_count_fraction);
                    246:                        len = strlen(buf);
                    247:                        while (len > 2 && buf[len-1] == '0')
                    248:                                len--;
                    249:                        buf[len] = '\0';
                    250:                        parg.p_string = buf;
                    251:                        error("Horizontal shift %s of screen width", &parg);
1.1       etheisen  252:                }
                    253:                break;
                    254:        }
                    255: }
1.7       shadchin  256:        public void
                    257: calc_shift_count()
                    258: {
                    259:        if (shift_count_fraction < 0)
                    260:                return;
                    261:        shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
                    262: }
1.1       etheisen  263:
                    264: #if USERFILE
                    265:        public void
                    266: opt_k(type, s)
                    267:        int type;
                    268:        char *s;
                    269: {
                    270:        PARG parg;
                    271:
                    272:        switch (type)
                    273:        {
                    274:        case INIT:
1.4       millert   275:                if (lesskey(s, 0))
1.1       etheisen  276:                {
                    277:                        parg.p_string = s;
                    278:                        error("Cannot use lesskey file \"%s\"", &parg);
                    279:                }
                    280:                break;
                    281:        }
                    282: }
                    283: #endif
                    284:
                    285: #if TAGS
                    286: /*
                    287:  * Handler for -t option.
                    288:  */
                    289:        public void
                    290: opt_t(type, s)
                    291:        int type;
                    292:        char *s;
                    293: {
                    294:        IFILE save_ifile;
                    295:        POSITION pos;
                    296:
                    297:        switch (type)
                    298:        {
                    299:        case INIT:
                    300:                tagoption = s;
                    301:                /* Do the rest in main() */
                    302:                break;
                    303:        case TOGGLE:
1.4       millert   304:                if (secure)
                    305:                {
                    306:                        error("tags support is not available", NULL_PARG);
                    307:                        break;
                    308:                }
1.1       etheisen  309:                findtag(skipsp(s));
1.4       millert   310:                save_ifile = save_curr_ifile();
1.7       shadchin  311:                /*
                    312:                 * Try to open the file containing the tag
                    313:                 * and search for the tag in that file.
                    314:                 */
                    315:                if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
1.1       etheisen  316:                {
1.7       shadchin  317:                        /* Failed: reopen the old file. */
1.4       millert   318:                        reedit_ifile(save_ifile);
1.1       etheisen  319:                        break;
                    320:                }
1.4       millert   321:                unsave_ifile(save_ifile);
1.1       etheisen  322:                jump_loc(pos, jump_sline);
                    323:                break;
                    324:        }
                    325: }
                    326:
                    327: /*
                    328:  * Handler for -T option.
                    329:  */
                    330:        public void
                    331: opt__T(type, s)
                    332:        int type;
                    333:        char *s;
                    334: {
                    335:        PARG parg;
                    336:
                    337:        switch (type)
                    338:        {
                    339:        case INIT:
                    340:                tags = s;
                    341:                break;
                    342:        case TOGGLE:
                    343:                s = skipsp(s);
1.4       millert   344:                tags = lglob(s);
1.1       etheisen  345:                break;
                    346:        case QUERY:
                    347:                parg.p_string = tags;
                    348:                error("Tags file \"%s\"", &parg);
                    349:                break;
                    350:        }
                    351: }
                    352: #endif
                    353:
                    354: /*
                    355:  * Handler for -p option.
                    356:  */
                    357:        public void
                    358: opt_p(type, s)
                    359:        int type;
1.4       millert   360:        register char *s;
1.1       etheisen  361: {
                    362:        switch (type)
                    363:        {
                    364:        case INIT:
                    365:                /*
                    366:                 * Unget a search command for the specified string.
                    367:                 * {{ This won't work if the "/" command is
                    368:                 *    changed or invalidated by a .lesskey file. }}
                    369:                 */
1.8     ! millert   370:                if (less_is_more) {
        !           371:                        /*
        !           372:                         * In "more" mode, the -p argument is a command,
        !           373:                         * not a search string, run for each file.
        !           374:                         */
        !           375:                        every_first_cmd = save(s);
        !           376:                } else {
        !           377:                        plusoption = TRUE;
        !           378:                        ungetsc(s);
1.7       shadchin  379:                        ungetsc("/");
1.8     ! millert   380:                }
1.1       etheisen  381:                break;
                    382:        }
                    383: }
                    384:
                    385: /*
                    386:  * Handler for -P option.
                    387:  */
                    388:        public void
                    389: opt__P(type, s)
                    390:        int type;
1.4       millert   391:        register char *s;
1.1       etheisen  392: {
1.4       millert   393:        register char **proto;
1.1       etheisen  394:        PARG parg;
                    395:
                    396:        switch (type)
                    397:        {
                    398:        case INIT:
                    399:        case TOGGLE:
                    400:                /*
                    401:                 * Figure out which prototype string should be changed.
                    402:                 */
                    403:                switch (*s)
                    404:                {
1.4       millert   405:                case 's':  proto = &prproto[PR_SHORT];  s++;    break;
1.1       etheisen  406:                case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
                    407:                case 'M':  proto = &prproto[PR_LONG];   s++;    break;
                    408:                case '=':  proto = &eqproto;            s++;    break;
1.4       millert   409:                case 'h':  proto = &hproto;             s++;    break;
                    410:                case 'w':  proto = &wproto;             s++;    break;
1.1       etheisen  411:                default:   proto = &prproto[PR_SHORT];          break;
                    412:                }
                    413:                free(*proto);
                    414:                *proto = save(s);
                    415:                break;
                    416:        case QUERY:
                    417:                parg.p_string = prproto[pr_type];
                    418:                error("%s", &parg);
                    419:                break;
                    420:        }
                    421: }
                    422:
                    423: /*
                    424:  * Handler for the -b option.
                    425:  */
                    426:        /*ARGSUSED*/
                    427:        public void
                    428: opt_b(type, s)
                    429:        int type;
                    430:        char *s;
                    431: {
                    432:        switch (type)
                    433:        {
1.4       millert   434:        case INIT:
1.1       etheisen  435:        case TOGGLE:
                    436:                /*
1.4       millert   437:                 * Set the new number of buffers.
1.1       etheisen  438:                 */
1.4       millert   439:                ch_setbufspace(bufspace);
1.1       etheisen  440:                break;
1.4       millert   441:        case QUERY:
1.1       etheisen  442:                break;
                    443:        }
                    444: }
                    445:
                    446: /*
                    447:  * Handler for the -i option.
                    448:  */
                    449:        /*ARGSUSED*/
                    450:        public void
                    451: opt_i(type, s)
                    452:        int type;
                    453:        char *s;
                    454: {
                    455:        switch (type)
                    456:        {
                    457:        case TOGGLE:
                    458:                chg_caseless();
                    459:                break;
                    460:        case QUERY:
                    461:        case INIT:
                    462:                break;
                    463:        }
                    464: }
                    465:
                    466: /*
                    467:  * Handler for the -V option.
                    468:  */
                    469:        /*ARGSUSED*/
                    470:        public void
                    471: opt__V(type, s)
                    472:        int type;
                    473:        char *s;
                    474: {
                    475:        switch (type)
                    476:        {
                    477:        case TOGGLE:
                    478:        case QUERY:
1.4       millert   479:                dispversion();
                    480:                break;
1.1       etheisen  481:        case INIT:
1.4       millert   482:                /*
                    483:                 * Force output to stdout per GNU standard for --version output.
                    484:                 */
                    485:                any_display = 1;
                    486:                putstr("less ");
                    487:                putstr(version);
1.7       shadchin  488:                putstr("\nCopyright (C) 1984-2009 Mark Nudelman\n\n");
1.4       millert   489:                putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
                    490:                putstr("For information about the terms of redistribution,\n");
                    491:                putstr("see the file named README in the less distribution.\n");
                    492:                putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
                    493:                quit(QUIT_OK);
1.1       etheisen  494:                break;
                    495:        }
                    496: }
                    497:
1.4       millert   498: #if MSDOS_COMPILER
1.1       etheisen  499: /*
1.4       millert   500:  * Parse an MSDOS color descriptor.
1.1       etheisen  501:  */
                    502:        static void
                    503: colordesc(s, fg_color, bg_color)
                    504:        char *s;
                    505:        int *fg_color;
                    506:        int *bg_color;
                    507: {
                    508:        int fg, bg;
                    509:        int err;
                    510:
1.4       millert   511:        fg = getnum(&s, "D", &err);
1.1       etheisen  512:        if (err)
                    513:        {
                    514:                error("Missing fg color in -D", NULL_PARG);
                    515:                return;
                    516:        }
                    517:        if (*s != '.')
1.7       shadchin  518:                bg = nm_bg_color;
1.1       etheisen  519:        else
                    520:        {
                    521:                s++;
1.4       millert   522:                bg = getnum(&s, "D", &err);
1.1       etheisen  523:                if (err)
                    524:                {
1.7       shadchin  525:                        error("Missing bg color in -D", NULL_PARG);
1.1       etheisen  526:                        return;
                    527:                }
                    528:        }
1.4       millert   529:        if (*s != '\0')
                    530:                error("Extra characters at end of -D option", NULL_PARG);
1.1       etheisen  531:        *fg_color = fg;
                    532:        *bg_color = bg;
                    533: }
                    534:
                    535: /*
                    536:  * Handler for the -D option.
                    537:  */
                    538:        /*ARGSUSED*/
                    539:        public void
                    540: opt_D(type, s)
                    541:        int type;
                    542:        char *s;
                    543: {
                    544:        switch (type)
                    545:        {
                    546:        case INIT:
                    547:        case TOGGLE:
                    548:                switch (*s++)
                    549:                {
                    550:                case 'n':
                    551:                        colordesc(s, &nm_fg_color, &nm_bg_color);
                    552:                        break;
                    553:                case 'd':
                    554:                        colordesc(s, &bo_fg_color, &bo_bg_color);
                    555:                        break;
                    556:                case 'u':
                    557:                        colordesc(s, &ul_fg_color, &ul_bg_color);
                    558:                        break;
                    559:                case 'k':
                    560:                        colordesc(s, &bl_fg_color, &bl_bg_color);
                    561:                        break;
                    562:                case 's':
                    563:                        colordesc(s, &so_fg_color, &so_bg_color);
                    564:                        break;
                    565:                default:
                    566:                        error("-D must be followed by n, d, u, k or s", NULL_PARG);
                    567:                        break;
                    568:                }
                    569:                if (type == TOGGLE)
                    570:                {
1.7       shadchin  571:                        at_enter(AT_STANDOUT);
                    572:                        at_exit();
1.1       etheisen  573:                }
                    574:                break;
                    575:        case QUERY:
                    576:                break;
                    577:        }
                    578: }
                    579: #endif
                    580:
                    581: /*
1.4       millert   582:  * Handler for the -x option.
                    583:  */
                    584:        public void
                    585: opt_x(type, s)
                    586:        int type;
                    587:        register char *s;
                    588: {
                    589:        extern int tabstops[];
                    590:        extern int ntabstops;
                    591:        extern int tabdefault;
                    592:        char msg[60+(4*TABSTOP_MAX)];
                    593:        int i;
                    594:        PARG p;
                    595:
                    596:        switch (type)
                    597:        {
                    598:        case INIT:
                    599:        case TOGGLE:
                    600:                /* Start at 1 because tabstops[0] is always zero. */
                    601:                for (i = 1;  i < TABSTOP_MAX;  )
                    602:                {
                    603:                        int n = 0;
                    604:                        s = skipsp(s);
                    605:                        while (*s >= '0' && *s <= '9')
                    606:                                n = (10 * n) + (*s++ - '0');
                    607:                        if (n > tabstops[i-1])
                    608:                                tabstops[i++] = n;
                    609:                        s = skipsp(s);
                    610:                        if (*s++ != ',')
                    611:                                break;
                    612:                }
                    613:                if (i < 2)
                    614:                        return;
                    615:                ntabstops = i;
                    616:                tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
                    617:                break;
                    618:        case QUERY:
                    619:                strlcpy(msg, "Tab stops ", sizeof(msg));
                    620:                if (ntabstops > 2)
                    621:                {
                    622:                        for (i = 1;  i < ntabstops;  i++)
                    623:                        {
                    624:                                if (i > 1)
                    625:                                        strlcat(msg, ",", sizeof(msg));
                    626:                                snprintf(msg+strlen(msg),
                    627:                                    sizeof(msg)-strlen(msg), "%d", tabstops[i]);
                    628:                        }
                    629:                        snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
                    630:                            " and then ");
                    631:                }
                    632:                snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
1.7       shadchin  633:                    "every %d spaces", tabdefault);
1.4       millert   634:                p.p_string = msg;
                    635:                error("%s", &p);
                    636:                break;
                    637:        }
                    638: }
                    639:
                    640:
                    641: /*
                    642:  * Handler for the -" option.
                    643:  */
                    644:        public void
                    645: opt_quote(type, s)
                    646:        int type;
                    647:        register char *s;
                    648: {
                    649:        char buf[3];
                    650:        PARG parg;
                    651:
                    652:        switch (type)
                    653:        {
                    654:        case INIT:
                    655:        case TOGGLE:
                    656:                if (s[0] == '\0')
                    657:                {
                    658:                        openquote = closequote = '\0';
                    659:                        break;
                    660:                }
                    661:                if (s[1] != '\0' && s[2] != '\0')
                    662:                {
                    663:                        error("-\" must be followed by 1 or 2 chars", NULL_PARG);
                    664:                        return;
                    665:                }
                    666:                openquote = s[0];
                    667:                if (s[1] == '\0')
                    668:                        closequote = openquote;
                    669:                else
                    670:                        closequote = s[1];
                    671:                break;
                    672:        case QUERY:
                    673:                buf[0] = openquote;
                    674:                buf[1] = closequote;
                    675:                buf[2] = '\0';
                    676:                parg.p_string = buf;
                    677:                error("quotes %s", &parg);
                    678:                break;
                    679:        }
                    680: }
                    681:
                    682: /*
1.1       etheisen  683:  * "-?" means display a help message.
                    684:  * If from the command line, exit immediately.
                    685:  */
                    686:        /*ARGSUSED*/
                    687:        public void
                    688: opt_query(type, s)
                    689:        int type;
                    690:        char *s;
                    691: {
                    692:        switch (type)
                    693:        {
                    694:        case QUERY:
                    695:        case TOGGLE:
                    696:                error("Use \"h\" for help", NULL_PARG);
                    697:                break;
                    698:        case INIT:
1.7       shadchin  699:                dohelp = 1;
1.1       etheisen  700:        }
                    701: }
                    702:
                    703: /*
                    704:  * Get the "screen window" size.
                    705:  */
                    706:        public int
                    707: get_swindow()
                    708: {
                    709:        if (swindow > 0)
                    710:                return (swindow);
                    711:        return (sc_height + swindow);
                    712: }
                    713: