home *** CD-ROM | disk | FTP | other *** search
- /*
-
- cmdln.cpp
- 7-30-91
- Command line option parser
-
- Copyright 1991
- John W. Small
- All rights reserved
- Use freely but acknowledge authorship and copyright.
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, Virginia 22102 8072 USA
-
- John Small
- Voice: (703) 759-3838
- CIS: 73757,2233
-
-
-
- Notes:
-
-
- 1. Call getOption() repeatedly to parse command
- line arguments. The options to look for along with
- the argc and argv must be passed as parameters to
- the constructor CmdLn() or the member function
- CmdLnReset(). The options string is a string of
- the option characters that may appear on your
- programs command line after the switch character,
- '/' or '-' for DOS. If an option takes an argument
- then a colon must immediately follow that option
- character in the options string to let
- getOption() know to look for the argument. The
- syntax for the option string is as follows:
-
- options string ::= {optch[:]}*
-
- Your read the syntax as: An options string is zero
- or more (the "*" indicates this) option characters
- any of which may be followed by a colon to indicate
- that the option has an argument.
-
-
- 2. GetOption() returns the current option
- character being processed along with any argument
- in the variable optArg. OptArg is valid only
- when an option requiring an argument is processed.
- If the argument is missing then optArg == 0. If
- the current option character being processed is
- unrecognized, i.e. not in the options string passed
- to CmdLn(), then getOption() returns '?' with
- the unrecognized character stored in optNot. This
- is the only time that optNot is valid!
- getOption() returns -1 when there are no more
- options to process. The variable, optCh,
- maintains a copy of the latest value returned by
- getOption().
-
-
- 3. When your program is invoked, getOption()
- recognizes clusters of command line options. A
- cluster is the switch character followed immediately
- by any number of option characters, no white space.
- The options clusters must preceed any other command
- line parameters since getOption() stops processing
- on the first parameter that is not a switch. This
- is the Unix convention. If you would like to be
- able to intersperse command line switches with other
- parameters on the command line then call
- lookForMoreOptions() to reenable getOption()
- to continue looking for more options. If an option
- takes an argument then the option's character must
- be the last option in the cluster with the argument
- immediately following or separated by white space.
- The argument must not have any white space, though
- it may contain the switch character.
-
- command line option cluster ::=
-
- {'/'|'-'}{[optch]*argch[whitespace]argument}|optch+
-
- Wow! That reads: a command line option cluster
- starts with the switch character ('/' or '-' in DOS)
- with one or more option characters (+ means one or
- more) or (| means or) any number of option
- characters, only the last of which is allowed to
- take an argument. The argument can be either tacked
- on to the end of the option cluster or stand off by
- itself. In either case, argument contains no white
- space! If a switch character appears in a cluster
- by itself or if two switch characters lead off a
- cluster then no more options are processed and the
- next parameter starts the non switched arguments.
- This allows the first non switched argument to start
- with the switch character, i.e. let the preceeding
- cluster be either a single switch character or lead
- off with two switch characters. The switch
- characters are defined in the static variable:
- switches. Switches is currently defined for MS DOS.
-
-
- 4. For example, if the options string contains
- "C:af:z" then 'C' and 'f' take arguments. A valid
- command line would be:
-
- cmd /afnew /zC cmdfile outfile
-
- with repeated calls to getOption() returning:
-
- 'a'
- 'f' with optArg == "new"
- 'z'
- 'C' with optArg == "cmdfile"
- -1 with Argi() == 4
-
- The variable, argi, is the index into the next
- unprocessed argv cell. You can use Argi() to
- initialize your index into the non-switched
- command line parameters.
-
-
- 5. Compile and run cmdlnd.cpp. Be sure you
- understand the demo code before using cmdln.cpp.
-
- */
-
- #include <string.h> /* strchr() */
- #include <cmdln.hpp>
-
- static char switches[] = "/-";
- /*
- Switches is initialized here for DOS switch
- characters. Change as necessary for your
- host OS shell.
- */
-
- void CmdLn::CmdLnReset(int argc, char *argv[],
- char *options)
- {
- this->argv = argv;
- this->options = options;
- opt = (char *) 0;
- this->argc = argc;
- optEnd = 0;
- optCh = optNot = '\0';
- optArg = (char *) 0;
- argi = 1;
- }
-
- int CmdLn::getOption(void)
- {
-
- char *lookup;
-
- optArg = (char *)0;
- if (optEnd) /* no more options allowed */
- return (optCh = 0);
- if (!opt || (*opt == '\0')) {
- if (argi >= argc) /* no more parameters */
- return (optEnd = optCh = -1);
- /* end of options */
- opt = argv[argi];
- /* next possible option cluster */
- if (!strchr(switches,*opt))
- /* Not an option cluster? */
- return (optEnd = optCh = -1);
- /* start non option parameters */
- argi++; /* next possible parameter */
- opt++; /* next possible option */
- if (!*opt || strchr(switches,*opt))
- /* Two switches or one by itself */
- return (optEnd = optCh = -1);
- /* means end of options */
- }
- if ((lookup = strchr(
- /* validate option character */
- options? options : "",
- optNot = *opt++))
- == (char *)0)
- return (optCh = '?');
- /* unknown option */
- if (lookup[1] == ':') {
- /* option takes argument */
- if (*opt != '\0')
- /* Is argument in this parameter? */
- optArg = opt;
- else if (argi < argc)
- /* Is argument in next parameter? */
- optArg = argv[argi++];
- opt = (char *) 0;
- /* no more options in this parameter */
- }
- return (optCh = *lookup);
- /* return option */
- }
-
- void CmdLn::nextCluster(void) { opt = (char *) 0; }
- /* start processing in next cluster */
-
- void CmdLn::lookForMoreOptions(void)
- {
- if (optEnd) {
- opt = (char *) 0;
- argi++;
- optEnd = 0;
- }
- }
-