aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/cmd.hpp89
-rw-r--r--src/cmd/meson.build2
-rw-r--r--src/cmd/test.cpp41
3 files changed, 132 insertions, 0 deletions
diff --git a/src/cmd/cmd.hpp b/src/cmd/cmd.hpp
new file mode 100644
index 0000000..37bb3ce
--- /dev/null
+++ b/src/cmd/cmd.hpp
@@ -0,0 +1,89 @@
+/*
+ * 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/cgit/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#ifndef SMOLBOTE_CMD_HPP
+#define SMOLBOTE_CMD_HPP
+
+#include "version.h"
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <functional>
+#include <iostream>
+
+namespace command_line
+{
+template <typename T>
+using subcommand_fn = std::function<int(const QStringList &, T &)>;
+template <typename T>
+using map = std::unordered_map<std::string, subcommand_fn<T>>;
+
+// a helper function to join the keys of a command_map into a string
+template <typename T>
+[[nodiscard]] inline QString join_keys(const map<T> &map, const QString sep = ", ")
+{
+ QString k;
+ for(auto it = map.cbegin(); it != map.cend(); ++it) {
+ k += QString::fromStdString(it->first);
+ if(std::next(it) != map.cend()) {
+ k += sep;
+ }
+ }
+ return k;
+}
+
+template <typename T>
+[[nodiscard]] std::function<int(T &)> process(T &app, const map<T> &map, const std::string &d)
+{
+ const QCommandLineOption build({ "b", "build" }, "Display build information.");
+ const QCommandLineOption config({ "c", "config" }, "Set the configuration file.", "file");
+ const QCommandLineOption noRemote("no-remote", "Do not accept or send remote commands.");
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription("smolbote: yet another no-frills browser");
+ parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
+ parser.addHelpOption();
+ parser.addVersionOption();
+
+ parser.addOption(build);
+ parser.addOption(config);
+ parser.addOption(noRemote);
+
+ parser.addPositionalArgument("subcommand", QString("%1; default: %2").arg(join_keys(map), QString::fromStdString(d)));
+ parser.addPositionalArgument("urls", "List of URLs to open.");
+
+ parser.process(app);
+
+ if(parser.isSet(build)) {
+ std::cout << app.applicationName().toStdString() << " " << poi_Version << std::endl;
+ exit(0);
+ }
+
+ if constexpr(requires { app.loadConfiguration(parser.value(config)); }) {
+ app.loadConfiguration(parser.value(config));
+ } else {
+ qDebug("warning: cannot init configuration");
+ }
+
+ if constexpr(requires { app.enableRemote(true); }) {
+ app.enableRemote(!parser.isSet(noRemote));
+ }
+
+ const auto args = parser.positionalArguments();
+
+ if(args.count() >= 1) {
+ auto i = map.find(args.first().toStdString());
+ if(i != map.end())
+ return std::bind(i->second, args, std::placeholders::_1);
+ }
+
+ return std::bind(map.at(d), args, std::placeholders::_1);
+}
+
+} // namespace
+
+#endif
diff --git a/src/cmd/meson.build b/src/cmd/meson.build
new file mode 100644
index 0000000..466647f
--- /dev/null
+++ b/src/cmd/meson.build
@@ -0,0 +1,2 @@
+test('command line parser', executable('cmd_test', ['test.cpp', version_h], dependencies: [ dep_qt5 ]))
+
diff --git a/src/cmd/test.cpp b/src/cmd/test.cpp
new file mode 100644
index 0000000..fc102ff
--- /dev/null
+++ b/src/cmd/test.cpp
@@ -0,0 +1,41 @@
+#include "cmd.hpp"
+#include <QCoreApplication>
+
+int sub_bookmarks(const QStringList &l, QCoreApplication &)
+{
+ const QCommandLineOption q("q", "something");
+ QCommandLineParser parser;
+ parser.setApplicationDescription("testing bookmarks editor");
+ parser.addHelpOption();
+ parser.addOption(q);
+
+ if(l.count() <= 1) {
+ parser.showHelp();
+ }
+ parser.process(l);
+ return 0;
+}
+
+int sub_list(const QStringList &args, QCoreApplication &)
+{
+ for(const auto &x : args) {
+ qDebug("-%s", qUtf8Printable(x));
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ app.setApplicationName("cmd_test");
+ app.setApplicationVersion("0.1.0");
+
+ const command_line::map<QCoreApplication> m{
+ { "bookmarks", &sub_bookmarks },
+ { "list", &sub_list }
+ };
+
+ const auto f = command_line::process<QCoreApplication>(app, m, "list");
+ return f(app);
+}
+