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: }

Defined functions

getnum defined in line 313; used 4 times
init_option defined in line 133; never used
scan_option defined in line 241; never used
toggle_option defined in line 167; never used

Defined variables

all_options defined in line 128; used 2 times
back_scroll defined in line 39; used 1 times
  • in line 73
bs_mode defined in line 34; used 1 times
clean_data defined in line 26; used 1 times
  • in line 58
f_nbufs defined in line 23; used 3 times
know_dumb defined in line 35; used 1 times
  • in line 64
option defined in line 56; used 3 times
p_nbufs defined in line 23; used 3 times
pr_type defined in line 33; used 1 times
public defined in line 167; never used
quiet defined in line 28; used 1 times
quit_at_eof defined in line 36; used 1 times
  • in line 67
squeeze defined in line 37; used 1 times
  • in line 89
tabstop defined in line 38; used 1 times
  • in line 84
top_scroll defined in line 31; used 1 times
  • in line 78
top_search defined in line 29; used 1 times
  • in line 95
twiddle defined in line 40; used 1 times

Defined struct's

option defined in line 49; used 6 times

Defined macros

BOOL defined in line 15; used 9 times
DEF_F_NBUFS defined in line 46; used 1 times
DEF_P_NBUFS defined in line 47; used 1 times
NO_TOGGLE defined in line 18; used 5 times
NUMBER defined in line 17; used 4 times
TRIPLE defined in line 16; used 8 times
toupper defined in line 10; used 3 times
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: ?E00
Valid CSS Valid XHTML 1.0 Strict