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

1.1       etheisen    1: /*
1.9       shadchin    2:  * Copyright (C) 1984-2012  Mark Nudelman
1.11      nicm        3:  * Modified for use with illumos by Garrett D'Amore.
                      4:  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
1.1       etheisen    5:  *
1.4       millert     6:  * You may distribute under the terms of either the GNU General Public
                      7:  * License or the Less License, as specified in the README file.
1.1       etheisen    8:  *
1.9       shadchin    9:  * For more information, see the README file.
1.1       etheisen   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:
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 less_is_more;
1.1       etheisen   51: extern char *namelogfile;
                     52: extern int force_logfile;
                     53: extern int logfile;
1.10      nicm       54: char *tagoption = NULL;
1.1       etheisen   55: extern char *tags;
                     56:
1.10      nicm       57: int shift_count;       /* Number of positions to shift horizontally */
                     58: static int shift_count_fraction = -1;
1.1       etheisen   59:
                     60: /*
                     61:  * Handler for -o option.
                     62:  */
1.10      nicm       63: void
                     64: opt_o(int type, char *s)
1.1       etheisen   65: {
                     66:        PARG parg;
                     67:
1.10      nicm       68:        if (secure) {
1.13      deraadt    69:                error("log file support is not available", NULL);
1.4       millert    70:                return;
                     71:        }
1.10      nicm       72:        switch (type) {
1.1       etheisen   73:        case INIT:
                     74:                namelogfile = s;
                     75:                break;
                     76:        case TOGGLE:
1.10      nicm       77:                if (ch_getflags() & CH_CANSEEK) {
1.13      deraadt    78:                        error("Input is not a pipe", NULL);
1.1       etheisen   79:                        return;
                     80:                }
1.10      nicm       81:                if (logfile >= 0) {
1.13      deraadt    82:                        error("Log file is already in use", NULL);
1.1       etheisen   83:                        return;
                     84:                }
                     85:                s = skipsp(s);
1.4       millert    86:                namelogfile = lglob(s);
1.1       etheisen   87:                use_logfile(namelogfile);
                     88:                sync_logfile();
                     89:                break;
                     90:        case QUERY:
1.10      nicm       91:                if (logfile < 0) {
1.13      deraadt    92:                        error("No log file", NULL);
1.10      nicm       93:                } else {
1.1       etheisen   94:                        parg.p_string = namelogfile;
                     95:                        error("Log file \"%s\"", &parg);
                     96:                }
                     97:                break;
                     98:        }
                     99: }
                    100:
                    101: /*
                    102:  * Handler for -O option.
                    103:  */
1.10      nicm      104: void
                    105: opt__O(int type, char *s)
1.1       etheisen  106: {
                    107:        force_logfile = TRUE;
                    108:        opt_o(type, s);
                    109: }
                    110:
                    111: /*
1.7       shadchin  112:  * Handlers for -j option.
1.1       etheisen  113:  */
1.10      nicm      114: void
                    115: opt_j(int type, char *s)
1.1       etheisen  116: {
1.7       shadchin  117:        PARG parg;
                    118:        char buf[16];
                    119:        int len;
1.1       etheisen  120:        int err;
1.7       shadchin  121:
1.10      nicm      122:        switch (type) {
1.7       shadchin  123:        case INIT:
                    124:        case TOGGLE:
1.10      nicm      125:                if (*s == '.') {
1.7       shadchin  126:                        s++;
                    127:                        jump_sline_fraction = getfraction(&s, "j", &err);
                    128:                        if (err)
1.13      deraadt   129:                                error("Invalid line fraction", NULL);
1.7       shadchin  130:                        else
                    131:                                calc_jump_sline();
1.10      nicm      132:                } else {
1.7       shadchin  133:                        int sline = getnum(&s, "j", &err);
1.10      nicm      134:                        if (err) {
1.13      deraadt   135:                                error("Invalid line number", NULL);
1.10      nicm      136:                        } else {
1.7       shadchin  137:                                jump_sline = sline;
                    138:                                jump_sline_fraction = -1;
                    139:                        }
                    140:                }
                    141:                break;
                    142:        case QUERY:
1.10      nicm      143:                if (jump_sline_fraction < 0) {
1.7       shadchin  144:                        parg.p_int =  jump_sline;
                    145:                        error("Position target at screen line %d", &parg);
1.10      nicm      146:                } else {
                    147:                        (void) snprintf(buf, sizeof (buf), ".%06d",
                    148:                            jump_sline_fraction);
1.7       shadchin  149:                        len = strlen(buf);
                    150:                        while (len > 2 && buf[len-1] == '0')
                    151:                                len--;
                    152:                        buf[len] = '\0';
                    153:                        parg.p_string = buf;
                    154:                        error("Position target at screen position %s", &parg);
                    155:                }
                    156:                break;
                    157:        }
                    158: }
                    159:
1.10      nicm      160: void
                    161: calc_jump_sline(void)
1.7       shadchin  162: {
                    163:        if (jump_sline_fraction < 0)
                    164:                return;
                    165:        jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
                    166: }
                    167:
                    168: /*
                    169:  * Handlers for -# option.
                    170:  */
1.10      nicm      171: void
                    172: opt_shift(int type, char *s)
1.7       shadchin  173: {
                    174:        PARG parg;
                    175:        char buf[16];
                    176:        int len;
                    177:        int err;
                    178:
1.10      nicm      179:        switch (type) {
1.1       etheisen  180:        case INIT:
1.7       shadchin  181:        case TOGGLE:
1.10      nicm      182:                if (*s == '.') {
1.7       shadchin  183:                        s++;
                    184:                        shift_count_fraction = getfraction(&s, "#", &err);
                    185:                        if (err)
1.13      deraadt   186:                                error("Invalid column fraction", NULL);
1.7       shadchin  187:                        else
                    188:                                calc_shift_count();
1.10      nicm      189:                } else {
1.7       shadchin  190:                        int hs = getnum(&s, "#", &err);
1.10      nicm      191:                        if (err) {
1.13      deraadt   192:                                error("Invalid column number", NULL);
1.10      nicm      193:                        } else {
1.7       shadchin  194:                                shift_count = hs;
                    195:                                shift_count_fraction = -1;
                    196:                        }
                    197:                }
                    198:                break;
                    199:        case QUERY:
1.10      nicm      200:                if (shift_count_fraction < 0) {
1.7       shadchin  201:                        parg.p_int = shift_count;
                    202:                        error("Horizontal shift %d columns", &parg);
1.10      nicm      203:                } else {
1.7       shadchin  204:
1.10      nicm      205:                        (void) snprintf(buf, sizeof (buf), ".%06d",
                    206:                            shift_count_fraction);
1.7       shadchin  207:                        len = strlen(buf);
                    208:                        while (len > 2 && buf[len-1] == '0')
                    209:                                len--;
                    210:                        buf[len] = '\0';
                    211:                        parg.p_string = buf;
                    212:                        error("Horizontal shift %s of screen width", &parg);
1.1       etheisen  213:                }
                    214:                break;
                    215:        }
                    216: }
1.10      nicm      217:
                    218: void
                    219: calc_shift_count(void)
1.7       shadchin  220: {
                    221:        if (shift_count_fraction < 0)
                    222:                return;
                    223:        shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
                    224: }
1.1       etheisen  225:
1.10      nicm      226: void
                    227: opt_k(int type, char *s)
1.1       etheisen  228: {
                    229:        PARG parg;
                    230:
1.10      nicm      231:        switch (type) {
1.1       etheisen  232:        case INIT:
1.10      nicm      233:                if (lesskey(s, 0)) {
1.1       etheisen  234:                        parg.p_string = s;
                    235:                        error("Cannot use lesskey file \"%s\"", &parg);
                    236:                }
                    237:                break;
                    238:        }
                    239: }
                    240:
                    241: /*
                    242:  * Handler for -t option.
                    243:  */
1.10      nicm      244: void
                    245: opt_t(int type, char *s)
1.1       etheisen  246: {
                    247:        IFILE save_ifile;
1.10      nicm      248:        off_t pos;
1.1       etheisen  249:
1.10      nicm      250:        switch (type) {
1.1       etheisen  251:        case INIT:
                    252:                tagoption = s;
                    253:                /* Do the rest in main() */
                    254:                break;
                    255:        case TOGGLE:
1.10      nicm      256:                if (secure) {
1.13      deraadt   257:                        error("tags support is not available", NULL);
1.4       millert   258:                        break;
                    259:                }
1.1       etheisen  260:                findtag(skipsp(s));
1.4       millert   261:                save_ifile = save_curr_ifile();
1.7       shadchin  262:                /*
                    263:                 * Try to open the file containing the tag
                    264:                 * and search for the tag in that file.
                    265:                 */
1.10      nicm      266:                if (edit_tagfile() || (pos = tagsearch()) == -1) {
1.7       shadchin  267:                        /* Failed: reopen the old file. */
1.4       millert   268:                        reedit_ifile(save_ifile);
1.1       etheisen  269:                        break;
                    270:                }
1.4       millert   271:                unsave_ifile(save_ifile);
1.1       etheisen  272:                jump_loc(pos, jump_sline);
                    273:                break;
                    274:        }
                    275: }
                    276:
                    277: /*
                    278:  * Handler for -T option.
                    279:  */
1.10      nicm      280: void
                    281: opt__T(int type, char *s)
1.1       etheisen  282: {
                    283:        PARG parg;
                    284:
1.10      nicm      285:        switch (type) {
1.1       etheisen  286:        case INIT:
                    287:                tags = s;
                    288:                break;
                    289:        case TOGGLE:
                    290:                s = skipsp(s);
1.4       millert   291:                tags = lglob(s);
1.1       etheisen  292:                break;
                    293:        case QUERY:
                    294:                parg.p_string = tags;
                    295:                error("Tags file \"%s\"", &parg);
                    296:                break;
                    297:        }
                    298: }
                    299:
                    300: /*
                    301:  * Handler for -p option.
                    302:  */
1.10      nicm      303: void
                    304: opt_p(int type, char *s)
1.1       etheisen  305: {
1.10      nicm      306:        switch (type) {
1.1       etheisen  307:        case INIT:
                    308:                /*
                    309:                 * Unget a search command for the specified string.
                    310:                 * {{ This won't work if the "/" command is
                    311:                 *    changed or invalidated by a .lesskey file. }}
                    312:                 */
1.10      nicm      313:                plusoption = TRUE;
                    314:                ungetsc(s);
                    315:                /*
                    316:                 * In "more" mode, the -p argument is a command,
                    317:                 * not a search string, so we don't need a slash.
                    318:                 */
                    319:                if (!less_is_more)
1.7       shadchin  320:                        ungetsc("/");
1.1       etheisen  321:                break;
                    322:        }
                    323: }
                    324:
                    325: /*
                    326:  * Handler for -P option.
                    327:  */
1.10      nicm      328: void
                    329: opt__P(int type, char *s)
1.1       etheisen  330: {
1.10      nicm      331:        char **proto;
1.1       etheisen  332:        PARG parg;
                    333:
1.10      nicm      334:        switch (type) {
1.1       etheisen  335:        case INIT:
                    336:        case TOGGLE:
                    337:                /*
                    338:                 * Figure out which prototype string should be changed.
                    339:                 */
1.10      nicm      340:                switch (*s) {
1.4       millert   341:                case 's':  proto = &prproto[PR_SHORT];  s++;    break;
1.1       etheisen  342:                case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
                    343:                case 'M':  proto = &prproto[PR_LONG];   s++;    break;
                    344:                case '=':  proto = &eqproto;            s++;    break;
1.4       millert   345:                case 'h':  proto = &hproto;             s++;    break;
                    346:                case 'w':  proto = &wproto;             s++;    break;
1.1       etheisen  347:                default:   proto = &prproto[PR_SHORT];          break;
                    348:                }
                    349:                free(*proto);
1.12      tedu      350:                *proto = estrdup(s);
1.1       etheisen  351:                break;
                    352:        case QUERY:
                    353:                parg.p_string = prproto[pr_type];
                    354:                error("%s", &parg);
                    355:                break;
                    356:        }
                    357: }
                    358:
                    359: /*
                    360:  * Handler for the -b option.
                    361:  */
1.10      nicm      362: void
                    363: opt_b(int type, char *s)
1.1       etheisen  364: {
1.10      nicm      365:        switch (type) {
1.4       millert   366:        case INIT:
1.1       etheisen  367:        case TOGGLE:
                    368:                /*
1.4       millert   369:                 * Set the new number of buffers.
1.1       etheisen  370:                 */
1.4       millert   371:                ch_setbufspace(bufspace);
1.1       etheisen  372:                break;
1.4       millert   373:        case QUERY:
1.1       etheisen  374:                break;
                    375:        }
                    376: }
                    377:
                    378: /*
                    379:  * Handler for the -i option.
                    380:  */
1.10      nicm      381: void
                    382: opt_i(int type, char *s)
1.1       etheisen  383: {
1.10      nicm      384:        switch (type) {
1.1       etheisen  385:        case TOGGLE:
                    386:                chg_caseless();
                    387:                break;
                    388:        case QUERY:
                    389:        case INIT:
                    390:                break;
                    391:        }
                    392: }
                    393:
                    394: /*
                    395:  * Handler for the -V option.
                    396:  */
1.10      nicm      397: void
                    398: opt__V(int type, char *s)
1.1       etheisen  399: {
1.10      nicm      400:        switch (type) {
1.1       etheisen  401:        case TOGGLE:
                    402:        case QUERY:
1.4       millert   403:                dispversion();
                    404:                break;
1.1       etheisen  405:        case INIT:
1.4       millert   406:                /*
                    407:                 * Force output to stdout per GNU standard for --version output.
                    408:                 */
                    409:                any_display = 1;
                    410:                putstr("less ");
                    411:                putstr(version);
1.9       shadchin  412:                putstr(" (");
                    413:                putstr("POSIX ");
                    414:                putstr("regular expressions)\n");
1.11      nicm      415:                putstr("Copyright (C) 1984-2012 Mark Nudelman\n");
                    416:                putstr("Modified for use with illumos by Garrett D'Amore.\n");
                    417:                putstr("Copyright 2014 Garrett D'Amore\n\n");
1.10      nicm      418:                putstr("less comes with NO WARRANTY, ");
                    419:                putstr("to the extent permitted by law.\n");
1.4       millert   420:                putstr("For information about the terms of redistribution,\n");
                    421:                putstr("see the file named README in the less distribution.\n");
                    422:                putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
1.10      nicm      423:                putstr("\n");
1.4       millert   424:                quit(QUIT_OK);
1.1       etheisen  425:                break;
                    426:        }
                    427: }
                    428:
                    429: /*
1.4       millert   430:  * Handler for the -x option.
                    431:  */
1.10      nicm      432: void
                    433: opt_x(int type, char *s)
1.4       millert   434: {
                    435:        extern int tabstops[];
                    436:        extern int ntabstops;
                    437:        extern int tabdefault;
1.15    ! mmcc      438:        char tabs[60+(4*TABSTOP_MAX)];
1.4       millert   439:        int i;
                    440:        PARG p;
                    441:
1.10      nicm      442:        switch (type) {
1.4       millert   443:        case INIT:
                    444:        case TOGGLE:
                    445:                /* Start at 1 because tabstops[0] is always zero. */
1.10      nicm      446:                for (i = 1; i < TABSTOP_MAX; ) {
1.4       millert   447:                        int n = 0;
                    448:                        s = skipsp(s);
                    449:                        while (*s >= '0' && *s <= '9')
                    450:                                n = (10 * n) + (*s++ - '0');
                    451:                        if (n > tabstops[i-1])
                    452:                                tabstops[i++] = n;
                    453:                        s = skipsp(s);
                    454:                        if (*s++ != ',')
                    455:                                break;
                    456:                }
                    457:                if (i < 2)
                    458:                        return;
                    459:                ntabstops = i;
                    460:                tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
                    461:                break;
                    462:        case QUERY:
1.15    ! mmcc      463:                (void) strlcpy(tabs, "Tab stops ", sizeof(tabs));
1.10      nicm      464:                if (ntabstops > 2) {
                    465:                        for (i = 1;  i < ntabstops;  i++) {
1.4       millert   466:                                if (i > 1)
1.15    ! mmcc      467:                                        strlcat(tabs, ",", sizeof(tabs));
        !           468:                                (void) snprintf(tabs+strlen(tabs),
        !           469:                                    sizeof(tabs)-strlen(tabs),
        !           470:                                    "%d", tabstops[i]);
1.4       millert   471:                        }
1.15    ! mmcc      472:                        (void) snprintf(tabs+strlen(tabs),
        !           473:                            sizeof(tabs)-strlen(tabs), " and then ");
1.4       millert   474:                }
1.15    ! mmcc      475:                (void) snprintf(tabs+strlen(tabs), sizeof(tabs)-strlen(tabs),
1.7       shadchin  476:                    "every %d spaces", tabdefault);
1.15    ! mmcc      477:                p.p_string = tabs;
1.4       millert   478:                error("%s", &p);
                    479:                break;
                    480:        }
                    481: }
                    482:
                    483:
                    484: /*
                    485:  * Handler for the -" option.
                    486:  */
1.10      nicm      487: void
                    488: opt_quote(int type, char *s)
1.4       millert   489: {
                    490:        char buf[3];
                    491:        PARG parg;
                    492:
1.10      nicm      493:        switch (type) {
1.4       millert   494:        case INIT:
                    495:        case TOGGLE:
1.10      nicm      496:                if (s[0] == '\0') {
1.4       millert   497:                        openquote = closequote = '\0';
                    498:                        break;
                    499:                }
1.10      nicm      500:                if (s[1] != '\0' && s[2] != '\0') {
                    501:                        error("-\" must be followed by 1 or 2 chars",
1.13      deraadt   502:                            NULL);
1.4       millert   503:                        return;
                    504:                }
                    505:                openquote = s[0];
                    506:                if (s[1] == '\0')
                    507:                        closequote = openquote;
                    508:                else
                    509:                        closequote = s[1];
                    510:                break;
                    511:        case QUERY:
                    512:                buf[0] = openquote;
                    513:                buf[1] = closequote;
                    514:                buf[2] = '\0';
                    515:                parg.p_string = buf;
                    516:                error("quotes %s", &parg);
                    517:                break;
                    518:        }
                    519: }
                    520:
                    521: /*
1.1       etheisen  522:  * "-?" means display a help message.
                    523:  * If from the command line, exit immediately.
                    524:  */
1.10      nicm      525: void
                    526: opt_query(int type, char *s)
1.1       etheisen  527: {
1.10      nicm      528:        switch (type) {
1.1       etheisen  529:        case QUERY:
                    530:        case TOGGLE:
1.13      deraadt   531:                error("Use \"h\" for help", NULL);
1.1       etheisen  532:                break;
                    533:        case INIT:
1.7       shadchin  534:                dohelp = 1;
1.1       etheisen  535:        }
                    536: }
                    537:
                    538: /*
                    539:  * Get the "screen window" size.
                    540:  */
1.10      nicm      541: int
                    542: get_swindow(void)
1.1       etheisen  543: {
                    544:        if (swindow > 0)
                    545:                return (swindow);
                    546:        return (sc_height + swindow);
                    547: }