#ifndef __ctkCommandLineParser_h #define __ctkCommandLineParser_h // Qt includes #include #include #include class QSettings; // CTK includes #include "ctkCoreExport.h" /** * \ingroup Core * * The CTK command line parser. * * Use this class to add information about the command line arguments * your program understands and to easily parse them from a given list * of strings. * * This parser provides the following features: * *
    *
  • Add arguments by supplying a long name and/or a short name. * Arguments are validated using a regular expression. They can have * a default value and a help string.
  • *
  • Deprecated arguments.
  • *
  • Custom regular expressions for argument validation.
  • *
  • Set different argument name prefixes for native platform look and feel.
  • *
  • QSettings support. Default values for arguments can be read from * a QSettings object.
  • *
  • Create a help text for the command line arguments with support for * grouping arguments.
  • *
* * Here is an example how to use this class inside a main function: * * \code * #include * #include * #include * * int main(int argc, char** argv) * { * QCoreApplication app(argc, argv); * // This is used by QSettings * QCoreApplication::setOrganizationName("MyOrg"); * QCoreApplication::setApplicationName("MyApp"); * * ctkCommandLineParser parser; * // Use Unix-style argument names * parser.setArgumentPrefix("--", "-"); * // Enable QSettings support * parser.enableSettings("disable-settings"); * * // Add command line argument names * parser.addArgument("disable-settings", "", QVariant::Bool, "Do not use QSettings"); * parser.addArgument("help", "h", QVariant::Bool, "Show this help text"); * parser.addArgument("search-paths", "s", QVariant::StringList, "A list of paths to search"); * * // Parse the command line arguments * bool ok = false; * QHash parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok); * if (!ok) * { * QTextStream(stderr, QIODevice::WriteOnly) << "Error parsing arguments: " * << parser.errorString() << "\n"; * return EXIT_FAILURE; * } * * // Show a help message * if (parsedArgs.contains("help") || parsedArgs.contains("h")) * { * QTextStream(stdout, QIODevice::WriteOnly) << parser.helpText(); * return EXIT_SUCCESS; * } * * // Do something * * return EXIT_SUCCESS; * } * \endcode */ class CTK_CORE_EXPORT ctkCommandLineParser : public QObject { Q_OBJECT Q_PROPERTY(QString errorString READ errorString) Q_PROPERTY(QStringList unparsedArguments READ unparsedArguments) Q_PROPERTY(bool settingsEnabled READ settingsEnabled) public: typedef QObject Superclass; /** * Constructs a parser instance. * * If QSettings support is enabled by a call to enableSettings() * a default constructed QSettings instance will be used when parsing * the command line arguments. Make sure to call QCoreApplication::setOrganizationName() * and QCoreApplication::setApplicationName() before using default * constructed QSettings objects. * * @param newParent The QObject parent. */ ctkCommandLineParser(QObject* newParent = 0); /** * Constructs a parser instance. * * If QSettings support is enabled by a call to enableSettings() * the provided QSettings instance will be used. If the QSettings instance is * zero, a default constructed QSettings instance will be used when parsing * the command line arguments. Using a default constructed instance is usually * what you want, if you have called QCoreApplication::setOrganizationName() * and QCoreApplication::setApplicationName(). * * @param settings A QSettings instance which should be used. * @param newParent The QObject parent. * * */ ctkCommandLineParser(QSettings* settings, QObject* newParent = 0); ~ctkCommandLineParser(); /** * Parse a given list of command line arguments. * * This method parses a list of QString elements considering the known arguments * added by calls to addArgument(). If any one of the argument * values does not match the corresponding regular expression, * ok is set to false and an empty QHash object is returned. * * The keys in the returned QHash object correspond to the long argument string, * if it is not empty. Otherwise, the short argument string is used as key. The * QVariant values can safely be converted to the type specified in the * addArgument() method call. * * @param arguments A QStringList containing command line arguments. Usually * given by QCoreApplication::arguments(). * @param ok A pointer to a boolean variable. Will be set to true * if all regular expressions matched, false otherwise. * @return A QHash object mapping the long argument (if empty, the short one) * to a QVariant containing the value. */ QHash parseArguments(const QStringList &arguments, bool* ok = 0); /** * Convenient method allowing to parse a given list of command line arguments. * @see parseArguments(const QStringList &, bool*) */ QHash parseArguments(int argc, char** argv, bool* ok = 0); /** * Returns a detailed error description if a call to parseArguments() * failed. * * @return The error description, empty if no error occured. * @see parseArguments(const QStringList&, bool*) */ QString errorString() const; /** * This method returns all unparsed arguments, i.e. all arguments * for which no long or short name has been registered via a call * to addArgument(). * * @see addArgument() * * @return A list containing unparsed arguments. */ const QStringList& unparsedArguments() const; /** * Checks if the given argument has been added via a call * to addArgument(). * * @see addArgument() * * @param argument The argument to be checked. * @return true if the argument was added, false * otherwise. */ Q_INVOKABLE bool argumentAdded(const QString& argument) const; /** * Checks if the given argument has been parsed successfully by a previous * call to parseArguments(). * * @param argument The argument to be checked. * @return true if the argument was parsed, false * otherwise. */ Q_INVOKABLE bool argumentParsed(const QString& argument) const; /** * Adds a command line argument. An argument can have a long name * (like --long-argument-name), a short name (like -l), or both. The type * of the argument can be specified by using the type parameter. * The following types are supported: * * * * * * * * *
Type# of parametersDefault regular exprExample
QVariant::String1.*--test-string StringParameter
QVariant::Bool0does not apply--enable-something
QVariant::StringList-1.*--test-list string1 string2
QVariant::Int1-?[0-9]+--test-int -5
* * The regular expressions are used to validate the parameters of command line * arguments. You can restrict the valid set of parameters by calling * setExactMatchRegularExpression() for your argument. * * Optionally, a help string and a default value can be provided for the argument. If * the QVariant type of the default value does not match type, an * exception is thrown. Arguments with default values are always returned by * parseArguments(). * * You can also declare an argument deprecated, by setting deprecated * to true. Alternatively you can add a deprecated argument by calling * addDeprecatedArgument(). * * If the long or short argument has already been added, or if both are empty strings, * the method call has no effect. * * @param longarg The long argument name. * @param shortarg The short argument name. * @param type The argument type (see the list above for supported types). * @param argHelp A help string describing the argument. * @param defaultValue A default value for the argument. * @param ignoreRest All arguments after the current one will be ignored. * @param deprecated Declares the argument deprecated. * * @see setExactMatchRegularExpression() * @see addDeprecatedArgument() * @throws std::logic_error If the QVariant type of defaultValue * does not match type, a std::logic_error is thrown. */ void addArgument(const QString& longarg, const QString& shortarg, QVariant::Type type, const QString& argHelp = QString(), const QVariant& defaultValue = QVariant(), bool ignoreRest = false, bool deprecated = false); /** * Adds a deprecated command line argument. If a deprecated argument is provided * on the command line, argHelp is displayed in the console and * processing continues with the next argument. * * Deprecated arguments are grouped separately at the end of the help text * returned by helpText(). * * @param longarg The long argument name. * @param shortarg The short argument name. * @param argHelp A help string describing alternatives to the deprecated argument. */ void addDeprecatedArgument(const QString& longarg, const QString& shortarg, const QString& argHelp); /** * Sets a custom regular expression for validating argument parameters. The method * errorString() can be used the get the last error description. * * @param argument The previously added long or short argument name. * @param expression A regular expression which the arugment parameters must match. * @param exactMatchFailedMessage An error message explaining why the parameter did * not match. * * @return true if the argument was found and the regular expression was set, * false otherwise. * * @see errorString() */ bool setExactMatchRegularExpression(const QString& argument, const QString& expression, const QString& exactMatchFailedMessage); /** * The field width for the argument names without the help text. * * @return The argument names field width in the help text. */ int fieldWidth() const; /** * Creates a help text containing properly formatted argument names and help strings * provided by calls to addArgument(). The arguments can be grouped by * using beginGroup() and endGroup(). * * @param charPad The padding character. * @return The formatted help text. */ QString helpText(const char charPad = ' ') const; /** * Sets the argument prefix for long and short argument names. This can be used * to create native command line arguments without changing the calls to * addArgument(). For example on Unix-based systems, long argument * names start with "--" and short names with "-", while on Windows argument names * always start with "/". * * Note that all methods in ctkCommandLineParser which take an argument name * expect the name as it was supplied to addArgument. * * Example usage: * * \code * ctkCommandLineParser parser; * parser.setArgumentPrefix("--", "-"); * parser.addArgument("long-argument", "l", QVariant::String); * QStringList args; * args << "program name" << "--long-argument Hi"; * parser.parseArguments(args); * \endcode * * @param longPrefix The prefix for long argument names. * @param shortPrefix The prefix for short argument names. */ void setArgumentPrefix(const QString& longPrefix, const QString& shortPrefix); /** * Begins a new group for documenting arguments. All newly added arguments via * addArgument() will be put in the new group. You can close the * current group by calling endGroup() or be opening a new group. * * Note that groups cannot be nested and all arguments which do not belong to * a group will be listed at the top of the text created by helpText(). * * @param description The description of the group */ void beginGroup(const QString& description); /** * Ends the current group. * * @see beginGroup(const QString&) */ void endGroup(); /** * Enables QSettings support in ctkCommandLineParser. If an argument name is found * in the QSettings instance with a valid QVariant, the value is considered as * a default value and overwrites default values registered with * addArgument(). User supplied values on the command line overwrite * values in the QSettings instance, except for arguments with multiple parameters * which are merged with QSettings values. Call mergeSettings(false) * to disable merging. * * See ctkCommandLineParser(QSettings*) for information about how to * supply a QSettings instance. * * Additionally, a long and short argument name can be specified which will disable * QSettings support if supplied on the command line. The argument name must be * registered as a regular argument via addArgument(). * * @param disableLongArg Long argument name. * @param disableShortArg Short argument name. * * @see ctkCommandLineParser(QSettings*) */ void enableSettings(const QString& disableLongArg = "", const QString& disableShortArg = ""); /** * Controlls the merging behavior of user values and QSettings values. * * If merging is on (the default), user supplied values for an argument * which can take more than one parameter are merged with values stored * in the QSettings instance. If merging is off, the user values overwrite * the QSettings values. * * @param merge true enables QSettings merging, false * disables it. */ void mergeSettings(bool merge); /** * Can be used to check if QSettings support has been enabled by a call to * enableSettings(). * * @return true if QSettings support is enabled, false * otherwise. */ bool settingsEnabled() const; /** * Can be used to teach the parser to stop parsing the arguments and return False when * an unknown argument is encountered. By default StrictMode is disabled. * * @see parseArguments(const QStringList &, bool*) */ void setStrictModeEnabled(bool strictMode); private: class ctkInternal; ctkInternal * Internal; }; #endif