Source: fun/SimpleCLParser.h
|
|
|
|
#ifndef SIMPLECLPARSER_H
#define SIMPLECLPARSER_H
#include
#include // nuts, for QStringList template members
namespace fun {
#define OPT_CERR if( SimpleCLParser::commandLineArgs().getBool( QString("--cerr"), false ) ) cerr << __FILE__ << ": " <0 then it is used as a char * prefix
* for all arguments and calls setArgPrefix( argpre ) to make that the default.
*
* Note that the values are added to this list (or overwrite existing entries), and the list
* is not cleared by this function.
*
* 'startAt' says which element in argv[] to start with.
* If startAt == 0, then this->getString( "$0" ) will return argv[0], in standard shell/perl fashion.
* name (argv[0]) in the args list.
*/
virtual int setArgs( int argc, char *argv[], int startAt=0, const char *argpre = 0 );
/**
* Similar to setArgs( int... ) except that this one reads a whole line of options, parses that into
* an array, then passes it to setArgs(...). Note that this _may_ (but should not, ideally) behave slightly
* differently from arguments passed to the other form, which typically come in as command-line args
* (parsed by your shell). This functions uses lib/fun/StringTokenizer.cpp to do it's parsing, so
* any differences in behaviour should be resolved there.
*/
virtual int setArgs( QString args, QString separators = " " );
void setArgPrefix( const char *pre );
/**
If this is set in main(), other objects will have use of them
via commandLineArgs().
Only call the argumented version one time from main(), please.
*/
static SimpleCLParser & commandLineArgs( int argc, char *argv[] );
static SimpleCLParser & commandLineArgs();
/**
* isHelpSet() returns true if any of the following properties have been set:
* -?, --help, -help.
* It is intended to be used by applications, so they can call dump() and bail
* out if a user asks for help.
*/
virtual bool isHelpSet();
/**
* Describes arguments, for use with dump()
*/
void describe( const char *key, const char *type, const char *comments );
/**
* Dumps the arg descriptions, plus the current values, if they are set.
* If header is set it is printed out first.
* This is intended to be used with --help/-?.
*/
QString dump( QString header = QString() );
private:
const char *argprefix;
PropertyList *descr; // list of the descriptions of our args.
};
/**
* This is another simple command-line parser.
*
* This one takes references to the variables which you want to fill from
* the command line, and
* For example, if you take an input file & output file, some integer, and
* a boolean flag, you might declare these variables:
*
*
* QString infile("foo.in"), outfile("foo.out");
* int its = 10;
* bool hose = false;
*
*
* and register the arguments (and their descriptions) like this:
*
*
* OtherSimpleCLParser args;
* args.add("i filename", infile, "the input file");
* args.add("o filename", outfile, "the output file");
* args.add("it iterations", its, "number of times to iterate");
* args.add("h", hose, "hose things up");
* ...
* args.parse(argc, argv);
*
*
* If there were errors, a usage message was generated & printed, and the
* program was terminated. You can do additional checking afterwards:
*
*
* if (infile == outfile) args.usage("infile == outfile, you bozo");
*
*
* When you're all done checking the command line arguments, let the
* OtherSimpleCLParser object go out of scope, or call its dispose() method.
* (The variables you gave it will continue to contain the values which were
* passed on the command line, of course.)
*/
class OtherSimpleCLParser
{
public:
OtherSimpleCLParser() { }
~OtherSimpleCLParser() { dispose(); }
/**
* Adds a command-line flag to the list of arguments which will be
* looked for.
*
* @param flag Either just the flag, or the flag, a space, and some
* indication of what argument is expected (like "f filename"
* or "s name").
* @param val A reference to the variable which will be set to the value
* read from the command line.
* @param descr A description of the command-line flag. This will be
* used in the message generated by usage(), if usage() is
* called.
* @param required If this is true, then failing to pass the flag on the
* command line will cause usage() to be called.
*/
template
void add(const QString &flag, AC &val, const QString &descr, bool required = false);
/**
* Adds a positional command-line argument to the list of arguments
* which will be looked for.
*
* Note that all required positional arguments must precede
* optional positional arguments. Also, a positional argument
* type which takes multiple arguments (like QStringList) will cause
* everything after it to never be received, because all the arguments
* will go into the QStringList. (OK, rereading that, it doesn't even
* make sense to me. Sorry!)
*
* @param name some indication of what argument is expected (like
* "filename" or "name").
* @param val A reference to the variable which will be set to the value
* read from the command line.
* @param descr A description of the command-line flag. This will be
* used in the message generated by usage(), if usage() is
* called.
* @param required If this is true, then failing to pass the flag on the
* command line will cause usage() to be called.
*
*/
template
void addPositional(const QString &flag, AC &val, const QString &descr, bool required = false);
/**
* Parses the given arguments and puts their values into the variables
* passed to add(). If there are errors, usage() is called.
*/
void parse(int argc, char **argv);
/**
* Prints a formatted usage message to cerr and terminates the program.
* If a specific message is supplied, it's printed first.
*/
void usage(const QString &msg = QString());
/**
* Cleans up the storage allocated by calls to add(). Call this
* when you're done using the OtherSimpleCLParser (that is, after the last
* point when you'd call usage()), or just let it go out of scope.
*/
void dispose();
void assertGood(const QString &key, const QString &descr); // gcc 2.95.3 won't let us use this from inner classes if it's private
private:
class BaseArgHolder
{
public:
BaseArgHolder(OtherSimpleCLParser &p, const QString &k, const QString &d, bool p, bool r);// : key(k), descr(d), required(r), found(false) { int pos = key.find(' '); if (pos != -1) { argtype = key.right(key.length() - }
virtual ~BaseArgHolder() { } // otherwise gcc warns
// Called when the flag has been found on the command line. It
// should return true if the argument can be converted to the
// necessary type, or false otherwise.
virtual bool receive(const QString &arg) = 0;
// used to show the default value in the usage message--should
// convert the native value to a QString
virtual QString value() = 0;
// true if this flag can be specified multiple times on the
// command line.
virtual bool acceptsMultiple() = 0;
// true if this flag requires an argument. Basically this is true
// for everything except bool.
virtual bool needsArg() = 0;
QString key;
QString argtype;
QString descr;
bool positional;
bool required;
bool found;
};
template
class ArgHolder : public BaseArgHolder
{
public:
ArgHolder(OtherSimpleCLParser &p, const QString &k, const QString &d, AC &ar, bool pos, bool r) : BaseArgHolder(p, k, d, pos, r), ap(&ar) { }
virtual bool receive(const QString &arg);
virtual QString value();
virtual bool acceptsMultiple() { return false; }
virtual bool needsArg() { return true /*!argtype.isNull()*/; }
AC *ap;
};
std::vector args;
std::vector posArgs;
QString argv0;
};
template
void
OtherSimpleCLParser::add(const QString &flag, AC &val, const QString &descr, bool required)
{
args.push_back(new ArgHolder(*this, flag, descr, val, false, required));
}
template
void
OtherSimpleCLParser::addPositional(const QString &flag, AC &val, const QString &descr, bool required)
{
posArgs.push_back(new ArgHolder(*this, flag, descr, val, true, required));
}
} // namespace fun
#endif // SIMPLECLPARSER_H
| Generated by: stephan on cheyenne on Mon Aug 11 14:06:52 2003, using kdoc 2.0a54. |