diff --git a/src/app/core/qcommandlineoption.cpp b/src/app/core/qcommandlineoption.cpp index a18f3e2a9..a27b4e1d2 100644 --- a/src/app/core/qcommandlineoption.cpp +++ b/src/app/core/qcommandlineoption.cpp @@ -67,7 +67,7 @@ public: This class is used to describe an option on the command line. It allows different ways of defining the same option with multiple aliases possible. It is also used to describe how the option is used - it may be a flag (e.g. \c{-v}) - or take a value (e.g. \c{-o file}). + or take an argument (e.g. \c{-o file}). Examples: \snippet code/src_corelib_tools_qcommandlineoption.cpp 0 @@ -83,41 +83,6 @@ public: \since 5.2 */ -/*! - Constructs a command line option object with the name \a name. - - The name can be either short or long. If the name is one character in - length, it is considered a short name. Option names must not be empty, - must not start with a dash or a slash character, must not contain a \c{=} - and cannot be repeated. - - \sa setDescription(), setValueName(), setDefaultValues() -*/ -QCommandLineOption::QCommandLineOption(const QString &name) - : d(new QCommandLineOptionPrivate) -{ - d->setNames(QStringList(name)); -} - -/*! - Constructs a command line option object with the names \a names. - - This overload allows to set multiple names for the option, for instance - \c{o} and \c{output}. - - The names can be either short or long. Any name in the list that is one - character in length is a short name. Option names must not be empty, - must not start with a dash or a slash character, must not contain a \c{=} - and cannot be repeated. - - \sa setDescription(), setValueName(), setDefaultValues() -*/ -QCommandLineOption::QCommandLineOption(const QStringList &names) - : d(new QCommandLineOptionPrivate) -{ - d->setNames(names); -} - /*! Constructs a command line option object with the given arguments. @@ -133,12 +98,6 @@ QCommandLineOption::QCommandLineOption(const QStringList &names) In addition, the \a valueName can be set if the option expects a value. The default value for the option is set to \a defaultValue. - In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 - and later, it no longer is and can be used for C++11-style uniform - initialization: - - \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init - \sa setDescription(), setValueName(), setDefaultValues() */ QCommandLineOption::QCommandLineOption(const QString &name, const QString &description, @@ -170,12 +129,6 @@ QCommandLineOption::QCommandLineOption(const QString &name, const QString &descr In addition, the \a valueName can be set if the option expects a value. The default value for the option is set to \a defaultValue. - In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 - and later, it no longer is and can be used for C++11-style uniform - initialization: - - \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init-list - \sa setDescription(), setValueName(), setDefaultValues() */ QCommandLineOption::QCommandLineOption(const QStringList &names, const QString &description, @@ -234,8 +187,7 @@ QStringList QCommandLineOption::names() const void QCommandLineOptionPrivate::setNames(const QStringList &nameList) { - QStringList newNames; - newNames.reserve(nameList.size()); + names.clear(); if (nameList.isEmpty()) qWarning("QCommandLineOption: Options must have at least one name"); foreach (const QString &name, nameList) { @@ -250,11 +202,9 @@ void QCommandLineOptionPrivate::setNames(const QStringList &nameList) else if (name.contains(QLatin1Char('='))) qWarning("QCommandLineOption: Option names cannot contain a '='"); else - newNames.append(name); + names.append(name); } } - // commit - names.swap(newNames); } /*! @@ -267,8 +217,8 @@ void QCommandLineOptionPrivate::setNames(const QStringList &nameList) for the documentation of the option in the help output. An option with names \c{o} and \c{output}, and a value name of \c{file} will appear as \c{-o, --output }. - Call QCommandLineParser::value() if you expect the option to be present - only once, and QCommandLineParser::values() if you expect that option + Call QCommandLineParser::argument() if you expect the option to be present + only once, and QCommandLineParser::arguments() if you expect that option to be present multiple times. \sa valueName() @@ -326,13 +276,9 @@ QString QCommandLineOption::description() const */ void QCommandLineOption::setDefaultValue(const QString &defaultValue) { - QStringList newDefaultValues; - if (!defaultValue.isEmpty()) { - newDefaultValues.reserve(1); - newDefaultValues << defaultValue; - } - // commit: - d->defaultValues.swap(newDefaultValues); + d->defaultValues.clear(); + if (!defaultValue.isEmpty()) + d->defaultValues << defaultValue; } /*! @@ -358,4 +304,5 @@ QStringList QCommandLineOption::defaultValues() const return d->defaultValues; } + #endif //QT_VERSION < QT_VERSION_CHECK(5, 2, 0) diff --git a/src/app/core/qcommandlineoption.h b/src/app/core/qcommandlineoption.h index abc2abeae..b2f044fcb 100644 --- a/src/app/core/qcommandlineoption.h +++ b/src/app/core/qcommandlineoption.h @@ -36,12 +36,10 @@ class QCommandLineOptionPrivate; class QCommandLineOption { public: - explicit QCommandLineOption(const QString &name); - explicit QCommandLineOption(const QStringList &names); - /*implicit*/ QCommandLineOption(const QString &name, const QString &description, + explicit QCommandLineOption(const QString &name, const QString &description = QString(), const QString &valueName = QString(), const QString &defaultValue = QString()); - /*implicit*/ QCommandLineOption(const QStringList &names, const QString &description, + explicit QCommandLineOption(const QStringList &names, const QString &description = QString(), const QString &valueName = QString(), const QString &defaultValue = QString()); QCommandLineOption(const QCommandLineOption &other); diff --git a/src/app/core/qcommandlineparser.cpp b/src/app/core/qcommandlineparser.cpp index 814b3f1de..7d9ab7128 100644 --- a/src/app/core/qcommandlineparser.cpp +++ b/src/app/core/qcommandlineparser.cpp @@ -24,17 +24,11 @@ #include #include #include -#include -#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) -# include -#endif #include #include #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) -typedef QHash NameHash_t; - #ifdef Q_CC_GNU #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" @@ -42,6 +36,8 @@ typedef QHash NameHash_t; #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #endif +typedef QHash NameHash_t; + class QCommandLineParserPrivate { public: @@ -169,10 +165,6 @@ QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const Example: \snippet code/src_corelib_tools_qcommandlineparser_main.cpp 0 - If your compiler supports the C++11 standard, the three addOption() calls in - the above example can be simplified: - \snippet code/src_corelib_tools_qcommandlineparser_main.cpp cxx11 - Known limitation: the parsing of Qt options inside QCoreApplication and subclasses happens before QCommandLineParser exists, so it can't take it into account. This means any option value that looks like a builtin Qt option, will be treated by @@ -181,78 +173,6 @@ QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const QCoreApplication::arguments() before QCommandLineParser defines the \c{profile} option and parses the command line. - \section2 How to Use QCommandLineParser in Complex Applications - - In practice, additional error checking needs to be performed on the positional - arguments and option values. For example, ranges of numbers should be checked. - - It is then advisable to introduce a function to do the command line parsing - which takes a struct or class receiving the option values returning an - enumeration representing the result. The dnslookup example of the QtNetwork - module illustrates this: - - \snippet dnslookup.h 0 - - \snippet dnslookup.cpp 0 - - In the main function, help should be printed to the standard output if the help option - was passed and the application should return the exit code 0. - - If an error was detected, the error message should be printed to the standard - error output and the application should return an exit code other than 0. - - \snippet dnslookup.cpp 1 - - A special case to consider here are GUI applications on Windows and mobile - platforms. These applications may not use the standard output or error channels - since the output is either discarded or not accessible. - - For such GUI applications, it is recommended to display help texts and error messages - using a QMessageBox. To preserve the formatting of the help text, rich text - with \c
 elements should be used:
-
-    \code
-
-    switch (parseCommandLine(parser, &query, &errorMessage)) {
-    case CommandLineOk:
-        break;
-    case CommandLineError:
-#ifdef Q_OS_WIN
-        QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
-                             "

" + errorMessage + "

"
-                             + parser.helpText() + "
"); -#else - fputs(qPrintable(errorMessage), stderr); - fputs("\n\n", stderr); - fputs(qPrintable(parser.helpText()), stderr); -#endif - return 1; - case CommandLineVersionRequested: -#ifdef Q_OS_WIN - QMessageBox::information(0, QGuiApplication::applicationDisplayName(), - QGuiApplication::applicationDisplayName() + ' ' - + QCoreApplication::applicationVersion()); -#else - printf("%s %s\n", QGuiApplication::applicationDisplayName(), - qPrintable(QCoreApplication::applicationVersion())); -#endif - return 0; - case CommandLineHelpRequested: -#ifdef Q_OS_WIN - QMessageBox::warning(0, QGuiApplication::applicationDisplayName(), - "
"
-                             + parser.helpText() + "
"); - return 0; -#else - parser.showHelp(); - Q_UNREACHABLE(); -#endif - } - \endcode - - However, this does not apply to the dnslookup example, because it is a - console application. - \sa QCommandLineOption, QCoreApplication */ @@ -335,26 +255,6 @@ bool QCommandLineParser::addOption(const QCommandLineOption &option) return false; } -/*! - \since 5.4 - - Adds the options to look for while parsing. The options are specified by - the parameter \a options. - - Returns \c true if adding all of the options was successful; otherwise - returns \c false. - - See the documentation for addOption() for when this function may fail. -*/ -bool QCommandLineParser::addOptions(const QList &options) -{ - // should be optimized (but it's no worse than what was possible before) - bool result = true; - for (QList::const_iterator it = options.begin(), end = options.end(); it != end; ++it) - result &= addOption(*it); - return result; -} - /*! Adds the \c{-v} / \c{--version} option, which displays the version string of the application. @@ -366,9 +266,9 @@ bool QCommandLineParser::addOptions(const QList &options) */ QCommandLineOption QCommandLineParser::addVersionOption() { + d->builtinVersionOption = true; QCommandLineOption opt(QStringList() << QStringLiteral("v") << QStringLiteral("version"), tr("Displays version information.")); addOption(opt); - d->builtinVersionOption = true; return opt; } @@ -386,6 +286,7 @@ QCommandLineOption QCommandLineParser::addVersionOption() */ QCommandLineOption QCommandLineParser::addHelpOption() { + d->builtinHelpOption = true; QCommandLineOption opt(QStringList() #ifdef Q_OS_WIN << QStringLiteral("?") @@ -393,7 +294,6 @@ QCommandLineOption QCommandLineParser::addHelpOption() << QStringLiteral("h") << QStringLiteral("help"), tr("Displays this help.")); addOption(opt); - d->builtinHelpOption = true; return opt; } @@ -509,8 +409,10 @@ void QCommandLineParser::process(const QStringList &arguments) ::exit(EXIT_FAILURE); } - if (d->builtinVersionOption && isSet(QStringLiteral("version"))) - showVersion(); + if (d->builtinVersionOption && isSet(QStringLiteral("version"))) { + printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion())); + ::exit(EXIT_SUCCESS); + } if (d->builtinHelpOption && isSet(QStringLiteral("help"))) showHelp(EXIT_SUCCESS); @@ -804,8 +706,7 @@ QStringList QCommandLineParser::values(const QString &optionName) const */ bool QCommandLineParser::isSet(const QCommandLineOption &option) const { - // option.names() might be empty if the constructor failed - return !option.names().isEmpty() && isSet(option.names().first()); + return isSet(option.names().first()); } /*! @@ -899,22 +800,6 @@ QStringList QCommandLineParser::unknownOptionNames() const return d->unknownOptionNames; } -/*! - Displays the version information from QCoreApplication::applicationVersion(), - and exits the application. - This is automatically triggered by the --version option, but can also - be used to display the version when not using process(). - The exit code is set to EXIT_SUCCESS (0). - - \sa addVersionOption() - \since 5.4 -*/ -Q_NORETURN void QCommandLineParser::showVersion() -{ - fprintf(stdout, "%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion())); - ::exit(EXIT_SUCCESS); -} - /*! Displays the help information, and exits the application. This is automatically triggered by the --help option, but can also @@ -946,50 +831,11 @@ static QString wrapText(const QString &names, int longestOptionNameString, const { const QLatin1Char nl('\n'); QString text = QStringLiteral(" ") + names.leftJustified(longestOptionNameString) + QLatin1Char(' '); - const int indent = text.length(); - int lineStart = 0; - int lastBreakable = -1; - const int max = 79 - indent; - int x = 0; - const int len = description.length(); - - for (int i = 0; i < len; ++i) { - ++x; - const QChar c = description.at(i); - if (c.isSpace()) - lastBreakable = i; - - int breakAt = -1; - int nextLineStart = -1; - if (x > max && lastBreakable != -1) { - // time to break and we know where - breakAt = lastBreakable; - nextLineStart = lastBreakable + 1; - } else if ((x > max - 1 && lastBreakable == -1) || i == len - 1) { - // time to break but found nowhere [-> break here], or end of last line - breakAt = i + 1; - nextLineStart = breakAt; - } else if (c == nl) { - // forced break - breakAt = i; - nextLineStart = i + 1; - } - - if (breakAt != -1) { - const int numChars = breakAt - lineStart; - //qDebug() << "breakAt=" << description.at(breakAt) << "breakAtSpace=" << breakAtSpace << lineStart << "to" << breakAt << description.mid(lineStart, numChars); - if (lineStart > 0) - text += QString(indent, QLatin1Char(' ')); - text += description.midRef(lineStart, numChars) + nl; - x = 0; - lastBreakable = -1; - lineStart = nextLineStart; - if (lineStart < len && description.at(lineStart).isSpace()) - ++lineStart; // don't start a line with a space - i = lineStart; - } - } - + const int leftColumnWidth = text.length(); + const int rightColumnWidth = 79 - leftColumnWidth; + text += description.left(rightColumnWidth) + nl; + for (int n = rightColumnWidth; n < description.length(); n += rightColumnWidth) + text += QStringLiteral(" ").repeated(leftColumnWidth) + description.mid(n, rightColumnWidth) + nl; return text; } @@ -1045,6 +891,7 @@ QString QCommandLineParserPrivate::helpText() const return text; } + #ifdef Q_CC_GNU #pragma GCC diagnostic pop #endif diff --git a/src/app/core/qcommandlineparser.h b/src/app/core/qcommandlineparser.h index 568b25cbc..9842a1ce2 100644 --- a/src/app/core/qcommandlineparser.h +++ b/src/app/core/qcommandlineparser.h @@ -48,7 +48,6 @@ public: void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode); bool addOption(const QCommandLineOption &commandLineOption); - bool addOptions(const QList &options); QCommandLineOption addVersionOption(); QCommandLineOption addHelpOption(); @@ -75,7 +74,6 @@ public: QStringList optionNames() const; QStringList unknownOptionNames() const; - Q_NORETURN void showVersion(); Q_NORETURN void showHelp(int exitCode = 0); QString helpText() const;