Add QCommandLineOption::Flags containing HiddenFromHelp and ShortOptionStyle

This patch adds a new option, QCommandLineOption::ShortOptionStyle, which helps
applications (such as compilers, so moc and now qdoc) which need to mix long-style
and short flags.

[ChangeLog][QtCore][QCommandLineOption] Added flags() and setFlags() methods.
Added ShortOptionStyle and HiddenFromHelp flags.

Change-Id: I944ce56aff2b28ecd6bb9d2d23c4e726e9d06647
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Olivier Goffart 2016-03-17 12:48:38 +01:00 committed by Olivier Goffart (Woboq GmbH)
parent 17d3825874
commit 63274c95a3
5 changed files with 98 additions and 13 deletions

View File

@ -49,14 +49,12 @@ class QCommandLineOptionPrivate : public QSharedData
public:
Q_NEVER_INLINE
explicit QCommandLineOptionPrivate(const QString &name)
: names(removeInvalidNames(QStringList(name))),
hidden(false)
: names(removeInvalidNames(QStringList(name)))
{ }
Q_NEVER_INLINE
explicit QCommandLineOptionPrivate(const QStringList &names)
: names(removeInvalidNames(names)),
hidden(false)
: names(removeInvalidNames(names))
{ }
static QStringList removeInvalidNames(QStringList nameList);
@ -74,8 +72,7 @@ public:
//! The list of default values used for this option.
QStringList defaultValues;
//! Show or hide in --help
bool hidden;
QCommandLineOption::Flags flags;
};
/*!
@ -394,6 +391,7 @@ QStringList QCommandLineOption::defaultValues() const
return d->defaultValues;
}
#if QT_DEPRECATED_SINCE(5, 8)
/*!
Sets whether to hide this option in the user-visible help output.
@ -401,11 +399,12 @@ QStringList QCommandLineOption::defaultValues() const
a particular option makes it internal, i.e. not listed in the help output.
\since 5.6
\obsolete Use setFlags(QCommandLineOption::HiddenFromHelp), QCommandLineOption::HiddenFromHelp
\sa isHidden
*/
void QCommandLineOption::setHidden(bool hide)
{
d->hidden = hide;
d->flags.setFlag(HiddenFromHelp, hide);
}
/*!
@ -413,11 +412,52 @@ void QCommandLineOption::setHidden(bool hide)
false if the option is listed.
\since 5.6
\sa setHidden()
\obsolete Use flags() & QCommandLineOption::HiddenFromHelp
\sa setHidden(), QCommandLineOption::HiddenFromHelp
*/
bool QCommandLineOption::isHidden() const
{
return d->hidden;
return d->flags & HiddenFromHelp;
}
#endif
/*!
Returns a set of flags that affect this command-line option.
\since 5.8
\sa setFlags(), QCommandLineOption::Flags
*/
QCommandLineOption::Flags QCommandLineOption::flags() const
{
return d->flags;
}
/*!
Set the set of flags that affect this command-line option.
\since 5.8
\sa flags(), QCommandLineOption::Flags
*/
void QCommandLineOption::setFlags(Flags flags)
{
d->flags = flags;
}
/*!
\enum QCommandLineOption::Flag
\value HiddenFromHelp Hide this option in the user-visible help output. All
options are visible by default. Setting this flag for a particular
option makes it internal, i.e. not listed in the help output.
\value ShortOptionStyle The option will always be understood as a short
option, regardless of what was set by
QCommandLineParser::setSingleDashWordOptionMode.
This allows flags such as \c{-DDEFINE=VALUE} or \c{-I/include/path} to be
interpreted as short flags even when the parser is in
QCommandLineParser::ParseAsLongOptions mode.
\sa QCommandLineOption::setFlags(), QCommandLineOption::flags()
*/
QT_END_NAMESPACE

View File

@ -50,6 +50,12 @@ class QCommandLineOptionPrivate;
class Q_CORE_EXPORT QCommandLineOption
{
public:
enum Flag {
HiddenFromHelp = 0x1,
ShortOptionStyle = 0x2
};
Q_DECLARE_FLAGS(Flags, Flag)
explicit QCommandLineOption(const QString &name);
explicit QCommandLineOption(const QStringList &names);
/*implicit*/ QCommandLineOption(const QString &name, const QString &description,
@ -82,14 +88,24 @@ public:
void setDefaultValues(const QStringList &defaultValues);
QStringList defaultValues() const;
Flags flags() const;
void setFlags(Flags aflags);
#if QT_DEPRECATED_SINCE(5, 8)
QT_DEPRECATED_X("Use setFlags() with HiddenFromHelp)")
void setHidden(bool hidden);
QT_DEPRECATED_X("Use flags() and HiddenFromHelp")
bool isHidden() const;
#endif
private:
QSharedDataPointer<QCommandLineOptionPrivate> d;
};
Q_DECLARE_SHARED(QCommandLineOption)
Q_DECLARE_OPERATORS_FOR_FLAGS(QCommandLineOption::Flags)
QT_END_NAMESPACE

View File

@ -295,7 +295,9 @@ QCommandLineParser::~QCommandLineParser()
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.
arguments in such a way. There is an exception if the \c{a} option has the
QCommandLineOption::ShortOptionStyle flag set, in which case it is still
interpreted as \c{-a bc}.
\sa setSingleDashWordOptionMode()
*/
@ -762,6 +764,18 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
}
case QCommandLineParser::ParseAsLongOptions:
{
if (argument.size() > 2) {
const QString possibleShortOptionStyleName = argument.mid(1, 1);
const auto shortOptionIt = nameHash.constFind(possibleShortOptionStyleName);
if (shortOptionIt != nameHash.constEnd()) {
const auto &arg = commandLineOptionList.at(*shortOptionIt);
if (arg.flags() & QCommandLineOption::ShortOptionStyle) {
registerFoundOption(possibleShortOptionStyleName);
optionValuesHash[*shortOptionIt].append(argument.mid(2));
break;
}
}
}
const QString optionName = argument.mid(1).section(assignChar, 0, 0);
if (registerFoundOption(optionName)) {
if (!parseOptionValue(optionName, argument, &argumentIterator, args.end()))
@ -1097,7 +1111,7 @@ QString QCommandLineParserPrivate::helpText() const
optionNameList.reserve(commandLineOptionList.size());
int longestOptionNameString = 0;
for (const QCommandLineOption &option : commandLineOptionList) {
if (option.isHidden())
if (option.flags() & QCommandLineOption::HiddenFromHelp)
continue;
const QStringList optionNames = option.names();
QString optionNamesString;
@ -1116,7 +1130,7 @@ QString QCommandLineParserPrivate::helpText() const
++longestOptionNameString;
auto optionNameIterator = optionNameList.cbegin();
for (const QCommandLineOption &option : commandLineOptionList) {
if (option.isHidden())
if (option.flags() & QCommandLineOption::HiddenFromHelp)
continue;
text += wrapText(*optionNameIterator, longestOptionNameString, option.description());
++optionNameIterator;

View File

@ -71,8 +71,12 @@ int main(int argc, char *argv[])
// A hidden option
QCommandLineOption hiddenOption(QStringList() << QStringLiteral("hidden"));
hiddenOption.setDescription(QStringLiteral("THIS SHOULD NEVER APPEAR"));
hiddenOption.setHidden(true);
hiddenOption.setFlags(QCommandLineOption::HiddenFromHelp);
parser.addOption(hiddenOption);
QCommandLineOption hiddenOption2(QStringList() << QStringLiteral("hidden2"));
hiddenOption2.setDescription(QStringLiteral("NEITHER SHOULD THIS"));
hiddenOption2.setHidden(true);
parser.addOption(hiddenOption2);
// This program supports different options depending on the "command" (first argument).
// Call parse() to find out the positional arguments.

View File

@ -450,6 +450,13 @@ void tst_QCommandLineParser::testSingleDashWordOptionModes_data()
<< QStringList("abc") << QStringList("val");
QTest::newRow("implicitlylong_with_space") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-c" << "val")
<< QStringList("c") << QStringList("val");
QTest::newRow("forceshort_detached") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-I" << "45")
<< QStringList("I") << QStringList("45");
QTest::newRow("forceshort_attached") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-I46")
<< QStringList("I") << QStringList("46");
QTest::newRow("forceshort_mixed") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-I45" << "-nn")
<< (QStringList() << "I" << "nn") << QStringList("45");
}
void tst_QCommandLineParser::testSingleDashWordOptionModes()
@ -468,6 +475,10 @@ void tst_QCommandLineParser::testSingleDashWordOptionModes()
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.")));
QCommandLineOption forceShort(QStringLiteral("I"), QStringLiteral("always short option"),
QStringLiteral("path"), QStringLiteral("default"));
forceShort.setFlags(QCommandLineOption::ShortOptionStyle);
parser.addOption(forceShort);
QVERIFY(parser.parse(commandLine));
QCOMPARE(parser.optionNames(), expectedOptionNames);
for (int i = 0; i < expectedOptionValues.count(); ++i)