home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / EBKSRC.ZIP / CMDLN.CPP next >
C/C++ Source or Header  |  1991-07-30  |  6KB  |  210 lines

  1. /*
  2.  
  3.     cmdln.cpp
  4.     7-30-91
  5.     Command line option parser
  6.  
  7.     Copyright 1991
  8.     John W. Small
  9.     All rights reserved
  10.     Use freely but acknowledge authorship and copyright.
  11.  
  12.     PSW / Power SoftWare
  13.     P.O. Box 10072
  14.     McLean, Virginia 22102 8072 USA
  15.     
  16.     John Small
  17.     Voice: (703) 759-3838
  18.     CIS: 73757,2233
  19.  
  20.  
  21.  
  22.     Notes:
  23.  
  24.  
  25.     1.  Call getOption() repeatedly to parse command
  26.     line arguments.  The options to look for along with
  27.     the argc and argv must be passed as parameters to
  28.     the constructor CmdLn() or the member function
  29.     CmdLnReset().  The options string is a string of
  30.     the option characters that may appear on your
  31.     programs command line after the switch character,
  32.     '/' or '-' for DOS.  If an option takes argument
  33.     then a colon must immediately follow that option
  34.     character in the options string to let
  35.     getOption() know to look for the argument.  The
  36.     syntax for the option string is as follows:
  37.  
  38.         options string ::= {optch[:]}*
  39.  
  40.     Your read the syntax as: An options string is zero
  41.     or more (the "*" indicates this) option characters
  42.     any of which may be followed by a colon to indicate
  43.     that the option has an argument.
  44.  
  45.  
  46.     2. GetOption() returns the current option
  47.     character being processed along with any argument
  48.     in the variable optArg.  OptArg is valid only
  49.     when an option requiring an argument is processed.
  50.     If the argument is missing then optArg == 0.  If
  51.     the current option character being processed is
  52.     unrecognized, i.e. not in the options string passed
  53.     to CmdLn(), then getOption() returns '?' with
  54.     the unrecognized character stored in optNot.  This
  55.     is the only time that optNot is valid!
  56.     getOption() returns -1 when there are no more
  57.     options to process.  The variable, optCh,
  58.     maintains a copy of the latest value returned by
  59.     getOption().
  60.  
  61.  
  62.     3.  When your program is invoked, getOption()
  63.     recognizes clusters of command line options.  A
  64.     cluster is the switch character followed immediately
  65.     by any number of option characters, no white space.
  66.     The options clusters must preceed any other command
  67.     line parameters since getOption() stops processing
  68.     on the first parameter that is not a switch.  This
  69.     is the Unix convention.  If you would like to be
  70.     able to intersperse command line switches with other
  71.     parameters on the command line then call
  72.     lookForMoreOptions() to reenable getOption()
  73.     to continue looking for more options.  If an option
  74.     takes an argument then the option's character must
  75.     be the last option in the cluster with the argument
  76.     immediately following or separated by white space.
  77.     The argument must not have any white space, though
  78.     it may contain the switch character.
  79.  
  80.     command line option cluster ::=
  81.  
  82.     {'/'|'-'}{[optch]*argch[whitespace]argument}|optch+
  83.  
  84.     Wow! That reads: a command line option cluster
  85.     starts with the switch character ('/' or '-' in DOS)
  86.     with one or more option characters (+ means one or
  87.     more) or (| means or) any number of option
  88.     characters, only the last of which is allowed to
  89.     take an argument.  The argument can be either tacked
  90.     on to the end of the option cluster or stand off by
  91.     itself.  In either case, argument contains no white
  92.     space!  If a switch character appears in a cluster
  93.     by itself or if two switch characters lead off a
  94.     cluster then no more options are processed and the
  95.     next parameter starts the non switched arguments.
  96.     This allows the first non switched argument to start
  97.     with the switch character, i.e. let the preceeding
  98.     cluster be either a single switch character or lead
  99.     off with two switch characters.  The switch
  100.     characters are defined in the static variable:
  101.     switches.  Switches is currently defined for MS DOS.
  102.  
  103.  
  104.     4.  For example, if the options string contains
  105.     "C:af:z" then 'C' and 'f' take arguments.  A valid
  106.     command line would be:
  107.  
  108.         cmd /afnew /zC cmdfile outfile
  109.  
  110.     with repeated calls to getOption() returning:
  111.  
  112.         'a'
  113.         'f' with optArg == "new"
  114.         'z'
  115.         'C' with optArg == "cmdfile"
  116.         -1  with Argi() == 4
  117.  
  118.     The variable, argi, is the index into the next
  119.     unprocessed argv cell.  You can use Argi() to
  120.     initialize your index into the non-switched
  121.     command line parameters.
  122.  
  123.  
  124.     5.  Compile and run cmdlnd.cpp.  Be sure you
  125.     understand the demo code before using cmdln.cpp.
  126.  
  127. */
  128.  
  129. #include <string.h>    /*  strchr()  */
  130. #include <cmdln.hpp>
  131.  
  132. static char switches[] = "/-";
  133. /*
  134.     Switches is initialized here for DOS switch
  135.     characters.  Change as necessary for your
  136.     host OS shell.
  137. */
  138.  
  139. void CmdLn::CmdLnReset(int argc, char *argv[],
  140.     char *options)
  141. {
  142.     this->argv = argv;
  143.     this->options = options;
  144.     opt = (char *) 0;
  145.     this->argc = argc;
  146.     optEnd = 0;
  147.     optCh = optNot = '\0';
  148.     optArg = (char *) 0;
  149.     argi = 1;
  150. }
  151.  
  152. int CmdLn::getOption(void)
  153. {
  154.  
  155.     char *lookup;
  156.  
  157.     optArg = (char *)0;
  158.     if (optEnd)    /* no more options allowed */
  159.         return (optCh = 0);
  160.     if (!opt || (*opt == '\0'))  {
  161.         if (argi >= argc) /* no more parameters */
  162.             return (optEnd = optCh = -1);
  163.             /* end of options */
  164.         opt = argv[argi];
  165.             /* next possible option cluster */
  166.         if (!strchr(switches,*opt))
  167.             /* Not an option cluster? */
  168.             return (optEnd = optCh = -1);
  169.             /* start non option parameters */
  170.         argi++; /* next possible parameter */
  171.         opt++;  /* next possible option */
  172.         if (!*opt || strchr(switches,*opt))
  173.             /* Two switches or one by itself */
  174.             return (optEnd = optCh = -1);
  175.             /* means end of options */
  176.     }
  177.     if ((lookup = strchr(
  178.         /* validate option character */
  179.         options? options : "",
  180.         optNot = *opt++))
  181.         == (char *)0)
  182.         return (optCh = '?');
  183.         /* unknown option */
  184.     if (lookup[1] == ':')  {
  185.         /* option takes argument */
  186.         if (*opt != '\0')
  187.             /* Is argument in this parameter? */
  188.             optArg = opt;
  189.         else if (argi < argc)
  190.             /* Is argument in next parameter? */
  191.             optArg = argv[argi++];
  192.         opt = (char *) 0;
  193.         /* no more options in this parameter */
  194.     }
  195.     return (optCh = *lookup);
  196.     /* return option */
  197. }
  198.  
  199. void CmdLn::nextCluster(void) { opt = (char *) 0; }
  200.     /* start processing in next cluster */
  201.  
  202. void CmdLn::lookForMoreOptions(void)
  203. {
  204.     if (optEnd)  {
  205.         opt = (char *) 0;
  206.         argi++;
  207.         optEnd = 0;
  208.     }
  209. }
  210.