C++ Library containing a lot of needful things: Stack Trace, Command Line Parser, Resource Handling, Configuration Files, Unix Command Execution, Directories, Regular Expressions, Tokenizer, Function Trace, Standard Extensions.
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
811 lines
26 KiB
811 lines
26 KiB
21 years ago
|
/** @file
|
||
|
|
||
|
$Id$
|
||
|
|
||
|
$Date$
|
||
|
$Author$
|
||
|
|
||
|
@copy © Marc Wäckerlin
|
||
|
@license LGPL, see file <a href="license.html">COPYING</a>
|
||
|
|
||
|
$Log$
|
||
20 years ago
|
Revision 1.7 2005/11/29 12:39:42 marc
|
||
|
make it compilable with gcc 4.0.2 and newer doxygen
|
||
|
|
||
20 years ago
|
Revision 1.6 2005/02/08 12:31:36 marc
|
||
|
new static methods to simplify access to options
|
||
|
|
||
21 years ago
|
Revision 1.5 2004/11/25 18:26:04 marc
|
||
|
Constness corrected
|
||
|
|
||
21 years ago
|
Revision 1.4 2004/10/07 09:23:39 marc
|
||
|
bugs in documentation
|
||
|
|
||
21 years ago
|
Revision 1.3 2004/08/31 16:23:29 marc
|
||
14 years ago
|
no include of stacktrace.hxx
|
||
21 years ago
|
|
||
21 years ago
|
Revision 1.2 2004/08/28 16:21:25 marc
|
||
|
mrw-c++-0.92 (mrw)
|
||
14 years ago
|
- new file: version.cxx
|
||
21 years ago
|
- new file header for all sources
|
||
|
- work around warning in mrw::auto<T>
|
||
|
- possibility to compile without log4cxx
|
||
|
- work around bugs in demangle.h and libiberty.h
|
||
|
- corrections in documentation
|
||
|
- added simple tracing mechanism
|
||
|
- more warnings
|
||
|
- small corrections in Auto<>::Free and a new test for it
|
||
|
- possibility to compile without stack trace
|
||
|
|
||
|
*/
|
||
14 years ago
|
#include <mrw/smartpointer.hxx>
|
||
21 years ago
|
#include <stdlib.h> // exit
|
||
|
#include <string>
|
||
21 years ago
|
#include <map>
|
||
21 years ago
|
#include <vector>
|
||
|
#include <set>
|
||
|
#include <list>
|
||
|
#include <exception>
|
||
|
#include <stdexcept>
|
||
|
#include <sstream>
|
||
|
#include <iostream>
|
||
|
|
||
|
namespace mrw {
|
||
|
|
||
|
/** @defgroup arguments C++ Evaluation of Command Line Arguments
|
||
|
|
||
|
@brief These classes do simple and easy command line argment evaluation
|
||
|
in C++.
|
||
|
|
||
|
Features:
|
||
|
- every argument has a long and a short option
|
||
|
- all arguments are optional and provide a default value
|
||
|
- the order of options is not important
|
||
|
- every option can take any (fixed) number of additional parameter of
|
||
|
type
|
||
|
- string
|
||
|
- integer
|
||
|
- boolean (@c "yes", @c "on", @c "true" evaluates to @c true)
|
||
|
- short options can be combined, instead of
|
||
|
@c -a @c -b @c -c @c 15 you can simply write @c -abc @c 15
|
||
|
- automated help display (support for option @c -h)
|
||
|
|
||
|
@c mrw::Args is the main user interface class that represents
|
||
|
all command line options with their arguments. It is implemented
|
||
|
as singleton, so the same instance can be accessed from
|
||
|
everywhere in the code. It mst be setup just in the beginning of
|
||
|
the @c main() function.
|
||
|
|
||
|
The other important class for the end user is @c mrw::Opt, one
|
||
|
possible option with additional parameter. The end user needs @c
|
||
|
mrw::Opt to setup all allowed command line options in the
|
||
|
beginning, bevore evaluation of the user given command line is
|
||
|
done (before @c argc and @c argv is shifted into @c mrw::Args.
|
||
|
|
||
|
The third class a user should know is @c mrw::Param. It
|
||
|
represents the arguments to one option. Every instance of @c
|
||
|
mrw::Opt owns one instance of @c mrw::Param that is either empty
|
||
|
or list of (mandatory) arguments of type @c std::string, @c int
|
||
|
or @c bool.
|
||
|
|
||
|
The classes are normally used this way:
|
||
|
|
||
|
@code
|
||
|
// this program may be called e.g. with the following arguments:
|
||
|
// ./a.out --coordinates 13 1 -vo out.txt -n MyName
|
||
21 years ago
|
int main(int argv, char const*const*const argv) {
|
||
21 years ago
|
try {
|
||
|
mrw::Args::instance()
|
||
|
// setup the possible options
|
||
|
<<mrw::Opt('h', "--help", "Show this help text")
|
||
|
<<mrw::Opt('v', "--verbose", "print more information")
|
||
|
<<mrw::Opt('q', "--quiet", "be quiet")
|
||
|
<<mrw::Opt('n', "--name", mrw::Param()<<"MRW", "name of the user")
|
||
|
<<mrw::Opt('o', "--output-file", mrw::Param()<<"", "file to load")
|
||
|
<<mrw::Opt('c', "--coordinates", mrw::Param()<<0<<0, "X, Y coordinate")
|
||
|
// set a description text for help
|
||
|
<<"This is a testprogram for argument evaluation in C++"
|
||
|
// define the help option
|
||
|
<<'h'
|
||
|
// shift in the command line arguments
|
||
|
<<argc<<argv;
|
||
|
...
|
||
|
// example usage of simple option
|
||
|
if (mrw::Args::instance().find('v')) // be verbose here
|
||
20 years ago
|
if (mrw::Args::have('v')) // the same, simpler: be verbose here
|
||
21 years ago
|
...
|
||
21 years ago
|
// example usage of option with one parameter
|
||
20 years ago
|
ifstream file(mrw::Args::toString('o').c_str());
|
||
21 years ago
|
...
|
||
|
// example usage of option with two parameter
|
||
20 years ago
|
int x = mrw::Args::instance().find('c')[0]->toInt(); // first integer
|
||
|
int y = mrw::Args::toInt('c', 1); // second; alternative, simpler access
|
||
21 years ago
|
...
|
||
|
return 0
|
||
|
}
|
||
|
} catch (mrw::exception& x) {
|
||
|
// trace error, print help or mention option -h
|
||
|
}
|
||
|
}
|
||
|
@endcode
|
||
|
*/
|
||
|
//@{
|
||
|
|
||
|
/** @brief List of additional (mandatory) parameter to one command
|
||
|
line argument.
|
||
14 years ago
|
@pre \#include<mrw/arg.hxx>
|
||
21 years ago
|
|
||
|
A new mandatory parameter is added to the list of parameter, by
|
||
|
shifting the default value into the instance of @c
|
||
|
mrw::Param. E.g. add a string, that defaults to @c "noname", an
|
||
|
integer, that defaults to @c 4, another integer that defaults to
|
||
21 years ago
|
@c 2 and a boolean that defaults to @c "true":
|
||
21 years ago
|
|
||
|
@code
|
||
|
// if you need the instance as variable:
|
||
|
mrw::Param p();
|
||
|
p<<"noname"<<4<<2<<true;
|
||
|
// or in an expression:
|
||
|
mrw::Opt o('e', "--example", mrw::Param()<<"noname"<<4<<2<<true, "");
|
||
|
@endcode
|
||
|
|
||
|
To access a value at a given position, simply use @c
|
||
|
operator[]. Then use @c mrw::Value::toString, @c
|
||
|
mrw::Value::toInt or @c mrw::Value::toBool to get the value of
|
||
|
that parameter. Of course yo must know the correct type of a
|
||
|
parameter at a given position, but since you are the programmer
|
||
|
you know it, or you can get it by running your program with the
|
||
|
help option, mostly @c -h. To retrieve the parameters setup in
|
||
|
the example above (connected to option @c -e or @c --example),
|
||
|
either the default value, or the value overwritten by the user,
|
||
|
simply type:
|
||
|
|
||
|
@code
|
||
|
mrw::Args& args = mrw::Args::instance();
|
||
|
std::string theString = args[0]->toString();
|
||
|
int firstInteger = args[1]->toInt();
|
||
|
int secondInteger = args[2]->toInt();
|
||
|
bool theBoolean = args[3]->toBool();
|
||
|
@endcode
|
||
|
|
||
21 years ago
|
<h3>Setup Command Line from Different Program Parts</h3>
|
||
21 years ago
|
|
||
|
If your software is large and splitted into different parts (or
|
||
|
sub projects or modules, ...), all with their own parameter, you
|
||
|
can use the following trick: Statical variables are initialized
|
||
|
before the @c main() function is called.
|
||
|
|
||
|
In part Abc write in a code file (not in a header file):
|
||
|
|
||
|
@code
|
||
|
class AbcArguments {
|
||
|
public:
|
||
|
AbcArguments() {
|
||
|
mrw::Args::instance()
|
||
|
<<mrw::Opt('n', "--name", mrw::Param()<<"MRW", "name of the user")
|
||
|
<<mrw::Opt('o', "--output-file", mrw::Param()<<"", "file to load")
|
||
|
<<mrw::Opt('c', "--coordinates", mrw::Param()<<0<<0,
|
||
|
"X, Y coordinate")
|
||
|
<<"Description text for part Abc, will be added to the\n"
|
||
|
"overall documentation";
|
||
|
}
|
||
|
};
|
||
|
static AbcArgument abcArgumentInitializer;
|
||
|
@endcode
|
||
|
|
||
|
Do the same for all other parts Then the @c main() function reduces to:
|
||
|
|
||
|
@code
|
||
21 years ago
|
int main(int argc, char const*const*const argv) {
|
||
21 years ago
|
// set the help and evaluate the user given arguments
|
||
|
mrw::Args::instance()
|
||
|
<<mrw::Opt('h', "--help", "Show this help text")
|
||
|
<<'h'<<argc<<argv;
|
||
|
...
|
||
|
}
|
||
|
@endcode
|
||
|
*/
|
||
|
class Param {
|
||
|
|
||
|
public:
|
||
|
|
||
|
/** @brief Abstract base class to represent one single parameter value.
|
||
14 years ago
|
@pre \#include<mrw/arg.hxx>
|
||
21 years ago
|
*/
|
||
|
class Value {
|
||
|
|
||
|
public:
|
||
|
|
||
|
virtual ~Value() {}
|
||
|
|
||
|
/** @brief If the instance is a @c std::string, return that
|
||
|
string, otherwise throw an exception.
|
||
|
@throw mrw::bad_cast if the instance is not a string
|
||
|
@return the string, if the instance is a string
|
||
|
*/
|
||
21 years ago
|
virtual const std::string& toString() const throw(std::exception);
|
||
21 years ago
|
|
||
|
/** @brief If the instance is an @c int, return that integer,
|
||
|
otherwise throw an exception.
|
||
|
@throw mrw::bad_cast if the instance is not a integer
|
||
|
@return the integer, if the instance is a integer
|
||
|
*/
|
||
21 years ago
|
virtual int toInt() const throw(std::exception);
|
||
|
|
||
21 years ago
|
/** @brief If the instance is an @c bool, return that boolean,
|
||
|
otherwise throw an exception.
|
||
|
@note the following typings are converted to @c true:
|
||
|
- true
|
||
|
- yes
|
||
|
- on
|
||
|
Everything else is converted to @c false.
|
||
|
@throw mrw::bad_cast if the instance is not a boolean
|
||
|
@return the boolean, if the instance is a boolean
|
||
|
*/
|
||
21 years ago
|
virtual bool toBool() const throw(std::exception);
|
||
21 years ago
|
|
||
|
/// @brief returns a printable representation of the value
|
||
21 years ago
|
virtual std::string printable() const throw(std::bad_exception) = 0;
|
||
21 years ago
|
|
||
|
/// @brief returns a printable typename of the value
|
||
21 years ago
|
virtual const std::string& typestr() const throw(std::bad_exception)=0;
|
||
21 years ago
|
|
||
|
protected:
|
||
21 years ago
|
/// Allow assign for Args, make it a friend.
|
||
|
friend class Args;
|
||
|
/// Only the class itself and friends (Args) are allowed to assign.
|
||
|
virtual void operator=(const std::string&) throw(std::exception) = 0;
|
||
21 years ago
|
};
|
||
|
|
||
|
private:
|
||
|
|
||
|
class StringValue: public Value {
|
||
|
public:
|
||
|
virtual ~StringValue() {}
|
||
21 years ago
|
StringValue(const std::string& s) throw(std::bad_exception): _s(s) {
|
||
21 years ago
|
}
|
||
21 years ago
|
virtual const std::string& toString() const throw(std::exception) {
|
||
21 years ago
|
return _s;
|
||
|
}
|
||
21 years ago
|
virtual const std::string& typestr() const throw(std::bad_exception) {
|
||
21 years ago
|
static std::string name("string");
|
||
|
return name;
|
||
|
}
|
||
21 years ago
|
virtual std::string printable() const throw(std::bad_exception) {
|
||
21 years ago
|
return _s;
|
||
|
}
|
||
|
protected:
|
||
21 years ago
|
virtual void operator=(const std::string& s) throw(std::exception) {
|
||
21 years ago
|
_s = s;
|
||
|
}
|
||
|
private:
|
||
|
std::string _s;
|
||
|
};
|
||
|
|
||
|
class IntValue: public Value {
|
||
|
public:
|
||
|
virtual ~IntValue() {}
|
||
21 years ago
|
IntValue(int i) throw(std::bad_exception): _i(i) {
|
||
21 years ago
|
}
|
||
21 years ago
|
virtual int toInt() const throw(std::exception) {
|
||
21 years ago
|
return _i;
|
||
|
}
|
||
21 years ago
|
virtual const std::string& typestr() const throw(std::bad_exception) {
|
||
21 years ago
|
static std::string name("integer");
|
||
|
return name;
|
||
|
}
|
||
21 years ago
|
virtual std::string printable() const throw(std::bad_exception) {
|
||
21 years ago
|
return ((std::stringstream&)(std::stringstream()<<_i)).str();
|
||
|
}
|
||
|
protected:
|
||
21 years ago
|
virtual void operator=(const std::string& s) throw(std::exception);
|
||
21 years ago
|
private:
|
||
|
int _i;
|
||
|
};
|
||
|
|
||
|
class BoolValue: public Value {
|
||
|
public:
|
||
|
virtual ~BoolValue() {}
|
||
21 years ago
|
BoolValue(bool b) throw(std::bad_exception): _b(b) {
|
||
21 years ago
|
}
|
||
21 years ago
|
virtual bool toBool() const throw(std::exception) {
|
||
21 years ago
|
return _b;
|
||
|
}
|
||
21 years ago
|
virtual const std::string& typestr() const throw(std::bad_exception) {
|
||
21 years ago
|
static std::string name("boolean (\"yes\" or \"no\")");
|
||
|
return name;
|
||
|
}
|
||
21 years ago
|
virtual std::string printable() const throw(std::bad_exception) {
|
||
21 years ago
|
return _b?"yes":"no";
|
||
|
}
|
||
|
protected:
|
||
21 years ago
|
virtual void operator=(const std::string& s) throw(std::exception) {
|
||
21 years ago
|
_b = s=="true" || s=="yes" || s=="on";
|
||
|
}
|
||
|
private:
|
||
|
bool _b;
|
||
|
};
|
||
|
|
||
|
typedef std::vector< mrw::SmartPointer<Value> > Params;
|
||
|
Params _params;
|
||
|
|
||
|
public:
|
||
|
|
||
|
/// @brief returns the number of (mandatory) parameter
|
||
|
int size() const throw(std::bad_exception) {
|
||
|
return _params.size();
|
||
|
}
|
||
|
|
||
|
/// @brief add one more mandatory string parameter
|
||
21 years ago
|
Param& operator<<(char const*const s) throw(std::bad_exception) {
|
||
21 years ago
|
_params.push_back(new StringValue(s));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// @brief add one more mandatory string parameter
|
||
21 years ago
|
Param& operator<<(const std::string& s) throw(std::bad_exception) {
|
||
21 years ago
|
_params.push_back(new StringValue(s));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// @brief add one more mandatory integer parameter
|
||
21 years ago
|
Param& operator<<(int i) throw(std::bad_exception) {
|
||
21 years ago
|
_params.push_back(new IntValue(i));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// @brief add one more mandatory boolean parameter
|
||
21 years ago
|
Param& operator<<(bool b) throw(std::bad_exception) {
|
||
21 years ago
|
_params.push_back(new BoolValue(b));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
21 years ago
|
/** @brief get parameter number @c i
|
||
21 years ago
|
@throw mrw::out_of_range if @c i is too big */
|
||
|
const mrw::SmartPointer<Value>& operator[](unsigned int i) const
|
||
21 years ago
|
throw(std::exception);
|
||
21 years ago
|
|
||
|
private:
|
||
|
|
||
21 years ago
|
/// Allow set for Args, make it a friend.
|
||
21 years ago
|
friend class Args; // allow set
|
||
21 years ago
|
/// Get a parameter with acces right for setting.
|
||
|
/// This is allowed for the class itself and friends (Args) only.
|
||
|
mrw::SmartPointer<Value>& setable(unsigned int i) throw(std::exception);
|
||
21 years ago
|
};
|
||
|
|
||
|
/** @brief this class represents one command line option
|
||
14 years ago
|
@pre \#include<mrw/arg.hxx>
|
||
21 years ago
|
|
||
|
The library user needs this class when setting up the list of
|
||
|
supported command line ooptions: Simply shift one instance of @c
|
||
|
mrw::Opt per supported command line option into @c
|
||
|
mrw::Args::instance(), e.g.:
|
||
|
|
||
|
@code
|
||
|
mrw::Args::instance()
|
||
|
<<mrw::Opt('h', "--help", "Show this help text");
|
||
|
@endcode
|
||
|
*/
|
||
|
class Opt {
|
||
|
|
||
|
public:
|
||
|
|
||
|
/** @brief create an @c mrw::Opt with additional parameter
|
||
|
@param shortname short name of the option
|
||
|
@param longname long name of the option, must start with "--"
|
||
|
@param param the additional parameter
|
||
21 years ago
|
@param helptext the help string for this option
|
||
21 years ago
|
*/
|
||
21 years ago
|
Opt(const char shortname, const std::string& longname,
|
||
|
const Param& param, const std::string& helptext)
|
||
|
throw(std::bad_exception):
|
||
21 years ago
|
_set(false), _shortname(shortname), _longname(longname),
|
||
21 years ago
|
_param(param), _help(helptext) {
|
||
21 years ago
|
}
|
||
|
|
||
|
/** @brief create a simple @c mrw::Opt
|
||
|
|
||
|
This option is either set or not set, there are no additional
|
||
|
parameter.
|
||
|
|
||
|
@param shortname short name of the option
|
||
|
@param longname long name of the option, must start with "--"
|
||
21 years ago
|
@param helptext the help string for this option
|
||
21 years ago
|
*/
|
||
21 years ago
|
Opt(const char shortname, const std::string& longname,
|
||
|
const std::string& helptext) throw(std::bad_exception):
|
||
21 years ago
|
_set(false), _shortname(shortname), _longname(longname),
|
||
21 years ago
|
_help(helptext) {
|
||
21 years ago
|
}
|
||
|
|
||
|
/** @brief get the help text for this option */
|
||
21 years ago
|
const std::string& help() const throw(std::bad_exception) {
|
||
21 years ago
|
return _help;
|
||
|
}
|
||
|
|
||
|
/** @brief find out, whether this option was set by the user
|
||
|
|
||
|
Example: Check whether the user has set the @c -v option for
|
||
20 years ago
|
verbose output, there are two ways for doing it:
|
||
21 years ago
|
|
||
|
@code
|
||
|
if (mrw::Args::instance().find('v')) // -v is set
|
||
20 years ago
|
if (mrw::Args::have('v')) // -v is set
|
||
21 years ago
|
@endcode
|
||
|
|
||
|
@return
|
||
|
- @c true if the user has started the program with this option
|
||
|
- @c false if the user has not set this option
|
||
|
*/
|
||
|
operator bool() const throw(std::bad_exception) {return _set;}
|
||
|
|
||
|
/** @brief get one of the additional parameter
|
||
|
|
||
|
If this option has additional parameter, get the @c i-th of them.
|
||
|
|
||
|
@throw mrw::out_of_range if @c i is too big
|
||
|
@param i number of the additional parameter to get (starting with @c 0)
|
||
|
@return a smart pointer to the value (default or given by the user)
|
||
|
*/
|
||
|
const mrw::SmartPointer<Param::Value>& operator[](unsigned int i) const
|
||
21 years ago
|
throw(std::exception) {
|
||
21 years ago
|
return _param[i];
|
||
|
}
|
||
|
|
||
|
private:
|
||
21 years ago
|
|
||
|
/// Allow set values, make Args a friend.
|
||
|
friend class Args;
|
||
|
/// Set @c _set to true, available only for friends (Args).
|
||
|
void set() const throw(std::bad_exception) {
|
||
21 years ago
|
_set = true;
|
||
|
}
|
||
21 years ago
|
Param& args() const throw(std::bad_exception) {
|
||
21 years ago
|
return _param;
|
||
|
}
|
||
|
mutable bool _set;
|
||
|
char _shortname;
|
||
|
std::string _longname;
|
||
|
mutable Param _param;
|
||
|
std::string _help;
|
||
|
};
|
||
|
|
||
|
/** @brief handle command line arguments
|
||
14 years ago
|
@pre \#include<mrw/arg.hxx>
|
||
21 years ago
|
|
||
|
This class handles command line arguments. It is a
|
||
|
singleton. Get the one and only instance of this class with @c
|
||
|
mrw::Args::instance(). It is setup by shifting values into this
|
||
|
class. The order is important, be sure that you shift in @c argc
|
||
|
and @c argv as last parameters.
|
||
|
|
||
|
Example setup:
|
||
|
|
||
|
@code
|
||
|
mrw::Args::instance()
|
||
|
<<mrw::Opt('h', "--help", "Show this help text")
|
||
|
<<mrw::Opt('v', "--verbose", "print more information")
|
||
|
<<"This is a testprogram for argument evaluation in C++"
|
||
|
<<'h'<<argc<<argv;
|
||
|
@endcode
|
||
|
*/
|
||
|
class Args {
|
||
|
|
||
|
public:
|
||
|
|
||
|
typedef std::list<std::string> OtherArgs;
|
||
|
|
||
|
/// @brief get the one and only instance
|
||
21 years ago
|
static Args& instance() throw(std::bad_exception) { // singleton
|
||
21 years ago
|
static Args _instance;
|
||
|
return _instance;
|
||
|
}
|
||
|
|
||
20 years ago
|
/** @brief check a simple option
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
if (mrw::Args::instance().find('x')) ...
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
if (mrw::Args::have('x')) ...
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
|
||
|
@throw mrw::out_of_range if the parameter is not available
|
||
|
(this would be a coding error)
|
||
|
*/
|
||
|
static bool have(char c) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c);
|
||
|
}
|
||
|
|
||
|
/** @brief get a simple string parameter
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
mrw::Args::instance().find('x')[0].toString()
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
mrw::Args::toString('x')
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
|
||
|
@throw mrw::bad_cast if the parameter is not a string
|
||
|
@throw mrw::out_of_range if the parameter is empty or not available
|
||
|
*/
|
||
|
static const std::string& toString(char c) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c)[0]->toString();
|
||
|
}
|
||
|
|
||
|
/** @brief get a simple integer parameter
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
mrw::Args::instance().find('x')[0].toInt()
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
mrw::Args::toInt('x')
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
|
||
|
@throw mrw::bad_cast if the parameter is not an int
|
||
|
@throw mrw::out_of_range if the parameter is empty or not available
|
||
|
*/
|
||
|
static int toInt(char c) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c)[0]->toInt();
|
||
|
}
|
||
|
|
||
|
/** @brief get a simple boolean parameter
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
mrw::Args::instance().find('x')[0].toBool()
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
mrw::Args::toBool('x')
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
|
||
|
@throw mrw::bad_cast if the parameter is not an bool
|
||
|
@throw mrw::out_of_range if the parameter is empty or not available
|
||
|
*/
|
||
|
static bool toBool(char c) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c)[0]->toBool();
|
||
|
}
|
||
|
|
||
|
/** @brief get the n-th string parameter
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
mrw::Args::instance().find('x')[n].toString()
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
mrw::Args::toString('x', n)
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
@param n the number of the parameter (starting at 0)
|
||
|
|
||
|
@throw mrw::bad_cast if the parameter is not a string
|
||
|
@throw mrw::out_of_range if the parameter is not available
|
||
|
*/
|
||
|
static const std::string& toString(char c, int n) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c)[n]->toString();
|
||
|
}
|
||
|
|
||
|
/** @brief get the n-th integer parameter
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
mrw::Args::instance().find('x')[n].toInt()
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
mrw::Args::toInt('x', n)
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
@param n the number of the parameter (starting at 0)
|
||
|
|
||
|
@throw mrw::bad_cast if the parameter is not an int
|
||
|
@throw mrw::out_of_range if the parameter is not available
|
||
|
*/
|
||
|
static int toInt(char c, int n) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c)[n]->toInt();
|
||
|
}
|
||
|
|
||
|
/** @brief get the n-th boolean parameter
|
||
|
|
||
|
This is a shortcut. Instead of the expression:
|
||
|
@code
|
||
|
mrw::Args::instance().find('x')[n].toBool()
|
||
|
@endcode
|
||
|
you can simply write the expression:
|
||
|
@code
|
||
|
mrw::Args::toBool('x', n)
|
||
|
@endcode
|
||
|
It is exactly the same.
|
||
|
|
||
|
@param c the short name of the parameter
|
||
|
@param n the number of the parameter (starting at 0)
|
||
|
|
||
|
@throw mrw::bad_cast if the parameter is not an bool
|
||
|
@throw mrw::out_of_range if the parameter not available
|
||
|
*/
|
||
|
static bool toBool(char c, int n) throw(std::exception) {
|
||
|
return mrw::Args::instance().find(c)[n]->toBool();
|
||
|
}
|
||
|
|
||
21 years ago
|
/** @brief setup an acceptable option
|
||
|
|
||
|
Setup an acceptable user option.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
@code
|
||
|
mrw::Args::instance()
|
||
|
<<mrw::Opt('v', "--verbose", "print more information");
|
||
|
@endcode
|
||
20 years ago
|
|
||
|
@throw mrw::invalid_argument if opt is not setup correctly
|
||
21 years ago
|
*/
|
||
20 years ago
|
Args& operator<<(const mrw::Opt& opt) throw(std::exception);
|
||
21 years ago
|
|
||
|
/** @brief setup the number of arguments
|
||
|
|
||
|
Setup the number of arguments.
|
||
|
This must be done before @c argv is shifted in.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
@code
|
||
21 years ago
|
int main(int argv, char const*const*const argv) {
|
||
21 years ago
|
mrw::Args::instance()<<argc<<argv;
|
||
|
...
|
||
|
}
|
||
|
@endcode
|
||
|
*/
|
||
21 years ago
|
Args& operator<<(int argc) throw(std::bad_exception) {
|
||
21 years ago
|
_argc = argc;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/** @brief setup the C array of command line arguments
|
||
|
|
||
|
Setup the C array of command line arguments. This must be the
|
||
|
very last thing shifted in.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
@code
|
||
21 years ago
|
int main(int argv, char const*const*const argv) {
|
||
21 years ago
|
mrw::Args::instance()<<argc<<argv;
|
||
|
...
|
||
|
}
|
||
|
@endcode
|
||
|
*/
|
||
21 years ago
|
Args& operator<<(char const*const*const argv) throw(std::exception);
|
||
21 years ago
|
|
||
|
/** @brief add a description text
|
||
|
|
||
|
Add a description text. This description text is shown in the
|
||
|
@c DESCRIPTION section of the help display. If the description
|
||
|
text is shifted in more then once, the different sections are
|
||
|
appended with new line and an empty line between.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
@code
|
||
|
mrw::Args::instance()<<"this is a description for --help";
|
||
|
@endcode
|
||
|
*/
|
||
21 years ago
|
Args& operator<<(const std::string& description) throw(std::exception) {
|
||
21 years ago
|
if (_description=="")
|
||
|
_description = description;
|
||
|
else
|
||
|
_description += "\n\n"+description;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/** @brief set the help option
|
||
|
|
||
|
Define which option prints the help text. There is no code
|
||
|
needed for printing the help text: if the help option has been
|
||
|
shifted in, help is printed automatically at user request,
|
||
|
then the program is terminated. Only specify the short option
|
||
|
name, the long option name is known.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
@code
|
||
|
mrw::Args::instance()<<'h';
|
||
|
@endcode
|
||
|
*/
|
||
21 years ago
|
Args& operator<<(char helpopt) throw(std::exception) {
|
||
|
_help = helpopt;
|
||
21 years ago
|
return *this;
|
||
|
}
|
||
|
|
||
|
/** @brief get an option, given the short option name
|
||
|
@throw mrw::out_of_range if the option does not exist
|
||
|
*/
|
||
21 years ago
|
const Opt& find(char c) const throw(std::exception);
|
||
21 years ago
|
|
||
|
/** @brief get an option, given the long option name
|
||
|
@throw mrw::out_of_range if the option does not exist
|
||
|
*/
|
||
21 years ago
|
const Opt& find(const std::string& s) const throw(std::exception);
|
||
|
|
||
21 years ago
|
/** @brief get all non interpreted options
|
||
|
|
||
|
All user options that don't fit the defined and interpreted
|
||
|
options. The meaning for this is, that a user may append,
|
||
|
e.g. a list of file names.
|
||
|
*/
|
||
|
const OtherArgs& otherArgs() {
|
||
|
return _otherargs;
|
||
|
}
|
||
|
|
||
|
/** @brief get the file name of the executable, that's @c argv[0] */
|
||
21 years ago
|
const std::string& filename() throw(std::bad_exception) {
|
||
21 years ago
|
return _filename;
|
||
|
}
|
||
|
|
||
|
/** @brief print the help text, then exit */
|
||
|
void help() {
|
||
|
std::cout<<"USAGE: "<<std::endl
|
||
|
<<" "<<_filename<<" [ OPTIONS ]"<<std::endl
|
||
|
<<"OPTIONS:"<<std::endl;
|
||
|
for (Options::iterator it(_options.begin()); it!=_options.end(); ++it) {
|
||
|
std::cout<<" -"<<it->_shortname<<" | "<<it->_longname;
|
||
|
for (int i(0); i<it->_param.size(); ++i)
|
||
|
std::cout<<" <"<<(*it)[i]->typestr()<<">";
|
||
|
if (it->_param.size()>0) std::cout<<" (default: ";
|
||
|
for (int i(0); i<it->_param.size()-1; ++i)
|
||
|
std::cout<<(*it)[i]->printable()<<" ";
|
||
|
if (it->_param.size()>0)
|
||
|
std::cout<<(*it)[it->_param.size()-1]->printable()<<")";
|
||
|
std::cout<<std::endl<<" "<<it->help()<<std::endl;
|
||
|
}
|
||
|
if (_description.size()>0)
|
||
|
std::cout<<"DESCRIPTION:"<<std::endl
|
||
|
<<_description<<std::endl;
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
private:
|
||
21 years ago
|
Args(): _argc(-1), _help(0) {} // singleton
|
||
|
Args& operator=(const Args&); // singleton, not implemented
|
||
21 years ago
|
Args& parse(int argc, char const*const*const argv) throw(std::exception);
|
||
21 years ago
|
typedef std::list<Opt> Options;
|
||
|
typedef std::map<char, Options::iterator> ShortOpts;
|
||
|
typedef std::map<std::string, Options::iterator> LongOpts;
|
||
|
std::string _filename;
|
||
|
Options _options;
|
||
|
ShortOpts _shortopts;
|
||
|
LongOpts _longopts;
|
||
|
OtherArgs _otherargs;
|
||
|
int _argc;
|
||
|
char _help;
|
||
|
std::string _description;
|
||
|
};
|
||
|
|
||
|
//@}
|
||
|
}
|