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

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