[BACK]Return to opttbl.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Annotation of src/usr.bin/less/opttbl.c, Revision 1.1.1.2

1.1       etheisen    1: /*
1.1.1.2 ! millert     2:  * Copyright (C) 1984-2002  Mark Nudelman
1.1       etheisen    3:  *
1.1.1.2 ! millert     4:  * You may distribute under the terms of either the GNU General Public
        !             5:  * License or the Less License, as specified in the README file.
1.1       etheisen    6:  *
1.1.1.2 ! millert     7:  * For more information about less, or for information on how to
        !             8:  * contact the author, see the README file.
1.1       etheisen    9:  */
                     10:
                     11:
                     12: /*
                     13:  * The option table.
                     14:  */
                     15:
                     16: #include "less.h"
                     17: #include "option.h"
                     18:
                     19: /*
                     20:  * Variables controlled by command line options.
                     21:  */
                     22: public int quiet;              /* Should we suppress the audible bell? */
                     23: public int how_search;         /* Where should forward searches start? */
                     24: public int top_scroll;         /* Repaint screen from top?
                     25:                                   (alternative is scroll from bottom) */
                     26: public int pr_type;            /* Type of prompt (short, medium, long) */
                     27: public int bs_mode;            /* How to process backspaces */
                     28: public int know_dumb;          /* Don't complain about dumb terminals */
                     29: public int quit_at_eof;                /* Quit after hitting end of file twice */
1.1.1.2 ! millert    30: public int quit_if_one_screen; /* Quit if EOF on first screen */
1.1       etheisen   31: public int squeeze;            /* Squeeze multiple blank lines into one */
                     32: public int tabstop;            /* Tab settings */
                     33: public int back_scroll;                /* Repaint screen on backwards movement */
                     34: public int forw_scroll;                /* Repaint screen on forward movement */
                     35: public int caseless;           /* Do "caseless" searches */
                     36: public int linenums;           /* Use line numbers */
                     37: public int autobuf;            /* Automatically allocate buffers as needed */
1.1.1.2 ! millert    38: public int bufspace;           /* Max buffer space per file (K) */
1.1       etheisen   39: public int ctldisp;            /* Send control chars to screen untranslated */
                     40: public int force_open;         /* Open the file even if not regular file */
                     41: public int swindow;            /* Size of scrolling window */
                     42: public int jump_sline;         /* Screen line of "jump target" */
                     43: public int chopline;           /* Truncate displayed lines at screen width */
                     44: public int no_init;            /* Disable sending ti/te termcap strings */
1.1.1.2 ! millert    45: public int no_keypad;          /* Disable sending ks/ke termcap strings */
        !            46: public int twiddle;             /* Show tildes after EOF */
        !            47: public int show_attn;          /* Hilite first unread line */
        !            48: public int shift_count;                /* Number of positions to shift horizontally */
        !            49: public int status_col;         /* Display a status column */
        !            50: public int use_lessopen;       /* Use the LESSOPEN filter */
1.1       etheisen   51: #if HILITE_SEARCH
                     52: public int hilite_search;      /* Highlight matched search patterns? */
                     53: #endif
                     54:
                     55: /*
1.1.1.2 ! millert    56:  * Long option names.
        !            57:  */
        !            58: static struct optname a_optname      = { "search-skip-screen",   NULL };
        !            59: static struct optname b_optname      = { "buffers",              NULL };
        !            60: static struct optname B__optname     = { "auto-buffers",         NULL };
        !            61: static struct optname c_optname      = { "clear-screen",         NULL };
        !            62: static struct optname d_optname      = { "dumb",                 NULL };
        !            63: #if MSDOS_COMPILER
        !            64: static struct optname D__optname     = { "color",                NULL };
        !            65: #endif
        !            66: static struct optname e_optname      = { "quit-at-eof",          NULL };
        !            67: static struct optname f_optname      = { "force",                NULL };
        !            68: static struct optname F__optname     = { "quit-if-one-screen",   NULL };
        !            69: #if HILITE_SEARCH
        !            70: static struct optname g_optname      = { "hilite-search",        NULL };
        !            71: #endif
        !            72: static struct optname h_optname      = { "max-back-scroll",      NULL };
        !            73: static struct optname i_optname      = { "ignore-case",          NULL };
        !            74: static struct optname j_optname      = { "jump-target",          NULL };
        !            75: static struct optname J__optname     = { "status-column",        NULL };
        !            76: #if USERFILE
        !            77: static struct optname k_optname      = { "lesskey-file",         NULL };
        !            78: #endif
        !            79: static struct optname L__optname     = { "no-lessopen",          NULL };
        !            80: static struct optname m_optname      = { "long-prompt",          NULL };
        !            81: static struct optname n_optname      = { "line-numbers",         NULL };
        !            82: #if LOGFILE
        !            83: static struct optname o_optname      = { "log-file",             NULL };
        !            84: static struct optname O__optname     = { "LOG-FILE",             NULL };
        !            85: #endif
        !            86: static struct optname p_optname      = { "pattern",              NULL };
        !            87: static struct optname P__optname     = { "prompt",               NULL };
        !            88: static struct optname q2_optname     = { "silent",               NULL };
        !            89: static struct optname q_optname      = { "quiet",                &q2_optname };
        !            90: static struct optname r_optname      = { "raw-control-chars",    NULL };
        !            91: static struct optname s_optname      = { "squeeze-blank-lines",  NULL };
        !            92: static struct optname S__optname     = { "chop-long-lines",      NULL };
        !            93: #if TAGS
        !            94: static struct optname t_optname      = { "tag",                  NULL };
        !            95: static struct optname T__optname     = { "tag-file",             NULL };
        !            96: #endif
        !            97: static struct optname u_optname      = { "underline-special",    NULL };
        !            98: static struct optname V__optname     = { "version",              NULL };
        !            99: static struct optname w_optname      = { "hilite-unread",        NULL };
        !           100: static struct optname x_optname      = { "tabs",                 NULL };
        !           101: static struct optname X__optname     = { "no-init",              NULL };
        !           102: static struct optname y_optname      = { "max-forw-scroll",      NULL };
        !           103: static struct optname z_optname      = { "window",               NULL };
        !           104: static struct optname quote_optname  = { "quotes",               NULL };
        !           105: static struct optname tilde_optname  = { "tilde",                NULL };
        !           106: static struct optname query_optname  = { "help",                 NULL };
        !           107: static struct optname pound_optname  = { "shift",                NULL };
        !           108: static struct optname keypad_optname = { "no-keypad",            NULL };
        !           109:
        !           110:
        !           111: /*
1.1       etheisen  112:  * Table of all options and their semantics.
1.1.1.2 ! millert   113:  *
        !           114:  * For BOOL and TRIPLE options, odesc[0], odesc[1], odesc[2] are
        !           115:  * the description of the option when set to 0, 1 or 2, respectively.
        !           116:  * For NUMBER options, odesc[0] is the prompt to use when entering
        !           117:  * a new value, and odesc[1] is the description, which should contain
        !           118:  * one %d which is replaced by the value of the number.
        !           119:  * For STRING options, odesc[0] is the prompt to use when entering
        !           120:  * a new value, and odesc[1], if not NULL, is the set of characters
        !           121:  * that are valid in the string.
1.1       etheisen  122:  */
1.1.1.2 ! millert   123: static struct loption option[] =
1.1       etheisen  124: {
1.1.1.2 ! millert   125:        { 'a', &a_optname,
        !           126:                BOOL, OPT_OFF, &how_search, NULL,
        !           127:                {
        !           128:                        "Search includes displayed screen",
        !           129:                        "Search skips displayed screen",
        !           130:                        NULL
        !           131:                }
        !           132:        },
        !           133:
        !           134:        { 'b', &b_optname,
        !           135:                NUMBER|INIT_HANDLER, 64, &bufspace, opt_b,
        !           136:                {
        !           137:                        "Max buffer space per file (K): ",
        !           138:                        "Max buffer space per file: %dK",
        !           139:                        NULL
        !           140:                }
        !           141:        },
        !           142:        { 'B', &B__optname,
        !           143:                BOOL, OPT_ON, &autobuf, NULL,
        !           144:                {
        !           145:                        "Don't automatically allocate buffers",
        !           146:                        "Automatically allocate buffers when needed",
        !           147:                        NULL
        !           148:                }
        !           149:        },
        !           150:        { 'c', &c_optname,
        !           151:                TRIPLE, OPT_OFF, &top_scroll, NULL,
        !           152:                {
        !           153:                        "Repaint by scrolling from bottom of screen",
        !           154:                        "Repaint by clearing each line",
        !           155:                        "Repaint by painting from top of screen"
        !           156:                }
        !           157:        },
        !           158:        { 'd', &d_optname,
        !           159:                BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
        !           160:                {
        !           161:                        "Assume intelligent terminal",
        !           162:                        "Assume dumb terminal",
        !           163:                        NULL
        !           164:                }
        !           165:        },
        !           166: #if MSDOS_COMPILER
        !           167:        { 'D', &D__optname,
        !           168:                STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
        !           169:                {
        !           170:                        "color desc: ",
        !           171:                        "Ddknsu0123456789.",
        !           172:                        NULL
        !           173:                }
        !           174:        },
        !           175: #endif
        !           176:        { 'e', &e_optname,
        !           177:                TRIPLE, OPT_OFF, &quit_at_eof, NULL,
        !           178:                {
        !           179:                        "Don't quit at end-of-file",
        !           180:                        "Quit at end-of-file",
        !           181:                        "Quit immediately at end-of-file"
        !           182:                }
        !           183:        },
        !           184:        { 'f', &f_optname,
        !           185:                BOOL, OPT_OFF, &force_open, NULL,
        !           186:                {
        !           187:                        "Open only regular files",
        !           188:                        "Open even non-regular files",
        !           189:                        NULL
        !           190:                }
        !           191:        },
        !           192:        { 'F', &F__optname,
        !           193:                BOOL, OPT_OFF, &quit_if_one_screen, NULL,
        !           194:                {
        !           195:                        "Don't quit if end-of-file on first screen",
        !           196:                        "Quit if end-of-file on first screen",
        !           197:                        NULL
        !           198:                }
1.1       etheisen  199:        },
                    200: #if HILITE_SEARCH
1.1.1.2 ! millert   201:        { 'g', &g_optname,
        !           202:                TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
        !           203:                {
        !           204:                        "Don't highlight search matches",
        !           205:                        "Highlight matches for previous search only",
        !           206:                        "Highlight all matches for previous search pattern",
        !           207:                }
        !           208:        },
        !           209: #endif
        !           210:        { 'h', &h_optname,
        !           211:                NUMBER, -1, &back_scroll, NULL,
        !           212:                {
        !           213:                        "Backwards scroll limit: ",
        !           214:                        "Backwards scroll limit is %d lines",
        !           215:                        NULL
        !           216:                }
        !           217:        },
        !           218:        { 'i', &i_optname,
        !           219:                TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i,
        !           220:                {
        !           221:                        "Case is significant in searches",
        !           222:                        "Ignore case in searches",
        !           223:                        "Ignore case in searches and in patterns"
        !           224:                }
        !           225:        },
        !           226:        { 'j', &j_optname,
        !           227:                NUMBER, 1, &jump_sline, NULL,
        !           228:                {
        !           229:                        "Target line: ",
        !           230:                        "Position target at screen line %d",
        !           231:                        NULL
        !           232:                }
        !           233:        },
        !           234:        { 'J', &J__optname,
        !           235:                BOOL|REPAINT, OPT_OFF, &status_col, NULL,
        !           236:                {
        !           237:                        "Don't display a status column",
        !           238:                        "Display a status column",
        !           239:                        NULL
        !           240:                }
1.1       etheisen  241:        },
                    242: #if USERFILE
1.1.1.2 ! millert   243:        { 'k', &k_optname,
        !           244:                STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
        !           245:                { NULL, NULL, NULL }
1.1       etheisen  246:        },
                    247: #endif
1.1.1.2 ! millert   248:        { 'l', NULL,
        !           249:                STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_l,
        !           250:                { NULL, NULL, NULL }
        !           251:        },
        !           252:        { 'L', &L__optname,
        !           253:                BOOL, OPT_ON, &use_lessopen, NULL,
        !           254:                {
        !           255:                        "Don't use the LESSOPEN filter",
        !           256:                        "Use the LESSOPEN filter",
        !           257:                        NULL
        !           258:                }
        !           259:        },
        !           260:        { 'm', &m_optname,
        !           261:                TRIPLE, OPT_OFF, &pr_type, NULL,
        !           262:                {
        !           263:                        "Short prompt",
        !           264:                        "Medium prompt",
        !           265:                        "Long prompt"
        !           266:                }
        !           267:        },
        !           268:        { 'n', &n_optname,
        !           269:                TRIPLE|REPAINT, OPT_ON, &linenums, NULL,
        !           270:                {
        !           271:                        "Don't use line numbers",
        !           272:                        "Use line numbers",
        !           273:                        "Constantly display line numbers"
        !           274:                }
1.1       etheisen  275:        },
                    276: #if LOGFILE
1.1.1.2 ! millert   277:        { 'o', &o_optname,
        !           278:                STRING, 0, NULL, opt_o,
        !           279:                { "log file: ", NULL, NULL }
        !           280:        },
        !           281:        { 'O', &O__optname,
        !           282:                STRING, 0, NULL, opt__O,
        !           283:                { "Log file: ", NULL, NULL }
1.1       etheisen  284:        },
                    285: #endif
1.1.1.2 ! millert   286:        { 'p', &p_optname,
        !           287:                STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p,
        !           288:                { NULL, NULL, NULL }
        !           289:        },
        !           290:        { 'P', &P__optname,
        !           291:                STRING, 0, NULL, opt__P,
        !           292:                { "prompt: ", NULL, NULL }
        !           293:        },
        !           294:        { 'q', &q_optname,
        !           295:                TRIPLE, OPT_OFF, &quiet, NULL,
        !           296:                {
        !           297:                        "Ring the bell for errors AND at eof/bof",
        !           298:                        "Ring the bell for errors but not at eof/bof",
        !           299:                        "Never ring the bell"
        !           300:                }
        !           301:        },
        !           302:        { 'r', &r_optname,
        !           303:                TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
        !           304:                {
        !           305:                        "Display control characters as ^X",
        !           306:                        "Display control characters directly",
        !           307:                        "Display control characters directly, processing ANSI sequences"
        !           308:                }
        !           309:        },
        !           310:        { 's', &s_optname,
        !           311:                BOOL|REPAINT, OPT_OFF, &squeeze, NULL,
        !           312:                {
        !           313:                        "Display all blank lines",
        !           314:                        "Squeeze multiple blank lines",
        !           315:                        NULL
        !           316:                }
        !           317:        },
        !           318:        { 'S', &S__optname,
        !           319:                BOOL|REPAINT, OPT_OFF, &chopline, NULL,
        !           320:                {
        !           321:                        "Fold long lines",
        !           322:                        "Chop long lines",
        !           323:                        NULL
        !           324:                }
1.1       etheisen  325:        },
                    326: #if TAGS
1.1.1.2 ! millert   327:        { 't', &t_optname,
        !           328:                STRING|NO_QUERY, 0, NULL, opt_t,
        !           329:                { "tag: ", NULL, NULL }
        !           330:        },
        !           331:        { 'T', &T__optname,
        !           332:                STRING, 0, NULL, opt__T,
        !           333:                { "tags file: ", NULL, NULL }
1.1       etheisen  334:        },
                    335: #endif
1.1.1.2 ! millert   336:        { 'u', &u_optname,
        !           337:                TRIPLE|REPAINT, OPT_OFF, &bs_mode, NULL,
        !           338:                {
        !           339:                        "Display underlined text in underline mode",
        !           340:                        "Backspaces cause overstrike",
        !           341:                        "Print backspace as ^H"
        !           342:                }
        !           343:        },
        !           344:        { 'V', &V__optname,
        !           345:                NOVAR, 0, NULL, opt__V,
        !           346:                { NULL, NULL, NULL }
        !           347:        },
        !           348:        { 'w', &w_optname,
        !           349:                TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL,
        !           350:                {
        !           351:                        "Don't highlight first unread line",
        !           352:                        "Highlight first unread line after forward-screen",
        !           353:                        "Highlight first unread line after any forward movement",
        !           354:                }
        !           355:        },
        !           356:        { 'x', &x_optname,
        !           357:                STRING|REPAINT, 0, NULL, opt_x,
        !           358:                {
        !           359:                        "Tab stops: ",
        !           360:                        "0123456789,",
        !           361:                        NULL
        !           362:                }
        !           363:        },
        !           364:        { 'X', &X__optname,
        !           365:                BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL,
        !           366:                {
        !           367:                        "Send init/deinit strings to terminal",
        !           368:                        "Don't use init/deinit strings",
        !           369:                        NULL
        !           370:                }
        !           371:        },
        !           372:        { 'y', &y_optname,
        !           373:                NUMBER, -1, &forw_scroll, NULL,
        !           374:                {
        !           375:                        "Forward scroll limit: ",
        !           376:                        "Forward scroll limit is %d lines",
        !           377:                        NULL
        !           378:                }
        !           379:        },
        !           380:        { 'z', &z_optname,
        !           381:                NUMBER, -1, &swindow, NULL,
        !           382:                {
        !           383:                        "Scroll window size: ",
        !           384:                        "Scroll window size is %d lines",
        !           385:                        NULL
        !           386:                }
        !           387:        },
        !           388:        { '"', &quote_optname,
        !           389:                STRING, 0, NULL, opt_quote,
        !           390:                { "quotes: ", NULL, NULL }
        !           391:        },
        !           392:        { '~', &tilde_optname,
        !           393:                BOOL|REPAINT, OPT_ON, &twiddle, NULL,
        !           394:                {
        !           395:                        "Don't show tildes after end of file",
        !           396:                        "Show tildes after end of file",
        !           397:                        NULL
        !           398:                }
        !           399:        },
        !           400:        { '?', &query_optname,
        !           401:                NOVAR, 0, NULL, opt_query,
        !           402:                { NULL, NULL, NULL }
        !           403:        },
        !           404:        { '#', &pound_optname,
        !           405:                NUMBER, 0, &shift_count, NULL,
        !           406:                {
        !           407:                        "Horizontal shift: ",
        !           408:                        "Horizontal shift %d positions",
        !           409:                        NULL
        !           410:                }
        !           411:        },
        !           412:        { '.', &keypad_optname,
        !           413:                BOOL|NO_TOGGLE, OPT_OFF, &no_keypad, NULL,
        !           414:                {
        !           415:                        "Use keypad mode",
        !           416:                        "Don't use keypad mode",
        !           417:                        NULL
        !           418:                }
1.1       etheisen  419:        },
1.1.1.2 ! millert   420:        { '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
1.1       etheisen  421: };
                    422:
                    423:
                    424: /*
                    425:  * Initialize each option to its default value.
                    426:  */
                    427:        public void
                    428: init_option()
                    429: {
1.1.1.2 ! millert   430:        register struct loption *o;
1.1       etheisen  431:
                    432:        for (o = option;  o->oletter != '\0';  o++)
                    433:        {
                    434:                /*
                    435:                 * Set each variable to its default.
                    436:                 */
                    437:                if (o->ovar != NULL)
                    438:                        *(o->ovar) = o->odefault;
1.1.1.2 ! millert   439:                if (o->otype & INIT_HANDLER)
        !           440:                        (*(o->ofunc))(INIT, (char *) NULL);
1.1       etheisen  441:        }
                    442: }
                    443:
                    444: /*
1.1.1.2 ! millert   445:  * Find an option in the option table, given its option letter.
1.1       etheisen  446:  */
1.1.1.2 ! millert   447:        public struct loption *
1.1       etheisen  448: findopt(c)
                    449:        int c;
                    450: {
1.1.1.2 ! millert   451:        register struct loption *o;
1.1       etheisen  452:
                    453:        for (o = option;  o->oletter != '\0';  o++)
                    454:        {
                    455:                if (o->oletter == c)
                    456:                        return (o);
                    457:                if ((o->otype & TRIPLE) && toupper(o->oletter) == c)
                    458:                        return (o);
                    459:        }
                    460:        return (NULL);
1.1.1.2 ! millert   461: }
        !           462:
        !           463: /*
        !           464:  *
        !           465:  */
        !           466:        static int
        !           467: is_optchar(c)
        !           468:        char c;
        !           469: {
        !           470:        if (SIMPLE_IS_UPPER(c))
        !           471:                return 1;
        !           472:        if (SIMPLE_IS_LOWER(c))
        !           473:                return 1;
        !           474:        if (c == '-')
        !           475:                return 1;
        !           476:        return 0;
        !           477: }
        !           478:
        !           479: /*
        !           480:  * Find an option in the option table, given its option name.
        !           481:  * p_optname is the (possibly partial) name to look for, and
        !           482:  * is updated to point after the matched name.
        !           483:  * p_oname if non-NULL is set to point to the full option name.
        !           484:  */
        !           485:        public struct loption *
        !           486: findopt_name(p_optname, p_oname, p_err)
        !           487:        char **p_optname;
        !           488:        char **p_oname;
        !           489:        int *p_err;
        !           490: {
        !           491:        char *optname = *p_optname;
        !           492:        register struct loption *o;
        !           493:        register struct optname *oname;
        !           494:        register int len;
        !           495:        int uppercase;
        !           496:        struct loption *maxo = NULL;
        !           497:        struct optname *maxoname = NULL;
        !           498:        int maxlen = 0;
        !           499:        int ambig = 0;
        !           500:        int exact = 0;
        !           501:        char *eq;
        !           502:
        !           503:        /*
        !           504:         * Check all options.
        !           505:         */
        !           506:        for (o = option;  o->oletter != '\0';  o++)
        !           507:        {
        !           508:                /*
        !           509:                 * Check all names for this option.
        !           510:                 */
        !           511:                for (oname = o->onames;  oname != NULL;  oname = oname->onext)
        !           512:                {
        !           513:                        /*
        !           514:                         * Try normal match first (uppercase == 0),
        !           515:                         * then, then if it's a TRIPLE option,
        !           516:                         * try uppercase match (uppercase == 1).
        !           517:                         */
        !           518:                        for (uppercase = 0;  uppercase <= 1;  uppercase++)
        !           519:                        {
        !           520:                                len = sprefix(optname, oname->oname, uppercase);
        !           521:                                if (len <= 0 || is_optchar(optname[len]))
        !           522:                                {
        !           523:                                        /*
        !           524:                                         * We didn't use all of the option name.
        !           525:                                         */
        !           526:                                        continue;
        !           527:                                }
        !           528:                                if (!exact && len == maxlen)
        !           529:                                        /*
        !           530:                                         * Already had a partial match,
        !           531:                                         * and now there's another one that
        !           532:                                         * matches the same length.
        !           533:                                         */
        !           534:                                        ambig = 1;
        !           535:                                else if (len > maxlen)
        !           536:                                {
        !           537:                                        /*
        !           538:                                         * Found a better match than
        !           539:                                         * the one we had.
        !           540:                                         */
        !           541:                                        maxo = o;
        !           542:                                        maxoname = oname;
        !           543:                                        maxlen = len;
        !           544:                                        ambig = 0;
        !           545:                                        exact = (len == (int)strlen(oname->oname));
        !           546:                                }
        !           547:                                if (!(o->otype & TRIPLE))
        !           548:                                        break;
        !           549:                        }
        !           550:                }
        !           551:        }
        !           552:        if (ambig)
        !           553:        {
        !           554:                /*
        !           555:                 * Name matched more than one option.
        !           556:                 */
        !           557:                if (p_err != NULL)
        !           558:                        *p_err = OPT_AMBIG;
        !           559:                return (NULL);
        !           560:        }
        !           561:        *p_optname = optname + maxlen;
        !           562:        if (p_oname != NULL)
        !           563:                *p_oname = maxoname == NULL ? NULL : maxoname->oname;
        !           564:        return (maxo);
1.1       etheisen  565: }