Long live QCommandLineParser!
The QCommandLineParser class provides a means for handling the command line options. QCoreApplication provides the command-line arguments as a simple list of strings. QCommandLineParser provides the ability to define a set of options, parse the command-line arguments, and store which options have actually been used, as well as option values. Done-with: Laszlo Papp <lpapp@kde.org> Change-Id: Ic7bebc10b3f8d8dd06ad0f4bb897c51d566e3b7c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
1411a6f1ac
commit
404598b613
1
.gitignore
vendored
1
.gitignore
vendored
@ -311,6 +311,7 @@ tests/auto/corelib/io/qresourceengine/qresourceengine
|
|||||||
tests/auto/corelib/codecs/qtextcodec/echo/echo
|
tests/auto/corelib/codecs/qtextcodec/echo/echo
|
||||||
tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness
|
tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness
|
||||||
tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper
|
tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper
|
||||||
|
tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper
|
||||||
tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver
|
tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver
|
||||||
tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger
|
tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger
|
||||||
tests/auto/dbus/qdbusabstractinterface/test/pinger_interface.*
|
tests/auto/dbus/qdbusabstractinterface/test/pinger_interface.*
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 David Faure <faure@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the documentation of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
//! [0]
|
||||||
|
QCommandLineOption verboseOption("verbose", "Verbose mode. Prints out more information.");
|
||||||
|
QCommandLineOption outputOption(QStringList() << "o" << "output", "Write generated data into <file>.", "file");
|
||||||
|
//! [0]
|
@ -0,0 +1,141 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 David Faure <faure@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the documentation of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
//! [0]
|
||||||
|
bool verbose = parser.isSet("verbose");
|
||||||
|
//! [0]
|
||||||
|
|
||||||
|
//! [1]
|
||||||
|
// Usage: image-editor file
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// file The file to open.
|
||||||
|
parser.addPositionalArgument("file", QCoreApplication::translate("main", "The file to open."));
|
||||||
|
|
||||||
|
// Usage: web-browser [urls...]
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// urls URLs to open, optionally.
|
||||||
|
parser.addPositionalArgument("urls", QCoreApplication::translate("main", "URLs to open, optionally."), "[urls...]");
|
||||||
|
|
||||||
|
// Usage: cp source destination
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// source Source file to copy.
|
||||||
|
// destination Destination directory.
|
||||||
|
parser.addPositionalArgument("source", QCoreApplication::translate("main", "Source file to copy."));
|
||||||
|
parser.addPositionalArgument("destination", QCoreApplication::translate("main", "Destination directory."));
|
||||||
|
//! [1]
|
||||||
|
|
||||||
|
//! [2]
|
||||||
|
parser.addPositionalArgument("command", "The command to execute.");
|
||||||
|
|
||||||
|
// Call parse() to find out the positional arguments.
|
||||||
|
parser.parse(QCoreApplication::arguments());
|
||||||
|
|
||||||
|
const QStringList args = parser.positionalArguments();
|
||||||
|
const QString command = args.isEmpty() ? QString() : args.first();
|
||||||
|
if (command == "resize") {
|
||||||
|
parser.clearPositionalArguments();
|
||||||
|
parser.addPositionalArgument("resize", "Resize the object to a new size.", "resize [resize_options]");
|
||||||
|
parser.addOption(QCommandLineOption("size", "New size.", "new_size"));
|
||||||
|
parser.process(app);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
This code results in context-dependent help:
|
||||||
|
|
||||||
|
$ tool --help
|
||||||
|
Usage: tool command
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
command The command to execute.
|
||||||
|
|
||||||
|
$ tool resize --help
|
||||||
|
Usage: tool resize [resize_options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--size <size> New size.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
resize Resize the object to a new size.
|
||||||
|
|
||||||
|
//! [2]
|
||||||
|
|
||||||
|
//! [3]
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
app.setApplicationName("my-copy-program");
|
||||||
|
app.setApplicationVersion("1.0");
|
||||||
|
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.addHelpOption("Test helper");
|
||||||
|
parser.addVersionOption();
|
||||||
|
parser.addRemainingArgument("source", QCoreApplication::translate("main", "Source file to copy."));
|
||||||
|
parser.addRemainingArgument("destination", QCoreApplication::translate("main", "Destination directory."));
|
||||||
|
|
||||||
|
// A boolean option with a single name (-p)
|
||||||
|
QCommandLineOption showProgressOption("p", QCoreApplication::translate("main", "Show progress during copy"));
|
||||||
|
parser.addOption(showProgressOption);
|
||||||
|
|
||||||
|
// A boolean option with multiple names (-f, --force)
|
||||||
|
QCommandLineOption forceOption(QStringList() << "f" << "force", "Overwrite existing files.");
|
||||||
|
parser.addOption(forceOption);
|
||||||
|
|
||||||
|
// An option with a value
|
||||||
|
QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
|
||||||
|
QCoreApplication::translate("main", "Copy all source files into <directory>."),
|
||||||
|
QCoreApplication::translate("main", "directory"));
|
||||||
|
parser.addOption(targetDirectoryOption);
|
||||||
|
|
||||||
|
// Process the actual command line arguments given by the user
|
||||||
|
parser.process(app);
|
||||||
|
|
||||||
|
const QStringList args = parser.remainingArguments();
|
||||||
|
// source is args.at(0), destination is args.at(1)
|
||||||
|
|
||||||
|
bool showProgress = parser.isSet(showProgressOption);
|
||||||
|
bool force = parser.isSet(forceOption);
|
||||||
|
QString targetDir = parser.value(targetDirectoryOption);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//! [3]
|
@ -589,6 +589,8 @@ void QCoreApplicationPrivate::initLocale()
|
|||||||
Note that some arguments supplied by the user may have been
|
Note that some arguments supplied by the user may have been
|
||||||
processed and removed by QCoreApplication.
|
processed and removed by QCoreApplication.
|
||||||
|
|
||||||
|
For more advanced command line option handling, create a QCommandLineParser.
|
||||||
|
|
||||||
\section1 Locale Settings
|
\section1 Locale Settings
|
||||||
|
|
||||||
On Unix/Linux Qt is configured to use the system locale settings by
|
On Unix/Linux Qt is configured to use the system locale settings by
|
||||||
@ -2060,7 +2062,7 @@ qint64 QCoreApplication::applicationPid()
|
|||||||
As a result of this, the string given by arguments().at(0) might not be
|
As a result of this, the string given by arguments().at(0) might not be
|
||||||
the program name on Windows, depending on how the application was started.
|
the program name on Windows, depending on how the application was started.
|
||||||
|
|
||||||
\sa applicationFilePath()
|
\sa applicationFilePath(), QCommandLineParser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QStringList QCoreApplication::arguments()
|
QStringList QCoreApplication::arguments()
|
||||||
|
308
src/corelib/tools/qcommandlineoption.cpp
Normal file
308
src/corelib/tools/qcommandlineoption.cpp
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
|
||||||
|
** Copyright (C) 2013 David Faure <faure@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qcommandlineoption.h"
|
||||||
|
|
||||||
|
#include "qset.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QCommandLineOptionPrivate : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline QCommandLineOptionPrivate()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void setNames(const QStringList &nameList);
|
||||||
|
|
||||||
|
//! The list of names used for this option.
|
||||||
|
QStringList names;
|
||||||
|
|
||||||
|
//! The documentation name for the value, if one is expected
|
||||||
|
//! Example: "-o <file>" means valueName == "file"
|
||||||
|
QString valueName;
|
||||||
|
|
||||||
|
//! The description used for this option.
|
||||||
|
QString description;
|
||||||
|
|
||||||
|
//! The list of default values used for this option.
|
||||||
|
QStringList defaultValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.2
|
||||||
|
\class QCommandLineOption
|
||||||
|
\brief The QCommandLineOption class defines a possible command-line option.
|
||||||
|
\inmodule QtCore
|
||||||
|
\ingroup shared
|
||||||
|
\ingroup tools
|
||||||
|
|
||||||
|
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 an argument (e.g. \c{-o file}).
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
\snippet code/src_corelib_tools_qcommandlineoption.cpp 0
|
||||||
|
|
||||||
|
\sa QCommandLineParser
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a command line option object with the given arguments.
|
||||||
|
|
||||||
|
The name of the option is set to \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.
|
||||||
|
|
||||||
|
The description is set to \a description. It is customary to add a "."
|
||||||
|
at the end of the description.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
\sa setDescription(), setValueName(), setDefaultValues()
|
||||||
|
*/
|
||||||
|
QCommandLineOption::QCommandLineOption(const QString &name, const QString &description,
|
||||||
|
const QString &valueName,
|
||||||
|
const QString &defaultValue)
|
||||||
|
: d(new QCommandLineOptionPrivate)
|
||||||
|
{
|
||||||
|
d->setNames(QStringList(name));
|
||||||
|
setValueName(valueName);
|
||||||
|
setDescription(description);
|
||||||
|
setDefaultValue(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a command line option object with the given arguments.
|
||||||
|
|
||||||
|
This overload allows to set multiple names for the option, for instance
|
||||||
|
\c{o} and \c{output}.
|
||||||
|
|
||||||
|
The names of the option are set to \a names.
|
||||||
|
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.
|
||||||
|
|
||||||
|
The description is set to \a description. It is customary to add a "."
|
||||||
|
at the end of the description.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
\sa setDescription(), setValueName(), setDefaultValues()
|
||||||
|
*/
|
||||||
|
QCommandLineOption::QCommandLineOption(const QStringList &names, const QString &description,
|
||||||
|
const QString &valueName,
|
||||||
|
const QString &defaultValue)
|
||||||
|
: d(new QCommandLineOptionPrivate)
|
||||||
|
{
|
||||||
|
d->setNames(names);
|
||||||
|
setValueName(valueName);
|
||||||
|
setDescription(description);
|
||||||
|
setDefaultValue(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a QCommandLineOption object that is a copy of the QCommandLineOption
|
||||||
|
object \a other.
|
||||||
|
|
||||||
|
\sa operator=()
|
||||||
|
*/
|
||||||
|
QCommandLineOption::QCommandLineOption(const QCommandLineOption &other)
|
||||||
|
: d(other.d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys the command line option object.
|
||||||
|
*/
|
||||||
|
QCommandLineOption::~QCommandLineOption()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Makes a copy of the \a other object and assigns it to this QCommandLineOption
|
||||||
|
object.
|
||||||
|
*/
|
||||||
|
QCommandLineOption &QCommandLineOption::operator=(const QCommandLineOption &other)
|
||||||
|
{
|
||||||
|
d = other.d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QCommandLineOption::swap(QCommandLineOption &other)
|
||||||
|
|
||||||
|
Swaps option \a other with this option. This operation is very
|
||||||
|
fast and never fails.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the names set for this option.
|
||||||
|
*/
|
||||||
|
QStringList QCommandLineOption::names() const
|
||||||
|
{
|
||||||
|
return d->names;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCommandLineOptionPrivate::setNames(const QStringList &nameList)
|
||||||
|
{
|
||||||
|
names.clear();
|
||||||
|
if (nameList.isEmpty())
|
||||||
|
qWarning("Options must have at least one name");
|
||||||
|
foreach (const QString &name, nameList) {
|
||||||
|
if (name.isEmpty())
|
||||||
|
qWarning("Option names cannot be empty");
|
||||||
|
else if (name.startsWith(QLatin1Char('-')))
|
||||||
|
qWarning("Option names cannot start with a '-'");
|
||||||
|
else if (name.startsWith(QLatin1Char('/')))
|
||||||
|
qWarning("Option names cannot start with a '/'");
|
||||||
|
else if (name.contains(QLatin1Char('=')))
|
||||||
|
qWarning("Option names cannot contain a '='");
|
||||||
|
else
|
||||||
|
names.append(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the name of the expected value, for the documentation, to \a valueName.
|
||||||
|
|
||||||
|
Options without a value assigned have a boolean-like behavior:
|
||||||
|
either the user specifies --option or they don't.
|
||||||
|
|
||||||
|
Options with a value assigned need to set a name for the expected value,
|
||||||
|
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 <file>}.
|
||||||
|
|
||||||
|
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()
|
||||||
|
*/
|
||||||
|
void QCommandLineOption::setValueName(const QString &valueName)
|
||||||
|
{
|
||||||
|
d->valueName = valueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the name of the expected value.
|
||||||
|
|
||||||
|
If empty, the option doesn't take a value.
|
||||||
|
|
||||||
|
\sa setValueName()
|
||||||
|
*/
|
||||||
|
QString QCommandLineOption::valueName() const
|
||||||
|
{
|
||||||
|
return d->valueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the description used for this option to \a description.
|
||||||
|
|
||||||
|
It is customary to add a "." at the end of the description.
|
||||||
|
|
||||||
|
The description is used by QCommandLineParser::showHelp().
|
||||||
|
|
||||||
|
\sa description()
|
||||||
|
*/
|
||||||
|
void QCommandLineOption::setDescription(const QString &description)
|
||||||
|
{
|
||||||
|
d->description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the description set for this option.
|
||||||
|
|
||||||
|
\sa setDescription()
|
||||||
|
*/
|
||||||
|
QString QCommandLineOption::description() const
|
||||||
|
{
|
||||||
|
return d->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the default value used for this option to \a defaultValue.
|
||||||
|
|
||||||
|
The default value is used if the user of the application does not specify
|
||||||
|
the option on the command line.
|
||||||
|
|
||||||
|
If \a defaultValue is empty, the option has no default values.
|
||||||
|
|
||||||
|
\sa defaultValues() setDefaultValues()
|
||||||
|
*/
|
||||||
|
void QCommandLineOption::setDefaultValue(const QString &defaultValue)
|
||||||
|
{
|
||||||
|
d->defaultValues.clear();
|
||||||
|
if (!defaultValue.isEmpty())
|
||||||
|
d->defaultValues << defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the list of default values used for this option to \a defaultValues.
|
||||||
|
|
||||||
|
The default values are used if the user of the application does not specify
|
||||||
|
the option on the command line.
|
||||||
|
|
||||||
|
\sa defaultValues() setDefaultValue()
|
||||||
|
*/
|
||||||
|
void QCommandLineOption::setDefaultValues(const QStringList &defaultValues)
|
||||||
|
{
|
||||||
|
d->defaultValues = defaultValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the default values set for this option.
|
||||||
|
|
||||||
|
\sa setDefaultValues()
|
||||||
|
*/
|
||||||
|
QStringList QCommandLineOption::defaultValues() const
|
||||||
|
{
|
||||||
|
return d->defaultValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
92
src/corelib/tools/qcommandlineoption.h
Normal file
92
src/corelib/tools/qcommandlineoption.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QCOMMANDLINEOPTION_H
|
||||||
|
#define QCOMMANDLINEOPTION_H
|
||||||
|
|
||||||
|
#include <QtCore/qstringlist.h>
|
||||||
|
#include <QtCore/qshareddata.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QCommandLineOptionPrivate;
|
||||||
|
|
||||||
|
class Q_CORE_EXPORT QCommandLineOption
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit QCommandLineOption(const QString &name, const QString &description = QString(),
|
||||||
|
const QString &valueName = QString(),
|
||||||
|
const QString &defaultValue = QString());
|
||||||
|
explicit QCommandLineOption(const QStringList &names, const QString &description = QString(),
|
||||||
|
const QString &valueName = QString(),
|
||||||
|
const QString &defaultValue = QString());
|
||||||
|
QCommandLineOption(const QCommandLineOption &other);
|
||||||
|
|
||||||
|
~QCommandLineOption();
|
||||||
|
|
||||||
|
QCommandLineOption &operator=(const QCommandLineOption &other);
|
||||||
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
|
inline QCommandLineOption &operator=(QCommandLineOption &&other)
|
||||||
|
{ qSwap(d, other.d); return *this; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline void swap(QCommandLineOption &other)
|
||||||
|
{ qSwap(d, other.d); }
|
||||||
|
|
||||||
|
QStringList names() const;
|
||||||
|
|
||||||
|
void setValueName(const QString &name);
|
||||||
|
QString valueName() const;
|
||||||
|
|
||||||
|
void setDescription(const QString &description);
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
void setDefaultValue(const QString &defaultValue);
|
||||||
|
void setDefaultValues(const QStringList &defaultValues);
|
||||||
|
QStringList defaultValues() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedDataPointer<QCommandLineOptionPrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QCOMMANDLINEOPTION_H
|
896
src/corelib/tools/qcommandlineparser.cpp
Normal file
896
src/corelib/tools/qcommandlineparser.cpp
Normal file
@ -0,0 +1,896 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
|
||||||
|
** Copyright (C) 2013 David Faure <faure@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qcommandlineparser.h"
|
||||||
|
|
||||||
|
#include <qcoreapplication.h>
|
||||||
|
#include <qhash.h>
|
||||||
|
#include <qvector.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
typedef QHash<QString, int> NameHash_t;
|
||||||
|
|
||||||
|
// Special value for "not found" when doing hash lookups.
|
||||||
|
static const NameHash_t::mapped_type optionNotFound = ~0;
|
||||||
|
|
||||||
|
class QCommandLineParserPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline QCommandLineParserPrivate()
|
||||||
|
: singleDashWordOptionMode(QCommandLineParser::ParseAsCompactedShortOptions),
|
||||||
|
builtinVersionOption(false),
|
||||||
|
builtinHelpOption(false),
|
||||||
|
needsParsing(true)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool parse(const QStringList &args);
|
||||||
|
void checkParsed(const char *method);
|
||||||
|
QStringList aliases(const QString &name) const;
|
||||||
|
QString helpText() const;
|
||||||
|
bool registerFoundOption(const QString &optionName);
|
||||||
|
bool parseOptionValue(const QString &optionName, const QString &argument,
|
||||||
|
QStringList::const_iterator *argumentIterator,
|
||||||
|
QStringList::const_iterator argsEnd);
|
||||||
|
|
||||||
|
//! Error text set when parse() returns false
|
||||||
|
QString errorText;
|
||||||
|
|
||||||
|
//! The command line options used for parsing
|
||||||
|
QList<QCommandLineOption> commandLineOptionList;
|
||||||
|
|
||||||
|
//! Hash mapping option names to their offsets in commandLineOptionList and optionArgumentList.
|
||||||
|
NameHash_t nameHash;
|
||||||
|
|
||||||
|
//! Option values found (only for options with a value)
|
||||||
|
QHash<int, QStringList> optionValuesHash;
|
||||||
|
|
||||||
|
//! Names of options found on the command line.
|
||||||
|
QStringList optionNames;
|
||||||
|
|
||||||
|
//! Arguments which did not belong to any option.
|
||||||
|
QStringList positionalArgumentList;
|
||||||
|
|
||||||
|
//! Names of options which were unknown.
|
||||||
|
QStringList unknownOptionNames;
|
||||||
|
|
||||||
|
//! Application description
|
||||||
|
QString description;
|
||||||
|
|
||||||
|
//! Documentation for positional arguments
|
||||||
|
struct PositionalArgumentDefinition
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
QString description;
|
||||||
|
QString syntax;
|
||||||
|
};
|
||||||
|
QVector<PositionalArgumentDefinition> positionalArgumentDefinitions;
|
||||||
|
|
||||||
|
//! The parsing mode for "-abc"
|
||||||
|
QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode;
|
||||||
|
|
||||||
|
//! Whether addVersionOption was called
|
||||||
|
bool builtinVersionOption;
|
||||||
|
|
||||||
|
//! Whether addHelpOption was called
|
||||||
|
bool builtinHelpOption;
|
||||||
|
|
||||||
|
//! True if parse() needs to be called
|
||||||
|
bool needsParsing;
|
||||||
|
};
|
||||||
|
|
||||||
|
QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
|
||||||
|
{
|
||||||
|
const NameHash_t::mapped_type optionOffset = nameHash.value(optionName, optionNotFound);
|
||||||
|
if (optionOffset == optionNotFound) {
|
||||||
|
qWarning("QCommandLineParser: option not defined: \"%s\"", qPrintable(optionName));
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
return commandLineOptionList.at(optionOffset).names();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.2
|
||||||
|
\class QCommandLineParser
|
||||||
|
\inmodule QtCore
|
||||||
|
\ingroup tools
|
||||||
|
|
||||||
|
\brief The QCommandLineParser class provides a means for handling the
|
||||||
|
command line options.
|
||||||
|
|
||||||
|
QCoreApplication provides the command-line arguments as a simple list of strings.
|
||||||
|
QCommandLineParser provides the ability to define a set of options, parse the
|
||||||
|
command-line arguments, and store which options have actually been used, as
|
||||||
|
well as option values.
|
||||||
|
|
||||||
|
Any argument that isn't an option (i.e. doesn't start with a \c{-}) is stored
|
||||||
|
as a "positional argument".
|
||||||
|
|
||||||
|
The parser handles short names, long names, more than one name for the same
|
||||||
|
option, and option values.
|
||||||
|
|
||||||
|
Options on the command line are recognized as starting with a single or
|
||||||
|
double \c{-} character(s).
|
||||||
|
The option \c{-} (single dash alone) is a special case, often meaning standard
|
||||||
|
input, and not treated as an option. The parser will treat everything after the
|
||||||
|
option \c{--} (double dash) as positional arguments.
|
||||||
|
|
||||||
|
Short options are single letters. The option \c{v} would be specified by
|
||||||
|
passing \c{-v} on the command line. In the default parsing mode, short options
|
||||||
|
can be written in a compact form, for instance \c{-abc} is equivalent to \c{-a -b -c}.
|
||||||
|
The parsing mode for can be set to ParseAsLongOptions, in which case \c{-abc}
|
||||||
|
will be parsed as the long option \a{abc}.
|
||||||
|
|
||||||
|
Long options are more than one letter long and cannot be compacted together.
|
||||||
|
The long option \c{verbose} would be passed as \c{--verbose} or \c{-verbose}.
|
||||||
|
|
||||||
|
Passing values to options can be done using the assignment operator: \c{-v=value}
|
||||||
|
\c{--verbose=value}, or a space: \c{-v value} \c{--verbose value}, i.e. the next
|
||||||
|
argument is used as value (even if it starts with a \c{-}).
|
||||||
|
|
||||||
|
The parser does not support optional values - if an option is set to
|
||||||
|
require a value, one must be present. If such an option is placed last
|
||||||
|
and has no value, the option will be treated as if it had not been
|
||||||
|
specified.
|
||||||
|
|
||||||
|
The parser does not automatically support negating or disabling long options
|
||||||
|
by using the format \c{--disable-option} or \c{--no-option}. However, it is
|
||||||
|
possible to handle this case explicitly by making an option with \c{no-option}
|
||||||
|
as one of its names, and handling the option explicitly.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\snippet code/src_corelib_tools_qcommandlineparser.cpp 3
|
||||||
|
|
||||||
|
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
|
||||||
|
QCoreApplication as a builtin Qt option. Example: \c{--profile -reverse} will
|
||||||
|
lead to QGuiApplication seeing the -reverse option set, and removing it from
|
||||||
|
QCoreApplication::arguments() before QCommandLineParser defines the \c{profile}
|
||||||
|
option and parses the command line.
|
||||||
|
|
||||||
|
\sa QCommandLineOption, QCoreApplication
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a command line parser object.
|
||||||
|
*/
|
||||||
|
QCommandLineParser::QCommandLineParser()
|
||||||
|
: d(new QCommandLineParserPrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys the command line parser object.
|
||||||
|
*/
|
||||||
|
QCommandLineParser::~QCommandLineParser()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\enum QCommandLineParser::SingleDashWordOptionMode
|
||||||
|
|
||||||
|
This enum describes the way the parser interprets command-line
|
||||||
|
options that use a single dash followed by multiple letters, as as \c{-abc}.
|
||||||
|
|
||||||
|
\value ParseAsCompactedShortOptions \c{-abc} is interpreted as \c{-a -b -c},
|
||||||
|
i.e. as three short options that have been compacted on the command-line,
|
||||||
|
if none of the options take a value. If \c{a} takes a value, then it
|
||||||
|
is interpreted as \c{-a bc}, i.e. the short option \c{a} followed by the value \c{bc}.
|
||||||
|
This is typically used in tools that behave like compilers, in order
|
||||||
|
to handle options such as \c{-DDEFINE=VALUE} or \c{-I/include/path}.
|
||||||
|
This is the default parsing mode. New applications are recommended to
|
||||||
|
use this mode.
|
||||||
|
|
||||||
|
\value ParseAsLongOptions \c{-abc} is interpreted as \c{--abc},
|
||||||
|
i.e. as the long option named \c{abc}. This is how Qt's own tools
|
||||||
|
(uic, rcc...) have always been parsing arguments. This mode should be
|
||||||
|
used for preserving compatibility in applications that were parsing
|
||||||
|
arguments in such a way.
|
||||||
|
|
||||||
|
\sa setSingleDashWordOptionMode()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the parsing mode to \a singleDashWordOptionMode.
|
||||||
|
This must be called before process() or parse().
|
||||||
|
*/
|
||||||
|
void QCommandLineParser::setSingleDashWordOptionMode(QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode)
|
||||||
|
{
|
||||||
|
d->singleDashWordOptionMode = singleDashWordOptionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Adds the option \a option to look for while parsing.
|
||||||
|
|
||||||
|
Returns true if adding the option was successful; otherwise returns false.
|
||||||
|
|
||||||
|
Adding the option fails if there is no name attached to the option, or
|
||||||
|
the option has a name that clashes with an option name added before.
|
||||||
|
*/
|
||||||
|
bool QCommandLineParser::addOption(const QCommandLineOption &option)
|
||||||
|
{
|
||||||
|
QStringList optionNames = option.names();
|
||||||
|
|
||||||
|
if (!optionNames.isEmpty()) {
|
||||||
|
foreach (const QString &name, optionNames) {
|
||||||
|
if (d->nameHash.contains(name))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->commandLineOptionList.append(option);
|
||||||
|
|
||||||
|
const int offset = d->commandLineOptionList.size() - 1;
|
||||||
|
foreach (const QString &name, optionNames)
|
||||||
|
d->nameHash.insert(name, offset);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Adds the \c{-v} / \c{--version} option, which displays the version string of the application.
|
||||||
|
|
||||||
|
This option is handled automatically by QCommandLineParser.
|
||||||
|
|
||||||
|
You can set the actual version string by using QCoreApplication::setApplicationVersion().
|
||||||
|
|
||||||
|
Returns the option instance, which can be used to call isSet().
|
||||||
|
*/
|
||||||
|
QCommandLineOption QCommandLineParser::addVersionOption()
|
||||||
|
{
|
||||||
|
d->builtinVersionOption = true;
|
||||||
|
QCommandLineOption opt(QStringList() << QStringLiteral("v") << QStringLiteral("version"), tr("Displays version information."));
|
||||||
|
addOption(opt);
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Adds the help option (\c{-h}, \c{--help} and \c{-?} on Windows)
|
||||||
|
This option is handled automatically by QCommandLineParser.
|
||||||
|
|
||||||
|
Remember to use setApplicationDescription to set the application description,
|
||||||
|
which will be displayed when this option is used.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\code
|
||||||
|
setApplicationDescription(QCoreApplication::translate("main", "The best application in the world"));
|
||||||
|
addHelpOption();
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Returns the option instance, which can be used to call isSet().
|
||||||
|
*/
|
||||||
|
QCommandLineOption QCommandLineParser::addHelpOption()
|
||||||
|
{
|
||||||
|
d->builtinHelpOption = true;
|
||||||
|
QCommandLineOption opt(QStringList()
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
<< QStringLiteral("?")
|
||||||
|
#endif
|
||||||
|
<< QStringLiteral("h")
|
||||||
|
<< QStringLiteral("help"), tr("Displays this help."));
|
||||||
|
addOption(opt);
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the application \a description shown by helpText().
|
||||||
|
Most applications don't need to call this directly, addHelpOption()
|
||||||
|
also sets the application description.
|
||||||
|
*/
|
||||||
|
void QCommandLineParser::setApplicationDescription(const QString &description)
|
||||||
|
{
|
||||||
|
d->description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the application description set in setApplicationDescription()
|
||||||
|
or addHelpOption().
|
||||||
|
*/
|
||||||
|
QString QCommandLineParser::applicationDescription() const
|
||||||
|
{
|
||||||
|
return d->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Defines an additional argument to the application, for the benefit of the help text.
|
||||||
|
|
||||||
|
The argument \a name and \a description will appear under the \c{Arguments:} section
|
||||||
|
of the help. If \a syntax is specified, it will be appended to the Usage line, otherwise
|
||||||
|
the \a name will be appended.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\snippet code/src_corelib_tools_qcommandlineparser.cpp 1
|
||||||
|
|
||||||
|
\sa addHelpOption(), helpText()
|
||||||
|
*/
|
||||||
|
void QCommandLineParser::addPositionalArgument(const QString &name, const QString &description, const QString &syntax)
|
||||||
|
{
|
||||||
|
QCommandLineParserPrivate::PositionalArgumentDefinition arg;
|
||||||
|
arg.name = name;
|
||||||
|
arg.description = description;
|
||||||
|
arg.syntax = syntax.isEmpty() ? name : syntax;
|
||||||
|
d->positionalArgumentDefinitions.append(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Clears the definitions of additional arguments from the help text.
|
||||||
|
|
||||||
|
This is only needed for the special case of tools which support multiple commands
|
||||||
|
with different options. Once the actual command has been identified, the options
|
||||||
|
for this command can be defined, and the help text for the command can be adjusted
|
||||||
|
accordingly.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\snippet code/src_corelib_tools_qcommandlineparser.cpp 2
|
||||||
|
*/
|
||||||
|
void QCommandLineParser::clearPositionalArguments()
|
||||||
|
{
|
||||||
|
d->positionalArgumentDefinitions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Parses the command line \a arguments.
|
||||||
|
|
||||||
|
Most programs don't need to call this, a simple call to process(app) is enough.
|
||||||
|
|
||||||
|
parse() is more low-level, and only does the parsing. The application will have to
|
||||||
|
take care of the error handling, using errorText() if parse() returns false.
|
||||||
|
This can be useful for instance to show a graphical error message in graphical programs.
|
||||||
|
|
||||||
|
Calling parse() instead of process() can also be useful in order to ignore unknown
|
||||||
|
options temporarily, because more option definitions will be provided later on
|
||||||
|
(depending on one of the arguments), before calling process().
|
||||||
|
|
||||||
|
Don't forget that \a arguments must start with the name of the executable (ignored, though).
|
||||||
|
|
||||||
|
Return false in case of a parse error (unknown option or missing value); returns true otherwise.
|
||||||
|
|
||||||
|
\sa process()
|
||||||
|
*/
|
||||||
|
bool QCommandLineParser::parse(const QStringList &arguments)
|
||||||
|
{
|
||||||
|
return d->parse(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a translated error text for the user.
|
||||||
|
This should only be called when parse() returns false.
|
||||||
|
*/
|
||||||
|
QString QCommandLineParser::errorText() const
|
||||||
|
{
|
||||||
|
if (!d->errorText.isEmpty())
|
||||||
|
return d->errorText;
|
||||||
|
if (d->unknownOptionNames.count() == 1)
|
||||||
|
return tr("Unknown option '%1'.").arg(d->unknownOptionNames.first());
|
||||||
|
if (d->unknownOptionNames.count() > 1)
|
||||||
|
return tr("Unknown options: %1.").arg(d->unknownOptionNames.join(QStringLiteral(", ")));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Processes the command line \a arguments.
|
||||||
|
|
||||||
|
This means both parsing them, and handling the builtin options,
|
||||||
|
\c{--version} if addVersionOption was called, \c{--help} if addHelpOption was called,
|
||||||
|
as well as giving an error on unknown option names.
|
||||||
|
In each of these three cases, the current process will then stop, using the exit() function.
|
||||||
|
|
||||||
|
\sa QCoreApplication::arguments(), parse()
|
||||||
|
*/
|
||||||
|
void QCommandLineParser::process(const QStringList &arguments)
|
||||||
|
{
|
||||||
|
if (!d->parse(arguments)) {
|
||||||
|
fprintf(stderr, "%s\n", qPrintable(errorText()));
|
||||||
|
::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->builtinVersionOption && isSet(QStringLiteral("version"))) {
|
||||||
|
printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion()));
|
||||||
|
::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->builtinHelpOption && isSet(QStringLiteral("help")))
|
||||||
|
showHelp(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
|
||||||
|
The command line is obtained from the QCoreApplication instance \a app.
|
||||||
|
*/
|
||||||
|
void QCommandLineParser::process(const QCoreApplication &app)
|
||||||
|
{
|
||||||
|
// QCoreApplication::arguments() is static, but the app instance must exist so we require it as parameter
|
||||||
|
Q_UNUSED(app);
|
||||||
|
process(QCoreApplication::arguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCommandLineParserPrivate::checkParsed(const char *method)
|
||||||
|
{
|
||||||
|
if (needsParsing)
|
||||||
|
qWarning("QCommandLineParser: call process() or parse() before %s", method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
Looks up the option \a optionName (found on the command line) and register it as found.
|
||||||
|
Returns true on success.
|
||||||
|
*/
|
||||||
|
bool QCommandLineParserPrivate::registerFoundOption(const QString &optionName)
|
||||||
|
{
|
||||||
|
if (nameHash.contains(optionName)) {
|
||||||
|
optionNames.append(optionName);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
unknownOptionNames.append(optionName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
\brief Parse the value for a given option, if it was defined to expect one.
|
||||||
|
|
||||||
|
The value is taken from the next argument, or after the equal sign in \a argument.
|
||||||
|
|
||||||
|
\param optionName the short option name
|
||||||
|
\param argument the argument from the command line currently parsed. Only used for -k=value parsing.
|
||||||
|
\param argumentIterator iterator to the currently parsed argument. Incremented if the next argument contains the value.
|
||||||
|
\param argsEnd args.end(), to check if ++argumentIterator goes out of bounds
|
||||||
|
Returns true on success.
|
||||||
|
*/
|
||||||
|
bool QCommandLineParserPrivate::parseOptionValue(const QString &optionName, const QString &argument,
|
||||||
|
QStringList::const_iterator *argumentIterator, QStringList::const_iterator argsEnd)
|
||||||
|
{
|
||||||
|
const QLatin1Char assignChar('=');
|
||||||
|
const NameHash_t::const_iterator nameHashIt = nameHash.constFind(optionName);
|
||||||
|
if (nameHashIt != nameHash.constEnd()) {
|
||||||
|
const int assignPos = argument.indexOf(assignChar);
|
||||||
|
const NameHash_t::mapped_type optionOffset = *nameHashIt;
|
||||||
|
const bool withValue = !commandLineOptionList.at(optionOffset).valueName().isEmpty();
|
||||||
|
if (withValue) {
|
||||||
|
if (assignPos == -1) {
|
||||||
|
++(*argumentIterator);
|
||||||
|
if (*argumentIterator == argsEnd) {
|
||||||
|
errorText = QCommandLineParser::tr("Missing value after '%1'.").arg(argument);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
optionValuesHash[optionOffset].append(*(*argumentIterator));
|
||||||
|
} else {
|
||||||
|
optionValuesHash[optionOffset].append(argument.mid(assignPos + 1));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (assignPos != -1) {
|
||||||
|
errorText = QCommandLineParser::tr("Unexpected value after '%1'.").arg(argument.left(assignPos));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Parse the list of arguments \a arguments.
|
||||||
|
|
||||||
|
Any results from a previous parse operation are removed.
|
||||||
|
The parser will not look for further options once it encounters the option
|
||||||
|
\c{--}; this does not include when \c{--} follows an option that requires a value.
|
||||||
|
|
||||||
|
Options that were successfully recognized, and their values, are
|
||||||
|
removed from the input list. If \c m_bRemoveUnknownLongNames is
|
||||||
|
\c true, unrecognized options are removed and placed into a list of
|
||||||
|
unknown option names. Anything left over is placed into a list of
|
||||||
|
leftover arguments.
|
||||||
|
*/
|
||||||
|
bool QCommandLineParserPrivate::parse(const QStringList &args)
|
||||||
|
{
|
||||||
|
needsParsing = false;
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
|
const QString doubleDashString(QStringLiteral("--"));
|
||||||
|
const QLatin1Char dashChar('-');
|
||||||
|
const QLatin1Char assignChar('=');
|
||||||
|
|
||||||
|
bool doubleDashFound = false;
|
||||||
|
errorText.clear();
|
||||||
|
positionalArgumentList.clear();
|
||||||
|
optionNames.clear();
|
||||||
|
unknownOptionNames.clear();
|
||||||
|
optionValuesHash.clear();
|
||||||
|
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
qWarning("QCommandLineParser: argument list cannot be empty, it should contain at least the executable name");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList::const_iterator argumentIterator = args.begin();
|
||||||
|
++argumentIterator; // skip executable name
|
||||||
|
|
||||||
|
for (; argumentIterator != args.end() ; ++argumentIterator) {
|
||||||
|
QString argument = *argumentIterator;
|
||||||
|
|
||||||
|
if (doubleDashFound) {
|
||||||
|
positionalArgumentList.append(argument);
|
||||||
|
} else if (argument.startsWith(doubleDashString)) {
|
||||||
|
if (argument.length() > 2) {
|
||||||
|
QString optionName = argument.mid(2).section(assignChar, 0, 0);
|
||||||
|
if (registerFoundOption(optionName)) {
|
||||||
|
if (!parseOptionValue(optionName, argument, &argumentIterator, args.end()))
|
||||||
|
error = true;
|
||||||
|
} else {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
doubleDashFound = true;
|
||||||
|
}
|
||||||
|
} else if (argument.startsWith(dashChar)) {
|
||||||
|
if (argument.size() == 1) { // single dash ("stdin")
|
||||||
|
positionalArgumentList.append(argument);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (singleDashWordOptionMode) {
|
||||||
|
case QCommandLineParser::ParseAsCompactedShortOptions:
|
||||||
|
{
|
||||||
|
QString optionName;
|
||||||
|
bool valueFound = false;
|
||||||
|
for (int pos = 1 ; pos < argument.size(); ++pos) {
|
||||||
|
optionName = argument.mid(pos, 1);
|
||||||
|
if (!registerFoundOption(optionName)) {
|
||||||
|
error = true;
|
||||||
|
} else {
|
||||||
|
const NameHash_t::const_iterator nameHashIt = nameHash.constFind(optionName);
|
||||||
|
Q_ASSERT(nameHashIt != nameHash.constEnd()); // checked by registerFoundOption
|
||||||
|
const NameHash_t::mapped_type optionOffset = *nameHashIt;
|
||||||
|
const bool withValue = !commandLineOptionList.at(optionOffset).valueName().isEmpty();
|
||||||
|
if (withValue) {
|
||||||
|
if (pos + 1 < argument.size()) {
|
||||||
|
if (argument.at(pos + 1) == assignChar)
|
||||||
|
++pos;
|
||||||
|
optionValuesHash[optionOffset].append(argument.mid(pos + 1));
|
||||||
|
valueFound = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pos + 1 < argument.size() && argument.at(pos + 1) == assignChar)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!valueFound && !parseOptionValue(optionName, argument, &argumentIterator, args.end()))
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QCommandLineParser::ParseAsLongOptions:
|
||||||
|
{
|
||||||
|
const QString optionName = argument.mid(1).section(assignChar, 0, 0);
|
||||||
|
if (registerFoundOption(optionName)) {
|
||||||
|
if (!parseOptionValue(optionName, argument, &argumentIterator, args.end()))
|
||||||
|
error = true;
|
||||||
|
} else {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
positionalArgumentList.append(argument);
|
||||||
|
}
|
||||||
|
if (argumentIterator == args.end())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return !error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Checks whether the option \a name was passed to the application.
|
||||||
|
|
||||||
|
Returns true if the option \a name was set, false otherwise.
|
||||||
|
|
||||||
|
This is the recommended way to check for options with no values.
|
||||||
|
|
||||||
|
The name provided can be any long or short name of any option that was
|
||||||
|
added with \c addOption(). All the options names are treated as being
|
||||||
|
equivalent. If the name is not recognized or that option was not present,
|
||||||
|
false is returned.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\snippet code/src_corelib_tools_qcommandlineparser.cpp 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool QCommandLineParser::isSet(const QString &name) const
|
||||||
|
{
|
||||||
|
d->checkParsed("isSet");
|
||||||
|
if (d->optionNames.contains(name))
|
||||||
|
return true;
|
||||||
|
const QStringList aliases = d->aliases(name);
|
||||||
|
foreach (const QString &optionName, d->optionNames) {
|
||||||
|
if (aliases.contains(optionName))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the option value found for the given option name \a optionName, or
|
||||||
|
an empty string if not found.
|
||||||
|
|
||||||
|
The name provided can be any long or short name of any option that was
|
||||||
|
added with \c addOption(). All the option names are treated as being
|
||||||
|
equivalent. If the name is not recognized or that option was not present, an
|
||||||
|
empty string is returned.
|
||||||
|
|
||||||
|
For options found by the parser, the last value found for
|
||||||
|
that option is returned. If the option wasn't specified on the command line,
|
||||||
|
the default value is returned.
|
||||||
|
|
||||||
|
An empty string is returned if the option does not take a value.
|
||||||
|
|
||||||
|
\sa values()
|
||||||
|
*/
|
||||||
|
|
||||||
|
QString QCommandLineParser::value(const QString &optionName) const
|
||||||
|
{
|
||||||
|
d->checkParsed("value");
|
||||||
|
const QStringList valueList = values(optionName);
|
||||||
|
|
||||||
|
if (!valueList.isEmpty())
|
||||||
|
return valueList.last();
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a list of option values found for the given option name \a
|
||||||
|
optionName, or an empty list if not found.
|
||||||
|
|
||||||
|
The name provided can be any long or short name of any option that was
|
||||||
|
added with \c addOption(). All the options names are treated as being
|
||||||
|
equivalent. If the name is not recognized or that option was not present, an
|
||||||
|
empty list is returned.
|
||||||
|
|
||||||
|
For options found by the parser, the list will contain an entry for
|
||||||
|
each time the option was encountered by the parser. If the option wasn't
|
||||||
|
specified on the command line, the default values are returned.
|
||||||
|
|
||||||
|
An empty list is returned if the option does not take a value.
|
||||||
|
|
||||||
|
\sa value()
|
||||||
|
*/
|
||||||
|
|
||||||
|
QStringList QCommandLineParser::values(const QString &optionName) const
|
||||||
|
{
|
||||||
|
d->checkParsed("values");
|
||||||
|
const NameHash_t::mapped_type optionOffset = d->nameHash.value(optionName, optionNotFound);
|
||||||
|
if (optionOffset != optionNotFound) {
|
||||||
|
QStringList values = d->optionValuesHash.value(optionOffset);
|
||||||
|
if (values.isEmpty())
|
||||||
|
values = d->commandLineOptionList.at(optionOffset).defaultValues();
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
qWarning("QCommandLineParser: option not defined: \"%s\"", qPrintable(optionName));
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
Returns true if the \a option was set, false otherwise.
|
||||||
|
*/
|
||||||
|
bool QCommandLineParser::isSet(const QCommandLineOption &option) const
|
||||||
|
{
|
||||||
|
return isSet(option.names().first());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
Returns the option value found for the given \a option, or
|
||||||
|
an empty string if not found.
|
||||||
|
*/
|
||||||
|
QString QCommandLineParser::value(const QCommandLineOption &option) const
|
||||||
|
{
|
||||||
|
return value(option.names().first());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
Returns a list of option values found for the given \a option,
|
||||||
|
or an empty list if not found.
|
||||||
|
*/
|
||||||
|
QStringList QCommandLineParser::values(const QCommandLineOption &option) const
|
||||||
|
{
|
||||||
|
return values(option.names().first());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a list of positional arguments.
|
||||||
|
|
||||||
|
These are all of the arguments that were not recognized as part of an
|
||||||
|
option.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QStringList QCommandLineParser::positionalArguments() const
|
||||||
|
{
|
||||||
|
d->checkParsed("positionalArguments");
|
||||||
|
return d->positionalArgumentList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a list of option names that were found.
|
||||||
|
|
||||||
|
This returns a list of all the recognized option names found by the
|
||||||
|
parser, in the order in which they were found. For any long options
|
||||||
|
that were in the form {--option=value}, the value part will have been
|
||||||
|
dropped.
|
||||||
|
|
||||||
|
The names in this list do not include the preceding dash characters.
|
||||||
|
Names may appear more than once in this list if they were encountered
|
||||||
|
more than once by the parser.
|
||||||
|
|
||||||
|
Any entry in the list can be used with \c value() or with
|
||||||
|
\c values() to get any relevant option values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QStringList QCommandLineParser::optionNames() const
|
||||||
|
{
|
||||||
|
d->checkParsed("optionNames");
|
||||||
|
return d->optionNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a list of unknown option names.
|
||||||
|
|
||||||
|
This list will include both long an short name options that were not
|
||||||
|
recognized. For any long options that were in the form {--option=value},
|
||||||
|
the value part will have been dropped and only the long name is added.
|
||||||
|
|
||||||
|
The names in this list do not include the preceding dash characters.
|
||||||
|
Names may appear more than once in this list if they were encountered
|
||||||
|
more than once by the parser.
|
||||||
|
|
||||||
|
\sa optionNames()
|
||||||
|
*/
|
||||||
|
|
||||||
|
QStringList QCommandLineParser::unknownOptionNames() const
|
||||||
|
{
|
||||||
|
d->checkParsed("unknownOptionNames");
|
||||||
|
return d->unknownOptionNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Displays the help information, and exits the application.
|
||||||
|
This is automatically triggered by the --help option, but can also
|
||||||
|
be used to display the help when the user is not invoking the
|
||||||
|
application correctly.
|
||||||
|
The exit code is set to \a exitCode. It should be set to 0 if the
|
||||||
|
user requested to see the help, and to any other value in case of
|
||||||
|
an error.
|
||||||
|
|
||||||
|
\sa helpText()
|
||||||
|
*/
|
||||||
|
Q_NORETURN void QCommandLineParser::showHelp(int exitCode)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "%s", qPrintable(d->helpText()));
|
||||||
|
::exit(exitCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a string containing the complete help information.
|
||||||
|
|
||||||
|
\sa showHelp()
|
||||||
|
*/
|
||||||
|
QString QCommandLineParser::helpText() const
|
||||||
|
{
|
||||||
|
return d->helpText();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString wrapText(const QString &names, int longestOptionNameString, const QString &description)
|
||||||
|
{
|
||||||
|
const QLatin1Char nl('\n');
|
||||||
|
QString text = QStringLiteral(" ") + names.leftJustified(longestOptionNameString) + QLatin1Char(' ');
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QCommandLineParserPrivate::helpText() const
|
||||||
|
{
|
||||||
|
const QLatin1Char nl('\n');
|
||||||
|
QString text;
|
||||||
|
const QString exeName = QCoreApplication::instance()->arguments().first();
|
||||||
|
QString usage = exeName;
|
||||||
|
if (!commandLineOptionList.isEmpty()) {
|
||||||
|
usage += QLatin1Char(' ');
|
||||||
|
usage += QCommandLineParser::tr("[options]");
|
||||||
|
}
|
||||||
|
foreach (const PositionalArgumentDefinition &arg, positionalArgumentDefinitions) {
|
||||||
|
usage += QLatin1Char(' ');
|
||||||
|
usage += arg.syntax;
|
||||||
|
}
|
||||||
|
text += QCommandLineParser::tr("Usage: %1").arg(usage) + nl;
|
||||||
|
if (!description.isEmpty())
|
||||||
|
text += description + nl;
|
||||||
|
text += nl;
|
||||||
|
if (!commandLineOptionList.isEmpty())
|
||||||
|
text += QCommandLineParser::tr("Options:") + nl;
|
||||||
|
QStringList optionNameList;
|
||||||
|
int longestOptionNameString = 0;
|
||||||
|
foreach (const QCommandLineOption &option, commandLineOptionList) {
|
||||||
|
QStringList optionNames;
|
||||||
|
foreach (const QString &optionName, option.names()) {
|
||||||
|
if (optionName.length() == 1)
|
||||||
|
optionNames.append(QLatin1Char('-') + optionName);
|
||||||
|
else
|
||||||
|
optionNames.append(QStringLiteral("--") + optionName);
|
||||||
|
}
|
||||||
|
QString optionNamesString = optionNames.join(QStringLiteral(", "));
|
||||||
|
if (!option.valueName().isEmpty())
|
||||||
|
optionNamesString += QStringLiteral(" <") + option.valueName() + QLatin1Char('>');
|
||||||
|
optionNameList.append(optionNamesString);
|
||||||
|
longestOptionNameString = qMax(longestOptionNameString, optionNamesString.length());
|
||||||
|
}
|
||||||
|
++longestOptionNameString;
|
||||||
|
for (int i = 0; i < commandLineOptionList.count(); ++i) {
|
||||||
|
const QCommandLineOption &option = commandLineOptionList.at(i);
|
||||||
|
text += wrapText(optionNameList.at(i), longestOptionNameString, option.description());
|
||||||
|
}
|
||||||
|
if (!positionalArgumentDefinitions.isEmpty()) {
|
||||||
|
if (!commandLineOptionList.isEmpty())
|
||||||
|
text += nl;
|
||||||
|
text += QCommandLineParser::tr("Arguments:") + nl;
|
||||||
|
foreach (const PositionalArgumentDefinition &arg, positionalArgumentDefinitions) {
|
||||||
|
text += wrapText(arg.name, longestOptionNameString, arg.description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
106
src/corelib/tools/qcommandlineparser.h
Normal file
106
src/corelib/tools/qcommandlineparser.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QCOMMANDLINEPARSER_H
|
||||||
|
#define QCOMMANDLINEPARSER_H
|
||||||
|
|
||||||
|
#include <QtCore/qstringlist.h>
|
||||||
|
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtCore/qcommandlineoption.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QCommandLineParserPrivate;
|
||||||
|
class QCoreApplication;
|
||||||
|
|
||||||
|
class Q_CORE_EXPORT QCommandLineParser
|
||||||
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(QCommandLineParser)
|
||||||
|
public:
|
||||||
|
QCommandLineParser();
|
||||||
|
~QCommandLineParser();
|
||||||
|
|
||||||
|
enum SingleDashWordOptionMode {
|
||||||
|
ParseAsCompactedShortOptions,
|
||||||
|
ParseAsLongOptions
|
||||||
|
};
|
||||||
|
void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode);
|
||||||
|
|
||||||
|
bool addOption(const QCommandLineOption &commandLineOption);
|
||||||
|
|
||||||
|
QCommandLineOption addVersionOption();
|
||||||
|
QCommandLineOption addHelpOption();
|
||||||
|
void setApplicationDescription(const QString &description);
|
||||||
|
QString applicationDescription() const;
|
||||||
|
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax = QString());
|
||||||
|
void clearPositionalArguments();
|
||||||
|
|
||||||
|
void process(const QStringList &arguments);
|
||||||
|
void process(const QCoreApplication &app);
|
||||||
|
|
||||||
|
bool parse(const QStringList &arguments);
|
||||||
|
QString errorText() const;
|
||||||
|
|
||||||
|
bool isSet(const QString &name) const;
|
||||||
|
QString value(const QString &name) const;
|
||||||
|
QStringList values(const QString &name) const;
|
||||||
|
|
||||||
|
bool isSet(const QCommandLineOption &option) const;
|
||||||
|
QString value(const QCommandLineOption &option) const;
|
||||||
|
QStringList values(const QCommandLineOption &option) const;
|
||||||
|
|
||||||
|
QStringList positionalArguments() const;
|
||||||
|
QStringList optionNames() const;
|
||||||
|
QStringList unknownOptionNames() const;
|
||||||
|
|
||||||
|
Q_NORETURN void showHelp(int exitCode = 0);
|
||||||
|
QString helpText() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(QCommandLineParser)
|
||||||
|
|
||||||
|
QCommandLineParserPrivate * const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QCOMMANDLINEPARSER_H
|
@ -12,6 +12,8 @@ HEADERS += \
|
|||||||
tools/qcache.h \
|
tools/qcache.h \
|
||||||
tools/qchar.h \
|
tools/qchar.h \
|
||||||
tools/qcollator_p.h \
|
tools/qcollator_p.h \
|
||||||
|
tools/qcommandlineoption.h \
|
||||||
|
tools/qcommandlineparser.h \
|
||||||
tools/qcontainerfwd.h \
|
tools/qcontainerfwd.h \
|
||||||
tools/qcryptographichash.h \
|
tools/qcryptographichash.h \
|
||||||
tools/qdatetime.h \
|
tools/qdatetime.h \
|
||||||
@ -69,6 +71,8 @@ SOURCES += \
|
|||||||
tools/qbytearray.cpp \
|
tools/qbytearray.cpp \
|
||||||
tools/qbytearraymatcher.cpp \
|
tools/qbytearraymatcher.cpp \
|
||||||
tools/qcollator.cpp \
|
tools/qcollator.cpp \
|
||||||
|
tools/qcommandlineoption.cpp \
|
||||||
|
tools/qcommandlineparser.cpp \
|
||||||
tools/qcryptographichash.cpp \
|
tools/qcryptographichash.cpp \
|
||||||
tools/qdatetime.cpp \
|
tools/qdatetime.cpp \
|
||||||
tools/qeasingcurve.cpp \
|
tools/qeasingcurve.cpp \
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
SUBDIRS += tst_qcommandlineparser.pro testhelper/qcommandlineparser_test_helper.pro
|
@ -0,0 +1,93 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 David Faure <faure@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
app.setApplicationVersion("1.0");
|
||||||
|
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.setApplicationDescription("Test helper");
|
||||||
|
parser.addHelpOption();
|
||||||
|
parser.addVersionOption();
|
||||||
|
parser.addPositionalArgument("parsingMode", "The parsing mode to test.");
|
||||||
|
parser.addPositionalArgument("command", "The command to execute.");
|
||||||
|
parser.addOption(QCommandLineOption("load", "Load file from URL.", "url"));
|
||||||
|
parser.addOption(QCommandLineOption(QStringList() << "o" << "output", "Set output file.", "file"));
|
||||||
|
parser.addOption(QCommandLineOption("D", "Define macro.", "key=value"));
|
||||||
|
|
||||||
|
// An option with a longer description, to test wrapping
|
||||||
|
QCommandLineOption noImplicitIncludesOption(QStringList() << QStringLiteral("n") << QStringLiteral("no-implicit-includes"));
|
||||||
|
noImplicitIncludesOption.setDescription(QStringLiteral("Disable automatic generation of implicit #include-directives."));
|
||||||
|
parser.addOption(noImplicitIncludesOption);
|
||||||
|
|
||||||
|
// This program supports different options depending on the "command" (first argument).
|
||||||
|
// Call parse() to find out the positional arguments.
|
||||||
|
parser.parse(QCoreApplication::arguments());
|
||||||
|
|
||||||
|
QStringList args = parser.positionalArguments();
|
||||||
|
if (args.isEmpty())
|
||||||
|
parser.showHelp(1);
|
||||||
|
parser.setSingleDashWordOptionMode(QCommandLineParser::SingleDashWordOptionMode(args.takeFirst().toInt()));
|
||||||
|
const QString command = args.isEmpty() ? QString() : args.first();
|
||||||
|
if (command == "resize") {
|
||||||
|
parser.clearPositionalArguments();
|
||||||
|
parser.addPositionalArgument("resize", "Resize the object to a new size.", "resize [resize_options]");
|
||||||
|
parser.addOption(QCommandLineOption("size", "New size.", "size"));
|
||||||
|
parser.process(app);
|
||||||
|
const QString size = parser.value("size");
|
||||||
|
printf("Resizing %s to %s and saving to %s\n", qPrintable(parser.value("load")), qPrintable(size), qPrintable(parser.value("o")));
|
||||||
|
} else {
|
||||||
|
// Call process again, to handle unknown options this time.
|
||||||
|
parser.process(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Positional arguments: %s\n", qPrintable(parser.positionalArguments().join(",")));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
QT = core
|
||||||
|
DESTDIR = ./
|
||||||
|
|
||||||
|
SOURCES += qcommandlineparser_test_helper.cpp
|
@ -0,0 +1,531 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 David Faure <faure@kde.org>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <QtCore/QCommandLineParser>
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(char**)
|
||||||
|
|
||||||
|
class tst_QCommandLineParser : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void parsingModes_data();
|
||||||
|
|
||||||
|
// In-process tests
|
||||||
|
void testInvalidOptions();
|
||||||
|
void testPositionalArguments();
|
||||||
|
void testBooleanOption_data();
|
||||||
|
void testBooleanOption();
|
||||||
|
void testMultipleNames_data();
|
||||||
|
void testMultipleNames();
|
||||||
|
void testSingleValueOption_data();
|
||||||
|
void testSingleValueOption();
|
||||||
|
void testValueNotSet();
|
||||||
|
void testMultipleValuesOption();
|
||||||
|
void testUnknownOptionErrorHandling_data();
|
||||||
|
void testUnknownOptionErrorHandling();
|
||||||
|
void testDoubleDash_data();
|
||||||
|
void testDoubleDash();
|
||||||
|
void testProcessNotCalled();
|
||||||
|
void testEmptyArgsList();
|
||||||
|
void testMissingOptionValue();
|
||||||
|
void testStdinArgument_data();
|
||||||
|
void testStdinArgument();
|
||||||
|
void testSingleDashWordOptionModes_data();
|
||||||
|
void testSingleDashWordOptionModes();
|
||||||
|
|
||||||
|
// QProcess-based tests using qcommandlineparser_test_helper
|
||||||
|
void testVersionOption();
|
||||||
|
void testHelpOption_data();
|
||||||
|
void testHelpOption();
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *empty_argv[] = { const_cast<char*>("tst_qcommandlineparser") };
|
||||||
|
static int empty_argc = 1;
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QCommandLineParser::SingleDashWordOptionMode)
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::parsingModes_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QCommandLineParser::SingleDashWordOptionMode>("parsingMode");
|
||||||
|
|
||||||
|
QTest::newRow("collapsed") << QCommandLineParser::ParseAsCompactedShortOptions;
|
||||||
|
QTest::newRow("implicitlylong") << QCommandLineParser::ParseAsLongOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testInvalidOptions()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "Option names cannot start with a '-'");
|
||||||
|
parser.addOption(QCommandLineOption(QStringLiteral("-v"), QStringLiteral("Displays version information.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testPositionalArguments()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "file.txt"));
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList() << QStringLiteral("file.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testBooleanOption_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QStringList>("args");
|
||||||
|
QTest::addColumn<QStringList>("expectedOptionNames");
|
||||||
|
QTest::addColumn<bool>("expectedIsSet");
|
||||||
|
|
||||||
|
QTest::newRow("set") << (QStringList() << "tst_qcommandlineparser" << "-b") << (QStringList() << "b") << true;
|
||||||
|
QTest::newRow("unset") << (QStringList() << "tst_qcommandlineparser") << QStringList() << false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testBooleanOption()
|
||||||
|
{
|
||||||
|
QFETCH(QStringList, args);
|
||||||
|
QFETCH(QStringList, expectedOptionNames);
|
||||||
|
QFETCH(bool, expectedIsSet);
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("b"), QStringLiteral("a boolean option"))));
|
||||||
|
QVERIFY(parser.parse(args));
|
||||||
|
QCOMPARE(parser.optionNames(), expectedOptionNames);
|
||||||
|
QCOMPARE(parser.isSet("b"), expectedIsSet);
|
||||||
|
QCOMPARE(parser.values("b"), QStringList());
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList());
|
||||||
|
// Should warn on typos
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: option not defined: \"c\"");
|
||||||
|
QVERIFY(!parser.isSet("c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testMultipleNames_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QStringList>("args");
|
||||||
|
QTest::addColumn<QStringList>("expectedOptionNames");
|
||||||
|
|
||||||
|
QTest::newRow("short") << (QStringList() << "tst_qcommandlineparser" << "-v") << (QStringList() << "v");
|
||||||
|
QTest::newRow("long") << (QStringList() << "tst_qcommandlineparser" << "--version") << (QStringList() << "version");
|
||||||
|
QTest::newRow("not_set") << (QStringList() << "tst_qcommandlineparser") << QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testMultipleNames()
|
||||||
|
{
|
||||||
|
QFETCH(QStringList, args);
|
||||||
|
QFETCH(QStringList, expectedOptionNames);
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineOption option(QStringList() << "v" << "version", QStringLiteral("Show version information"));
|
||||||
|
QCOMPARE(option.names(), QStringList() << "v" << "version");
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QVERIFY(parser.addOption(option));
|
||||||
|
QVERIFY(parser.parse(args));
|
||||||
|
QCOMPARE(parser.optionNames(), expectedOptionNames);
|
||||||
|
const bool expectedIsSet = !expectedOptionNames.isEmpty();
|
||||||
|
QCOMPARE(parser.isSet("v"), expectedIsSet);
|
||||||
|
QCOMPARE(parser.isSet("version"), expectedIsSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testSingleValueOption_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QStringList>("args");
|
||||||
|
QTest::addColumn<QStringList>("defaults");
|
||||||
|
QTest::addColumn<bool>("expectedIsSet");
|
||||||
|
|
||||||
|
QTest::newRow("short") << (QStringList() << "tst" << "-s" << "oxygen") << QStringList() << true;
|
||||||
|
QTest::newRow("long") << (QStringList() << "tst" << "--style" << "oxygen") << QStringList() << true;
|
||||||
|
QTest::newRow("longequal") << (QStringList() << "tst" << "--style=oxygen") << QStringList() << true;
|
||||||
|
QTest::newRow("default") << (QStringList() << "tst") << (QStringList() << "oxygen") << false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testSingleValueOption()
|
||||||
|
{
|
||||||
|
QFETCH(QStringList, args);
|
||||||
|
QFETCH(QStringList, defaults);
|
||||||
|
QFETCH(bool, expectedIsSet);
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QCommandLineOption option(QStringList() << "s" << "style", QStringLiteral("style name"), "styleName");
|
||||||
|
option.setDefaultValues(defaults);
|
||||||
|
QVERIFY(parser.addOption(option));
|
||||||
|
for (int mode = 0; mode < 2; ++mode) {
|
||||||
|
parser.setSingleDashWordOptionMode(QCommandLineParser::SingleDashWordOptionMode(mode));
|
||||||
|
QVERIFY(parser.parse(args));
|
||||||
|
QCOMPARE(parser.isSet("s"), expectedIsSet);
|
||||||
|
QCOMPARE(parser.isSet("style"), expectedIsSet);
|
||||||
|
QCOMPARE(parser.isSet(option), expectedIsSet);
|
||||||
|
QCOMPARE(parser.value("s"), QString("oxygen"));
|
||||||
|
QCOMPARE(parser.value("style"), QString("oxygen"));
|
||||||
|
QCOMPARE(parser.values("s"), QStringList() << "oxygen");
|
||||||
|
QCOMPARE(parser.values("style"), QStringList() << "oxygen");
|
||||||
|
QCOMPARE(parser.values(option), QStringList() << "oxygen");
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList());
|
||||||
|
}
|
||||||
|
// Should warn on typos
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: option not defined: \"c\"");
|
||||||
|
QVERIFY(parser.values("c").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testValueNotSet()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
// Not set, no default value
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QCommandLineOption option(QStringList() << "s" << "style", QStringLiteral("style name"));
|
||||||
|
option.setValueName("styleName");
|
||||||
|
QVERIFY(parser.addOption(option));
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst"));
|
||||||
|
QCOMPARE(parser.optionNames(), QStringList());
|
||||||
|
QVERIFY(!parser.isSet("s"));
|
||||||
|
QVERIFY(!parser.isSet("style"));
|
||||||
|
QCOMPARE(parser.value("s"), QString());
|
||||||
|
QCOMPARE(parser.value("style"), QString());
|
||||||
|
QCOMPARE(parser.values("s"), QStringList());
|
||||||
|
QCOMPARE(parser.values("style"), QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testMultipleValuesOption()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineOption option(QStringLiteral("param"), QStringLiteral("Pass parameter to the backend."));
|
||||||
|
option.setValueName("key=value");
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QVERIFY(parser.addOption(option));
|
||||||
|
{
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst" << "--param" << "key1=value1"));
|
||||||
|
QVERIFY(parser.isSet("param"));
|
||||||
|
QCOMPARE(parser.values("param"), QStringList() << "key1=value1");
|
||||||
|
QCOMPARE(parser.value("param"), QString("key1=value1"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst" << "--param" << "key1=value1" << "--param" << "key2=value2"));
|
||||||
|
QVERIFY(parser.isSet("param"));
|
||||||
|
QCOMPARE(parser.values("param"), QStringList() << "key1=value1" << "key2=value2");
|
||||||
|
QCOMPARE(parser.value("param"), QString("key2=value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString expected =
|
||||||
|
"Usage: tst_qcommandlineparser [options]\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" --param <key=value> Pass parameter to the backend.\n";
|
||||||
|
|
||||||
|
const QString exeName = QCoreApplication::instance()->arguments().first(); // e.g. debug\tst_qcommandlineparser.exe on Windows
|
||||||
|
expected.replace(QStringLiteral("tst_qcommandlineparser"), exeName);
|
||||||
|
QCOMPARE(parser.helpText(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testUnknownOptionErrorHandling_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QCommandLineParser::SingleDashWordOptionMode>("parsingMode");
|
||||||
|
QTest::addColumn<QStringList>("args");
|
||||||
|
QTest::addColumn<QStringList>("expectedUnknownOptionNames");
|
||||||
|
QTest::addColumn<QString>("expectedErrorText");
|
||||||
|
|
||||||
|
const QStringList args_hello = QStringList() << "tst_qcommandlineparser" << "--hello";
|
||||||
|
const QString error_hello("Unknown option 'hello'.");
|
||||||
|
QTest::newRow("unknown_name_collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << args_hello << QStringList("hello") << error_hello;
|
||||||
|
QTest::newRow("unknown_name_long") << QCommandLineParser::ParseAsLongOptions << args_hello << QStringList("hello") << error_hello;
|
||||||
|
|
||||||
|
const QStringList args_value = QStringList() << "tst_qcommandlineparser" << "-b=1";
|
||||||
|
QTest::newRow("bool_with_value_collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << args_value << QStringList() << QString("Unexpected value after '-b'.");
|
||||||
|
QTest::newRow("bool_with_value_long") << QCommandLineParser::ParseAsLongOptions << args_value << QStringList() << QString("Unexpected value after '-b'.");
|
||||||
|
|
||||||
|
const QStringList args_dash_long = QStringList() << "tst_qcommandlineparser" << "-bool";
|
||||||
|
const QString error_bool("Unknown options: o, o, l.");
|
||||||
|
QTest::newRow("unknown_name_long_collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << args_dash_long << (QStringList() << "o" << "o" << "l") << error_bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testUnknownOptionErrorHandling()
|
||||||
|
{
|
||||||
|
QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
|
||||||
|
QFETCH(QStringList, args);
|
||||||
|
QFETCH(QStringList, expectedUnknownOptionNames);
|
||||||
|
QFETCH(QString, expectedErrorText);
|
||||||
|
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.setSingleDashWordOptionMode(parsingMode);
|
||||||
|
QVERIFY(parser.addOption(QCommandLineOption(QStringList() << "b" << "bool", QStringLiteral("a boolean option"))));
|
||||||
|
QCOMPARE(parser.parse(args), expectedErrorText.isEmpty());
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), expectedUnknownOptionNames);
|
||||||
|
QCOMPARE(parser.errorText(), expectedErrorText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testDoubleDash_data()
|
||||||
|
{
|
||||||
|
parsingModes_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testDoubleDash()
|
||||||
|
{
|
||||||
|
QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
|
||||||
|
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.addOption(QCommandLineOption(QStringList() << "o" << "output", QStringLiteral("Output file"), QStringLiteral("filename")));
|
||||||
|
parser.setSingleDashWordOptionMode(parsingMode);
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "--output" << "foo"));
|
||||||
|
QCOMPARE(parser.value("output"), QString("foo"));
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList());
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "--" << "--output" << "bar" << "-b" << "bleh"));
|
||||||
|
QCOMPARE(parser.value("output"), QString());
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList() << "--output" << "bar" << "-b" << "bleh");
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testProcessNotCalled()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("b"), QStringLiteral("a boolean option"))));
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: call process() or parse() before isSet");
|
||||||
|
QVERIFY(!parser.isSet("b"));
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: call process() or parse() before values");
|
||||||
|
QCOMPARE(parser.values("b"), QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testEmptyArgsList()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: argument list cannot be empty, it should contain at least the executable name");
|
||||||
|
QVERIFY(!parser.parse(QStringList())); // invalid call, argv[0] is missing
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testMissingOptionValue()
|
||||||
|
{
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.addOption(QCommandLineOption(QStringLiteral("option"), QStringLiteral("An option"), "value"));
|
||||||
|
QVERIFY(!parser.parse(QStringList() << "argv0" << "--option")); // the user forgot to pass a value for --option
|
||||||
|
QCOMPARE(parser.value("option"), QString());
|
||||||
|
QCOMPARE(parser.errorText(), QString("Missing value after '--option'."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testStdinArgument_data()
|
||||||
|
{
|
||||||
|
parsingModes_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testStdinArgument()
|
||||||
|
{
|
||||||
|
QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
|
||||||
|
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.setSingleDashWordOptionMode(parsingMode);
|
||||||
|
parser.addOption(QCommandLineOption(QStringList() << "i" << "input", QStringLiteral("Input file."), QStringLiteral("filename")));
|
||||||
|
parser.addOption(QCommandLineOption("b", QStringLiteral("Boolean option.")));
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "--input" << "-"));
|
||||||
|
QCOMPARE(parser.value("input"), QString("-"));
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList());
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
|
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "--input" << "-" << "-b" << "arg"));
|
||||||
|
QCOMPARE(parser.value("input"), QString("-"));
|
||||||
|
QVERIFY(parser.isSet("b"));
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList() << "arg");
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
|
|
||||||
|
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "-"));
|
||||||
|
QCOMPARE(parser.value("input"), QString());
|
||||||
|
QVERIFY(!parser.isSet("b"));
|
||||||
|
QCOMPARE(parser.positionalArguments(), QStringList() << "-");
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testSingleDashWordOptionModes_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QCommandLineParser::SingleDashWordOptionMode>("parsingMode");
|
||||||
|
QTest::addColumn<QStringList>("commandLine");
|
||||||
|
QTest::addColumn<QStringList>("expectedOptionNames");
|
||||||
|
QTest::addColumn<QStringList>("expectedOptionValues");
|
||||||
|
|
||||||
|
QTest::newRow("collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-abc" << "val")
|
||||||
|
<< (QStringList() << "a" << "b" << "c") << (QStringList() << QString() << QString() << "val");
|
||||||
|
QTest::newRow("collapsed_with_equalsign_value") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-abc=val")
|
||||||
|
<< (QStringList() << "a" << "b" << "c") << (QStringList() << QString() << QString() << "val");
|
||||||
|
QTest::newRow("collapsed_explicit_longoption") << QCommandLineParser::ParseAsCompactedShortOptions << QStringList("--nn")
|
||||||
|
<< QStringList("nn") << QStringList();
|
||||||
|
QTest::newRow("collapsed_longoption_value") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "--abc" << "val")
|
||||||
|
<< QStringList("abc") << QStringList("val");
|
||||||
|
QTest::newRow("compiler") << QCommandLineParser::ParseAsCompactedShortOptions << QStringList("-cab")
|
||||||
|
<< QStringList("c") << QStringList("ab");
|
||||||
|
QTest::newRow("compiler_with_space") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-c" << "val")
|
||||||
|
<< QStringList("c") << QStringList("val");
|
||||||
|
|
||||||
|
QTest::newRow("implicitlylong") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-abc" << "val")
|
||||||
|
<< QStringList("abc") << QStringList("val");
|
||||||
|
QTest::newRow("implicitlylong_equal") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-abc=val")
|
||||||
|
<< QStringList("abc") << QStringList("val");
|
||||||
|
QTest::newRow("implicitlylong_longoption") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "--nn")
|
||||||
|
<< QStringList("nn") << QStringList();
|
||||||
|
QTest::newRow("implicitlylong_longoption_value") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "--abc" << "val")
|
||||||
|
<< QStringList("abc") << QStringList("val");
|
||||||
|
QTest::newRow("implicitlylong_with_space") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-c" << "val")
|
||||||
|
<< QStringList("c") << QStringList("val");
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testSingleDashWordOptionModes()
|
||||||
|
{
|
||||||
|
QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
|
||||||
|
QFETCH(QStringList, commandLine);
|
||||||
|
QFETCH(QStringList, expectedOptionNames);
|
||||||
|
QFETCH(QStringList, expectedOptionValues);
|
||||||
|
|
||||||
|
commandLine.prepend("tst_QCommandLineParser");
|
||||||
|
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.setSingleDashWordOptionMode(parsingMode);
|
||||||
|
parser.addOption(QCommandLineOption("a", QStringLiteral("a option.")));
|
||||||
|
parser.addOption(QCommandLineOption("b", QStringLiteral("b option.")));
|
||||||
|
parser.addOption(QCommandLineOption(QStringList() << "c" << "abc", QStringLiteral("c option."), QStringLiteral("value")));
|
||||||
|
parser.addOption(QCommandLineOption("nn", QStringLiteral("nn option.")));
|
||||||
|
QVERIFY(parser.parse(commandLine));
|
||||||
|
QCOMPARE(parser.optionNames(), expectedOptionNames);
|
||||||
|
for (int i = 0; i < expectedOptionValues.count(); ++i)
|
||||||
|
QCOMPARE(parser.value(parser.optionNames().at(i)), expectedOptionValues.at(i));
|
||||||
|
QCOMPARE(parser.unknownOptionNames(), QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testVersionOption()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINCE
|
||||||
|
QSKIP("Reading and writing to a process is not supported on Qt/CE");
|
||||||
|
#endif
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QProcess process;
|
||||||
|
process.start("testhelper/qcommandlineparser_test_helper", QStringList() << "0" << "--version");
|
||||||
|
QVERIFY(process.waitForFinished(5000));
|
||||||
|
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||||
|
QString output = process.readAll();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
output.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
|
||||||
|
#endif
|
||||||
|
QCOMPARE(output, QString("qcommandlineparser_test_helper 1.0\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testHelpOption_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QCommandLineParser::SingleDashWordOptionMode>("parsingMode");
|
||||||
|
QTest::addColumn<QString>("expectedHelpOutput");
|
||||||
|
|
||||||
|
QString expectedOutput =
|
||||||
|
"Usage: testhelper/qcommandlineparser_test_helper [options] parsingMode command\n"
|
||||||
|
"Test helper\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -h, --help Displays this help.\n"
|
||||||
|
" -v, --version Displays version information.\n"
|
||||||
|
" --load <url> Load file from URL.\n"
|
||||||
|
" -o, --output <file> Set output file.\n"
|
||||||
|
" -D <key=value> Define macro.\n"
|
||||||
|
" -n, --no-implicit-includes Disable automatic generation of implicit #include\n"
|
||||||
|
" -directives.\n"
|
||||||
|
"\n"
|
||||||
|
"Arguments:\n"
|
||||||
|
" parsingMode The parsing mode to test.\n"
|
||||||
|
" command The command to execute.\n";
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
expectedOutput.replace(" -h, --help Displays this help.\n",
|
||||||
|
" -?, -h, --help Displays this help.\n");
|
||||||
|
expectedOutput.replace("testhelper/", "testhelper\\");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QTest::newRow("collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << expectedOutput;
|
||||||
|
QTest::newRow("long") << QCommandLineParser::ParseAsLongOptions << expectedOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCommandLineParser::testHelpOption()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINCE
|
||||||
|
QSKIP("Reading and writing to a process is not supported on Qt/CE");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
|
||||||
|
QFETCH(QString, expectedHelpOutput);
|
||||||
|
QCoreApplication app(empty_argc, empty_argv);
|
||||||
|
QProcess process;
|
||||||
|
process.start("testhelper/qcommandlineparser_test_helper", QStringList() << QString::number(parsingMode) << "--help");
|
||||||
|
QVERIFY(process.waitForFinished(5000));
|
||||||
|
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||||
|
QString output = process.readAll();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
output.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
|
||||||
|
#endif
|
||||||
|
QCOMPARE(output, expectedHelpOutput);
|
||||||
|
|
||||||
|
process.start("testhelper/qcommandlineparser_test_helper", QStringList() << "0" << "resize" << "--help");
|
||||||
|
QVERIFY(process.waitForFinished(5000));
|
||||||
|
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||||
|
output = process.readAll();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
output.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
|
||||||
|
#endif
|
||||||
|
QByteArray expectedResizeHelp =
|
||||||
|
"Usage: testhelper/qcommandlineparser_test_helper [options] resize [resize_options]\n"
|
||||||
|
"Test helper\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -h, --help Displays this help.\n"
|
||||||
|
" -v, --version Displays version information.\n"
|
||||||
|
" --load <url> Load file from URL.\n"
|
||||||
|
" -o, --output <file> Set output file.\n"
|
||||||
|
" -D <key=value> Define macro.\n"
|
||||||
|
" -n, --no-implicit-includes Disable automatic generation of implicit #include\n"
|
||||||
|
" -directives.\n"
|
||||||
|
" --size <size> New size.\n"
|
||||||
|
"\n"
|
||||||
|
"Arguments:\n"
|
||||||
|
" resize Resize the object to a new size.\n";
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
expectedResizeHelp.replace(" -h, --help Displays this help.\n",
|
||||||
|
" -?, -h, --help Displays this help.\n");
|
||||||
|
expectedResizeHelp.replace("testhelper/", "testhelper\\");
|
||||||
|
#endif
|
||||||
|
QCOMPARE(output, QString(expectedResizeHelp));
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(tst_QCommandLineParser)
|
||||||
|
#include "tst_qcommandlineparser.moc"
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
CONFIG += testcase parallel_test
|
||||||
|
TARGET = tst_qcommandlineparser
|
||||||
|
QT = core testlib
|
||||||
|
SOURCES = tst_qcommandlineparser.cpp
|
@ -8,6 +8,7 @@ SUBDIRS=\
|
|||||||
qbytedatabuffer \
|
qbytedatabuffer \
|
||||||
qcache \
|
qcache \
|
||||||
qchar \
|
qchar \
|
||||||
|
qcommandlineparser \
|
||||||
qcontiguouscache \
|
qcontiguouscache \
|
||||||
qcryptographichash \
|
qcryptographichash \
|
||||||
qdate \
|
qdate \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user