Annotation of 43BSD/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:        { 'd', BOOL|NO_TOGGLE, 0, &know_dumb,
                     65:                { NULL, NULL, NULL}
                     66:        },
                     67:        { 'e', BOOL, 0, &quit_at_eof,
                     68:                { "Don't quit at end-of-file",
                     69:                  "Quit at end-of-file",
                     70:                  NULL
                     71:                }
                     72:        },
                     73:        { 'h', NUMBER, -1, &back_scroll,
                     74:                { "Backwards scroll limit is %d lines",
                     75:                  NULL, NULL
                     76:                }
                     77:        },
                     78:        { 'p', BOOL, 0, &top_scroll,
                     79:                { "Repaint by scrolling from bottom of screen",
                     80:                  "Repaint by painting from top of screen",
                     81:                  NULL
                     82:                }
                     83:        },
                     84:        { 'x', NUMBER, 8, &tabstop,
                     85:                { "Tab stops every %d spaces", 
                     86:                  NULL, NULL 
                     87:                }
                     88:        },
                     89:        { 's', BOOL, 0, &squeeze,
                     90:                { "Don't squeeze multiple blank lines",
                     91:                  "Squeeze multiple blank lines",
                     92:                  NULL
                     93:                }
                     94:        },
                     95:        { 't', BOOL, 1, &top_search,
                     96:                { "Forward search starts from bottom of screen",
                     97:                  "Forward search starts from top of screen",
                     98:                  NULL
                     99:                }
                    100:        },
                    101:        { 'w', BOOL, 1, &twiddle,
                    102:                { "Display nothing for lines after end-of-file",
                    103:                  "Display ~ for lines after end-of-file",
                    104:                  NULL
                    105:                }
                    106:        },
                    107:        { 'm', TRIPLE, 0, &pr_type,
                    108:                { "Prompt with a colon",
                    109:                  "Prompt with a message",
                    110:                  "Prompt with a verbose message"
                    111:                }
                    112:        },
                    113:        { 'q', TRIPLE, 0, &quiet,
                    114:                { "Ring the bell for errors AND at eof/bof",
                    115:                  "Ring the bell for errors but not at eof/bof",
                    116:                  "Never ring the bell"
                    117:                }
                    118:        },
                    119:        { 'u', TRIPLE, 0, &bs_mode,
                    120:                { "Underlined text displayed in underline mode",
                    121:                  "All backspaces cause overstrike",
                    122:                  "Backspaces print as ^H"
                    123:                }
                    124:        },
                    125:        { '\0' }
                    126: };
                    127: 
                    128: public char all_options[64];   /* List of all valid options */
                    129: 
                    130: /*
                    131:  * Initialize each option to its default value.
                    132:  */
                    133:        public void
                    134: init_option()
                    135: {
                    136:        register struct option *o;
                    137:        register char *p;
                    138: 
                    139:        /*
                    140:         * First do special cases, not in option table.
                    141:         */
                    142:        first_cmd = every_first_cmd = NULL;
                    143:        f_nbufs = DEF_F_NBUFS;          /* -bf */
                    144:        p_nbufs = DEF_P_NBUFS;          /* -bp */
                    145: 
                    146:        p = all_options;
                    147:        *p++ = 'b';
                    148: 
                    149:        for (o = option;  o->oletter != '\0';  o++)
                    150:        {
                    151:                /*
                    152:                 * Set each variable to its default.
                    153:                 * Also make a list of all options, in "all_options".
                    154:                 */
                    155:                *(o->ovar) = o->odefault;
                    156:                *p++ = o->oletter;
                    157:                if (o->otype & TRIPLE)
                    158:                        *p++ = toupper(o->oletter);
                    159:        }
                    160:        *p = '\0';
                    161: }
                    162: 
                    163: /*
                    164:  * Toggle command line flags from within the program.
                    165:  * Used by the "-" command.
                    166:  */
                    167:        public void
                    168: toggle_option(c)
                    169:        int c;
                    170: {
                    171:        register struct option *o;
                    172:        char message[100];
                    173:        char buf[5];
                    174: 
                    175:        /*
                    176:         * First check for special cases not handled by the option table.
                    177:         */
                    178:        switch (c)
                    179:        {
                    180:        case 'b':
                    181:                sprintf(message, "%d buffers", nbufs);
                    182:                error(message);
                    183:                return;
                    184:        }
                    185: 
                    186: 
                    187:        for (o = option;  o->oletter != '\0';  o++)
                    188:        {
                    189:                if ((o->otype & BOOL) && (o->oletter == c) &&
                    190:                        (o->otype & NO_TOGGLE) == 0)
                    191:                {
                    192:                        /*
                    193:                         * Boolean option: 
                    194:                         * just toggle it.
                    195:                         */
                    196:                        *(o->ovar) = ! *(o->ovar);
                    197:                        error(o->odesc[*(o->ovar)]);
                    198:                        return;
                    199:                } else if ((o->otype & TRIPLE) && (o->oletter == c) &&
                    200:                        (o->otype & NO_TOGGLE) == 0)
                    201:                {
                    202:                        /*
                    203:                         * Triple-valued option with lower case letter:
                    204:                         * make it 1 unless already 1, then make it 0.
                    205:                         */
                    206:                        *(o->ovar) = (*(o->ovar) == 1) ? 0 : 1;
                    207:                        error(o->odesc[*(o->ovar)]);
                    208:                        return;
                    209:                } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c) &&
                    210:                        (o->otype & NO_TOGGLE) == 0)
                    211:                {
                    212:                        /*
                    213:                         * Triple-valued option with upper case letter:
                    214:                         * make it 2 unless already 2, then make it 0.
                    215:                         */
                    216:                        *(o->ovar) = (*(o->ovar) == 2) ? 0 : 2;
                    217:                        error(o->odesc[*(o->ovar)]);
                    218:                        return;
                    219:                } else if ((o->otype & NUMBER) && (o->oletter == c) &&
                    220:                        (o->otype & NO_TOGGLE) == 0)
                    221:                {
                    222:                        sprintf(message, o->odesc[0], *(o->ovar));
                    223:                        error(message);
                    224:                        return;
                    225:                }
                    226:        }
                    227: 
                    228:        if (control_char(c))
                    229:                sprintf(buf, "^%c", carat_char(c));
                    230:        else
                    231:                sprintf(buf, "%c", c);
                    232:        sprintf(message, "\"-%s\": no such flag.  Use one of \"%s\"", 
                    233:                buf, all_options);
                    234:        error(message);
                    235: }
                    236: 
                    237: /*
                    238:  * Scan an argument (either from command line or from LESS environment 
                    239:  * variable) and process it.
                    240:  */
                    241:        public void
                    242: scan_option(s)
                    243:        char *s;
                    244: {
                    245:        register struct option *o;
                    246:        register int c;
                    247: 
                    248:        if (s == NULL)
                    249:                return;
                    250: 
                    251:     next:
                    252:        if (*s == '\0')
                    253:                return;
                    254:        switch (c = *s++)
                    255:        {
                    256:        case '-':
                    257:        case ' ':
                    258:        case '\t':
                    259:                goto next;
                    260:        case '+':
                    261:                if (*s == '+')
                    262:                        every_first_cmd = ++s;
                    263:                first_cmd = s;
                    264:                return;
                    265:        case 'b':
                    266:                switch (*s)
                    267:                {
                    268:                case 'f':
                    269:                        s++;
                    270:                        f_nbufs = getnum(&s, 'b');
                    271:                        break;
                    272:                case 'p':
                    273:                        s++;
                    274:                        p_nbufs = getnum(&s, 'b');
                    275:                        break;
                    276:                default:
                    277:                        f_nbufs = p_nbufs = getnum(&s, 'b');
                    278:                        break;
                    279:                }
                    280:                goto next;
                    281:        }
                    282: 
                    283:        for (o = option;  o->oletter != '\0';  o++)
                    284:        {
                    285:                if ((o->otype & BOOL) && (o->oletter == c))
                    286:                {
                    287:                        *(o->ovar) = ! o->odefault;
                    288:                        goto next;
                    289:                } else if ((o->otype & TRIPLE) && (o->oletter == c))
                    290:                {
                    291:                        *(o->ovar) = (o->odefault == 1) ? 0 : 1;
                    292:                        goto next;
                    293:                } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
                    294:                {
                    295:                        *(o->ovar) = (o->odefault == 2) ? 0 : 2;
                    296:                        goto next;
                    297:                } else if ((o->otype & NUMBER) && (o->oletter == c))
                    298:                {
                    299:                        *(o->ovar) = getnum(&s, c);
                    300:                        goto next;
                    301:                }
                    302:        }
                    303: 
                    304:        printf("\"-%c\": invalid flag\n", c);
                    305:        exit(1);
                    306: }
                    307: 
                    308: /*
                    309:  * Translate a string into a number.
                    310:  * Like atoi(), but takes a pointer to a char *, and updates
                    311:  * the char * to point after the translated number.
                    312:  */
                    313:        static int
                    314: getnum(sp, c)
                    315:        char **sp;
                    316:        int c;
                    317: {
                    318:        register char *s;
                    319:        register int n;
                    320: 
                    321:        s = *sp;
                    322:        if (*s < '0' || *s > '9')
                    323:        {
                    324:                printf("number is required after -%c\n", c);
                    325:                exit(1);
                    326:        }
                    327: 
                    328:        n = 0;
                    329:        while (*s >= '0' && *s <= '9')
                    330:                n = 10 * n + *s++ - '0';
                    331:        *sp = s;
                    332:        return (n);
                    333: }

unix.superglobalmegacorp.com

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