big update

This commit is contained in:
mes5k 2003-04-03 17:59:34 +00:00
parent 52b15b6e6e
commit aca51c23a8
8 changed files with 509 additions and 105 deletions

View File

@ -42,16 +42,18 @@ namespace TCLAP {
*/
class Arg
{
private:
static bool _ignoreRest;
protected:
/**
* The single char flag used to identify the argument.
* This value (preceded by a dash {-}), can be used to identify
* an argument on the command line. The _flag can be blank,
* in fact this is how unlabeled
* ValueArgs work. If the _flag is blank, the _labeled valued
* should be set to false. Note that the _flag does NOT include
* the dash as part of the flag.
* in fact this is how unlabeled args work. Unlabeled args must
* override appropriate functions to get correct handling. Note
* that the _flag does NOT include the dash as part of the flag.
*/
string _flag;
@ -88,13 +90,6 @@ class Arg
*/
bool _alreadySet;
/**
* Indicates whether the _flag is set or not.
* If the argument doesn't require a flag then the argument is
* handled differently.
*/
bool _labeled;
/**
* A pointer to a vistitor object.
* The visitor allows special handling to occur as soon as the
@ -107,9 +102,17 @@ class Arg
* Performs the special handling described by the Vistitor.
*/
void _checkWithVisitor() const;
/**
* Whether this argument can be ignored, if desired.
*/
bool _ignoreable;
public:
static void beginIgnoring() { Arg::_ignoreRest = true; }
static bool ignoreRest() { return Arg::_ignoreRest; }
/**
* Primary constructor.
*/
@ -142,7 +145,6 @@ class Arg
*/
~Arg();
/**
* Processes the argument.
* This is the method that handles the parsing and value assignment
@ -150,18 +152,18 @@ class Arg
* emits that an argument has matched and is being ignored. This
* should never really be used, any subclass should implement its
* own version of processArg.
* \param int* i - Pointer the the current argument in the list.
* \param int argc - Number of arguments. Passed in from main().
* \param char** argv - List of strings. Passed in from main().
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. What is
* passed in from main.
*/
virtual bool processArg(int *i, int argc, char** argv);
virtual bool processArg(int *i, vector<string>& args);
/**
* Operator ==.
* Equality operator.
* Equality operator. Must be virtual to handle unlabeled args.
*/
bool operator==(const Arg&);
virtual bool operator==(const Arg&);
/**
* Returns the argument flag.
@ -176,7 +178,7 @@ class Arg
/**
* Returns the argument description.
*/
const string& getDescription() const;
string getDescription() const;
/**
* Indicates whether the argument is required.
@ -194,10 +196,9 @@ class Arg
bool isAlreadySet() const;
/**
* Indicates whether the _flag value is blank or not.
* If the _flag is blank, the argument is considered unlabeled.
* Indicates whether the argument can be ignored, if desired.
*/
bool isLabeled() const;
bool isIgnoreable() const;
/**
* A method that tests whether a string matches this argument.
@ -211,7 +212,18 @@ class Arg
* Returns a simple string representation of the argument.
* Primarily for debugging.
*/
string toString() const;
virtual string toString() const;
/**
* Returns a short ID for the usage.
*/
virtual string shortID( const string& valueId = "val" ) const;
/**
* Returns a long ID for the usage.
*/
virtual string longID( const string& valueId = "val" ) const;
};
/**

View File

@ -25,7 +25,9 @@
#include <tclap/Arg.h>
#include <tclap/SwitchArg.h>
#include <tclap/MultiArg.h>
#include <tclap/UnlabeledMultiArg.h>
#include <tclap/ValueArg.h>
#include <tclap/UnlabeledValueArg.h>
#include <tclap/Visitor.h>
#include <string>
#include <vector>
@ -69,6 +71,7 @@ class CmdLine
#include "HelpVisitor.h"
#include "VersionVisitor.h"
#include "IgnoreRestVisitor.h"
#endif

View File

@ -0,0 +1,41 @@
/******************************************************************************
*
* file: IgnoreRestVisitor.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef __IGNORE_REST_VISITOR_H__
#define __IGNORE_REST_VISITOR_H__
#include <tclap/Visitor.h>
#include <tclap/Arg.h>
namespace TCLAP {
class IgnoreRestVisitor: public Visitor
{
public:
IgnoreRestVisitor() : Visitor() {};
void visit() { Arg::beginIgnoring(); }
};
}
#endif

View File

@ -20,8 +20,8 @@
*****************************************************************************/
#ifndef __MULTIPLE_UNLABELED_ARGUMENT_HH__
#define __MULTIPLE_UNLABELED_ARGUMENT_HH__
#ifndef __MULTIPLE_ARGUMENT_HH__
#define __MULTIPLE_ARGUMENT_HH__
#include <string>
#include <vector>
@ -38,29 +38,41 @@ class MultiArg : public Arg
protected:
vector<T> _values;
string _typeDesc;
void _extractValue(int i, vector<string>& args);
public:
MultiArg( const string& desc,
MultiArg( const string& flag,
const string& name,
const string& desc,
bool req,
const string& typeDesc,
Visitor* v = NULL);
~MultiArg();
bool processArg(int* i, int argc, char** argv);
virtual bool processArg(int* i, vector<string>& args);
const vector<T>& getValue() ;
virtual string shortID(const string& val="val") const;
virtual string longID(const string& val="val") const;
};
template<class T>
MultiArg<T>::MultiArg(const string& desc, Visitor* v)
: Arg( "", // flag
"...", // name
desc, // description
false, // required
true,
v) // value required
MultiArg<T>::MultiArg(const string& flag,
const string& name,
const string& desc,
bool req,
const string& typeDesc,
Visitor* v)
: Arg( flag, name, desc, req, true, v ),
_typeDesc( typeDesc )
{ };
template<class T>
@ -70,12 +82,32 @@ template<class T>
const vector<T>& MultiArg<T>::getValue() { return _values; };
template<class T>
bool MultiArg<T>::processArg(int *i, int argc, char** argv)
bool MultiArg<T>::processArg(int *i, vector<string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
if ( argMatches( args[*i] ) )
{
(*i)++;
if ( *i < args.size() )
{
_extractValue( *i, args );
return true;
}
else
throw( ArgException("Missing a value for this argument!",
toString() ) );
}
else
return false;
}
template<class T>
void MultiArg<T>::_extractValue(int i, vector<string>& args)
{
// can be called multiple times
T temp;
string ss(argv[*i]);
istringstream is(ss);
istringstream is(args[i]);
is >> temp;
if ( is.fail() )
throw( ArgException("Couldn't read argument value!", toString()));
@ -83,8 +115,22 @@ bool MultiArg<T>::processArg(int *i, int argc, char** argv)
_values.push_back(temp);
_checkWithVisitor();
}
return true;
template<class T>
string MultiArg<T>::shortID(const string& val) const
{
string id = Arg::shortID(_typeDesc) + " ... ";
return id;
}
template<class T>
string MultiArg<T>::longID(const string& val) const
{
string id = Arg::longID(_typeDesc) + " (accepted multiple times)";
return id;
}
}

View File

@ -38,7 +38,8 @@ class SwitchArg : public Arg
protected:
bool _value;
public:
SwitchArg(const string& flag,
@ -49,11 +50,14 @@ class SwitchArg : public Arg
~SwitchArg();
bool processArg(int* i, int argc, char** argv);
virtual bool processArg(int* i, vector<string>& args);
bool combinedSwitchesMatch(string& combined);
bool getValue() ;
};
}
#endif

View File

@ -0,0 +1,101 @@
/******************************************************************************
*
* file: UnlabeledMultiArg.h
*
* Copyright (c) 2003, Michael E. Smoot.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef __MULTIPLE_UNLABELED_ARGUMENT_HH__
#define __MULTIPLE_UNLABELED_ARGUMENT_HH__
#include <string>
#include <vector>
#include <sstream>
#include <tclap/Visitor.h>
using namespace std;
namespace TCLAP {
template<class T>
class UnlabeledMultiArg : public MultiArg<T>
{
public:
UnlabeledMultiArg( const string& name,
const string& desc,
const string& typeDesc,
bool ignoreable = false,
Visitor* v = NULL );
virtual bool processArg(int* i, vector<string>& args);
virtual string shortID(const string& val="val") const;
virtual string longID(const string& val="val") const;
virtual bool operator==(const Arg& a) const;
};
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const string& name,
const string& desc,
const string& typeDesc,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, false, typeDesc, v)
{
_ignoreable = ignoreable;
};
template<class T>
bool UnlabeledMultiArg<T>::processArg(int *i, vector<string>& args)
{
// never ignore an unlabeled multi arg
_extractValue( *i, args );
return true;
}
template<class T>
string UnlabeledMultiArg<T>::shortID(const string& val) const
{
string id = "<" + _typeDesc + "> ...";
return id;
}
template<class T>
string UnlabeledMultiArg<T>::longID(const string& val) const
{
string id = "<" + _typeDesc + "> (accepted multiple times)";
return id;
}
template<class T>
bool UnlabeledMultiArg<T>::operator==(const Arg& a) const
{
if ( _name == a.getName() || _description == a.getDescription() )
return true;
else
return false;
}
}
#endif

View File

@ -0,0 +1,174 @@
/******************************************************************************
*
* file: UnlabeledValueArg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef __UNLABELED_VALUE_ARGUMENT_HH__
#define __UNLABELED_VALUE_ARGUMENT_HH__
#include <string>
#include <vector>
#include <sstream>
#include <tclap/Visitor.h>
#include <tclap/Arg.h>
using namespace std;
namespace TCLAP {
/**
* The basic unlabeled argument that parses a value.
* This is a template class, which means the type T defines the type
* that a given object will attempt to parse when an UnlabeledValueArg
* is reached in the list of args that the CmdLine iterates over.
*/
template<class T>
class UnlabeledValueArg : public ValueArg<T>
{
public:
/**
* UnlabeledValueArg constructor.
* Note that this constructor does not have a required flag. Any
* unlabeled argument added to the CmdLine is by default required.
* If you want optional, unlabeled arguments then use an
* UnlabeledMultiArg.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg(const string& name,
const string& desc,
T value,
const string& typeDesc,
bool ignoreable = false,
Visitor* v = NULL);
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. Handling specific to
* unlabled arguments.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings.
*/
virtual bool processArg(int* i, vector<string>& args );
/**
* Overrides shortID for specific behavior.
*/
virtual string shortID(const string& val="val") const;
/**
* Overrides longID for specific behavior.
*/
virtual string longID(const string& val="val") const;
/**
* Overrides operator== for specific behavior.
*/
virtual bool operator==(const Arg& a ) const;
};
/**
* Constructor implemenation.
*/
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const string& name,
const string& desc,
T val,
const string& typeDesc,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, true, val, typeDesc, v)
{
_ignoreable = ignoreable;
};
/**
* Implementation of processArg().
*/
template<class T>
bool UnlabeledValueArg<T>::processArg(int *i, vector<string>& args)
{
// never ignore an unlabeled arg
if ( _alreadySet )
return false;
_extractValue( *i, args );
_alreadySet = true;
return true;
}
/**
* Overriding shortID for specific output.
*/
template<class T>
string UnlabeledValueArg<T>::shortID(const string& val) const
{
string id = "<" + _typeDesc + ">";
return id;
}
/**
* Overriding longID for specific output.
*/
template<class T>
string UnlabeledValueArg<T>::longID(const string& val) const
{
// Ideally we would like to be able to use RTTI to return the name
// of the type required for this argument. However, g++ at least,
// doesn't appear to return terribly useful "names" of the types.
string id = "<" + _typeDesc + ">";
return id;
}
/**
* Overriding operator== for specific behavior.
*/
template<class T>
bool UnlabeledValueArg<T>::operator==(const Arg& a ) const
{
if ( _name == a.getName() || _description == a.getDescription() )
return true;
else
return false;
}
}
#endif

View File

@ -34,11 +34,12 @@ using namespace std;
namespace TCLAP {
/**
* The basic argument that parses a value.
* The basic labeled argument that parses a value.
* This is a template class, which means the type T defines the type
* that a given object will attempt to parse when the flag/name is matched
* on the command line. Note that a ValueArg does not necessarily have to
* have a flag specified, making this an unlabled argument.
* on the command line. While there is nothing stopping you from creating
* an unflagged ValueArg, it is unwise and would cause significant problems.
* Instead use an UnlabeledValueArg.
*/
template<class T>
class ValueArg : public Arg
@ -53,10 +54,23 @@ class ValueArg : public Arg
T _value;
/**
* Extracts the value at position i from the argv list.
* A human readable description of the type to be parsed.
* This is a hack, plain and simple. Ideally we would use RTTI to
* return the name of type T, but until there is some sort of
* consistent support for human readable names, we are left to our
* own devices.
*/
void _extractValue( int i, char** argv );
string _typeDesc;
/**
* Extracts the string at position i from the args list.
* Attempts to parse string as type T, if this fails an exception
* is thrown.
* \param i - The index of the argument to extract.
* \param args - Mutable list of strings.
*/
void _extractValue( int i, vector<string>& args );
public:
/**
@ -65,22 +79,31 @@ class ValueArg : public Arg
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg(const string& flag,
const string& name,
const string& desc,
bool req,
T value,
const string& typeDesc,
Visitor* v = NULL);
/**
* Unlabeled ValueArg constructor.
*/
ValueArg(const string& name,
const string& desc,
T value,
Visitor* v = NULL);
/**
* Destructor.
*/
@ -91,21 +114,33 @@ class ValueArg : public Arg
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. It knows the difference
* between labeled and unlabeled.
* \param int* i - Pointer the the current argument in the list.
* \param int argc - Number of arguments. Passed in from main().
* \param char** argv - List of strings. Passed in from main().
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, int argc, char** argv);
virtual bool processArg(int* i, vector<string>& args );
/**
* Returns the value of the argument.
*/
T& getValue() ;
/**
* Specialization of shortID.
*/
virtual string shortID(const string& val = "val") const;
/**
* Specialization of longID.
*/
virtual string longID(const string& val = "val") const;
};
/**
* Labeled constructor implementation.
* Constructor implementation.
*/
template<class T>
ValueArg<T>::ValueArg(const string& flag,
@ -113,25 +148,11 @@ ValueArg<T>::ValueArg(const string& flag,
const string& desc,
bool req,
T val,
const string& typeDesc,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val )
{
if ( _flag == "" )
throw( ArgException( "No flag specified for labeled ValueArg!",
toString() ) );
};
/**
* Unlabeled constructor implemenation.
*/
template<class T>
ValueArg<T>::ValueArg(const string& name,
const string& desc,
T val,
Visitor* v)
: Arg("", name, desc, true, true, v),
_value( val )
_value( val ),
_typeDesc( typeDesc )
{ };
/**
@ -150,11 +171,12 @@ T& ValueArg<T>::getValue() { return _value; };
* Implementation of processArg().
*/
template<class T>
bool ValueArg<T>::processArg(int *i, int argc, char** argv)
bool ValueArg<T>::processArg(int *i, vector<string>& args)
{
if ( _labeled )
{
string flag = argv[*i];
if ( _ignoreable && Arg::ignoreRest() )
return false;
string flag = args[*i];
if ( argMatches( flag ) )
{
@ -162,9 +184,9 @@ bool ValueArg<T>::processArg(int *i, int argc, char** argv)
throw( ArgException("Argument already set!", toString()) );
(*i)++;
if (*i < argc )
if (*i < args.size() )
{
_extractValue( *i, argv);
_extractValue( *i, args);
_alreadySet = true;
@ -175,40 +197,41 @@ bool ValueArg<T>::processArg(int *i, int argc, char** argv)
else
throw( ArgException("Missing a value for this argument!",
toString() ) );
}
else
return false;
}
else
{
if ( _alreadySet )
return false;
if ( *i < argc )
{
_extractValue( *i, argv );
_alreadySet = true;
return true;
}
else
throw( ArgException("Missing a value for this argument!",
toString()));
}
}
/**
* Implementation of _extractValue.
*/
template<class T>
void ValueArg<T>::_extractValue(int i, char** argv)
void ValueArg<T>::_extractValue(int i, vector<string>& args)
{
string ss(argv[i]);
istringstream is(ss);
istringstream is(args[i]);
is >> _value;
if ( is.fail() )
throw( ArgException("Couldn't read argument value!", toString() ) );
}
/**
* Implementation of shortID.
*/
template<class T>
string ValueArg<T>::shortID(const string& val) const
{
return Arg::shortID( _typeDesc );
}
/**
* Implementation of longID.
*/
template<class T>
string ValueArg<T>::longID(const string& val) const
{
return Arg::longID( _typeDesc );
}
}
#endif