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

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