Annotation of 43BSDReno/contrib/mh/miscellany/less/option.c, revision 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.