mirror of
https://github.com/cuberite/TCLAP.git
synced 2025-08-04 10:16:41 -04:00
712 lines
40 KiB
HTML
712 lines
40 KiB
HTML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Templatized C++ Command Line Parser Manual</title><link rel="stylesheet" href="style.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.61.3" /></head><body><div class="book" lang="en" xml:lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="id2868300"></a>Templatized C++ Command Line Parser Manual</h1></div><div><div class="author"><h3 class="author"><span class="firstname">Michael</span> <span class="othername">E</span> <span class="surname">Smoot</span></h3></div></div><div><p class="copyright">Copyright © 2003,2004 Michael E. Smoot</p></div></div><div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="#id2868084">Basic Usage</a></dt><dd><dl><dt><a href="#ARG_PROPERTIES">Argument Properties</a></dt><dt><a href="#ARGUMENT_TYPES">Types of Arguments</a></dt><dt><a href="#COMPILING">Compiling</a></dt></dl></dd><dt>2. <a href="#COMPLICATIONS">Complications</a></dt><dd><dl><dt><a href="#COMBINE_SWITCHES">I want to combine multiple switches into one argument...</a></dt><dt><a href="#MULTI_ARG">I tried passing multiple values on the command line with the
|
||
same flag and it didn't work...</a></dt><dt><a href="#UNLABELED_VALUE_ARG">I don't like labelling all of my arguments...</a></dt><dt><a href="#UNLABELED_MULTI_ARG">I want an arbitrary number of unlabeled arguments to be accepted...</a></dt><dt><a href="#XOR">I want one argument or the other, but not both...</a></dt><dt><a href="#NO_FLAG">I have more arguments than single flags make sense for...</a></dt><dt><a href="#ALLOWED_LIST">I want to constrain the values allowed for a particular
|
||
argument...</a></dt><dt><a href="#ARG_ADD_CMDLINE">I want the Args to add themselves to the CmdLine...</a></dt><dt><a href="#CHANGE_OUTPUT">I want different output than what is provided...</a></dt></dl></dd><dt>3. <a href="#EXCEPTIONS">Exceptions to the Rules</a></dt><dd><dl><dt><a href="#IGNORE_ARGS">Ignoring arguments</a></dt><dt><a href="#COMBINED_SWITCHES">Multiple Identical Switches</a></dt><dt><a href="#DESCRIPTION_EXCEPTIONS">Type Descriptions</a></dt></dl></dd><dt>4. <a href="#VISITORS">Visitors</a></dt><dt>5. <a href="#MORE_INFO">More Information</a></dt></dl></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id2868084"></a>Chapter 1. Basic Usage</h2></div></div><div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#ARG_PROPERTIES">Argument Properties</a></dt><dt><a href="#ARGUMENT_TYPES">Types of Arguments</a></dt><dt><a href="#COMPILING">Compiling</a></dt></dl></div><p>
|
||
<span class="emphasis"><em>TCLAP</em></span> has a few key classes to be aware of.
|
||
The first is the
|
||
<tt class="classname">CmdLine</tt> (command line) class. This class parses
|
||
the command line passed to it according to the arguments that it
|
||
contains. Arguments are separate objects that are added to the
|
||
<tt class="classname">CmdLine</tt> object one at a time. The five
|
||
argument classes are: <tt class="classname">ValueArg</tt>,
|
||
<tt class="classname">UnlabeledValueArg</tt>,
|
||
<tt class="classname">SwitchArg</tt>, <tt class="classname">MultiArg</tt> and
|
||
<tt class="classname">UnlabeledMultiArg</tt>.
|
||
These classes are templatized, which means they can be defined to parse
|
||
a value of any <a href="#FOOTNOTES"> type**</a>. Once you add the
|
||
arguments to the <tt class="classname">CmdLine</tt> object, it parses the
|
||
command line
|
||
and assigns the data it finds to the specific argument objects it
|
||
contains. Your program accesses the values parsed by
|
||
calls to the <tt class="methodname">getValue()</tt> methods of the
|
||
argument objects.
|
||
</p><p>
|
||
Here is a simple <a href="test1.cpp" target="_top"> example</a> ...
|
||
|
||
</p><pre class="programlisting">
|
||
#include <string>
|
||
#include <iostream>
|
||
#include <algorithm>
|
||
#include <tclap/CmdLine.h>
|
||
|
||
using namespace TCLAP;
|
||
using namespace std;
|
||
|
||
int main(int argc, char** argv)
|
||
{
|
||
// Wrap everything in a try block. Do this every time,
|
||
// because exceptions will be thrown for problems.
|
||
try {
|
||
|
||
// Define the command line object.
|
||
CmdLine cmd("Command description message", ' ', "0.9");
|
||
|
||
// Define a value argument and add it to the command line.
|
||
ValueArg<string> nameArg("n","name","Name to print",true,"homer","string");
|
||
cmd.add( nameArg );
|
||
|
||
// Define a switch and add it to the command line.
|
||
SwitchArg reverseSwitch("r","reverse","Print name backwards", false);
|
||
cmd.add( reverseSwitch );
|
||
|
||
// Parse the args.
|
||
cmd.parse( argc, argv );
|
||
|
||
// Get the value parsed by each arg.
|
||
string name = nameArg.getValue();
|
||
bool reverseName = reverseSwitch.getValue();
|
||
|
||
// Do what you intend too...
|
||
if ( reverseName )
|
||
{
|
||
reverse(name.begin(),name.end());
|
||
cout << "My name (spelled backwards) is: " << name << endl;
|
||
}
|
||
else
|
||
cout << "My name is: " << name << endl;
|
||
|
||
|
||
} catch (ArgException &e) // catch any exceptions
|
||
{ cerr << "error: " << e.error() << " for arg " << e.argId() << endl; }
|
||
}
|
||
</pre><p>
|
||
|
||
The output should look like:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
% test1 -n mike
|
||
My name is: mike
|
||
|
||
% test1 -n mike -r
|
||
My name (spelled backwards) is: ekim
|
||
|
||
% test1 -r -n mike
|
||
My name (spelled backwards) is: ekim
|
||
|
||
% test1 -r
|
||
PARSE ERROR:
|
||
One or more required arguments missing!
|
||
|
||
Brief USAGE:
|
||
test1 [-r] -n <string> [--] [-v] [-h]
|
||
|
||
For complete USAGE and HELP type:
|
||
test1 --help
|
||
|
||
|
||
% test1 --help
|
||
|
||
USAGE:
|
||
|
||
test1 [-r] -n <string> [--] [-v] [-h]
|
||
|
||
|
||
Where:
|
||
|
||
-r, --reverse
|
||
Print name backwards
|
||
|
||
-n <string> --name <string>
|
||
(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
|
||
|
||
</pre><p>
|
||
</p><p>
|
||
This example shows a number of different properties of the
|
||
library...
|
||
</p><div class="itemizedlist"><ul type="disc"><li>Arguments can appear in any order (...mostly,
|
||
<a href="#COMPLICATIONS" title="Chapter 2. Complications"> more</a> on this later).</li><li>The <i class="parameter"><tt>help</tt></i>, <i class="parameter"><tt>version</tt></i>
|
||
and <i class="parameter"><tt>--</tt></i><tt class="classname">SwitchArg</tt>s
|
||
are specified automatically. Using either the <i class="parameter"><tt>-h</tt></i> or
|
||
<i class="parameter"><tt>--help</tt></i> flag will cause the USAGE message to be displayed,
|
||
<i class="parameter"><tt>-v</tt></i> or <i class="parameter"><tt>--version</tt></i> will cause
|
||
any version information to
|
||
be displayed, and <i class="parameter"><tt>--</tt></i> or
|
||
<i class="parameter"><tt>--ignore_rest</tt></i> will cause the
|
||
remaining labeled arguments to be ingored. These switches are
|
||
included automatically on every command line and there is no way to
|
||
turn this off (unless you change <tt class="filename">CmdLine.h</tt> yourself).
|
||
More <a href="#VISITORS" title="Chapter 4. Visitors"> later</a> on how we get this to
|
||
work.</li><li>If there is an error parsing the command line (e.g. a required
|
||
argument isn't provided), the program exits and displays a brief
|
||
USAGE and an error message.</li><li>The program name is assumed to always be argv[0], so it isn't
|
||
specified directly.</li><li>A delimiter character can be specified. This means that if you
|
||
prefer arguments of the style <i class="parameter"><tt>-s=asdf</tt></i> instead of
|
||
<i class="parameter"><tt>-s asdf</tt></i>, you can do so.</li><li><span class="emphasis"><em>Always wrap everything in a try block that catches
|
||
ArgExceptions!</em></span> Any problems found in constructing the
|
||
<tt class="classname">CmdLine</tt> or the <tt class="classname">Arg</tt>s will
|
||
throw an <tt class="classname">ArgException</tt>.</li></ul></div><p>
|
||
</p><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="ARG_PROPERTIES"></a>Argument Properties</h2></div></div><div></div></div><p>
|
||
Arguments, whatever their type, have a few common basic properties.
|
||
These properties are set in the constructors of the arguments.
|
||
</p><div class="itemizedlist"><ul type="disc"><li>First is the flag or the character preceeded by a dash(-) that
|
||
signals the beginning of the argument on the command line.</li><li>Arguments also have names, which can, if desired also be used
|
||
as a flag on the command line, this time preceeded by two dashes
|
||
(--) [like the familiar <tt class="function">getopt_long()</tt>].</li><li>Next is the description of the argument. This is a short
|
||
description of the argument displayed in the help/usage message
|
||
when needed.</li><li>The boolean value in <tt class="classname">ValueArg</tt>s
|
||
indicates whether the
|
||
argument is required to be present (<tt class="classname">SwitchArg</tt>s
|
||
can't be required, as that would defeat the purpose).</li><li>Next, the default value the arg should assume if the arg isn't
|
||
required or entered on the command line.</li><li>Last, for <tt class="classname">ValueArg</tt>s is a short
|
||
description of the type
|
||
that the argument expects (yes its an ugly
|
||
<a href="#DESCRIPTION_EXCEPTIONS" title="Type Descriptions"> hack</a>).
|
||
Note that the order of
|
||
arguments on the command line (so far) doesn't matter. Any argument
|
||
not matching an <tt class="classname">Arg</tt> added to the command
|
||
line will cause an
|
||
exception to be thrown (<a href="#COMPLICATIONS" title="Chapter 2. Complications"> for the
|
||
most part</a>, with some <a href="#EXCEPTIONS" title="Chapter 3. Exceptions to the Rules"> exceptions</a>).
|
||
</li></ul></div><p>
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="ARGUMENT_TYPES"></a>Types of Arguments</h2></div></div><div></div></div><p>
|
||
There are two primary types of arguments:
|
||
</p><p>
|
||
</p><div class="itemizedlist"><ul type="disc"><li><tt class="classname">SwitchArg</tt>s are what the name implies:
|
||
simple, on/off, boolean switches. Use <tt class="classname">SwitchArg</tt>s
|
||
anytime you want to turn
|
||
some sort of system property on or off. <tt class="classname">SwitchArg</tt>s
|
||
don't parse a value. They return <tt class="constant">TRUE</tt> or
|
||
<tt class="constant">FALSE</tt>, depending on whether the switch has been found
|
||
on the command line and what the default value was defined as.</li><li><tt class="classname">ValueArg</tt>s are arguments that read a
|
||
value of some type
|
||
from the command line. Any time you need a file name, a number,
|
||
etc. use a <tt class="classname">ValueArg</tt> or one of its variants.
|
||
<a href="#UNLABELED_VALUE_ARG" title="I don't like labelling all of my arguments..."> UnlabedValueArg</a>,
|
||
<a href="#MULTI_ARG" title="I tried passing multiple values on the command line with the same flag and it didn't work..."> MultiArg</a>, and
|
||
<a href="#UNLABELED_MULTI_ARG" title="I want an arbitrary number of unlabeled arguments to be accepted..."> UnlabeledMultiArg</a> are
|
||
special cases of <tt class="classname">ValueArg</tt>s and are described below. All
|
||
<tt class="classname">ValueArg</tt>s are
|
||
<a href="#FOOTNOTES"> templatized**</a> and will attempt to parse
|
||
the string its flag matches on the command line as the type it is
|
||
specified as. <tt class="classname">ValueArg<int></tt>
|
||
will attempt to parse an
|
||
int, <tt class="classname">ValueArg<float></tt> will attempt to
|
||
parse a float, etc. If <tt class="methodname">operator>></tt>
|
||
for the specified type doesn't
|
||
recognize the string on the command line as its defined type, then
|
||
an exception will be thrown.</li></ul></div><p>
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="COMPILING"></a>Compiling</h2></div></div><div></div></div><p>
|
||
<span class="emphasis"><em>TCLAP</em></span> is implemented entirely in header files
|
||
which means you only need to include CmdLine.h to use the library.
|
||
</p><pre class="programlisting">
|
||
#include <tclap/CmdLine.h>
|
||
</pre><p>
|
||
You'll need to make sure that your compiler can see the header
|
||
files. If you do the usual "make install" then your compiler should
|
||
see the files by default. Alternatively, you can use the -I
|
||
complier argument to specify the exact location of the libraries.
|
||
</p><pre class="programlisting">
|
||
c++ -o my_program -I /some/place/tclap-1.X/include my_program.cpp
|
||
</pre><p>
|
||
Where /some/place/tclap-1.X is the place you have unpacked the
|
||
distribution.
|
||
</p><p>
|
||
Finally, if you want to include <span class="emphasis"><em>TCLAP</em></span> as part of
|
||
your software
|
||
(which is perfectly OK, even encouraged) then simply copy the
|
||
contents of /some/place/tclap-1.X/include (the tclap directory and
|
||
all of the header files it contains) into your include
|
||
directory.
|
||
</p><p>
|
||
<span class="emphasis"><em>TCLAP</em></span> was developed on Linux and MacOSX systems.
|
||
It is also known
|
||
to work on Windows, Sun and Alpha platforms. We've made every
|
||
effort to keep the library compliant with the ANSI C++ standard so
|
||
if your compiler meets the standard, then this library should work
|
||
for you. Please let us know if this is not the case!
|
||
</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2853438"></a>Windows Note</h3></div></div><div></div></div><p>
|
||
As we understand things, Visual C++ does not have the file
|
||
<tt class="filename">config.h</tt> which is used to make platform
|
||
specific definitions. In this situation, we assume that you
|
||
have access to <tt class="classname">sstream</tt>. Our understanding is that
|
||
this should not be a problem for VC++ 7.x. However, if this
|
||
is not the case and you need to use <tt class="classname">strstream</tt>,
|
||
then simply tell your compiler to define the variable
|
||
<tt class="constant">HAVE_STRSTREAM</tt> and undefine
|
||
<tt class="constant">HAVE_SSTREAM</tt> That
|
||
<span class="emphasis"><em>should</em></span> work. We think. Alternatively, just edit
|
||
the files <tt class="filename">ValueArg.h</tt> and <tt class="filename">MultiArg.h</tt>.
|
||
</p></div><p>
|
||
</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2853498"></a>Random Note</h3></div></div><div></div></div><p>
|
||
If your compiler doesn't support the <tt class="methodname">using</tt> syntax used
|
||
in <tt class="classname">UnlabeledValueArg</tt> and
|
||
<tt class="classname">UnlabeledMultiArg</tt> to support two stage name lookup,
|
||
then you have two options. Either comment out the statements if you don't
|
||
need two stage name lookup, or do a bunch of search and replace and use
|
||
the <tt class="methodname">this</tt> pointer syntax: e.g.
|
||
<tt class="methodname">this->_ignoreable</tt> instead
|
||
of just <tt class="methodname">_ignorable</tt> (do this for each variable
|
||
or method referenced by <tt class="methodname">using</tt>).
|
||
</p></div><p>
|
||
</p></div></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="COMPLICATIONS"></a>Chapter 2. Complications</h2></div></div><div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#COMBINE_SWITCHES">I want to combine multiple switches into one argument...</a></dt><dt><a href="#MULTI_ARG">I tried passing multiple values on the command line with the
|
||
same flag and it didn't work...</a></dt><dt><a href="#UNLABELED_VALUE_ARG">I don't like labelling all of my arguments...</a></dt><dt><a href="#UNLABELED_MULTI_ARG">I want an arbitrary number of unlabeled arguments to be accepted...</a></dt><dt><a href="#XOR">I want one argument or the other, but not both...</a></dt><dt><a href="#NO_FLAG">I have more arguments than single flags make sense for...</a></dt><dt><a href="#ALLOWED_LIST">I want to constrain the values allowed for a particular
|
||
argument...</a></dt><dt><a href="#ARG_ADD_CMDLINE">I want the Args to add themselves to the CmdLine...</a></dt><dt><a href="#CHANGE_OUTPUT">I want different output than what is provided...</a></dt></dl></div><p>
|
||
Naturally, what we have seen to this point doesn't satisfy all of
|
||
our needs.
|
||
</p><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="COMBINE_SWITCHES"></a>I want to combine multiple switches into one argument...</h2></div></div><div></div></div><p>
|
||
Multiple <tt class="classname">SwitchArg</tt>s 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:
|
||
|
||
</p><pre class="programlisting">
|
||
% command -a -b -c
|
||
</pre><p>
|
||
|
||
<span class="emphasis"><em>or</em></span>
|
||
|
||
</p><pre class="programlisting">
|
||
% command -abc
|
||
</pre><p>
|
||
|
||
<span class="emphasis"><em>or</em></span>
|
||
|
||
</p><pre class="programlisting">
|
||
% command -ba -c
|
||
</pre><p>
|
||
|
||
This is to make this library more in line with the POSIX and GNU
|
||
standards (as I understand them).
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="MULTI_ARG"></a>I tried passing multiple values on the command line with the
|
||
same flag and it didn't work...</h2></div></div><div></div></div><p>
|
||
Correct. You can neither specify mulitple <tt class="classname">ValueArg</tt>s
|
||
or <tt class="classname">SwitchArg</tt>s with the same flag in the code nor
|
||
on the command line. Exceptions will occur in either case.
|
||
For <tt class="classname">SwitchArg</tt>s
|
||
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 <span class="emphasis"><em>once</em></span> by specifying
|
||
the flag or not (<a href="#EXCEPTIONS" title="Chapter 3. Exceptions to the Rules"> yeah but...</a>).
|
||
</p><p>
|
||
However, there <span class="emphasis"><em>are</em></span> 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...
|
||
</p><pre class="programlisting">
|
||
% fooCompiler -L /dir/num1 -L /dir/num2 file.foo
|
||
</pre><p>
|
||
In situations like this, you will want to use a
|
||
<tt class="classname">MultiArg</tt>. A
|
||
<tt class="classname">MultiArg</tt> is essentially a
|
||
<tt class="classname">ValueArg</tt> that appends any
|
||
value that it matches and parses onto a vector of values. When the
|
||
<tt class="methodname">getValue()</tt> method is called, a vector of
|
||
values, instead of a single value is returned. A
|
||
<tt class="classname">MultiArg</tt> is declared much like
|
||
a <tt class="classname">ValueArg</tt>:
|
||
|
||
|
||
</p><pre class="programlisting">
|
||
MultiArg<int> itest("i", "intTest", "multi int test", false,"int" );
|
||
cmd.add( itest );
|
||
</pre><p>
|
||
|
||
Note that <tt class="classname">MultiArg</tt>s can be added to the
|
||
<tt class="classname">CmdLine</tt> in any order (unlike
|
||
<a href="#UNLABELED_MULTI_ARG" title="I want an arbitrary number of unlabeled arguments to be accepted..."> UnlabeledMultiArg</a>).
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="UNLABELED_VALUE_ARG"></a>I don't like labelling all of my arguments...</h2></div></div><div></div></div><p>
|
||
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 <b class="command">copy</b>. All <b class="command">copy</b> does is
|
||
copy the file specified
|
||
in the first argument to the file specified in the second argument.
|
||
We can do this using <tt class="classname">UnlabeledValueArg</tt>s which are pretty
|
||
much just <tt class="classname">ValueArg</tt>s without the flag specified,
|
||
which tells
|
||
the <tt class="classname">CmdLine</tt> object to treat them accordingly.
|
||
The code would look like this:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
UnlabeledValueArg<float> nolabel( "name", "unlabeled test", 3.14,
|
||
"nameString" );
|
||
cmd.add( nolabel );
|
||
|
||
</pre><p>
|
||
|
||
Everything else is handled identically to what is seen above. The
|
||
only difference to be aware of, and this is important: <span class="emphasis"><em>the order
|
||
that UnlabeledValueArgs are added to the <tt class="classname">CmdLine</tt>
|
||
is the order that they will be parsed!!!!</em></span>
|
||
This is <span class="emphasis"><em>not</em></span> the case for normal
|
||
<tt class="classname">SwitchArg</tt>s and <tt class="classname">ValueArg</tt>s.
|
||
What happens internally is the first argument that the
|
||
<tt class="classname">CmdLine</tt> doesn't recognize is assumed to be
|
||
the first <tt class="classname">UnlabeledValueArg</tt> and
|
||
parses it as such. Note that you are allowed to intersperse labeled
|
||
args (SwitchArgs and ValueArgs) in between
|
||
<tt class="classname">UnlabeledValueArgs</tt> (either on the command line
|
||
or in the declaration), but the <tt class="classname">UnlabeledValueArgs</tt>
|
||
will still be parsed in the order they are added. Just remember that order is
|
||
important for unlabeled arguments.
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="UNLABELED_MULTI_ARG"></a>I want an arbitrary number of unlabeled arguments to be accepted...</h2></div></div><div></div></div><p>
|
||
Don't worry, we've got you covered. Say you want a strange command
|
||
that searches each file specified for a given string (let's call it
|
||
<b class="command">grep</b>), but you don't want to have to type in all of the file
|
||
names or write a script to do it for you. Say,
|
||
|
||
</p><pre class="programlisting">
|
||
% grep pattern *.txt
|
||
</pre><p>
|
||
|
||
First remember that the <span class="emphasis"><em>*</em></span> is handled by the shell and
|
||
expanded accordingly, so what the program <b class="command">grep</b> sees is
|
||
really something like:
|
||
|
||
</p><pre class="programlisting">
|
||
% grep pattern file1.txt file2.txt fileZ.txt
|
||
</pre><p>
|
||
|
||
To handle situations where multiple, unlabled arguments are needed,
|
||
we provide the <tt class="classname">UnlabeledMultiArg</tt>.
|
||
<tt class="classname">UnlabeledMultiArg</tt>s
|
||
are declared much like everything else, but with only a description
|
||
of the arguments. By default, if an <tt class="classname">UnlabeledMultiArg</tt>
|
||
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 <tt class="classname">UnlabeledValueArg</tt>s: order matters!
|
||
In fact, <span class="emphasis"><em>an UnlabeledMultiArg must be the last argument added to the
|
||
CmdLine!</em></span>. Here is what a declaration looks like:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
//
|
||
// UnlabeledMultiArg must be the LAST argument added!
|
||
//
|
||
UnlabeledMultiArg<string> multi("file names");
|
||
cmd.add( multi );
|
||
cmd.parse(argc, argv);
|
||
|
||
vector<string> fileNames = multi.getValue();
|
||
|
||
</pre><p>
|
||
|
||
You must only ever specify one (1) <tt class="classname">UnlabeledMultiArg</tt>.
|
||
One <tt class="classname">UnlabeledMultiArg</tt> will read every unlabeled
|
||
Arg that wasn't already processed by a
|
||
<tt class="classname">UnlabeledValueArg</tt> into a
|
||
<tt class="classname">vector</tt> of type T. Any
|
||
<tt class="classname">UnlabeledValueArg</tt> or other
|
||
<tt class="classname">UnlabeledMultiArg</tt> specified after the first
|
||
<tt class="classname">UnlabeledMultiArg</tt> will be ignored, and if
|
||
they are required,
|
||
exceptions will be thrown. When you call the
|
||
<tt class="methodname">getValue()</tt>
|
||
method of the <tt class="classname">UnlabeledValueArg</tt> argument,
|
||
a <tt class="classname">vector</tt>
|
||
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 <tt class="classname">UnlabeledMultiArg</tt> as type
|
||
<tt class="classname">string</tt> and parse the different values yourself or use
|
||
several <tt class="classname">UnlabeledValueArg</tt>s.
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="XOR"></a>I want one argument or the other, but not both...</h2></div></div><div></div></div><p>
|
||
Suppose you have a command that must read input from one of two
|
||
possible locations, either a local file or a URL. The command
|
||
<span class="emphasis"><em>must</em></span> read something, so <span class="emphasis"><em>one</em></span>
|
||
argument is required, but
|
||
not both, yet neither argument is strictly necessary by itself.
|
||
This is called "exclusive or" or "XOR". To accomodate this
|
||
situation, there is now an option to add two or more
|
||
<tt class="classname">Arg</tt>s to
|
||
a <tt class="classname">CmdLine</tt> that are exclusively or'd with one another:
|
||
<tt class="methodname">xorAdd()</tt>. This means that exactly one of the
|
||
<tt class="classname">Arg</tt>s must be set and no more.
|
||
</p><p>
|
||
<tt class="methodname">xorAdd()</tt> comes in two flavors, either
|
||
<tt class="methodname">xorAdd(Arg& a, Arg& b)</tt>
|
||
to add just two <tt class="classname">Arg</tt>s to be xor'd and
|
||
<tt class="methodname">xorAdd( vector<Arg*> xorList )</tt>
|
||
to add more than two <tt class="classname">Arg</tt>s.
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
|
||
ValueArg<string> fileArg("f","file","File name to read",true,"homer",
|
||
"filename");
|
||
ValueArg<string> urlArg("u","url","URL to load",true,
|
||
"http://example.com", "URL");
|
||
|
||
cmd.xorAdd( fileArg, urlArg );
|
||
cmd.parse(argc, argv);
|
||
|
||
</pre><p>
|
||
|
||
Once one <tt class="classname">Arg</tt> in the xor list is matched on the
|
||
<tt class="classname">CmdLine</tt> then the others in the xor list will be
|
||
marked as set. The question then, is how to determine which of the
|
||
<tt class="classname">Arg</tt>s has been set? This is accomplished by calling the
|
||
isSet() method for each <tt class="classname">Arg</tt>. If the
|
||
<tt class="classname">Arg</tt> has been
|
||
matched on the command line, the <tt class="methodname">isSet()</tt> will return
|
||
<tt class="constant">TRUE</tt>, whereas if the <tt class="classname">Arg</tt>
|
||
has been set as a result of matching the other <tt class="classname">Arg</tt>
|
||
that was xor'd <tt class="methodname">isSet()</tt> will
|
||
return <tt class="constant">FALSE</tt>.
|
||
(Of course, if the <tt class="classname">Arg</tt> was not xor'd and
|
||
wasn't matched, it will also return <tt class="constant">FALSE</tt>.)
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
if ( fileArg.isSet() )
|
||
readFile( fileArg.getValue() );
|
||
else if ( urlArg.isSet() )
|
||
readURL( urlArg.getValue() );
|
||
else
|
||
// Should never get here because TCLAP will note that one of the
|
||
// required args above has not been set.
|
||
throw("Very bad things...");
|
||
|
||
</pre><p>
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="NO_FLAG"></a>I have more arguments than single flags make sense for...</h2></div></div><div></div></div><p>
|
||
Some commands have so many options that single flags no longer map
|
||
sensibly to the available options. In this case, it is desirable to
|
||
specify <tt class="classname">Arg</tt>s using only long options. This one is easy to
|
||
accomplish, just make the flag value blank in the <tt class="classname">Arg</tt>
|
||
constructor. This will tell the <tt class="classname">Arg</tt> that only the long
|
||
option should be matched and will force users to specify the long
|
||
option on the command line. The help output is updated accordingly.
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
ValueArg<string> fileArg("","file","File name",true,"homer","filename");
|
||
|
||
SwitchArg caseSwitch("","upperCase","Print in upper case",false);
|
||
|
||
</pre><p>
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="ALLOWED_LIST"></a>I want to constrain the values allowed for a particular
|
||
argument...</h2></div></div><div></div></div><p>
|
||
There are now constructors for all of the <tt class="classname">Arg</tt>s
|
||
that parse values that allow a list of values to be specified for that
|
||
particular <tt class="classname">Arg</tt>. When the value for the
|
||
<tt class="classname">Arg</tt> is parsed,
|
||
it is checked against the list of values specified in the
|
||
constructor. If the value is in the list then it is accepted. If
|
||
not, then an exception is thrown. Here is a simple example:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
vector<string> allowed;
|
||
allowed.push_back("homer");
|
||
allowed.push_back("marge");
|
||
allowed.push_back("bart");
|
||
allowed.push_back("lisa");
|
||
allowed.push_back("maggie");
|
||
|
||
ValueArg<string> nameArg("n","name","Name to print",true,"homer",allowed);
|
||
cmd.add( nameArg );
|
||
|
||
</pre><p>
|
||
|
||
Instead of a type description being specified in the
|
||
<tt class="classname">Arg</tt>, a
|
||
type description is created by concatenating the values in the
|
||
allowed list using the operator<< for the specified type. The
|
||
help/usage for the <tt class="classname">Arg</tt> therefore lists the
|
||
allowable values. Because of this, it is assumed that list should
|
||
be relatively small, although there is no limit on this.
|
||
</p><p>
|
||
Obviously, a list of allowed values isn't always the best way to
|
||
constrain things. For instance, one might wish to allow only
|
||
integers greater than 0. In this case, the best strategy is for you
|
||
to evaluate the value returned from the <tt class="methodname">getValue()</tt>
|
||
call and if it
|
||
isn't valid, throw an <tt class="classname">ArgException</tt>. Be sure that the
|
||
description provided with the <tt class="classname">Arg</tt> reflects
|
||
the constraint you choose.
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="ARG_ADD_CMDLINE"></a>I want the Args to add themselves to the CmdLine...</h2></div></div><div></div></div><p>
|
||
New constructors have beed added for each <tt class="classname">Arg</tt>
|
||
that take a <tt class="classname">CmdLine</tt> object as an argument.
|
||
Each <tt class="classname">Arg</tt> then
|
||
<tt class="methodname">add</tt>s itself to the <tt class="classname">CmdLine</tt>
|
||
object. There is no difference in how the <tt class="classname">Arg</tt>
|
||
is handled between this method and calling the
|
||
<tt class="methodname">add()</tt> method directly. At the moment, there is
|
||
no way to do an <tt class="methodname">xorAdd()</tt> from the constructor. Here
|
||
is an example:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
// Create the command line.
|
||
CmdLine cmd("this is a message", '=', "0.99" );
|
||
|
||
// Note that the following args take the "cmd" object as arguments.
|
||
SwitchArg btest("B","existTestB", "exist Test B", false, cmd );
|
||
|
||
ValueArg<string> stest("s", "stringTest", "string test", true, "homer",
|
||
"string", cmd );
|
||
|
||
UnlabeledValueArg<string> utest("unTest1","unlabeled test one",
|
||
"default","string", cmd );
|
||
|
||
// NO add() calls!
|
||
|
||
// Parse the command line.
|
||
cmd.parse(argc,argv);
|
||
|
||
</pre><p>
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="CHANGE_OUTPUT"></a>I want different output than what is provided...</h2></div></div><div></div></div><p>
|
||
It is straightforward to change the output generated by
|
||
<span class="emphasis"><em>TCLAP</em></span>. Either subclass the
|
||
<tt class="classname">StdOutput</tt> class and re-implement the methods you choose,
|
||
or write your own class that implements the
|
||
<tt class="classname">CmdLineOutput</tt> interface. Once you have done this,
|
||
then use the <tt class="classname">CmdLine</tt> <tt class="methodname">setOutput</tt>
|
||
method to tell the <tt class="classname">CmdLine</tt> to use your new output
|
||
class. Here is a simple example:
|
||
</p><pre class="programlisting">
|
||
class MyOutput : public StdOutput
|
||
{
|
||
public:
|
||
virtual void failure(CmdLineInterface& c, ArgException& e)
|
||
{
|
||
cerr << "My special failure message for: " << endl
|
||
<< e.what() << endl;
|
||
}
|
||
};
|
||
|
||
int main(int argc, char** argv)
|
||
{
|
||
CmdLine cmd("this is a message", ' ', "0.99" );
|
||
|
||
// set the output
|
||
MyOutput my;
|
||
cmd.setOutput( &my );
|
||
|
||
// proceed normally ...
|
||
</pre><p>
|
||
|
||
See <tt class="filename">test4.cpp</tt> in the examples directory for the full
|
||
example.
|
||
</p></div></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="EXCEPTIONS"></a>Chapter 3. Exceptions to the Rules</h2></div></div><div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#IGNORE_ARGS">Ignoring arguments</a></dt><dt><a href="#COMBINED_SWITCHES">Multiple Identical Switches</a></dt><dt><a href="#DESCRIPTION_EXCEPTIONS">Type Descriptions</a></dt></dl></div><p>
|
||
Like all good rules, there are many exceptions....
|
||
</p><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="IGNORE_ARGS"></a>Ignoring arguments</h2></div></div><div></div></div><p>
|
||
The <i class="parameter"><tt>--</tt></i> flag is automatically included in the
|
||
<tt class="classname">CmdLine</tt>.
|
||
As (almost) per POSIX and GNU standards, any argument specified
|
||
after the <i class="parameter"><tt>--</tt></i> flag is ignored.
|
||
<span class="emphasis"><em>Almost</em></span> because if an
|
||
<tt class="classname">UnlabeledValueArg</tt> that has not been set or an
|
||
<tt class="classname">UnlabeledMultiArg</tt> has been specified, by default
|
||
we will assign any arguments beyond the <i class="parameter"><tt>--</tt></i>
|
||
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 <i class="parameter"><tt>--</tt></i> flag is
|
||
passed on the command line, the <tt class="classname">CmdLine</tt> will
|
||
<span class="emphasis"><em>still</em></span> test to make sure all of the required
|
||
arguments are present.
|
||
</p><p>
|
||
Of course, this isn't how POSIX/GNU handle things, they explicitly
|
||
ignore arguments after the <i class="parameter"><tt>--</tt></i>. To accomodate this,
|
||
we can make both <tt class="classname">UnlabeledValueArg</tt>s and
|
||
<tt class="classname">UnlabeledMultiArg</tt>s ignoreable in their constructors.
|
||
See the <a href="html/index.html" target="_top"> API Documentation</a> for details.
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="COMBINED_SWITCHES"></a>Multiple Identical Switches</h2></div></div><div></div></div><p>
|
||
If you absolutely must allow for multiple, identical switches, then
|
||
don't use a <tt class="classname">SwitchArg</tt>, instead use a
|
||
<tt class="classname">MultiArg</tt> of type
|
||
<tt class="classname">bool</tt>. 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
|
||
heart's content.
|
||
</p></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="DESCRIPTION_EXCEPTIONS"></a>Type Descriptions</h2></div></div><div></div></div><p>
|
||
Ideally this library would use RTTI to return a human readable name
|
||
of the type declared for a particular argument. Unfortunately, at
|
||
least for <b class="command">g++</b>, the names returned aren't
|
||
particularly useful.
|
||
</p></div></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="VISITORS"></a>Chapter 4. Visitors</h2></div></div><div></div></div><p>
|
||
Disclaimer: Almost no one will have any use for
|
||
<tt class="classname">Visitor</tt>s, they were
|
||
added to provide special handling for default arguments. Nothing
|
||
that <tt class="classname">Visitor</tt>s do couldn't be accomplished
|
||
by the user after the
|
||
command line has been parsed. If you're still interested, keep
|
||
reading...
|
||
</p><p>
|
||
Some of you may be wondering how we get the <i class="parameter"><tt>--help</tt></i>,
|
||
<i class="parameter"><tt>--version</tt></i> and <i class="parameter"><tt>--</tt></i>
|
||
arguments to do their thing without mucking up the
|
||
<tt class="classname">CmdLine</tt> code with lots of <span class="emphasis"><em>if</em></span>
|
||
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 that's what inspired me.
|
||
</p><p>
|
||
If we want some argument to do some sort of special handling,
|
||
besides simply parsing a value, then we add a <tt class="classname">Visitor</tt>
|
||
pointer to the <tt class="classname">Arg</tt>. More specifically, we add a
|
||
<span class="emphasis"><em>subclass</em></span> of the <tt class="classname">Visitor</tt>
|
||
class. Once the argument has been successfully parsed, the
|
||
<tt class="classname">Visitor</tt> for that argument is
|
||
called. Any data that needs to be operated on is declared in the
|
||
<tt class="classname">Visitor</tt> constructor and then operated on in the
|
||
<tt class="methodname">visit()</tt> method. A <tt class="classname">Visitor</tt>
|
||
is added to an <tt class="classname">Arg</tt> as the last argument in its
|
||
declaration. This may sound
|
||
complicated, but it is pretty straightforward. Let's see an
|
||
example.
|
||
</p><p>
|
||
Say you want to add an <i class="parameter"><tt>--authors</tt></i> flag to a program that
|
||
prints the names of the authors when present. First subclass
|
||
<tt class="classname">Visitor</tt>:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
#include "Visitor.h"
|
||
#include <string>
|
||
#include <iostream>
|
||
|
||
class AuthorVisitor : public Visitor
|
||
{
|
||
protected:
|
||
string _author;
|
||
public:
|
||
AuthorVisitor(const string& name ) : Visitor(), _author(name) {} ;
|
||
void visit() { cout << "AUTHOR: " << _author << endl; exit(0); };
|
||
};
|
||
|
||
</pre><p>
|
||
|
||
Now include this class definition somewhere and go about creating
|
||
your command line. When you create the author switch, add the
|
||
<tt class="classname">AuthorVisitor</tt> pointer as follows:
|
||
|
||
</p><pre class="programlisting">
|
||
|
||
SwitchArg author("a","author","Prints author name", false,
|
||
new AuthorVisitor("Homer J. Simpson") );
|
||
cmd.add( author );
|
||
|
||
</pre><p>
|
||
|
||
Now, any time the <i class="parameter"><tt>-a</tt></i> or
|
||
<i class="parameter"><tt>--author</tt></i> flag is specified,
|
||
the program will print the author name, Homer J. Simpson and exit
|
||
without processing any further (as specified in the
|
||
<tt class="methodname">visit()</tt> method).
|
||
</p></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="MORE_INFO"></a>Chapter 5. More Information</h2></div></div><div></div></div><p>
|
||
For more information, look at the <a href="html/index.html" target="_top">
|
||
API Documentation</a> and the examples included with the
|
||
distribution.
|
||
</p><p>
|
||
<span class="emphasis"><em>Happy coding!</em></span>
|
||
</p><p><a id="FOOTNOTES"></a>
|
||
** In theory, any type that supports operator>> and
|
||
operator<< should work, although I've really only tried
|
||
things with basic types like int, float, string, etc.
|
||
</p></div></div></body></html>
|