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

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.4       millert    69:                error("log file support is not available", NULL_PARG);
                     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.1       etheisen   78:                        error("Input is not a pipe", NULL_PARG);
                     79:                        return;
                     80:                }
1.10      nicm       81:                if (logfile >= 0) {
1.1       etheisen   82:                        error("Log file is already in use", NULL_PARG);
                     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.1       etheisen   92:                        error("No log file", NULL_PARG);
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)
                    129:                                error("Invalid line fraction", NULL_PARG);
                    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.7       shadchin  135:                                error("Invalid line number", NULL_PARG);
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)
                    186:                                error("Invalid column fraction", NULL_PARG);
                    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.7       shadchin  192:                                error("Invalid column number", NULL_PARG);
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.4       millert   257:                        error("tags support is not available", NULL_PARG);
                    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: /*ARGSUSED*/
                    363: void
                    364: opt_b(int type, char *s)
1.1       etheisen  365: {
1.10      nicm      366:        switch (type) {
1.4       millert   367:        case INIT:
1.1       etheisen  368:        case TOGGLE:
                    369:                /*
1.4       millert   370:                 * Set the new number of buffers.
1.1       etheisen  371:                 */
1.4       millert   372:                ch_setbufspace(bufspace);
1.1       etheisen  373:                break;
1.4       millert   374:        case QUERY:
1.1       etheisen  375:                break;
                    376:        }
                    377: }
                    378:
                    379: /*
                    380:  * Handler for the -i option.
                    381:  */
1.10      nicm      382: /*ARGSUSED*/
                    383: void
                    384: opt_i(int type, char *s)
1.1       etheisen  385: {
1.10      nicm      386:        switch (type) {
1.1       etheisen  387:        case TOGGLE:
                    388:                chg_caseless();
                    389:                break;
                    390:        case QUERY:
                    391:        case INIT:
                    392:                break;
                    393:        }
                    394: }
                    395:
                    396: /*
                    397:  * Handler for the -V option.
                    398:  */
1.10      nicm      399: /*ARGSUSED*/
                    400: void
                    401: opt__V(int type, char *s)
1.1       etheisen  402: {
1.10      nicm      403:        switch (type) {
1.1       etheisen  404:        case TOGGLE:
                    405:        case QUERY:
1.4       millert   406:                dispversion();
                    407:                break;
1.1       etheisen  408:        case INIT:
1.4       millert   409:                /*
                    410:                 * Force output to stdout per GNU standard for --version output.
                    411:                 */
                    412:                any_display = 1;
                    413:                putstr("less ");
                    414:                putstr(version);
1.9       shadchin  415:                putstr(" (");
                    416:                putstr("POSIX ");
                    417:                putstr("regular expressions)\n");
1.11      nicm      418:                putstr("Copyright (C) 1984-2012 Mark Nudelman\n");
                    419:                putstr("Modified for use with illumos by Garrett D'Amore.\n");
                    420:                putstr("Copyright 2014 Garrett D'Amore\n\n");
1.10      nicm      421:                putstr("less comes with NO WARRANTY, ");
                    422:                putstr("to the extent permitted by law.\n");
1.4       millert   423:                putstr("For information about the terms of redistribution,\n");
                    424:                putstr("see the file named README in the less distribution.\n");
                    425:                putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
1.10      nicm      426:                putstr("\n");
1.4       millert   427:                quit(QUIT_OK);
1.1       etheisen  428:                break;
                    429:        }
                    430: }
                    431:
                    432: /*
1.4       millert   433:  * Handler for the -x option.
                    434:  */
1.10      nicm      435: void
                    436: opt_x(int type, char *s)
1.4       millert   437: {
                    438:        extern int tabstops[];
                    439:        extern int ntabstops;
                    440:        extern int tabdefault;
                    441:        char msg[60+(4*TABSTOP_MAX)];
                    442:        int i;
                    443:        PARG p;
                    444:
1.10      nicm      445:        switch (type) {
1.4       millert   446:        case INIT:
                    447:        case TOGGLE:
                    448:                /* Start at 1 because tabstops[0] is always zero. */
1.10      nicm      449:                for (i = 1; i < TABSTOP_MAX; ) {
1.4       millert   450:                        int n = 0;
                    451:                        s = skipsp(s);
                    452:                        while (*s >= '0' && *s <= '9')
                    453:                                n = (10 * n) + (*s++ - '0');
                    454:                        if (n > tabstops[i-1])
                    455:                                tabstops[i++] = n;
                    456:                        s = skipsp(s);
                    457:                        if (*s++ != ',')
                    458:                                break;
                    459:                }
                    460:                if (i < 2)
                    461:                        return;
                    462:                ntabstops = i;
                    463:                tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
                    464:                break;
                    465:        case QUERY:
1.10      nicm      466:                (void) strlcpy(msg, "Tab stops ", sizeof(msg));
                    467:                if (ntabstops > 2) {
                    468:                        for (i = 1;  i < ntabstops;  i++) {
1.4       millert   469:                                if (i > 1)
                    470:                                        strlcat(msg, ",", sizeof(msg));
1.10      nicm      471:                                (void) snprintf(msg+strlen(msg),
1.4       millert   472:                                    sizeof(msg)-strlen(msg), "%d", tabstops[i]);
                    473:                        }
1.10      nicm      474:                        (void) snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
1.4       millert   475:                            " and then ");
                    476:                }
1.10      nicm      477:                (void) snprintf(msg+strlen(msg), sizeof(msg)-strlen(msg),
1.7       shadchin  478:                    "every %d spaces", tabdefault);
1.4       millert   479:                p.p_string = msg;
                    480:                error("%s", &p);
                    481:                break;
                    482:        }
                    483: }
                    484:
                    485:
                    486: /*
                    487:  * Handler for the -" option.
                    488:  */
1.10      nicm      489: void
                    490: opt_quote(int type, char *s)
1.4       millert   491: {
                    492:        char buf[3];
                    493:        PARG parg;
                    494:
1.10      nicm      495:        switch (type) {
1.4       millert   496:        case INIT:
                    497:        case TOGGLE:
1.10      nicm      498:                if (s[0] == '\0') {
1.4       millert   499:                        openquote = closequote = '\0';
                    500:                        break;
                    501:                }
1.10      nicm      502:                if (s[1] != '\0' && s[2] != '\0') {
                    503:                        error("-\" must be followed by 1 or 2 chars",
                    504:                            NULL_PARG);
1.4       millert   505:                        return;
                    506:                }
                    507:                openquote = s[0];
                    508:                if (s[1] == '\0')
                    509:                        closequote = openquote;
                    510:                else
                    511:                        closequote = s[1];
                    512:                break;
                    513:        case QUERY:
                    514:                buf[0] = openquote;
                    515:                buf[1] = closequote;
                    516:                buf[2] = '\0';
                    517:                parg.p_string = buf;
                    518:                error("quotes %s", &parg);
                    519:                break;
                    520:        }
                    521: }
                    522:
                    523: /*
1.1       etheisen  524:  * "-?" means display a help message.
                    525:  * If from the command line, exit immediately.
                    526:  */
1.10      nicm      527: /*ARGSUSED*/
                    528: void
                    529: opt_query(int type, char *s)
1.1       etheisen  530: {
1.10      nicm      531:        switch (type) {
1.1       etheisen  532:        case QUERY:
                    533:        case TOGGLE:
                    534:                error("Use \"h\" for help", NULL_PARG);
                    535:                break;
                    536:        case INIT:
1.7       shadchin  537:                dohelp = 1;
1.1       etheisen  538:        }
                    539: }
                    540:
                    541: /*
                    542:  * Get the "screen window" size.
                    543:  */
1.10      nicm      544: int
                    545: get_swindow(void)
1.1       etheisen  546: {
                    547:        if (swindow > 0)
                    548:                return (swindow);
                    549:        return (sc_height + swindow);
                    550: }