Annotation of 43BSD/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:        { '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.