QCommandLineParser: add parsing mode for options after arguments
The new mode, ParseAsPositionalArguments, allows to interpret "application argument --opt" as having two positional arguments, "argument" and "--opt". This mode is useful for executables that aim to launch other executables (e.g. wrappers, debugging tools, etc.) or who support internal commands followed by options for the command. "argument" is the name of the command, and all options occurring after it can be collected and parsed by another command line parser, possibly in another executable. [ChangeLog][QtCore][QCommandLineParser] Add parsing mode for options after arguments, to allow treating them as more arguments. Change-Id: I48d5fcf90f2f59deda8422538b8ebf2680fae828 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
aabbb87f4a
commit
74117b5100
@ -53,6 +53,7 @@ class QCommandLineParserPrivate
|
||||
public:
|
||||
inline QCommandLineParserPrivate()
|
||||
: singleDashWordOptionMode(QCommandLineParser::ParseAsCompactedShortOptions),
|
||||
optionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsOptions),
|
||||
builtinVersionOption(false),
|
||||
builtinHelpOption(false),
|
||||
needsParsing(true)
|
||||
@ -103,6 +104,9 @@ public:
|
||||
//! The parsing mode for "-abc"
|
||||
QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode;
|
||||
|
||||
//! How to parse "arg -option"
|
||||
QCommandLineParser::OptionsAfterPositionalArgumentsMode optionsAfterPositionalArgumentsMode;
|
||||
|
||||
//! Whether addVersionOption was called
|
||||
bool builtinVersionOption;
|
||||
|
||||
@ -298,6 +302,41 @@ void QCommandLineParser::setSingleDashWordOptionMode(QCommandLineParser::SingleD
|
||||
d->singleDashWordOptionMode = singleDashWordOptionMode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QCommandLineParser::OptionsAfterPositionalArgumentsMode
|
||||
|
||||
This enum describes the way the parser interprets options that
|
||||
occur after positional arguments.
|
||||
|
||||
\value ParseAsOptions \c{application argument --opt -t} is interpreted as setting
|
||||
the options \c{opt} and \c{t}, just like \c{application --opt -t argument} would do.
|
||||
This is the default parsing mode. In order to specify that \c{--opt} and \c{-t}
|
||||
are positional arguments instead, the user can use \c{--}, as in
|
||||
\c{application argument -- --opt -t}.
|
||||
|
||||
\value ParseAsPositionalArguments \c{application argument --opt} is interpreted as
|
||||
having two positional arguments, \c{argument} and \c{--opt}.
|
||||
This mode is useful for executables that aim to launch other executables
|
||||
(e.g. wrappers, debugging tools, etc.) or that support internal commands
|
||||
followed by options for the command. \c{argument} is the name of the command,
|
||||
and all options occurring after it can be collected and parsed by another
|
||||
command line parser, possibly in another executable.
|
||||
|
||||
\sa setOptionsAfterPositionalArgumentsMode()
|
||||
|
||||
\since 5.5
|
||||
*/
|
||||
|
||||
/*!
|
||||
Sets the parsing mode to \a parsingMode.
|
||||
This must be called before process() or parse().
|
||||
\since 5.5
|
||||
*/
|
||||
void QCommandLineParser::setOptionsAfterPositionalArgumentsMode(QCommandLineParser::OptionsAfterPositionalArgumentsMode parsingMode)
|
||||
{
|
||||
d->optionsAfterPositionalArgumentsMode = parsingMode;
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds the option \a option to look for while parsing.
|
||||
|
||||
@ -640,7 +679,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
|
||||
const QLatin1Char dashChar('-');
|
||||
const QLatin1Char assignChar('=');
|
||||
|
||||
bool doubleDashFound = false;
|
||||
bool forcePositional = false;
|
||||
errorText.clear();
|
||||
positionalArgumentList.clear();
|
||||
optionNames.clear();
|
||||
@ -658,7 +697,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
|
||||
for (; argumentIterator != args.end() ; ++argumentIterator) {
|
||||
QString argument = *argumentIterator;
|
||||
|
||||
if (doubleDashFound) {
|
||||
if (forcePositional) {
|
||||
positionalArgumentList.append(argument);
|
||||
} else if (argument.startsWith(doubleDashString)) {
|
||||
if (argument.length() > 2) {
|
||||
@ -670,7 +709,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
|
||||
error = true;
|
||||
}
|
||||
} else {
|
||||
doubleDashFound = true;
|
||||
forcePositional = true;
|
||||
}
|
||||
} else if (argument.startsWith(dashChar)) {
|
||||
if (argument.size() == 1) { // single dash ("stdin")
|
||||
@ -722,6 +761,8 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
|
||||
}
|
||||
} else {
|
||||
positionalArgumentList.append(argument);
|
||||
if (optionsAfterPositionalArgumentsMode == QCommandLineParser::ParseAsPositionalArguments)
|
||||
forcePositional = true;
|
||||
}
|
||||
if (argumentIterator == args.end())
|
||||
break;
|
||||
|
@ -57,6 +57,12 @@ public:
|
||||
};
|
||||
void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode);
|
||||
|
||||
enum OptionsAfterPositionalArgumentsMode {
|
||||
ParseAsOptions,
|
||||
ParseAsPositionalArguments
|
||||
};
|
||||
void setOptionsAfterPositionalArgumentsMode(OptionsAfterPositionalArgumentsMode mode);
|
||||
|
||||
bool addOption(const QCommandLineOption &commandLineOption);
|
||||
bool addOptions(const QList<QCommandLineOption> &options);
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <QtCore/QCommandLineParser>
|
||||
|
||||
Q_DECLARE_METATYPE(char**)
|
||||
Q_DECLARE_METATYPE(QCommandLineParser::OptionsAfterPositionalArgumentsMode)
|
||||
|
||||
class tst_QCommandLineParser : public QObject
|
||||
{
|
||||
@ -51,6 +52,8 @@ private slots:
|
||||
void testPositionalArguments();
|
||||
void testBooleanOption_data();
|
||||
void testBooleanOption();
|
||||
void testOptionsAndPositional_data();
|
||||
void testOptionsAndPositional();
|
||||
void testMultipleNames_data();
|
||||
void testMultipleNames();
|
||||
void testSingleValueOption_data();
|
||||
@ -141,6 +144,40 @@ void tst_QCommandLineParser::testBooleanOption()
|
||||
QVERIFY(!parser.isSet("c"));
|
||||
}
|
||||
|
||||
void tst_QCommandLineParser::testOptionsAndPositional_data()
|
||||
{
|
||||
QTest::addColumn<QStringList>("args");
|
||||
QTest::addColumn<QStringList>("expectedOptionNames");
|
||||
QTest::addColumn<bool>("expectedIsSet");
|
||||
QTest::addColumn<QStringList>("expectedPositionalArguments");
|
||||
QTest::addColumn<QCommandLineParser::OptionsAfterPositionalArgumentsMode>("parsingMode");
|
||||
|
||||
const QStringList arg = QStringList() << "arg";
|
||||
QTest::newRow("before_positional_default") << (QStringList() << "tst_qcommandlineparser" << "-b" << "arg") << (QStringList() << "b") << true << arg << QCommandLineParser::ParseAsOptions;
|
||||
QTest::newRow("after_positional_default") << (QStringList() << "tst_qcommandlineparser" << "arg" << "-b") << (QStringList() << "b") << true << arg << QCommandLineParser::ParseAsOptions;
|
||||
QTest::newRow("before_positional_parseAsArg") << (QStringList() << "tst_qcommandlineparser" << "-b" << "arg") << (QStringList() << "b") << true << arg << QCommandLineParser::ParseAsPositionalArguments;
|
||||
QTest::newRow("after_positional_parseAsArg") << (QStringList() << "tst_qcommandlineparser" << "arg" << "-b") << (QStringList()) << false << (QStringList() << "arg" << "-b") << QCommandLineParser::ParseAsPositionalArguments;
|
||||
}
|
||||
|
||||
void tst_QCommandLineParser::testOptionsAndPositional()
|
||||
{
|
||||
QFETCH(QStringList, args);
|
||||
QFETCH(QStringList, expectedOptionNames);
|
||||
QFETCH(bool, expectedIsSet);
|
||||
QFETCH(QStringList, expectedPositionalArguments);
|
||||
QFETCH(QCommandLineParser::OptionsAfterPositionalArgumentsMode, parsingMode);
|
||||
|
||||
QCoreApplication app(empty_argc, empty_argv);
|
||||
QCommandLineParser parser;
|
||||
parser.setOptionsAfterPositionalArgumentsMode(parsingMode);
|
||||
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(), expectedPositionalArguments);
|
||||
}
|
||||
|
||||
void tst_QCommandLineParser::testMultipleNames_data()
|
||||
{
|
||||
QTest::addColumn<QStringList>("args");
|
||||
|
Loading…
Reference in New Issue
Block a user