From 63aef9f68f9943e9b1556d2c05953519dc3cea43 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sat, 27 Jan 2018 19:58:22 +0100 Subject: Split cmd parsing from main into CommandLine class --- src/commandline.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/commandline.h | 38 +++++++++++++++++ src/main.cpp | 104 +++++++++++----------------------------------- 3 files changed, 179 insertions(+), 80 deletions(-) create mode 100644 src/commandline.cpp create mode 100644 src/commandline.h (limited to 'src') diff --git a/src/commandline.cpp b/src/commandline.cpp new file mode 100644 index 0000000..adfdf52 --- /dev/null +++ b/src/commandline.cpp @@ -0,0 +1,117 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "commandline.h" +#include "version.h" +#include +#include +#include + +void printOption(const QCommandLineOption &option) +{ + std::cout << "- " + << std::setw(20) << std::left << option.names().join(", ").toStdString() + << std::setw(40) << std::left << option.description().toStdString() + << std::setw(30) << std::left << option.defaultValues().join(", ").toStdString() + << std::endl; +} + +QString defaultUserConfigLocation() +{ + // try to locate an existing config + QString path = QStandardPaths::locate(QStandardPaths::AppConfigLocation, "smolbote.cfg"); + + // it's possible there is no config, so set the path properly + if(path.isEmpty()) + path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/smolbote.cfg"; + + return path; +} + +CommandLine::CommandLine() + : QCommandLineParser() + , helpOption(addHelpOption()) + , versionOption(addVersionOption()) + , configOption({ "c", "config" }, "Set configuration file.", "path", defaultUserConfigLocation()) + , defaultConfigOption("default-config", "Set the default configuration file.", "path", "") + , profileOption({ "p", "profile" }, "Use this profile.", "profile", "") + , socketOption("socket", "Local server socket", "name", "") + , newWindowOption("in-new-window", "Open URL in new window") +{ + setApplicationDescription("yet another no-frills browser"); + + addOption(configOption); + addOption(defaultConfigOption); + addOption(profileOption); + addOption(socketOption); + addOption(newWindowOption); + + addPositionalArgument("URL", "URL(s) to open"); +} + +void CommandLine::parseCommandLine(const QCoreApplication &app) +{ + QCommandLineParser::parse(app.arguments()); + + application = const_cast(&app); + + if(isSet(helpOption)) { + printHelp(0); + } + + if(isSet(versionOption)) { + printVersion(); + } + + // create a list of unknown QCommandLineOption's + // parser.addOptions() takes a list, so this is a QList + + for(const QString &opt : unknownOptionNames()) { + QCommandLineOption o(opt, "dummy desc", "dummy value"); + opts.append(o); + } + + // add list and reparse to set the new options + addOptions(opts); + parse(app.arguments()); +} +void CommandLine::printHelp(int exitCode) +{ + std::cout << "Usage: " << application->arguments().at(0).toStdString() << " [options] URL" << std::endl; + std::cout << application->applicationName().toStdString() << " " << SMOLBOTE_DESCRIBE << ": " + << applicationDescription().toStdString() << std::endl + << std::endl; + + std::cout << "Options: " << std::endl; + printOption(helpOption); + printOption(versionOption); + printOption(configOption); + printOption(defaultConfigOption); + printOption(profileOption); + printOption(socketOption); + printOption(newWindowOption); + std::cout << std::endl; + + std::cout << "You can also overwrite configuration options using the syntax: " << std::endl + << "--browser.setting.path=value" << std::endl + << std::endl; + + std::cout << "Arguments: " << std::endl; + std::cout << "- " + << std::setw(20) << std::left << "URL" + << std::setw(40) << std::left << "URL(s) to open" + << std::endl + << std::endl; + + exit(0); +} +void CommandLine::printVersion() +{ + std::cout << application->applicationName().toStdString() << " " << SMOLBOTE_DESCRIBE << std::endl; + exit(0); +} diff --git a/src/commandline.h b/src/commandline.h new file mode 100644 index 0000000..99aa1cb --- /dev/null +++ b/src/commandline.h @@ -0,0 +1,38 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_COMMANDLINE_H +#define SMOLBOTE_COMMANDLINE_H + +#include + +class CommandLine : public QCommandLineParser +{ +public: + CommandLine(); + + void parseCommandLine(const QCoreApplication &app); + void printHelp(int exitCode = 0); + void printVersion(); + + const QCommandLineOption helpOption; + const QCommandLineOption versionOption; + + const QCommandLineOption configOption; + const QCommandLineOption defaultConfigOption; + const QCommandLineOption profileOption; + const QCommandLineOption socketOption; + const QCommandLineOption newWindowOption; + + QList opts; + +private: + QCoreApplication *application; +}; + +#endif //SMOLBOTE_COMMANDLINE_H diff --git a/src/main.cpp b/src/main.cpp index ae40f60..51087ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,10 +7,10 @@ */ #include "browser.h" +#include "commandline.h" #include "src/mainwindow/mainwindow.h" #include "version.h" -#include -#include +#include #include // startup time measuring @@ -29,75 +29,31 @@ int main(int argc, char **argv) timer.start(); #endif - QCommandLineParser parser; - parser.setApplicationDescription("yet another no-frills browser"); - QCommandLineOption helpOption = parser.addHelpOption(); - QCommandLineOption versionOption = parser.addVersionOption(); - - // user config, ~/.config/smolbote/smolbote.cfg or empty if there is none - QCommandLineOption configOption({ "c", "config" }, "Set configuration file.", "path"); - { - // try to locate an existing config - QString path = QStandardPaths::locate(QStandardPaths::AppConfigLocation, "smolbote.cfg"); - - // it's possible there is no config, so set the path properly - if(path.isEmpty()) - path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/smolbote.cfg"; - - configOption.setDefaultValue(path); - } - parser.addOption(configOption); - - // default config, :/poi.cfg - QCommandLineOption defaultConfigOption("default-config", "Set the default configuration file.", "path"); - parser.addOption(defaultConfigOption); - - QCommandLineOption profileOption({ "p", "profile" }, "Use this profile.", "PROFILE"); - profileOption.setDefaultValue(""); - parser.addOption(profileOption); - - QCommandLineOption socketOption("socket", "Set socket to use for IPC, leave blank for default, 'none' to disable.", "name"); - socketOption.setDefaultValue(""); - parser.addOption(socketOption); - - QCommandLineOption newWindowOption("in-new-window", "Open URL in new window"); - parser.addOption(newWindowOption); - - parser.addPositionalArgument("URL", "URL(s) to open"); - - // use parse instead of process - // process calls exit() on unknown options - parser.parse(instance.arguments()); - - if(parser.isSet(helpOption)) { - parser.showHelp(0); - } - - if(parser.isSet(versionOption)) { - parser.showVersion(); - } + CommandLine parser; + parser.parseCommandLine(instance); #ifdef QT_DEBUG - qDebug("config=%s", qUtf8Printable(parser.value(configOption))); - qDebug("default-config=%s", qUtf8Printable(parser.value(defaultConfigOption))); - qDebug("socket=%s", qUtf8Printable(parser.value(socketOption))); - qDebug("profile=%s", qUtf8Printable(parser.value(profileOption))); + qDebug("config=%s", qUtf8Printable(parser.value(parser.configOption))); + qDebug("default-config=%s", qUtf8Printable(parser.value(parser.defaultConfigOption))); + qDebug("profile=%s", qUtf8Printable(parser.value(parser.profileOption))); + qDebug("socket=%s", qUtf8Printable(parser.value(parser.socketOption))); + #endif std::shared_ptr config = std::make_shared(); // first load the default configuration - if(parser.isSet(defaultConfigOption)) { + if(!parser.value(parser.defaultConfigOption).isEmpty()) { qDebug("Reading default configuration [%s]: %s", - qUtf8Printable(parser.value(defaultConfigOption)), - config->read(parser.value(defaultConfigOption)) ? "ok" : "failed"); + qUtf8Printable(parser.value(parser.defaultConfigOption)), + config->read(parser.value(parser.defaultConfigOption)) ? "ok" : "failed"); } // then load in the user configuration, which will overwrite it - if(parser.isSet(configOption)) { + if(!parser.value(parser.configOption).isEmpty()) { qDebug("Reading configuration [%s]: %s", - qUtf8Printable(parser.value(configOption)), - config->read(parser.value(configOption)) ? "ok" : "failed"); + qUtf8Printable(parser.value(parser.configOption)), + config->read(parser.value(parser.configOption)) ? "ok" : "failed"); } // parse command-line overrides @@ -106,27 +62,15 @@ int main(int argc, char **argv) // unfortunately, QCommandLineParser will only give us the unknown option // names, so we need to build a list, add them as options, reparse, and then // we get their values - if(!parser.unknownOptionNames().isEmpty()) { - int _argc = parser.unknownOptionNames().length() + 1; + if(!parser.opts.isEmpty()) { + int _argc = parser.opts.length() + 1; const char *_argv[_argc]; // program_options requires 0 to be the program name, otherwise it seems to fail _argv[0] = qUtf8Printable(instance.arguments().at(0)); - // create a list of unknown QCommandLineOption's - // parser.addOptions() takes a list, so this is a QList - QList opts; - for(const QString &opt : parser.unknownOptionNames()) { - QCommandLineOption o(opt, "dummy desc", "dummy value"); - opts.append(o); - } - - // add list and reparse to set the new options - parser.addOptions(opts); - parser.parse(instance.arguments()); - for(int i = 1; i < _argc; ++i) { - _argv[i] = qUtf8Printable(QString("--%1=%2").arg(opts[i - 1].names().at(0), parser.value(opts[i - 1]))); + _argv[i] = qUtf8Printable(QString("--%1=%2").arg(parser.opts[i - 1].names().at(0), parser.value(parser.opts[i - 1]))); } qDebug("Parsing command-line overrides: %s", config->parse(_argc, _argv) ? "ok" : "failed"); @@ -134,22 +78,22 @@ int main(int argc, char **argv) // check for other instances // if we socket hasn't been disabled (socket is not none) - if(parser.value(socketOption) != "none") { - bool bindOk = instance.bindLocalSocket(parser.value(socketOption)); + if(parser.value(parser.socketOption) != "none") { + bool bindOk = instance.bindLocalSocket(parser.value(parser.socketOption)); if(bindOk) { qDebug("Connected to local socket: %s", qUtf8Printable(instance.serverName())); } else { // pass arguments to new instance - return instance.sendMessage(parser.value(profileOption), parser.isSet(newWindowOption), parser.positionalArguments()); + return instance.sendMessage(parser.value(parser.profileOption), parser.isSet(parser.newWindowOption), parser.positionalArguments()); } } instance.setConfiguration(config); - if(parser.isSet(profileOption)) - instance.createSession(parser.value(profileOption), parser.isSet(newWindowOption), parser.positionalArguments()); + if(parser.isSet(parser.profileOption)) + instance.createSession(parser.value(parser.profileOption), parser.isSet(parser.newWindowOption), parser.positionalArguments()); else - instance.createSession(QString::fromStdString(config->value("browser.profile").value()), parser.isSet(newWindowOption), parser.positionalArguments()); + instance.createSession(QString::fromStdString(config->value("browser.profile").value()), parser.isSet(parser.newWindowOption), parser.positionalArguments()); #ifdef QT_DEBUG qDebug("Startup complete in %lldms", timer.elapsed()); -- cgit v1.2.1