home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d034 / less.lha / Less / option.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-09-03  |  7.5 KB  |  334 lines

  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. }
  334.