home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / less373.zip / optfunc.c < prev    next >
C/C++ Source or Header  |  2002-01-14  |  10KB  |  592 lines

  1. /*
  2.  * Copyright (C) 1984-2000  Mark Nudelman
  3.  *
  4.  * You may distribute under the terms of either the GNU General Public
  5.  * License or the Less License, as specified in the README file.
  6.  *
  7.  * For more information about less, or for information on how to 
  8.  * contact the author, see the README file.
  9.  */
  10.  
  11.  
  12. /*
  13.  * Handling functions for command line options.
  14.  *
  15.  * Most options are handled by the generic code in option.c.
  16.  * But all string options, and a few non-string options, require
  17.  * special handling specific to the particular option.
  18.  * This special processing is done by the "handling functions" in this file.
  19.  *
  20.  * Each handling function is passed a "type" and, if it is a string
  21.  * option, the string which should be "assigned" to the option.
  22.  * The type may be one of:
  23.  *    INIT    The option is being initialized from the command line.
  24.  *    TOGGLE    The option is being changed from within the program.
  25.  *    QUERY    The setting of the option is merely being queried.
  26.  */
  27.  
  28. #include "less.h"
  29. #include "option.h"
  30.  
  31. extern int nbufs;
  32. extern int bufspace;
  33. extern int pr_type;
  34. extern int plusoption;
  35. extern int swindow;
  36. extern int sc_height;
  37. extern int secure;
  38. extern int dohelp;
  39. extern int any_display;
  40. extern char openquote;
  41. extern char closequote;
  42. extern char *prproto[];
  43. extern char *eqproto;
  44. extern char *hproto;
  45. extern char *wproto;
  46. extern IFILE curr_ifile;
  47. extern char version[];
  48. #if LOGFILE
  49. extern char *namelogfile;
  50. extern int force_logfile;
  51. extern int logfile;
  52. #endif
  53. #if TAGS
  54. public char *tagoption = NULL;
  55. extern char *tags;
  56. extern int jump_sline;
  57. #endif
  58. #if MSDOS_COMPILER
  59. extern int nm_fg_color, nm_bg_color;
  60. extern int bo_fg_color, bo_bg_color;
  61. extern int ul_fg_color, ul_bg_color;
  62. extern int so_fg_color, so_bg_color;
  63. extern int bl_fg_color, bl_bg_color;
  64. #endif
  65.  
  66.  
  67. #if LOGFILE
  68. /*
  69.  * Handler for -o option.
  70.  */
  71.     public void
  72. opt_o(type, s)
  73.     int type;
  74.     char *s;
  75. {
  76.     PARG parg;
  77.  
  78.     if (secure)
  79.     {
  80.         error("log file support is not available", NULL_PARG);
  81.         return;
  82.     }
  83.     switch (type)
  84.     {
  85.     case INIT:
  86.         namelogfile = s;
  87.         break;
  88.     case TOGGLE:
  89.         if (ch_getflags() & CH_CANSEEK)
  90.         {
  91.             error("Input is not a pipe", NULL_PARG);
  92.             return;
  93.         }
  94.         if (logfile >= 0)
  95.         {
  96.             error("Log file is already in use", NULL_PARG);
  97.             return;
  98.         }
  99.         s = skipsp(s);
  100.         namelogfile = lglob(s);
  101.         use_logfile(namelogfile);
  102.         sync_logfile();
  103.         break;
  104.     case QUERY:
  105.         if (logfile < 0)
  106.             error("No log file", NULL_PARG);
  107.         else
  108.         {
  109.             parg.p_string = namelogfile;
  110.             error("Log file \"%s\"", &parg);
  111.         }
  112.         break;
  113.     }
  114. }
  115.  
  116. /*
  117.  * Handler for -O option.
  118.  */
  119.     public void
  120. opt__O(type, s)
  121.     int type;
  122.     char *s;
  123. {
  124.     force_logfile = TRUE;
  125.     opt_o(type, s);
  126. }
  127. #endif
  128.  
  129. /*
  130.  * Handlers for -l option.
  131.  */
  132.     public void
  133. opt_l(type, s)
  134.     int type;
  135.     char *s;
  136. {
  137.     int err;
  138.     int n;
  139.     char *t;
  140.     
  141.     switch (type)
  142.     {
  143.     case INIT:
  144.         t = s;
  145.         n = getnum(&t, 'l', &err);
  146.         if (err || n <= 0)
  147.         {
  148.             error("Line number is required after -l", NULL_PARG);
  149.             return;
  150.         }
  151.         plusoption = TRUE;
  152.         ungetsc(s);
  153.         break;
  154.     }
  155. }
  156.  
  157. #if USERFILE
  158.     public void
  159. opt_k(type, s)
  160.     int type;
  161.     char *s;
  162. {
  163.     PARG parg;
  164.  
  165.     switch (type)
  166.     {
  167.     case INIT:
  168.         if (lesskey(s, 0))
  169.         {
  170.             parg.p_string = s;
  171.             error("Cannot use lesskey file \"%s\"", &parg);
  172.         }
  173.         break;
  174.     }
  175. }
  176. #endif
  177.  
  178. #if TAGS
  179. /*
  180.  * Handler for -t option.
  181.  */
  182.     public void
  183. opt_t(type, s)
  184.     int type;
  185.     char *s;
  186. {
  187.     IFILE save_ifile;
  188.     POSITION pos;
  189.  
  190.     switch (type)
  191.     {
  192.     case INIT:
  193.         tagoption = s;
  194.         /* Do the rest in main() */
  195.         break;
  196.     case TOGGLE:
  197.         if (secure)
  198.         {
  199.             error("tags support is not available", NULL_PARG);
  200.             break;
  201.         }
  202.         findtag(skipsp(s));
  203.         save_ifile = save_curr_ifile();
  204.         if (edit_tagfile())
  205.             break;
  206.         if ((pos = tagsearch()) == NULL_POSITION)
  207.         {
  208.             reedit_ifile(save_ifile);
  209.             break;
  210.         }
  211.         unsave_ifile(save_ifile);
  212.         jump_loc(pos, jump_sline);
  213.         break;
  214.     }
  215. }
  216.  
  217. /*
  218.  * Handler for -T option.
  219.  */
  220.     public void
  221. opt__T(type, s)
  222.     int type;
  223.     char *s;
  224. {
  225.     PARG parg;
  226.  
  227.     switch (type)
  228.     {
  229.     case INIT:
  230.         tags = s;
  231.         break;
  232.     case TOGGLE:
  233.         s = skipsp(s);
  234.         tags = lglob(s);
  235.         break;
  236.     case QUERY:
  237.         parg.p_string = tags;
  238.         error("Tags file \"%s\"", &parg);
  239.         break;
  240.     }
  241. }
  242. #endif
  243.  
  244. /*
  245.  * Handler for -p option.
  246.  */
  247.     public void
  248. opt_p(type, s)
  249.     int type;
  250.     register char *s;
  251. {
  252.     switch (type)
  253.     {
  254.     case INIT:
  255.         /*
  256.          * Unget a search command for the specified string.
  257.          * {{ This won't work if the "/" command is
  258.          *    changed or invalidated by a .lesskey file. }}
  259.          */
  260.         plusoption = TRUE;
  261.         ungetsc(s);
  262.         ungetsc("/");
  263.         break;
  264.     }
  265. }
  266.  
  267. /*
  268.  * Handler for -P option.
  269.  */
  270.     public void
  271. opt__P(type, s)
  272.     int type;
  273.     register char *s;
  274. {
  275.     register char **proto;
  276.     PARG parg;
  277.  
  278.     switch (type)
  279.     {
  280.     case INIT:
  281.     case TOGGLE:
  282.         /*
  283.          * Figure out which prototype string should be changed.
  284.          */
  285.         switch (*s)
  286.         {
  287.         case 's':  proto = &prproto[PR_SHORT];    s++;    break;
  288.         case 'm':  proto = &prproto[PR_MEDIUM];    s++;    break;
  289.         case 'M':  proto = &prproto[PR_LONG];    s++;    break;
  290.         case '=':  proto = &eqproto;        s++;    break;
  291.         case 'h':  proto = &hproto;        s++;    break;
  292.         case 'w':  proto = &wproto;        s++;    break;
  293.         default:   proto = &prproto[PR_SHORT];        break;
  294.         }
  295.         free(*proto);
  296.         *proto = save(s);
  297.         break;
  298.     case QUERY:
  299.         parg.p_string = prproto[pr_type];
  300.         error("%s", &parg);
  301.         break;
  302.     }
  303. }
  304.  
  305. /*
  306.  * Handler for the -b option.
  307.  */
  308.     /*ARGSUSED*/
  309.     public void
  310. opt_b(type, s)
  311.     int type;
  312.     char *s;
  313. {
  314.     switch (type)
  315.     {
  316.     case INIT:
  317.     case TOGGLE:
  318.         /*
  319.          * Set the new number of buffers.
  320.          */
  321.         ch_setbufspace(bufspace);
  322.         break;
  323.     case QUERY:
  324.         break;
  325.     }
  326. }
  327.  
  328. /*
  329.  * Handler for the -i option.
  330.  */
  331.     /*ARGSUSED*/
  332.     public void
  333. opt_i(type, s)
  334.     int type;
  335.     char *s;
  336. {
  337.     switch (type)
  338.     {
  339.     case TOGGLE:
  340.         chg_caseless();
  341.         break;
  342.     case QUERY:
  343.     case INIT:
  344.         break;
  345.     }
  346. }
  347.  
  348. /*
  349.  * Handler for the -V option.
  350.  */
  351.     /*ARGSUSED*/
  352.     public void
  353. opt__V(type, s)
  354.     int type;
  355.     char *s;
  356. {
  357.     switch (type)
  358.     {
  359.     case TOGGLE:
  360.     case QUERY:
  361.         dispversion();
  362.         break;
  363.     case INIT:
  364.         /*
  365.          * Force output to stdout per GNU standard for --version output.
  366.          */
  367.         any_display = 1;
  368.         putstr("less ");
  369.         putstr(version);
  370.         putstr("\nCopyright (C) 2001 Mark Nudelman\n\n");
  371.         putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
  372.         putstr("For information about the terms of redistribution,\n");
  373.         putstr("see the file named README in the less distribution.\n");
  374.         putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
  375.         quit(QUIT_OK);
  376.         break;
  377.     }
  378. }
  379.  
  380. #if MSDOS_COMPILER
  381. /*
  382.  * Parse an MSDOS color descriptor.
  383.  */
  384.        static void
  385. colordesc(s, fg_color, bg_color)
  386.     char *s;
  387.     int *fg_color;
  388.     int *bg_color;
  389. {
  390.     int fg, bg;
  391.     int err;
  392.     
  393.     fg = getnum(&s, 'D', &err);
  394.     if (err)
  395.     {
  396.         error("Missing fg color in -D", NULL_PARG);
  397.         return;
  398.     }
  399.     if (*s != '.')
  400.         bg = 0;
  401.     else
  402.     {
  403.         s++;
  404.         bg = getnum(&s, 'D', &err);
  405.         if (err)
  406.         {
  407.             error("Missing fg color in -D", NULL_PARG);
  408.             return;
  409.         }
  410.     }
  411.     if (*s != '\0')
  412.         error("Extra characters at end of -D option", NULL_PARG);
  413.     *fg_color = fg;
  414.     *bg_color = bg;
  415. }
  416.  
  417. /*
  418.  * Handler for the -D option.
  419.  */
  420.     /*ARGSUSED*/
  421.     public void
  422. opt_D(type, s)
  423.     int type;
  424.     char *s;
  425. {
  426.     switch (type)
  427.     {
  428.     case INIT:
  429.     case TOGGLE:
  430.         switch (*s++)
  431.         {
  432.         case 'n':
  433.             colordesc(s, &nm_fg_color, &nm_bg_color);
  434.             break;
  435.         case 'd':
  436.             colordesc(s, &bo_fg_color, &bo_bg_color);
  437.             break;
  438.         case 'u':
  439.             colordesc(s, &ul_fg_color, &ul_bg_color);
  440.             break;
  441.         case 'k':
  442.             colordesc(s, &bl_fg_color, &bl_bg_color);
  443.             break;
  444.         case 's':
  445.             colordesc(s, &so_fg_color, &so_bg_color);
  446.             break;
  447.         default:
  448.             error("-D must be followed by n, d, u, k or s", NULL_PARG);
  449.             break;
  450.         }
  451.         if (type == TOGGLE)
  452.         {
  453.             so_enter();
  454.             so_exit();
  455.         }
  456.         break;
  457.     case QUERY:
  458.         break;
  459.     }
  460. }
  461. #endif
  462.  
  463. /*
  464.  * Handler for the -x option.
  465.  */
  466.     public void
  467. opt_x(type, s)
  468.     int type;
  469.     register char *s;
  470. {
  471.     extern int tabstops[];
  472.     extern int ntabstops;
  473.     extern int tabdefault;
  474.     char msg[60+(4*TABSTOP_MAX)];
  475.     int i;
  476.     PARG p;
  477.  
  478.     switch (type)
  479.     {
  480.     case INIT:
  481.     case TOGGLE:
  482.         /* Start at 1 because tabstops[0] is always zero. */
  483.         for (i = 1;  i < TABSTOP_MAX;  )
  484.         {
  485.             int n = 0;
  486.             while (*s >= '0' && *s <= '9')
  487.                 n = (10 * n) + (*s++ - '0');
  488.             if (n > tabstops[i-1])
  489.                 tabstops[i++] = n;
  490.             if (*s++ != ',')
  491.                 break;
  492.         }
  493.         if (i < 2)
  494.             return;
  495.         ntabstops = i;
  496.         tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
  497.         break;
  498.     case QUERY:
  499.         strcpy(msg, "Tab stops ");
  500.         if (ntabstops > 2)
  501.         {
  502.             for (i = 1;  i < ntabstops;  i++)
  503.             {
  504.                 if (i > 1)
  505.                     strcat(msg, ",");
  506.                 sprintf(msg+strlen(msg), "%d", tabstops[i]);
  507.             }
  508.             sprintf(msg+strlen(msg), " and then ");
  509.         }
  510.         sprintf(msg+strlen(msg), "every %d spaces",
  511.             tabdefault);
  512.         p.p_string = msg;
  513.         error("%s", &p);
  514.         break;
  515.     }
  516. }
  517.  
  518.  
  519. /*
  520.  * Handler for the -" option.
  521.  */
  522.     public void
  523. opt_quote(type, s)
  524.     int type;
  525.     register char *s;
  526. {
  527.     char buf[3];
  528.     PARG parg;
  529.  
  530.     switch (type)
  531.     {
  532.     case INIT:
  533.     case TOGGLE:
  534.         if (s[0] == '\0')
  535.         {
  536.             openquote = closequote = '\0';
  537.             break;
  538.         }
  539.         if (s[1] != '\0' && s[2] != '\0')
  540.         {
  541.             error("-\" must be followed by 1 or 2 chars", NULL_PARG);
  542.             return;
  543.         }
  544.         openquote = s[0];
  545.         if (s[1] == '\0')
  546.             closequote = openquote;
  547.         else
  548.             closequote = s[1];
  549.         break;
  550.     case QUERY:
  551.         buf[0] = openquote;
  552.         buf[1] = closequote;
  553.         buf[2] = '\0';
  554.         parg.p_string = buf;
  555.         error("quotes %s", &parg);
  556.         break;
  557.     }
  558. }
  559.  
  560. /*
  561.  * "-?" means display a help message.
  562.  * If from the command line, exit immediately.
  563.  */
  564.     /*ARGSUSED*/
  565.     public void
  566. opt_query(type, s)
  567.     int type;
  568.     char *s;
  569. {
  570.     switch (type)
  571.     {
  572.     case QUERY:
  573.     case TOGGLE:
  574.         error("Use \"h\" for help", NULL_PARG);
  575.         break;
  576.     case INIT:
  577.         dohelp = 1;
  578.     }
  579. }
  580.  
  581. /*
  582.  * Get the "screen window" size.
  583.  */
  584.     public int
  585. get_swindow()
  586. {
  587.     if (swindow > 0)
  588.         return (swindow);
  589.     return (sc_height + swindow);
  590. }
  591.  
  592.