Changed clang format to new agreement
This commit is contained in:
committed by
borgmanJeremy
parent
2cbccc3d0a
commit
0d5386edd4
@@ -25,38 +25,32 @@ CommandArgument::CommandArgument(const QString& name,
|
||||
, m_description(description)
|
||||
{}
|
||||
|
||||
void
|
||||
CommandArgument::setName(const QString& name)
|
||||
void CommandArgument::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandArgument::name() const
|
||||
QString CommandArgument::name() const
|
||||
{
|
||||
return m_name;
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void
|
||||
CommandArgument::setDescription(const QString& description)
|
||||
void CommandArgument::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandArgument::description() const
|
||||
QString CommandArgument::description() const
|
||||
{
|
||||
return m_description;
|
||||
return m_description;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandArgument::isRoot() const
|
||||
bool CommandArgument::isRoot() const
|
||||
{
|
||||
return m_name.isEmpty() && m_description.isEmpty();
|
||||
return m_name.isEmpty() && m_description.isEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
CommandArgument::operator==(const CommandArgument& arg) const
|
||||
bool CommandArgument::operator==(const CommandArgument& arg) const
|
||||
{
|
||||
return m_description == arg.m_description && m_name == arg.m_name;
|
||||
return m_description == arg.m_description && m_name == arg.m_name;
|
||||
}
|
||||
|
||||
@@ -22,20 +22,20 @@
|
||||
class CommandArgument
|
||||
{
|
||||
public:
|
||||
CommandArgument();
|
||||
explicit CommandArgument(const QString& name, const QString& description);
|
||||
CommandArgument();
|
||||
explicit CommandArgument(const QString& name, const QString& description);
|
||||
|
||||
void setName(const QString& name);
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
QString name() const;
|
||||
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
|
||||
bool isRoot() const;
|
||||
bool isRoot() const;
|
||||
|
||||
bool operator==(const CommandArgument& arg) const;
|
||||
bool operator==(const CommandArgument& arg) const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_description;
|
||||
QString m_name;
|
||||
QString m_description;
|
||||
};
|
||||
|
||||
@@ -34,399 +34,386 @@ auto versionOption =
|
||||
auto helpOption =
|
||||
CommandOption({ "h", "help" }, QStringLiteral("Displays this help"));
|
||||
|
||||
QString
|
||||
optionsToString(const QList<CommandOption>& options,
|
||||
const QList<CommandArgument>& arguments)
|
||||
QString optionsToString(const QList<CommandOption>& options,
|
||||
const QList<CommandArgument>& arguments)
|
||||
{
|
||||
int size = 0; // track the largest size
|
||||
QStringList dashedOptionList;
|
||||
// save the dashed options and its size in order to print the description
|
||||
// of every option at the same horizontal character position.
|
||||
for (auto const& option : options) {
|
||||
QStringList dashedOptions = option.dashedNames();
|
||||
QString joinedDashedOptions = dashedOptions.join(QStringLiteral(", "));
|
||||
if (!option.valueName().isEmpty()) {
|
||||
joinedDashedOptions += QStringLiteral(" <%1>").arg(option.valueName());
|
||||
int size = 0; // track the largest size
|
||||
QStringList dashedOptionList;
|
||||
// save the dashed options and its size in order to print the description
|
||||
// of every option at the same horizontal character position.
|
||||
for (auto const& option : options) {
|
||||
QStringList dashedOptions = option.dashedNames();
|
||||
QString joinedDashedOptions = dashedOptions.join(QStringLiteral(", "));
|
||||
if (!option.valueName().isEmpty()) {
|
||||
joinedDashedOptions +=
|
||||
QStringLiteral(" <%1>").arg(option.valueName());
|
||||
}
|
||||
if (joinedDashedOptions.length() > size) {
|
||||
size = joinedDashedOptions.length();
|
||||
}
|
||||
dashedOptionList << joinedDashedOptions;
|
||||
}
|
||||
if (joinedDashedOptions.length() > size) {
|
||||
size = joinedDashedOptions.length();
|
||||
// check the length of the arguments
|
||||
for (auto const& arg : arguments) {
|
||||
if (arg.name().length() > size)
|
||||
size = arg.name().length();
|
||||
}
|
||||
dashedOptionList << joinedDashedOptions;
|
||||
}
|
||||
// check the length of the arguments
|
||||
for (auto const& arg : arguments) {
|
||||
if (arg.name().length() > size)
|
||||
size = arg.name().length();
|
||||
}
|
||||
// generate the text
|
||||
QString result;
|
||||
if (!dashedOptionList.isEmpty()) {
|
||||
result += QObject::tr("Options") + ":\n";
|
||||
QString linePadding = QStringLiteral(" ").repeated(size + 4).prepend("\n");
|
||||
for (int i = 0; i < options.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(dashedOptionList.at(i).leftJustified(size, ' '))
|
||||
.arg(options.at(i).description().replace(QLatin1String("\n"),
|
||||
linePadding));
|
||||
// generate the text
|
||||
QString result;
|
||||
if (!dashedOptionList.isEmpty()) {
|
||||
result += QObject::tr("Options") + ":\n";
|
||||
QString linePadding =
|
||||
QStringLiteral(" ").repeated(size + 4).prepend("\n");
|
||||
for (int i = 0; i < options.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(dashedOptionList.at(i).leftJustified(size, ' '))
|
||||
.arg(options.at(i).description().replace(
|
||||
QLatin1String("\n"), linePadding));
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QLatin1String("\n");
|
||||
}
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QLatin1String("\n");
|
||||
result += QObject::tr("Arguments") + ":\n";
|
||||
}
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QObject::tr("Arguments") + ":\n";
|
||||
}
|
||||
for (int i = 0; i < arguments.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(arguments.at(i).name().leftJustified(size, ' '))
|
||||
.arg(arguments.at(i).description());
|
||||
}
|
||||
return result;
|
||||
for (int i = 0; i < arguments.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(arguments.at(i).name().leftJustified(size, ' '))
|
||||
.arg(arguments.at(i).description());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
bool
|
||||
CommandLineParser::processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
bool CommandLineParser::processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
{
|
||||
QString argument = *actualIt;
|
||||
bool ok = true;
|
||||
bool isValidArg = false;
|
||||
for (Node& n : actualNode->subNodes) {
|
||||
if (n.argument.name() == argument) {
|
||||
actualNode = &n;
|
||||
isValidArg = true;
|
||||
break;
|
||||
QString argument = *actualIt;
|
||||
bool ok = true;
|
||||
bool isValidArg = false;
|
||||
for (Node& n : actualNode->subNodes) {
|
||||
if (n.argument.name() == argument) {
|
||||
actualNode = &n;
|
||||
isValidArg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isValidArg) {
|
||||
auto nextArg = actualNode->argument;
|
||||
m_foundArgs.append(nextArg);
|
||||
// check next is help
|
||||
++actualIt;
|
||||
ok = processIfOptionIsHelp(args, actualIt, actualNode);
|
||||
--actualIt;
|
||||
} else {
|
||||
ok = false;
|
||||
out << QStringLiteral("'%1' is not a valid argument.").arg(argument);
|
||||
}
|
||||
return ok;
|
||||
if (isValidArg) {
|
||||
auto nextArg = actualNode->argument;
|
||||
m_foundArgs.append(nextArg);
|
||||
// check next is help
|
||||
++actualIt;
|
||||
ok = processIfOptionIsHelp(args, actualIt, actualNode);
|
||||
--actualIt;
|
||||
} else {
|
||||
ok = false;
|
||||
out << QStringLiteral("'%1' is not a valid argument.").arg(argument);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode)
|
||||
bool CommandLineParser::processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode)
|
||||
{
|
||||
QString arg = *actualIt;
|
||||
bool ok = true;
|
||||
// track values
|
||||
int equalsPos = arg.indexOf(QLatin1String("="));
|
||||
QString valueStr;
|
||||
if (equalsPos != -1) {
|
||||
valueStr = arg.mid(equalsPos + 1); // right
|
||||
arg = arg.mid(0, equalsPos); // left
|
||||
}
|
||||
// check format -x --xx...
|
||||
bool isDoubleDashed = arg.startsWith(QLatin1String("--"));
|
||||
ok = isDoubleDashed ? arg.length() > 3 : arg.length() == 2;
|
||||
if (!ok) {
|
||||
out << QStringLiteral("the option %1 has a wrong format.").arg(arg);
|
||||
return ok;
|
||||
}
|
||||
arg = isDoubleDashed ? arg.remove(0, 2) : arg.remove(0, 1);
|
||||
// get option
|
||||
auto endIt = actualNode->options.cend();
|
||||
auto optionIt = endIt;
|
||||
for (auto i = actualNode->options.cbegin(); i != endIt; ++i) {
|
||||
if ((*i).names().contains(arg)) {
|
||||
optionIt = i;
|
||||
break;
|
||||
QString arg = *actualIt;
|
||||
bool ok = true;
|
||||
// track values
|
||||
int equalsPos = arg.indexOf(QLatin1String("="));
|
||||
QString valueStr;
|
||||
if (equalsPos != -1) {
|
||||
valueStr = arg.mid(equalsPos + 1); // right
|
||||
arg = arg.mid(0, equalsPos); // left
|
||||
}
|
||||
}
|
||||
if (optionIt == endIt) {
|
||||
QString argName = actualNode->argument.name();
|
||||
if (argName.isEmpty()) {
|
||||
argName = qApp->applicationName();
|
||||
}
|
||||
out << QStringLiteral("the option '%1' is not a valid option "
|
||||
"for the argument '%2'.")
|
||||
.arg(arg)
|
||||
.arg(argName);
|
||||
ok = false;
|
||||
return ok;
|
||||
}
|
||||
// check presence of values
|
||||
CommandOption option = *optionIt;
|
||||
bool requiresValue = !(option.valueName().isEmpty());
|
||||
if (!requiresValue && equalsPos != -1) {
|
||||
out << QStringLiteral("the option '%1' contains a '=' and it doesn't "
|
||||
"require a value.")
|
||||
.arg(arg);
|
||||
ok = false;
|
||||
return ok;
|
||||
} else if (requiresValue && valueStr.isEmpty()) {
|
||||
// find in the next
|
||||
if (actualIt + 1 != args.cend()) {
|
||||
++actualIt;
|
||||
} else {
|
||||
out << QStringLiteral("Expected value after the option '%1'.").arg(arg);
|
||||
ok = false;
|
||||
return ok;
|
||||
}
|
||||
valueStr = *actualIt;
|
||||
}
|
||||
// check the value correctness
|
||||
if (requiresValue) {
|
||||
ok = option.checkValue(valueStr);
|
||||
// check format -x --xx...
|
||||
bool isDoubleDashed = arg.startsWith(QLatin1String("--"));
|
||||
ok = isDoubleDashed ? arg.length() > 3 : arg.length() == 2;
|
||||
if (!ok) {
|
||||
QString err = option.errorMsg();
|
||||
if (!err.endsWith(QLatin1String(".")))
|
||||
err += QLatin1String(".");
|
||||
out << err;
|
||||
return ok;
|
||||
out << QStringLiteral("the option %1 has a wrong format.").arg(arg);
|
||||
return ok;
|
||||
}
|
||||
option.setValue(valueStr);
|
||||
}
|
||||
m_foundOptions.append(option);
|
||||
return ok;
|
||||
arg = isDoubleDashed ? arg.remove(0, 2) : arg.remove(0, 1);
|
||||
// get option
|
||||
auto endIt = actualNode->options.cend();
|
||||
auto optionIt = endIt;
|
||||
for (auto i = actualNode->options.cbegin(); i != endIt; ++i) {
|
||||
if ((*i).names().contains(arg)) {
|
||||
optionIt = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optionIt == endIt) {
|
||||
QString argName = actualNode->argument.name();
|
||||
if (argName.isEmpty()) {
|
||||
argName = qApp->applicationName();
|
||||
}
|
||||
out << QStringLiteral("the option '%1' is not a valid option "
|
||||
"for the argument '%2'.")
|
||||
.arg(arg)
|
||||
.arg(argName);
|
||||
ok = false;
|
||||
return ok;
|
||||
}
|
||||
// check presence of values
|
||||
CommandOption option = *optionIt;
|
||||
bool requiresValue = !(option.valueName().isEmpty());
|
||||
if (!requiresValue && equalsPos != -1) {
|
||||
out << QStringLiteral("the option '%1' contains a '=' and it doesn't "
|
||||
"require a value.")
|
||||
.arg(arg);
|
||||
ok = false;
|
||||
return ok;
|
||||
} else if (requiresValue && valueStr.isEmpty()) {
|
||||
// find in the next
|
||||
if (actualIt + 1 != args.cend()) {
|
||||
++actualIt;
|
||||
} else {
|
||||
out << QStringLiteral("Expected value after the option '%1'.")
|
||||
.arg(arg);
|
||||
ok = false;
|
||||
return ok;
|
||||
}
|
||||
valueStr = *actualIt;
|
||||
}
|
||||
// check the value correctness
|
||||
if (requiresValue) {
|
||||
ok = option.checkValue(valueStr);
|
||||
if (!ok) {
|
||||
QString err = option.errorMsg();
|
||||
if (!err.endsWith(QLatin1String(".")))
|
||||
err += QLatin1String(".");
|
||||
out << err;
|
||||
return ok;
|
||||
}
|
||||
option.setValue(valueStr);
|
||||
}
|
||||
m_foundOptions.append(option);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::parse(const QStringList& args)
|
||||
bool CommandLineParser::parse(const QStringList& args)
|
||||
{
|
||||
m_foundArgs.clear();
|
||||
m_foundOptions.clear();
|
||||
bool ok = true;
|
||||
Node* actualNode = &m_parseTree;
|
||||
auto it = ++args.cbegin();
|
||||
// check version option
|
||||
QStringList dashedVersion = versionOption.dashedNames();
|
||||
if (m_withVersion && args.length() > 1 &&
|
||||
dashedVersion.contains(args.at(1))) {
|
||||
if (args.length() == 2) {
|
||||
printVersion();
|
||||
m_foundOptions << versionOption;
|
||||
} else {
|
||||
out << "Invalid arguments after the version option.";
|
||||
ok = false;
|
||||
m_foundArgs.clear();
|
||||
m_foundOptions.clear();
|
||||
bool ok = true;
|
||||
Node* actualNode = &m_parseTree;
|
||||
auto it = ++args.cbegin();
|
||||
// check version option
|
||||
QStringList dashedVersion = versionOption.dashedNames();
|
||||
if (m_withVersion && args.length() > 1 &&
|
||||
dashedVersion.contains(args.at(1))) {
|
||||
if (args.length() == 2) {
|
||||
printVersion();
|
||||
m_foundOptions << versionOption;
|
||||
} else {
|
||||
out << "Invalid arguments after the version option.";
|
||||
ok = false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
// check help option
|
||||
ok = processIfOptionIsHelp(args, it, actualNode);
|
||||
// process the other args
|
||||
for (; it != args.cend() && ok; ++it) {
|
||||
const QString& value = *it;
|
||||
if (value.startsWith(QLatin1String("-"))) {
|
||||
ok = processOptions(args, it, actualNode);
|
||||
|
||||
} else {
|
||||
ok = processArgs(args, it, actualNode);
|
||||
}
|
||||
}
|
||||
if (!ok && !m_generalErrorMessage.isEmpty()) {
|
||||
out << QStringLiteral(" %1\n").arg(m_generalErrorMessage);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
// check help option
|
||||
ok = processIfOptionIsHelp(args, it, actualNode);
|
||||
// process the other args
|
||||
for (; it != args.cend() && ok; ++it) {
|
||||
const QString& value = *it;
|
||||
if (value.startsWith(QLatin1String("-"))) {
|
||||
ok = processOptions(args, it, actualNode);
|
||||
}
|
||||
|
||||
CommandOption CommandLineParser::addVersionOption()
|
||||
{
|
||||
m_withVersion = true;
|
||||
return versionOption;
|
||||
}
|
||||
|
||||
CommandOption CommandLineParser::addHelpOption()
|
||||
{
|
||||
m_withHelp = true;
|
||||
return helpOption;
|
||||
}
|
||||
|
||||
bool CommandLineParser::AddArgument(const CommandArgument& arg,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
bool res = true;
|
||||
Node* n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
ok = processArgs(args, it, actualNode);
|
||||
Node child;
|
||||
child.argument = arg;
|
||||
n->subNodes.append(child);
|
||||
}
|
||||
}
|
||||
if (!ok && !m_generalErrorMessage.isEmpty()) {
|
||||
out << QStringLiteral(" %1\n").arg(m_generalErrorMessage);
|
||||
}
|
||||
return ok;
|
||||
return res;
|
||||
}
|
||||
|
||||
CommandOption
|
||||
CommandLineParser::addVersionOption()
|
||||
bool CommandLineParser::AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
m_withVersion = true;
|
||||
return versionOption;
|
||||
}
|
||||
|
||||
CommandOption
|
||||
CommandLineParser::addHelpOption()
|
||||
{
|
||||
m_withHelp = true;
|
||||
return helpOption;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::AddArgument(const CommandArgument& arg,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
bool res = true;
|
||||
Node* n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
Node child;
|
||||
child.argument = arg;
|
||||
n->subNodes.append(child);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
bool res = true;
|
||||
Node* n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
n->options.append(option);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
bool res = true;
|
||||
for (auto const& option : options) {
|
||||
if (!AddOption(option, parent)) {
|
||||
res = false;
|
||||
break;
|
||||
bool res = true;
|
||||
Node* n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
n->options.append(option);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
||||
bool CommandLineParser::AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
m_generalErrorMessage = msg;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::isSet(const CommandArgument& arg) const
|
||||
{
|
||||
return m_foundArgs.contains(arg);
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::isSet(const CommandOption& option) const
|
||||
{
|
||||
return m_foundOptions.contains(option);
|
||||
}
|
||||
|
||||
QString
|
||||
CommandLineParser::value(const CommandOption& option) const
|
||||
{
|
||||
QString value = option.value();
|
||||
for (const CommandOption& fOption : m_foundOptions) {
|
||||
if (option == fOption) {
|
||||
value = fOption.value();
|
||||
break;
|
||||
bool res = true;
|
||||
for (auto const& option : options) {
|
||||
if (!AddOption(option, parent)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::printVersion()
|
||||
void CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
||||
{
|
||||
out << "Flameshot " << qApp->applicationVersion() << "\nCompiled with Qt "
|
||||
<< static_cast<QString>(QT_VERSION_STR) << "\n";
|
||||
m_generalErrorMessage = msg;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::printHelp(QStringList args, const Node* node)
|
||||
void CommandLineParser::setDescription(const QString& description)
|
||||
{
|
||||
args.removeLast(); // remove the help, it's always the last
|
||||
QString helpText;
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
// add usage info
|
||||
QString argName = node->argument.name();
|
||||
if (argName.isEmpty()) {
|
||||
argName = qApp->applicationName();
|
||||
}
|
||||
QString argText =
|
||||
node->subNodes.isEmpty() ? "" : "[" + QObject::tr("arguments") + "]";
|
||||
helpText += QObject::tr("Usage") + ": %1 [%2-" + QObject::tr("options") +
|
||||
QStringLiteral("] %3\n\n")
|
||||
.arg(args.join(QStringLiteral(" ")))
|
||||
.arg(argName)
|
||||
.arg(argText);
|
||||
bool CommandLineParser::isSet(const CommandArgument& arg) const
|
||||
{
|
||||
return m_foundArgs.contains(arg);
|
||||
}
|
||||
|
||||
// short section about default behavior
|
||||
helpText += QObject::tr("Per default runs Flameshot in the background and \
|
||||
bool CommandLineParser::isSet(const CommandOption& option) const
|
||||
{
|
||||
return m_foundOptions.contains(option);
|
||||
}
|
||||
|
||||
QString CommandLineParser::value(const CommandOption& option) const
|
||||
{
|
||||
QString value = option.value();
|
||||
for (const CommandOption& fOption : m_foundOptions) {
|
||||
if (option == fOption) {
|
||||
value = fOption.value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void CommandLineParser::printVersion()
|
||||
{
|
||||
out << "Flameshot " << qApp->applicationVersion() << "\nCompiled with Qt "
|
||||
<< static_cast<QString>(QT_VERSION_STR) << "\n";
|
||||
}
|
||||
|
||||
void CommandLineParser::printHelp(QStringList args, const Node* node)
|
||||
{
|
||||
args.removeLast(); // remove the help, it's always the last
|
||||
QString helpText;
|
||||
|
||||
// add usage info
|
||||
QString argName = node->argument.name();
|
||||
if (argName.isEmpty()) {
|
||||
argName = qApp->applicationName();
|
||||
}
|
||||
QString argText =
|
||||
node->subNodes.isEmpty() ? "" : "[" + QObject::tr("arguments") + "]";
|
||||
helpText += QObject::tr("Usage") + ": %1 [%2-" + QObject::tr("options") +
|
||||
QStringLiteral("] %3\n\n")
|
||||
.arg(args.join(QStringLiteral(" ")))
|
||||
.arg(argName)
|
||||
.arg(argText);
|
||||
|
||||
// short section about default behavior
|
||||
helpText += QObject::tr("Per default runs Flameshot in the background and \
|
||||
adds a tray icon for configuration.");
|
||||
helpText += "\n\n";
|
||||
helpText += "\n\n";
|
||||
|
||||
// add command options and subarguments
|
||||
QList<CommandArgument> subArgs;
|
||||
for (const Node& n : node->subNodes)
|
||||
subArgs.append(n.argument);
|
||||
auto modifiedOptions = node->options;
|
||||
if (m_withHelp)
|
||||
modifiedOptions << helpOption;
|
||||
if (m_withVersion && node == &m_parseTree) {
|
||||
modifiedOptions << versionOption;
|
||||
}
|
||||
helpText += optionsToString(modifiedOptions, subArgs);
|
||||
// print it
|
||||
out << helpText;
|
||||
}
|
||||
|
||||
CommandLineParser::Node*
|
||||
CommandLineParser::findParent(const CommandArgument& parent)
|
||||
{
|
||||
if (parent == CommandArgument()) {
|
||||
return &m_parseTree;
|
||||
}
|
||||
// find the parent in the subNodes recursively
|
||||
Node* res = nullptr;
|
||||
for (auto i = m_parseTree.subNodes.begin(); i != m_parseTree.subNodes.end();
|
||||
++i) {
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
// add command options and subarguments
|
||||
QList<CommandArgument> subArgs;
|
||||
for (const Node& n : node->subNodes)
|
||||
subArgs.append(n.argument);
|
||||
auto modifiedOptions = node->options;
|
||||
if (m_withHelp)
|
||||
modifiedOptions << helpOption;
|
||||
if (m_withVersion && node == &m_parseTree) {
|
||||
modifiedOptions << versionOption;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
helpText += optionsToString(modifiedOptions, subArgs);
|
||||
// print it
|
||||
out << helpText;
|
||||
}
|
||||
|
||||
CommandLineParser::Node*
|
||||
CommandLineParser::recursiveParentSearch(const CommandArgument& parent,
|
||||
Node& node) const
|
||||
CommandLineParser::Node* CommandLineParser::findParent(
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
Node* res = nullptr;
|
||||
if (node.argument == parent) {
|
||||
res = &node;
|
||||
} else {
|
||||
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i) {
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
}
|
||||
if (parent == CommandArgument()) {
|
||||
return &m_parseTree;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
// find the parent in the subNodes recursively
|
||||
Node* res = nullptr;
|
||||
for (auto i = m_parseTree.subNodes.begin(); i != m_parseTree.subNodes.end();
|
||||
++i) {
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::processIfOptionIsHelp(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
CommandLineParser::Node* CommandLineParser::recursiveParentSearch(
|
||||
const CommandArgument& parent,
|
||||
Node& node) const
|
||||
{
|
||||
bool ok = true;
|
||||
auto dashedHelpNames = helpOption.dashedNames();
|
||||
if (m_withHelp && actualIt != args.cend() &&
|
||||
dashedHelpNames.contains(*actualIt)) {
|
||||
if (actualIt + 1 == args.cend()) {
|
||||
m_foundOptions << helpOption;
|
||||
printHelp(args, actualNode);
|
||||
actualIt++;
|
||||
Node* res = nullptr;
|
||||
if (node.argument == parent) {
|
||||
res = &node;
|
||||
} else {
|
||||
out << "Invalid arguments after the help option.";
|
||||
ok = false;
|
||||
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i) {
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CommandLineParser::processIfOptionIsHelp(
|
||||
const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
{
|
||||
bool ok = true;
|
||||
auto dashedHelpNames = helpOption.dashedNames();
|
||||
if (m_withHelp && actualIt != args.cend() &&
|
||||
dashedHelpNames.contains(*actualIt)) {
|
||||
if (actualIt + 1 == args.cend()) {
|
||||
m_foundOptions << helpOption;
|
||||
printHelp(args, actualNode);
|
||||
actualIt++;
|
||||
} else {
|
||||
out << "Invalid arguments after the help option.";
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -24,69 +24,70 @@
|
||||
class CommandLineParser
|
||||
{
|
||||
public:
|
||||
CommandLineParser();
|
||||
CommandLineParser();
|
||||
|
||||
bool parse(const QStringList& args);
|
||||
bool parse(const QStringList& args);
|
||||
|
||||
CommandArgument rootArgument() const { return CommandArgument(); }
|
||||
CommandArgument rootArgument() const { return CommandArgument(); }
|
||||
|
||||
CommandOption addVersionOption();
|
||||
CommandOption addHelpOption();
|
||||
CommandOption addVersionOption();
|
||||
CommandOption addHelpOption();
|
||||
|
||||
bool AddArgument(const CommandArgument& arg,
|
||||
bool AddArgument(const CommandArgument& arg,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
|
||||
bool AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
|
||||
bool AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
bool AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
|
||||
bool AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
void setGeneralErrorMessage(const QString& msg);
|
||||
void setDescription(const QString& description);
|
||||
|
||||
void setGeneralErrorMessage(const QString& msg);
|
||||
void setDescription(const QString& description);
|
||||
|
||||
bool isSet(const CommandArgument& arg) const;
|
||||
bool isSet(const CommandOption& option) const;
|
||||
QString value(const CommandOption& option) const;
|
||||
bool isSet(const CommandArgument& arg) const;
|
||||
bool isSet(const CommandOption& option) const;
|
||||
QString value(const CommandOption& option) const;
|
||||
|
||||
private:
|
||||
bool m_withHelp = false;
|
||||
bool m_withVersion = false;
|
||||
QString m_description;
|
||||
QString m_generalErrorMessage;
|
||||
bool m_withHelp = false;
|
||||
bool m_withVersion = false;
|
||||
QString m_description;
|
||||
QString m_generalErrorMessage;
|
||||
|
||||
struct Node
|
||||
{
|
||||
explicit Node(const CommandArgument& arg)
|
||||
: argument(arg)
|
||||
{}
|
||||
Node() {}
|
||||
bool operator==(const Node& n) const
|
||||
struct Node
|
||||
{
|
||||
return argument == n.argument && options == n.options &&
|
||||
subNodes == n.subNodes;
|
||||
}
|
||||
CommandArgument argument;
|
||||
QList<CommandOption> options;
|
||||
QList<Node> subNodes;
|
||||
};
|
||||
explicit Node(const CommandArgument& arg)
|
||||
: argument(arg)
|
||||
{}
|
||||
Node() {}
|
||||
bool operator==(const Node& n) const
|
||||
{
|
||||
return argument == n.argument && options == n.options &&
|
||||
subNodes == n.subNodes;
|
||||
}
|
||||
CommandArgument argument;
|
||||
QList<CommandOption> options;
|
||||
QList<Node> subNodes;
|
||||
};
|
||||
|
||||
Node m_parseTree;
|
||||
QList<CommandOption> m_foundOptions;
|
||||
QList<CommandArgument> m_foundArgs;
|
||||
Node m_parseTree;
|
||||
QList<CommandOption> m_foundOptions;
|
||||
QList<CommandArgument> m_foundArgs;
|
||||
|
||||
// helper functions
|
||||
void printVersion();
|
||||
void printHelp(QStringList args, const Node* node);
|
||||
Node* findParent(const CommandArgument& parent);
|
||||
Node* recursiveParentSearch(const CommandArgument& parent, Node& node) const;
|
||||
bool processIfOptionIsHelp(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode);
|
||||
// helper functions
|
||||
void printVersion();
|
||||
void printHelp(QStringList args, const Node* node);
|
||||
Node* findParent(const CommandArgument& parent);
|
||||
Node* recursiveParentSearch(const CommandArgument& parent,
|
||||
Node& node) const;
|
||||
bool processIfOptionIsHelp(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode);
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ CommandOption::CommandOption(const QString& name,
|
||||
, m_valueName(valueName)
|
||||
, m_value(defaultValue)
|
||||
{
|
||||
m_checker = [](QString const&) { return true; };
|
||||
m_checker = [](QString const&) { return true; };
|
||||
}
|
||||
|
||||
CommandOption::CommandOption(const QStringList& names,
|
||||
@@ -38,103 +38,89 @@ CommandOption::CommandOption(const QStringList& names,
|
||||
, m_valueName(valueName)
|
||||
, m_value(defaultValue)
|
||||
{
|
||||
m_checker = [](QString const&) -> bool { return true; };
|
||||
m_checker = [](QString const&) -> bool { return true; };
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setName(const QString& name)
|
||||
void CommandOption::setName(const QString& name)
|
||||
{
|
||||
m_names = QStringList() << name;
|
||||
m_names = QStringList() << name;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setNames(const QStringList& names)
|
||||
void CommandOption::setNames(const QStringList& names)
|
||||
{
|
||||
m_names = names;
|
||||
m_names = names;
|
||||
}
|
||||
|
||||
QStringList
|
||||
CommandOption::names() const
|
||||
QStringList CommandOption::names() const
|
||||
{
|
||||
return m_names;
|
||||
return m_names;
|
||||
}
|
||||
|
||||
QStringList
|
||||
CommandOption::dashedNames() const
|
||||
QStringList CommandOption::dashedNames() const
|
||||
{
|
||||
QStringList dashedNames;
|
||||
for (const QString& name : m_names) {
|
||||
// prepend "-" to single character options, and "--" to the others
|
||||
QString dashedName = (name.length() == 1)
|
||||
? QStringLiteral("-%1").arg(name)
|
||||
: QStringLiteral("--%1").arg(name);
|
||||
dashedNames << dashedName;
|
||||
}
|
||||
return dashedNames;
|
||||
QStringList dashedNames;
|
||||
for (const QString& name : m_names) {
|
||||
// prepend "-" to single character options, and "--" to the others
|
||||
QString dashedName = (name.length() == 1)
|
||||
? QStringLiteral("-%1").arg(name)
|
||||
: QStringLiteral("--%1").arg(name);
|
||||
dashedNames << dashedName;
|
||||
}
|
||||
return dashedNames;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setValueName(const QString& name)
|
||||
void CommandOption::setValueName(const QString& name)
|
||||
{
|
||||
m_valueName = name;
|
||||
m_valueName = name;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::valueName() const
|
||||
QString CommandOption::valueName() const
|
||||
{
|
||||
return m_valueName;
|
||||
return m_valueName;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setValue(const QString& value)
|
||||
void CommandOption::setValue(const QString& value)
|
||||
{
|
||||
if (m_valueName.isEmpty()) {
|
||||
m_valueName = QLatin1String("value");
|
||||
}
|
||||
m_value = value;
|
||||
if (m_valueName.isEmpty()) {
|
||||
m_valueName = QLatin1String("value");
|
||||
}
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::value() const
|
||||
QString CommandOption::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::addChecker(const function<bool(const QString&)> checker,
|
||||
const QString& errMsg)
|
||||
void CommandOption::addChecker(const function<bool(const QString&)> checker,
|
||||
const QString& errMsg)
|
||||
{
|
||||
m_checker = checker;
|
||||
m_errorMsg = errMsg;
|
||||
m_checker = checker;
|
||||
m_errorMsg = errMsg;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandOption::checkValue(const QString& value) const
|
||||
bool CommandOption::checkValue(const QString& value) const
|
||||
{
|
||||
return m_checker(value);
|
||||
return m_checker(value);
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::description() const
|
||||
QString CommandOption::description() const
|
||||
{
|
||||
return m_description;
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setDescription(const QString& description)
|
||||
void CommandOption::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::errorMsg() const
|
||||
QString CommandOption::errorMsg() const
|
||||
{
|
||||
return m_errorMsg;
|
||||
return m_errorMsg;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandOption::operator==(const CommandOption& option) const
|
||||
bool CommandOption::operator==(const CommandOption& option) const
|
||||
{
|
||||
return m_description == option.m_description && m_names == option.m_names &&
|
||||
m_valueName == option.m_valueName;
|
||||
return m_description == option.m_description && m_names == option.m_names &&
|
||||
m_valueName == option.m_valueName;
|
||||
}
|
||||
|
||||
@@ -25,44 +25,44 @@ using std::function;
|
||||
class CommandOption
|
||||
{
|
||||
public:
|
||||
CommandOption(const QString& name,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
CommandOption(const QString& name,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
|
||||
CommandOption(const QStringList& names,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
CommandOption(const QStringList& names,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
|
||||
void setName(const QString& name);
|
||||
void setNames(const QStringList& names);
|
||||
QStringList names() const;
|
||||
QStringList dashedNames() const;
|
||||
void setName(const QString& name);
|
||||
void setNames(const QStringList& names);
|
||||
QStringList names() const;
|
||||
QStringList dashedNames() const;
|
||||
|
||||
void setValueName(const QString& name);
|
||||
QString valueName() const;
|
||||
void setValueName(const QString& name);
|
||||
QString valueName() const;
|
||||
|
||||
void setValue(const QString& value);
|
||||
QString value() const;
|
||||
void setValue(const QString& value);
|
||||
QString value() const;
|
||||
|
||||
void addChecker(const function<bool(QString const&)> checker,
|
||||
const QString& errMsg);
|
||||
bool checkValue(const QString& value) const;
|
||||
void addChecker(const function<bool(QString const&)> checker,
|
||||
const QString& errMsg);
|
||||
bool checkValue(const QString& value) const;
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
|
||||
QString errorMsg() const;
|
||||
QString errorMsg() const;
|
||||
|
||||
bool operator==(const CommandOption& option) const;
|
||||
bool operator==(const CommandOption& option) const;
|
||||
|
||||
private:
|
||||
QStringList m_names;
|
||||
QString m_description;
|
||||
QString m_valueName;
|
||||
QString m_value;
|
||||
QStringList m_names;
|
||||
QString m_description;
|
||||
QString m_valueName;
|
||||
QString m_value;
|
||||
|
||||
function<bool(QString const&)> m_checker;
|
||||
QString m_errorMsg;
|
||||
function<bool(QString const&)> m_checker;
|
||||
QString m_errorMsg;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user