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

Defined functions

getnum defined in line 319; used 4 times

Defined variables

all_options defined in line 134; used 2 times
bs_mode defined in line 34; used 3 times
clean_data defined in line 26; used 2 times
f_nbufs defined in line 23; used 4 times
know_dumb defined in line 35; used 3 times
option defined in line 56; used 3 times
p_nbufs defined in line 23; used 4 times
pr_type defined in line 33; used 2 times
public defined in line 173; never used
squeeze defined in line 37; used 3 times
top_search defined in line 29; used 2 times

Defined struct's

option defined in line 49; used 6 times

Defined macros

BOOL defined in line 15; used 10 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 6 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: 1913
Valid CSS Valid XHTML 1.0 Strict