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

1.1       etheisen    1: /*
1.9     ! shadchin    2:  * Copyright (C) 1984-2012  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.9     ! shadchin    7:  * For more information, see the README file.
1.1       etheisen    8:  */
                      9:
                     10:
                     11: /*
                     12:  * Handling functions for command line options.
                     13:  *
                     14:  * Most options are handled by the generic code in option.c.
                     15:  * But all string options, and a few non-string options, require
                     16:  * special handling specific to the particular option.
                     17:  * This special processing is done by the "handling functions" in this file.
                     18:  *
                     19:  * Each handling function is passed a "type" and, if it is a string
                     20:  * option, the string which should be "assigned" to the option.
                     21:  * The type may be one of:
                     22:  *     INIT    The option is being initialized from the command line.
                     23:  *     TOGGLE  The option is being changed from within the program.
                     24:  *     QUERY   The setting of the option is merely being queried.
                     25:  */
                     26:
                     27: #include "less.h"
                     28: #include "option.h"
                     29:
                     30: extern int nbufs;
1.4       millert    31: extern int bufspace;
1.1       etheisen   32: extern int pr_type;
                     33: extern int plusoption;
                     34: extern int swindow;
1.7       shadchin   35: extern int sc_width;
1.1       etheisen   36: extern int sc_height;
1.4       millert    37: extern int secure;
1.7       shadchin   38: extern int dohelp;
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.7       shadchin   48: extern int jump_sline;
                     49: extern int jump_sline_fraction;
                     50: extern int shift_count;
                     51: extern int shift_count_fraction;
                     52: extern int less_is_more;
1.1       etheisen   53: #if LOGFILE
                     54: extern char *namelogfile;
                     55: extern int force_logfile;
                     56: extern int logfile;
                     57: #endif
                     58: #if TAGS
                     59: public char *tagoption = NULL;
                     60: extern char *tags;
                     61: #endif
1.4       millert    62: #if MSDOS_COMPILER
1.1       etheisen   63: extern int nm_fg_color, nm_bg_color;
                     64: extern int bo_fg_color, bo_bg_color;
                     65: extern int ul_fg_color, ul_bg_color;
                     66: extern int so_fg_color, so_bg_color;
                     67: extern int bl_fg_color, bl_bg_color;
                     68: #endif
1.8       millert    69: extern char *every_first_cmd;
1.1       etheisen   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.4       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.4       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.7       shadchin  135:  * Handlers for -j option.
1.1       etheisen  136:  */
                    137:        public void
1.7       shadchin  138: opt_j(type, s)
1.1       etheisen  139:        int type;
                    140:        char *s;
                    141: {
1.7       shadchin  142:        PARG parg;
                    143:        char buf[16];
                    144:        int len;
1.1       etheisen  145:        int err;
1.7       shadchin  146:
                    147:        switch (type)
                    148:        {
                    149:        case INIT:
                    150:        case TOGGLE:
                    151:                if (*s == '.')
                    152:                {
                    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:                        snprintf(buf, sizeof(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:
1.1       etheisen  212:        switch (type)
                    213:        {
                    214:        case INIT:
1.7       shadchin  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
1.1       etheisen  242:                {
1.7       shadchin  243:
                    244:                        snprintf(buf, sizeof(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.7       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.4       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.4       millert   303:                if (secure)
                    304:                {
                    305:                        error("tags support is not available", NULL_PARG);
                    306:                        break;
                    307:                }
1.1       etheisen  308:                findtag(skipsp(s));
1.4       millert   309:                save_ifile = save_curr_ifile();
1.7       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.7       shadchin  316:                        /* Failed: reopen the old file. */
1.4       millert   317:                        reedit_ifile(save_ifile);
1.1       etheisen  318:                        break;
                    319:                }
1.4       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.4       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;
1.4       millert   359:        register char *s;
1.1       etheisen  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:                 */
1.8       millert   369:                if (less_is_more) {
                    370:                        /*
                    371:                         * In "more" mode, the -p argument is a command,
                    372:                         * not a search string, run for each file.
                    373:                         */
                    374:                        every_first_cmd = save(s);
                    375:                } else {
                    376:                        plusoption = TRUE;
                    377:                        ungetsc(s);
1.7       shadchin  378:                        ungetsc("/");
1.8       millert   379:                }
1.1       etheisen  380:                break;
                    381:        }
                    382: }
                    383:
                    384: /*
                    385:  * Handler for -P option.
                    386:  */
                    387:        public void
                    388: opt__P(type, s)
                    389:        int type;
1.4       millert   390:        register char *s;
1.1       etheisen  391: {
1.4       millert   392:        register char **proto;
1.1       etheisen  393:        PARG parg;
                    394:
                    395:        switch (type)
                    396:        {
                    397:        case INIT:
                    398:        case TOGGLE:
                    399:                /*
                    400:                 * Figure out which prototype string should be changed.
                    401:                 */
                    402:                switch (*s)
                    403:                {
1.4       millert   404:                case 's':  proto = &prproto[PR_SHORT];  s++;    break;
1.1       etheisen  405:                case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
                    406:                case 'M':  proto = &prproto[PR_LONG];   s++;    break;
                    407:                case '=':  proto = &eqproto;            s++;    break;
1.4       millert   408:                case 'h':  proto = &hproto;             s++;    break;
                    409:                case 'w':  proto = &wproto;             s++;    break;
1.1       etheisen  410:                default:   proto = &prproto[PR_SHORT];          break;
                    411:                }
                    412:                free(*proto);
                    413:                *proto = save(s);
                    414:                break;
                    415:        case QUERY:
                    416:                parg.p_string = prproto[pr_type];
                    417:                error("%s", &parg);
                    418:                break;
                    419:        }
                    420: }
                    421:
                    422: /*
                    423:  * Handler for the -b option.
                    424:  */
                    425:        /*ARGSUSED*/
                    426:        public void
                    427: opt_b(type, s)
                    428:        int type;
                    429:        char *s;
                    430: {
                    431:        switch (type)
                    432:        {
1.4       millert   433:        case INIT:
1.1       etheisen  434:        case TOGGLE:
                    435:                /*
1.4       millert   436:                 * Set the new number of buffers.
1.1       etheisen  437:                 */
1.4       millert   438:                ch_setbufspace(bufspace);
1.1       etheisen  439:                break;
1.4       millert   440:        case QUERY:
1.1       etheisen  441:                break;
                    442:        }
                    443: }
                    444:
                    445: /*
                    446:  * Handler for the -i option.
                    447:  */
                    448:        /*ARGSUSED*/
                    449:        public void
                    450: opt_i(type, s)
                    451:        int type;
                    452:        char *s;
                    453: {
                    454:        switch (type)
                    455:        {
                    456:        case TOGGLE:
                    457:                chg_caseless();
                    458:                break;
                    459:        case QUERY:
                    460:        case INIT:
                    461:                break;
                    462:        }
                    463: }
                    464:
                    465: /*
                    466:  * Handler for the -V option.
                    467:  */
                    468:        /*ARGSUSED*/
                    469:        public void
                    470: opt__V(type, s)
                    471:        int type;
                    472:        char *s;
                    473: {
                    474:        switch (type)
                    475:        {
                    476:        case TOGGLE:
                    477:        case QUERY:
1.4       millert   478:                dispversion();
                    479:                break;
1.1       etheisen  480:        case INIT:
1.4       millert   481:                /*
                    482:                 * Force output to stdout per GNU standard for --version output.
                    483:                 */
                    484:                any_display = 1;
                    485:                putstr("less ");
                    486:                putstr(version);
1.9     ! shadchin  487:                putstr(" (");
        !           488: #if HAVE_GNU_REGEX
        !           489:                putstr("GNU ");
        !           490: #endif
        !           491: #if HAVE_POSIX_REGCOMP
        !           492:                putstr("POSIX ");
        !           493: #endif
        !           494: #if HAVE_PCRE
        !           495:                putstr("PCRE ");
        !           496: #endif
        !           497: #if HAVE_RE_COMP
        !           498:                putstr("BSD ");
        !           499: #endif
        !           500: #if HAVE_REGCMP
        !           501:                putstr("V8 ");
        !           502: #endif
        !           503: #if HAVE_V8_REGCOMP
        !           504:                putstr("Spencer V8 ");
        !           505: #endif
        !           506: #if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP
        !           507:                putstr("no ");
        !           508: #endif
        !           509:                putstr("regular expressions)\n");
        !           510:                putstr("Copyright (C) 1984-2012 Mark Nudelman\n\n");
1.4       millert   511:                putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
                    512:                putstr("For information about the terms of redistribution,\n");
                    513:                putstr("see the file named README in the less distribution.\n");
                    514:                putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
                    515:                quit(QUIT_OK);
1.1       etheisen  516:                break;
                    517:        }
                    518: }
                    519:
1.4       millert   520: #if MSDOS_COMPILER
1.1       etheisen  521: /*
1.4       millert   522:  * Parse an MSDOS color descriptor.
1.1       etheisen  523:  */
                    524:        static void
                    525: colordesc(s, fg_color, bg_color)
                    526:        char *s;
                    527:        int *fg_color;
                    528:        int *bg_color;
                    529: {
                    530:        int fg, bg;
                    531:        int err;
                    532:
1.4       millert   533:        fg = getnum(&s, "D", &err);
1.1       etheisen  534:        if (err)
                    535:        {
                    536:                error("Missing fg color in -D", NULL_PARG);
                    537:                return;
                    538:        }
                    539:        if (*s != '.')
1.7       shadchin  540:                bg = nm_bg_color;
1.1       etheisen  541:        else
                    542:        {
                    543:                s++;
1.4       millert   544:                bg = getnum(&s, "D", &err);
1.1       etheisen  545:                if (err)
                    546:                {
1.7       shadchin  547:                        error("Missing bg color in -D", NULL_PARG);
1.1       etheisen  548:                        return;
                    549:                }
                    550:        }
1.4       millert   551:        if (*s != '\0')
                    552:                error("Extra characters at end of -D option", NULL_PARG);
1.1       etheisen  553:        *fg_color = fg;
                    554:        *bg_color = bg;
                    555: }
                    556:
                    557: /*
                    558:  * Handler for the -D option.
                    559:  */
                    560:        /*ARGSUSED*/
                    561:        public void
                    562: opt_D(type, s)
                    563:        int type;
                    564:        char *s;
                    565: {
                    566:        switch (type)
                    567:        {
                    568:        case INIT:
                    569:        case TOGGLE:
                    570:                switch (*s++)
                    571:                {
                    572:                case 'n':
                    573:                        colordesc(s, &nm_fg_color, &nm_bg_color);
                    574:                        break;
                    575:                case 'd':
                    576:                        colordesc(s, &bo_fg_color, &bo_bg_color);
                    577:                        break;
                    578:                case 'u':
                    579:                        colordesc(s, &ul_fg_color, &ul_bg_color);
                    580:                        break;
                    581:                case 'k':
                    582:                        colordesc(s, &bl_fg_color, &bl_bg_color);
                    583:                        break;
                    584:                case 's':
                    585:                        colordesc(s, &so_fg_color, &so_bg_color);
                    586:                        break;
                    587:                default:
                    588:                        error("-D must be followed by n, d, u, k or s", NULL_PARG);
                    589:                        break;
                    590:                }
                    591:                if (type == TOGGLE)
                    592:                {
1.7       shadchin  593:                        at_enter(AT_STANDOUT);
                    594:                        at_exit();
1.1       etheisen  595:                }
                    596:                break;
                    597:        case QUERY:
                    598:                break;
                    599:        }
                    600: }
                    601: #endif
                    602:
                    603: /*
1.4       millert   604:  * Handler for the -x option.
                    605:  */
                    606:        public void
                    607: opt_x(type, s)
                    608:        int type;
                    609:        register char *s;
                    610: {
                    611:        extern int tabstops[];
                    612:        extern int ntabstops;
                    613:        extern int tabdefault;
                    614:        char msg[60+(4*TABSTOP_MAX)];
                    615:        int i;
                    616:        PARG p;
                    617:
                    618:        switch (type)
                    619:        {
                    620:        case INIT:
                    621:        case TOGGLE:
                    622:                /* Start at 1 because tabstops[0] is always zero. */
                    623:                for (i = 1;  i < TABSTOP_MAX;  )
                    624:                {
                    625:                        int n = 0;
                    626:                        s = skipsp(s);
                    627:                        while (*s >= '0' && *s <= '9')
                    628:                                n = (10 * n) + (*s++ - '0');
                    629:                        if (n > tabstops[i-1])
                    630:                                tabstops[i++] = n;
                    631:                        s = skipsp(s);
                    632:                        if (*s++ != ',')
                    633:                                break;
                    634:                }
                    635:                if (i < 2)
                    636:                        return;
                    637:                ntabstops = i;
                    638:                tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
                    639:                break;
                    640:        case QUERY:
                    641:                strlcpy(msg, "Tab stops ", sizeof(msg));
                    642:                if (ntabstops > 2)
                    643:                {
                    644:                        for (i = 1;  i < ntabstops;  i++)
                    645:                        {
                    646:                                if (i > 1)
                    647:                                        strlcat(msg, ",", sizeof(msg));
                    648:                                snprintf(msg+strlen(msg),
                    649:                                    sizeof(msg)-strlen(msg), "%d", tabstops[i]);
                    650:                        }
                    651:                        snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
                    652:                            " and then ");
                    653:                }
                    654:                snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
1.7       shadchin  655:                    "every %d spaces", tabdefault);
1.4       millert   656:                p.p_string = msg;
                    657:                error("%s", &p);
                    658:                break;
                    659:        }
                    660: }
                    661:
                    662:
                    663: /*
                    664:  * Handler for the -" option.
                    665:  */
                    666:        public void
                    667: opt_quote(type, s)
                    668:        int type;
                    669:        register char *s;
                    670: {
                    671:        char buf[3];
                    672:        PARG parg;
                    673:
                    674:        switch (type)
                    675:        {
                    676:        case INIT:
                    677:        case TOGGLE:
                    678:                if (s[0] == '\0')
                    679:                {
                    680:                        openquote = closequote = '\0';
                    681:                        break;
                    682:                }
                    683:                if (s[1] != '\0' && s[2] != '\0')
                    684:                {
                    685:                        error("-\" must be followed by 1 or 2 chars", NULL_PARG);
                    686:                        return;
                    687:                }
                    688:                openquote = s[0];
                    689:                if (s[1] == '\0')
                    690:                        closequote = openquote;
                    691:                else
                    692:                        closequote = s[1];
                    693:                break;
                    694:        case QUERY:
                    695:                buf[0] = openquote;
                    696:                buf[1] = closequote;
                    697:                buf[2] = '\0';
                    698:                parg.p_string = buf;
                    699:                error("quotes %s", &parg);
                    700:                break;
                    701:        }
                    702: }
                    703:
                    704: /*
1.1       etheisen  705:  * "-?" means display a help message.
                    706:  * If from the command line, exit immediately.
                    707:  */
                    708:        /*ARGSUSED*/
                    709:        public void
                    710: opt_query(type, s)
                    711:        int type;
                    712:        char *s;
                    713: {
                    714:        switch (type)
                    715:        {
                    716:        case QUERY:
                    717:        case TOGGLE:
                    718:                error("Use \"h\" for help", NULL_PARG);
                    719:                break;
                    720:        case INIT:
1.7       shadchin  721:                dohelp = 1;
1.1       etheisen  722:        }
                    723: }
                    724:
                    725: /*
                    726:  * Get the "screen window" size.
                    727:  */
                    728:        public int
                    729: get_swindow()
                    730: {
                    731:        if (swindow > 0)
                    732:                return (swindow);
                    733:        return (sc_height + swindow);
                    734: }
                    735: