Files
oak-editor/app/common/commandlineparser.cpp
T
Thomas Wilshaw 8d6bd5e929 Fix Help option in headless mode on Windows
Help option failed when Olive was run in its own directory as strrchr
failed. If all else fails basename is equal to argv[0] and we don't
increment in the print statement. Tested on Windows 7.
2020-09-02 23:35:44 +01:00

154 lines
3.8 KiB
C++

/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "commandlineparser.h"
#include <QCoreApplication>
#include <QDebug>
CommandLineParser::~CommandLineParser()
{
foreach (const KnownOption& o, options_) {
delete o.option;
}
foreach (const KnownPositionalArgument& a, positional_args_) {
delete a.option;
}
}
const CommandLineParser::Option *CommandLineParser::AddOption(const QStringList &strings, const QString &description)
{
Option* o = new Option();
options_.append({strings, description, o});
return o;
}
const CommandLineParser::PositionalArgument *CommandLineParser::AddPositionalArgument(const QString &name, const QString &description, bool required)
{
PositionalArgument* a = new PositionalArgument();
positional_args_.append({name, description, a, required});
return a;
}
void CommandLineParser::Process(int argc, char **argv)
{
int positional_index = 0;
for (int i=1; i<argc; i++) {
if (argv[i][0] == '-') {
// Must be an option
// Skip past first dashes
const char* arg_basename = &argv[i][1];
bool matched_known = false;
for (int j=0; j<options_.size(); j++) {
KnownOption& o = options_[j];
foreach (const QString& s, o.args) {
if (!s.compare(arg_basename, Qt::CaseInsensitive)) {
// Flag discovered!
o.option->Set();
matched_known = true;
goto found_flag;
}
}
}
found_flag:
if (!matched_known) {
qWarning() << "Unknown parameter:" << argv[i];
}
} else {
// Must be a positional flag
if (positional_index < positional_args_.size()) {
positional_args_[positional_index].option->SetSetting(argv[i]);
positional_index++;
} else {
qWarning() << "Unknown parameter:" << argv[i];
}
}
}
}
void CommandLineParser::PrintHelp(const char* filename)
{
printf("%s %s\n",
QCoreApplication::applicationName().toUtf8().constData(),
QCoreApplication::applicationVersion().toUtf8().constData());
printf("Copyright (C) 2018-2020 Olive Team\n");
QString positional_args;
for (int i=0; i<positional_args_.size(); i++) {
if (i > 0) {
positional_args.append(' ');
}
positional_args.append('[');
positional_args.append(positional_args_.at(i).name);
positional_args.append(']');
}
const char* basename;
bool path = true;
#ifdef Q_OS_WINDOWS
basename = strrchr(filename, '\\');
if (!basename) {
basename = strrchr(filename, '/');
}
if (!basename) {
basename = filename;
path = false;
}
#else
basename = strrchr(filename, '/');
#endif
printf("Usage: %s [options] %s\n\n", path ? basename + 1 : basename, positional_args.toUtf8().constData());
foreach (const KnownOption& o, options_) {
QString all_args;
for (int i=0; i<o.args.size(); i++) {
if (i > 0) {
all_args.append(QStringLiteral(", "));
}
const QString& this_arg = o.args.at(i);
all_args.append('-');
all_args.append(this_arg);
}
printf(" %s\n", all_args.toUtf8().constData());
printf(" %s\n\n", o.description.toUtf8().constData());
}
printf("\n");
}