Annotation of 43BSDReno/contrib/mh/miscellany/less/option.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Process command line options.
                      3:  * Each option is a single letter which controls a program variable.
                      4:  * The options have defaults which may be changed via
                      5:  * the command line option, or toggled via the "-" command.
                      6:  */
                      7: 
                      8: #include "less.h"
                      9: 
                     10: #define        toupper(c)      ((c)-'a'+'A')
                     11: 
                     12: /*
                     13:  * Types of options.
                     14:  */
                     15: #define        BOOL            01      /* Boolean option: 0 or 1 */
                     16: #define        TRIPLE          02      /* Triple-valued option: 0, 1 or 2 */
                     17: #define        NUMBER          04      /* Numeric option */
                     18: #define        NO_TOGGLE       0100    /* Option cannot be toggled with "-" cmd */
                     19: 
                     20: /*
                     21:  * Variables controlled by command line options.
                     22:  */
                     23: public int p_nbufs, f_nbufs;   /* Number of buffers.  There are two values,
                     24:                                   one used for input from a pipe and 
                     25:                                   the other for input from a file. */
                     26: public int clean_data;         /* Can we assume the data is "clean"? 
                     27:                                   (That is, free of nulls, etc) */
                     28: public int quiet;              /* Should we suppress the audible bell? */
                     29: public int top_search;         /* Should forward searches start at the top 
                     30:                                   of the screen? (alternative is bottom) */
                     31: public int top_scroll;         /* Repaint screen from top?
                     32:                                   (alternative is scroll from bottom) */
                     33: public int pr_type;            /* Type of prompt (short, medium, long) */
                     34: public int bs_mode;            /* How to process backspaces */
                     35: public int know_dumb;          /* Don't complain about dumb terminals */
                     36: public int quit_at_eof;                /* Quit after hitting end of file twice */
                     37: public int squeeze;            /* Squeeze multiple blank lines into one */
                     38: public int tabstop;            /* Tab settings */
                     39: public int back_scroll;                /* Repaint screen on backwards movement */
                     40: public int twiddle;            /* Display "~" for lines after EOF */
                     41: 
                     42: extern int nbufs;
                     43: extern char *first_cmd;
                     44: extern char *every_first_cmd;
                     45: 
                     46: #define        DEF_F_NBUFS     5       /* Default for f_nbufs */
                     47: #define        DEF_P_NBUFS     12      /* Default for p_nbufs */
                     48: 
                     49: static struct option
                     50: {
                     51:        char oletter;           /* The controlling letter (a-z) */
                     52:        char otype;             /* Type of the option */
                     53:        int odefault;           /* Default value */
                     54:        int *ovar;              /* Pointer to the associated variable */
                     55:        char *odesc[3];         /* Description of each value */
                     56: } option[] =
                     57: {
                     58:        { 'c', BOOL, 0, &clean_data,
                     59:                { "Don't assume data is clean",
                     60:                  "Assume data is clean",
                     61:                  NULL
                     62:                }
                     63:        },
                     64: #ifndef        NRTC
                     65:        { 'd', BOOL|NO_TOGGLE, 0, &know_dumb,
                     66:                { NULL, NULL, NULL}
                     67:        },
                     68: #else  NRTC
                     69:        { 'd', BOOL|NO_TOGGLE, 1, &know_dumb,
                     70:                { NULL, NULL, NULL}
                     71:        },
                     72: #endif NRTC
                     73:        { 'e', BOOL, 0, &quit_at_eof,
                     74:                { "Don't quit at end-of-file",
                     75:                  "Quit at end-of-file",
                     76:                  NULL
                     77:                }
                     78:        },
                     79:        { 'h', NUMBER, -1, &back_scroll,
                     80:                { "Backwards scroll limit is %d lines",
                     81:                  NULL, NULL
                     82:                }
                     83:        },
                     84:        { 'p', BOOL, 0, &top_scroll,
                     85:                { "Repaint by scrolling from bottom of screen",
                     86:                  "Repaint by painting from top of screen",
                     87:                  NULL
                     88:                }
                     89:        },
                     90:        { 'x', NUMBER, 8, &tabstop,
                     91:                { "Tab stops every %d spaces", 
                     92:                  NULL, NULL 
                     93:                }
                     94:        },
                     95:        { 's', BOOL, 0, &squeeze,
                     96:                { "Don't squeeze multiple blank lines",
                     97:                  "Squeeze multiple blank lines",
                     98:                  NULL
                     99:                }
                    100:        },
                    101:        { 't', BOOL, 1, &top_search,
                    102:                { "Forward search starts from bottom of screen",
                    103:                  "Forward search starts from top of screen",
                    104:                  NULL
                    105:                }
                    106:        },
                    107:        { 'w', BOOL, 1, &twiddle,
                    108:                { "Display nothing for lines after end-of-file",
                    109:                  "Display ~ for lines after end-of-file",
                    110:                  NULL
                    111:                }
                    112:        },
                    113:        { 'm', TRIPLE, 0, &pr_type,
                    114:                { "Prompt with a colon",
                    115:                  "Prompt with a message",
                    116:                  "Prompt with a verbose message"
                    117:                }
                    118:        },
                    119:        { 'q', TRIPLE, 0, &quiet,
                    120:                { "Ring the bell for errors AND at eof/bof",
                    121:                  "Ring the bell for errors but not at eof/bof",
                    122:                  "Never ring the bell"
                    123:                }
                    124:        },
                    125:        { 'u', TRIPLE, 0, &bs_mode,
                    126:                { "Underlined text displayed in underline mode",
                    127:                  "All backspaces cause overstrike",
                    128:                  "Backspaces print as ^H"
                    129:                }
                    130:        },
                    131:        { '\0' }
                    132: };
                    133: 
                    134: public char all_options[64];   /* List of all valid options */
                    135: 
                    136: /*
                    137:  * Initialize each option to its default value.
                    138:  */
                    139:        public void
                    140: init_option()
                    141: {
                    142:        register struct option *o;
                    143:        register char *p;
                    144: 
                    145:        /*
                    146:         * First do special cases, not in option table.
                    147:         */
                    148:        first_cmd = every_first_cmd = NULL;
                    149:        f_nbufs = DEF_F_NBUFS;          /* -bf */
                    150:        p_nbufs = DEF_P_NBUFS;          /* -bp */
                    151: 
                    152:        p = all_options;
                    153:        *p++ = 'b';
                    154: 
                    155:        for (o = option;  o->oletter != '\0';  o++)
                    156:        {
                    157:                /*
                    158:                 * Set each variable to its default.
                    159:                 * Also make a list of all options, in "all_options".
                    160:                 */
                    161:                *(o->ovar) = o->odefault;
                    162:                *p++ = o->oletter;
                    163:                if (o->otype & TRIPLE)
                    164:                        *p++ = toupper(o->oletter);
                    165:        }
                    166:        *p = '\0';
                    167: }
                    168: 
                    169: /*
                    170:  * Toggle command line flags from within the program.
                    171:  * Used by the "-" command.
                    172:  */
                    173:        public void
                    174: toggle_option(c)
                    175:        int c;
                    176: {
                    177:        register struct option *o;
                    178:        char message[100];
                    179:        char buf[5];
                    180: 
                    181:        /*
                    182:         * First check for special cases not handled by the option table.
                    183:         */
                    184:        switch (c)
                    185:        {
                    186:        case 'b':
                    187:                sprintf(message, "%d buffers", nbufs);
                    188:                error(message);
                    189:                return;
                    190:        }
                    191: 
                    192: 
                    193:        for (o = option;  o->oletter != '\0';  o++)
                    194:        {
                    195:                if ((o->otype & BOOL) && (o->oletter == c) &&
                    196:                        (o->otype & NO_TOGGLE) == 0)
                    197:                {
                    198:                        /*
                    199:                         * Boolean option: 
                    200:                         * just toggle it.
                    201:                         */
                    202:                        *(o->ovar) = ! *(o->ovar);
                    203:                        error(o->odesc[*(o->ovar)]);
                    204:                        return;
                    205:                } else if ((o->otype & TRIPLE) && (o->oletter == c) &&
                    206:                        (o->otype & NO_TOGGLE) == 0)
                    207:                {
                    208:                        /*
                    209:                         * Triple-valued option with lower case letter:
                    210:                         * make it 1 unless already 1, then make it 0.
                    211:                         */
                    212:                        *(o->ovar) = (*(o->ovar) == 1) ? 0 : 1;
                    213:                        error(o->odesc[*(o->ovar)]);
                    214:                        return;
                    215:                } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c) &&
                    216:                        (o->otype & NO_TOGGLE) == 0)
                    217:                {
                    218:                        /*
                    219:                         * Triple-valued option with upper case letter:
                    220:                         * make it 2 unless already 2, then make it 0.
                    221:                         */
                    222:                        *(o->ovar) = (*(o->ovar) == 2) ? 0 : 2;
                    223:                        error(o->odesc[*(o->ovar)]);
                    224:                        return;
                    225:                } else if ((o->otype & NUMBER) && (o->oletter == c) &&
                    226:                        (o->otype & NO_TOGGLE) == 0)
                    227:                {
                    228:                        sprintf(message, o->odesc[0], *(o->ovar));
                    229:                        error(message);
                    230:                        return;
                    231:                }
                    232:        }
                    233: 
                    234:        if (control_char(c))
                    235:                sprintf(buf, "^%c", carat_char(c));
                    236:        else
                    237:                sprintf(buf, "%c", c);
                    238:        sprintf(message, "\"-%s\": no such flag.  Use one of \"%s\"", 
                    239:                buf, all_options);
                    240:        error(message);
                    241: }
                    242: 
                    243: /*
                    244:  * Scan an argument (either from command line or from LESS environment 
                    245:  * variable) and process it.
                    246:  */
                    247:        public void
                    248: scan_option(s)
                    249:        char *s;
                    250: {
                    251:        register struct option *o;
                    252:        register int c;
                    253: 
                    254:        if (s == NULL)
                    255:                return;
                    256: 
                    257:     next:
                    258:        if (*s == '\0')
                    259:                return;
                    260:        switch (c = *s++)
                    261:        {
                    262:        case '-':
                    263:        case ' ':
                    264:        case '\t':
                    265:                goto next;
                    266:        case '+':
                    267:                if (*s == '+')
                    268:                        every_first_cmd = ++s;
                    269:                first_cmd = s;
                    270:                return;
                    271:        case 'b':
                    272:                switch (*s)
                    273:                {
                    274:                case 'f':
                    275:                        s++;
                    276:                        f_nbufs = getnum(&s, 'b');
                    277:                        break;
                    278:                case 'p':
                    279:                        s++;
                    280:                        p_nbufs = getnum(&s, 'b');
                    281:                        break;
                    282:                default:
                    283:                        f_nbufs = p_nbufs = getnum(&s, 'b');
                    284:                        break;
                    285:                }
                    286:                goto next;
                    287:        }
                    288: 
                    289:        for (o = option;  o->oletter != '\0';  o++)
                    290:        {
                    291:                if ((o->otype & BOOL) && (o->oletter == c))
                    292:                {
                    293:                        *(o->ovar) = ! o->odefault;
                    294:                        goto next;
                    295:                } else if ((o->otype & TRIPLE) && (o->oletter == c))
                    296:                {
                    297:                        *(o->ovar) = (o->odefault == 1) ? 0 : 1;
                    298:                        goto next;
                    299:                } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
                    300:                {
                    301:                        *(o->ovar) = (o->odefault == 2) ? 0 : 2;
                    302:                        goto next;
                    303:                } else if ((o->otype & NUMBER) && (o->oletter == c))
                    304:                {
                    305:                        *(o->ovar) = getnum(&s, c);
                    306:                        goto next;
                    307:                }
                    308:        }
                    309: 
                    310:        printf("\"-%c\": invalid flag\n", c);
                    311:        exit(1);
                    312: }
                    313: 
                    314: /*
                    315:  * Translate a string into a number.
                    316:  * Like atoi(), but takes a pointer to a char *, and updates
                    317:  * the char * to point after the translated number.
                    318:  */
                    319:        static int
                    320: getnum(sp, c)
                    321:        char **sp;
                    322:        int c;
                    323: {
                    324:        register char *s;
                    325:        register int n;
                    326: 
                    327:        s = *sp;
                    328:        if (*s < '0' || *s > '9')
                    329:        {
                    330:                printf("number is required after -%c\n", c);
                    331:                exit(1);
                    332:        }
                    333: 
                    334:        n = 0;
                    335:        while (*s >= '0' && *s <= '9')
                    336:                n = 10 * n + *s++ - '0';
                    337:        *sp = s;
                    338:        return (n);
                    339: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.