diff --git a/docs/index.html b/docs/index.html
index 14967f8..fccc834 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -21,7 +21,17 @@
+
+
+
tclap -- Templatized C++ Command Line Parser Library
+ |
+
+
+ |
+
+
This is a small library that provides a simple interface for defining
and accessing command line arguments. It was intially inspired by the
user friendly CLAP
@@ -34,9 +44,10 @@ my interpretation of what most argument situations are.
- See the manual for how things work.
- See the API documentation for detailed
-implementation.
-- Download the source here.
-
- Send any feeback, comments, patches, etc. to Mike.
+implementation information.
+- Visit the Sourceforge project page.
+
- Download the source here.
+- Send any feeback, comments, patches, etc. to mes (_at_) aescon (_dot_) com.
Happy coding!
diff --git a/docs/manual.html b/docs/manual.html
index ac58d5a..f7f165f 100644
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -21,19 +21,28 @@
-C++ Command Line Parser Examples
+
+Templatized C++ Command Line Parser Examples
+ |
+
+
+ |
+
Basic usage
There are a few key classes to be aware of. The first is the CmdLine
-or command line class. This is the class that parses that command line
+or command line class. This is the class that parses the command line
passed to it according to the arguments that it contains. Arguments are
separate objects that are added to CmdLine object one at a time. There
-are three types of arguments, ValueArg, SwitchArg and
-MultiArg. Once the arguments are added to the command line object,
+are five types of arguments, ValueArg, UnlabeledValueArg,
+SwitchArg, MultiArg and UnlabeledMultiArg.
+Once the arguments are added to the command line object,
the command line is parsed which assigns the data on the command line to
-the specific arguments. The values are accessed by calls to the getValue()
-methods of the argument objects.
+the specific argument objects. The values are accessed by calls to
+the getValue() methods of the argument objects.
-Here is a simple example ...
+Here is a simple example ...
#include < string >
@@ -50,7 +59,8 @@ int main(int argc, char** argv)
CmdLine cmd(argv[0], "Command description message", "0.9");
// Define a value argument and add it to the command line.
- ValueArg nameArg("n","name","Name to print",true,"homer");
+ ValueArg < string > nameArg("n","name","Name to print",true,"homer",
+ "nameString");
cmd.add( nameArg );
// Define a switch and add it to the command line.
@@ -99,23 +109,34 @@ PARSE ERROR: for argument: undefined
USAGE:
- tester [-u] -n name [-v] [-h]
+ test1 [-u] -n < nameString > [--] [-v] [-h]
Where:
- [-u] = Print in upper case
- -n name = Name to print
- [-v] = displays version information and exits
- [-h] = displays usage information and exits
+ -u, --upperCase
+ Print in upper case
+
+ -n < nameString >, --name < nameString >
+ (required) (value required) Name to print
+
+ --, --ignore_rest
+ Ignores the rest of the labeled arguments following this flag.
+
+ -v, --version
+ Displays version information and exits.
+
+ -h, --help
+ Displays usage information and exits.
Command description message
+
This example shows a number of different properties of the library...
- Arguments can appear in any order (...mostly, more on this later).
-- The version and help arguments are specified automatically.
+- The version, help and -- arguments are specified automatically.
- If a required argument isn't provided, the program exits and displays
the USAGE, along with an error message.
@@ -123,49 +144,114 @@ the USAGE, along with an error message.
Arguments, whatever their type, have a few common basic properties. First
is the flag or the character preceeded by a dash(-) that signals the beginning
of the argument. Arguments also have names, which can, if desired also be
-used as a flag on the command line, this time preceeded by two dashes (--).
-Next is the description of the argument. This is displayed in the help/usage
+used as a flag on the command line, this time preceeded by two dashes (--)
+[like the familiar getopt_long()].
+Next is the description of the argument. This is a short description of
+the argument displayed in the help/usage
message when needed. The boolean value in ValueArgs indicates
whether the argument is required to be present (SwitchArgs can't
-be required, as that would defeat the purpose). Finally, is the default
-value the arg should assume if the arg isn't required or entered on the
-command line.
+be required, as that would defeat the purpose). Next, the default
+value the arg should assume if the arg isn't required or entered on the
+command line. Last, for ValueArgs is a short description of the type
+that the argument expects (yes its an ugly
+hack).
+
SwitchArgs are what the name implies, simple on/off, boolean switches.
Use SwitchArgs anytime you want to turn some sort of system property
-on or off.
+on or off. Note that multiple SwitchArgs can be combined into a single
+argument on the command line. If you have switches -a, -b and -c it is
+valid to do either:
+
+
+ % command -a -b -c
+
+
+or
+
+
+ % command -abc
+
+
+This is to make this library more in line with the POSIX and GNU standards (as
+I understand them).
+
ValueArgs are arguments that read a value of some type from the
-command line. Note that the order of arguments (so far) don't matter. Any
-argument not matching an *Arg added to the command line will cause
-an exception to be thrown.
+command line. Note that the order of arguments on the command line(so far)
+doesn't matter. Any
+argument not matching an Arg added to the command line will cause
+an exception to be thrown
+(for the most part, with some
+exceptions).
-Note in the output of the USAGE above, that there are two arguments that
+Note in the output of the USAGE above, that there are three arguments that
were not explicitly specified by the user in the code.
These are the help
-and version SwitchArgs. Using either the -h or
+and version and -- SwitchArgs. Using either the
+-h or
--help flag will cause the USAGE message to be displayed
and -v or --version will cause
-any version information to be displayed. These switches are included
+any version information to be displayed and -- or --ignore_rest
+will cause the remaining labeled arguments to be ingored.
+These switches are included
automatically on every command line. Currently there is no way to turn this
-off, but thats kind of the point. More later on how we get this to work.
+off, but then, thats kind of the point.
+More later on how we get this to work.
Complications
Naturally, what we have seen to this point doesn't satisfy all of our needs.
+I tried passing multiple values on the command line with the same flag and it didn't work...
+Correct. You can neither specify mulitple ValueArgs or
+SwitchArgs with the same flag in the code nor on the command line.
+Exceptions will occur in either case. For SwitchArgs it simply doesn't
+make sense to allow a particular flag to be turned on or off repeatedly on
+the command
+line. All you should ever need is to set your state once by specifying
+the flag or not (yeah but...).
+
+However, there are situations where you might want
+multiple values for the same flag to be specified. Imagine a compiler that
+allows you to specify multiple directories to search for libraries...
+
+
+ % fooCompiler -L /dir/num1 -L /dir/num2 file.foo
+
+
+In situations like this, you will want to use a MultiArg. A
+MultiArg is essentially a ValueArg that appends any value
+that it matches and parses onto a vector of values. When the getValue()
+method id called, a vector of values, instead of a single value is returned.
+A MultiArg is declared much like a ValueArg:
+
+
+ ...
+
+ MultiArg < int > itest("i", "intTest", "multi int test", false,"int" );
+ cmd.add( itest );
+
+ ...
+
+
+Note that MultiArgs can be added to the CmdLine in any
+order (unlike UnlabeledMultiArgs).
But I don't like labelling all of my arguments...
-To this point all of our arguments have had labels indentifying them, but
+To this point all of our arguments have had labels (flags) indentifying them
+on the command line, but
there are some situations where flags are burdensome and not worth the effort.
-One example might be if you want to implement a magical command, we'll call
+One example might be if you want to implement a magical command we'll call
copy. All copy does is copy the file specified in the first
-argument to file specified in the second argument. We can do this using
-ValueArgs that don't have a flag specified, which tells the
+argument to the file specified in the second argument. We can do this using
+UnlabeledValueArgs which are pretty much just ValueArgs without
+the flag specified, which tells the
CmdLine object to treat them accordingly. The code would look like
this:
...
- ValueArg nolabel( "name", "unlabeled test", 3.14 );
+ UnlabeledValueArg < float > nolabel( "name", "unlabeled test", 3.14,
+ "nameString" );
cmd.add( nolabel );
...
@@ -173,15 +259,19 @@ this:
Everything else is handled identically to what is seen above. The only
difference to be aware of, and this is important: the order that
-unlabeled ValueArgs are added to the CmdLine is the order that
+UnlabeledValueArgs are added to the CmdLine is the order that
they will be parsed!!!! This is not the case for normal
SwitchArgs and ValueArgs. What happens internally is the
-first argument that the CmdLine doesn't recognize is assumed to be the
-first unlabeled ValueArg and parses it as such. Note that you
-are allowed to intersperse labeled args in between unlabeled args (either
-on the command line or in the declaration), but the unlabeled args will
-still be parsed in the order they are added. Just remember that order
-is important.
+first argument that the CmdLine doesn't recognize is assumed to be the
+first UnlabeledValueArg and parses it as such. Note that you
+are allowed to intersperse labeled args (SwitchArgs and ValueArgs) in
+between UnlabeledValueArgs (either
+on the command line or in the declaration), but the UnlabeledValueArgs
+will still be parsed in the order they are added. Just remember that order
+is important for unlabeled arguments.
+
+
+
But I want an arbitrary number of arguments to be accepted...
Don't worry, we've got you covered. Say you want a strange command that
searches each file specified for a given string (lets call it grep),
@@ -201,13 +291,14 @@ like:
To handle situations where multiple, unlabled arguments are needed, we
-provide the MultiArg. MultiArgs are declared much like
+provide the UnlabeledMultiArg. UnlabeledMultiArgs are declared
+much like
everything else, but with only a description of the arguments. By default,
-if a MultiArg is specified, then at least one is required to be
-present or an exception will be thrown. The most important thing to remember
-is, that like unlabeled ValueArgs order matters, in fact: a
-MultiArg must be the last argument added to the CmdLine!. Here is
-what it looks like:
+if an UnlabeledMultiArg is specified, then at least one is required
+to be present or an exception will be thrown. The most important thing to
+remember is, that like UnlabeledValueArgs: order matters! In fact, an
+UnlabeledMultiArg must be the last argument added to the CmdLine!.
+Here is what a declaration looks like:
...
@@ -215,21 +306,24 @@ what it looks like:
//
// MultiArg must be the LAST argument added!
//
- MultiArg multi("file names");
+ UnlabeledMultiArg < string > multi("file names");
cmd.add( multi );
cmd.parse(argc, argv);
- vector fileNames = multi.getValue();
+ vector < string > fileNames = multi.getValue();
...
-You must only ever specify one (1) MultiArg. One MultiArg will
-read every unlabeled Arg that wasn't already processed by a ValueArg
-into a vector of type T. When you call the getValue() method of the
-argument, a vector will be returned. If you can imagine a
+You must only ever specify one (1) UnlabeledMultiArg.
+One UnlabeledMultiArg will
+read every unlabeled Arg that wasn't already processed by a
+UnlabeledValueArg
+into a vector of type T. When you call the getValue() method
+of the argument, a vector will be returned. If you can imagine a
situation where there will be multiple args of multiple types (stings, ints,
-floats, etc.) then just declare the MultiArg as type string
+floats, etc.) then just declare the UnlabeledMultiArg as type
+string
and parse the different values yourself.
@@ -239,29 +333,27 @@ to provide special handling for default arguments. Nothing that Visitors
do couldn't be accomplished by the user after the command line has been parsed.
If you're still interested, keep reading...
-Some of you may be wondering how we get the --help and --version
+Some of you may be wondering how we get the --help, --version
+and --
arguments to do their thing without mucking up the CmdLine code
with lots of if statements and type checking. This is accomplished
by using a variation on the Visitor Pattern. Actually, it may not be a Visitor
Pattern at all, but thats what inspired me.
If we want some argument to do some sort of special handling, besides simply
-parsing a value, then we add a Visitor pointer to the *Arg.
+parsing a value, then we add a Visitor pointer to the Arg.
More specifically, we add a subclass of the Visitor class.
Once the argument has been successfully parsed, the Visitor for
that argument is called.
Any data that needs to be operated on is declared in the Visitor
constructor and then operated on in the visit() method. A
-Visitor is added to an *Arg as the last argument in its
+Visitor is added to an Arg as the last argument in its
declaration. This may sound complicated, but its pretty straightforward.
Lets see an example.
-
Say you want to add an --authors flag to a program that prints the
names of the authors when present. First subclass Visitor:
-
-
-
+
#include "Visitor.h"
#include < string >
@@ -284,7 +376,7 @@ pointer as follows:
...
- SwitchArg author("-a","author","Prints author name", false,
+ SwitchArg author("a","author","Prints author name", false,
new AuthorVisitor("Homer J. Simpson");
cmd.add( author );
@@ -294,7 +386,39 @@ pointer as follows:
Now, any time the -a or --author flag is specified, the
program will print the author name, Homer J. Simpson and exit without
-processing any further.
+processing any further (as specified in the visit() method.
+
+Exceptions
+Like all good rules, there are many exceptions....
+Ignoring arguments...
+The -- flag is automatically included in the CmdLine. As (almost)
+per POSIX and GNU standards, any argument specified after the -- flag
+is ignored. Almost because if an UnlabeledValueArg that has
+not been set or an UnlabeledMultiArg has been specified, by default
+we will assign any arguments beyond the -- to the those arguments
+as per the rules above. This is primarily useful if you want to pass in
+arguments with a dash as the first character of the argument. It should be
+noted that even if the -- flag is passed on the command line,
+the CmdLine will still test to make sure all of the required
+arguments are present.
+
+Of course, this isn't how POSIX/GNU handle things, they explicitly
+ignore arguments after the --. To accomodate this, we can make both
+UnlabeledValueArgs and UnlabeledMultiArgs ignoreable in
+their constructors. See
+the API Documentation for details.
+Multiple Identical Switches
+If you absolutely must allow for multiple, identical switches to be allowed,
+don't use a SwitchArg, instead use a MultiArg of type
+bool. This means you'll need to specify
+a 1 or 0 on the command line with the switch (as values are required), but
+this should allow you to turn your favorite switch on and off to your hearts
+content.
+
+Type Descriptions
+Ideally this library would use RTTI to return a human readable name of the
+type declared for a particular argument. Unfortunately, at least for g++,
+the names returned aren't particularly useful.
More Information
For more information, look at
the API Documentation