Source: fun/SimpleCLParser.h


Annotated List
Files
Globals
Hierarchy
Index
#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.