diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2020-07-22 22:17:58 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-11-03 11:39:02 -0500 |
| commit | cf289d7f95f6b5730cceaa8e6e22b4b33cf050c8 (patch) | |
| tree | 1a6ca6cd2a2a95d3fbfb02635cc5cd18b9d5bf2c | |
| parent | a8b6f227302f2264eea38ce95d82ddc5aebf1100 (diff) | |
command usage lines, exe options
| -rw-r--r-- | src/commandline.cpp | 178 | ||||
| -rw-r--r-- | src/commandline.h | 27 |
2 files changed, 147 insertions, 58 deletions
diff --git a/src/commandline.cpp b/src/commandline.cpp index 819ac1c6..3f8a6b1a 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -67,6 +67,7 @@ std::optional<int> CommandLine::run(const std::wstring& line) .run(); po::store(parsed, m_vm); + po::notify(m_vm); auto opts = po::collect_unrecognized( parsed.options, po::include_positional); @@ -80,28 +81,43 @@ std::optional<int> CommandLine::run(const std::wstring& line) // remove the command name itself opts.erase(opts.begin()); - auto co = c->options(); - co.add_options() - ("help", "shows this message"); + try + { + po::wcommand_line_parser parser(opts); - po::wcommand_line_parser parser(opts); - parser.options(co); + auto co = c->allOptions(); + parser.options(co); - if (c->allow_unregistered()) { - parser.allow_unregistered(); - } + if (c->allow_unregistered()) { + parser.allow_unregistered(); + } - parsed = parser.run(); + auto pos = c->positional(); + parser.positional(pos); - po::store(parsed, m_vm); + parsed = parser.run(); - if (m_vm.count("help")) { - env::Console console; - std::cout << usage(c.get()) << "\n"; - return 0; + po::store(parsed, m_vm); + po::notify(m_vm); + + if (m_vm.count("help")) { + env::Console console; + std::cout << usage(c.get()) << "\n"; + return 0; + } + + return c->run(line, m_vm, opts); } + catch(po::error& e) + { + env::Console console; - return c->run(line, m_vm, opts); + std::cerr + << e.what() << "\n" + << usage(c.get()) << "\n"; + + return 1; + } } } } @@ -157,7 +173,7 @@ void CommandLine::createOptions() { m_visibleOptions.add_options() ("help", "show this message") - ("multiple", "allow multiple instances of MO to run; see below") + ("multiple", "allow multiple MO processes to run; see below") ("instance,i", po::value<std::string>(), "use the given instance (defaults to last used)") ("profile,p", po::value<std::string>(), "use the given profile (defaults to last used)"); @@ -184,10 +200,10 @@ std::string CommandLine::usage(const Command* c) const if (c) { oss - << " ModOrganizer.exe [options] " << c->name() << " [command-options]\n" + << " ModOrganizer.exe [global-options] " << c->usageLine() << "\n" << "\n" << "Command options:\n" - << c->options() << "\n"; + << c->visibleOptions() << "\n"; } else { oss << " ModOrganizer.exe [options] [[command] [command-options]]\n" @@ -263,18 +279,24 @@ const QStringList& CommandLine::untouched() const std::string CommandLine::more() const { return - "Multiple instances\n" - " --multiple can be used to allow multiple instances of MO to run\n" + "Multiple processes\n" + " A note on terminology: 'instance' can either mean an MO process\n" + " that's running on the system, or a set of mods and profiles managed\n" + " by MO. To avoid confusion, the term 'process' is used below for the\n" + " former.\n" + " \n" + " --multiple can be used to allow multiple MO processes to run\n" " simultaneously. This is unsupported and can create all sorts of weird\n" - " problems. To minimize the problems:\n" + " problems. To minimize these:\n" " \n" - " 1) Never have multiple MO instances opened that manage the same\n" + " 1) Never have multiple MO processes running that manage the same\n" " game instance.\n" - " 2) If an executable is launched from an instance, only this\n" - " instance may launch executables until all instances are closed.\n" + " 2) If an executable is launched from an MO process, only this\n" + " process may launch executables until all processes are \n" + " terminated.\n" " \n" - " It is recommended to close _all_ instances of MO as soon as multiple\n" - " instances become unnecessary."; + " It is recommended to close _all_ MO processes as soon as multiple\n" + " processes become unnecessary."; } @@ -288,22 +310,65 @@ std::string Command::description() const return meta().description; } +std::string Command::usageLine() const +{ + return name() + " " + getUsageLine(); +} + bool Command::allow_unregistered() const { return false; } -po::options_description Command::options() const +po::options_description Command::allOptions() const +{ + po::options_description d; + + d.add(visibleOptions()); + d.add(getInternalOptions()); + + return d; +} + +po::options_description Command::visibleOptions() const +{ + po::options_description d(getVisibleOptions()); + + d.add_options() + ("help", "shows this message"); + + return d; +} + +po::positional_options_description Command::positional() const +{ + return getPositional(); +} + +std::string Command::getUsageLine() const +{ + return "[options]"; +} + +po::options_description Command::getVisibleOptions() const +{ + // no-op + return {}; +} + +po::options_description Command::getInternalOptions() const { - return doOptions(); + // no-op + return {}; } -po::options_description Command::doOptions() const +po::positional_options_description Command::getPositional() const { // no-op return {}; } + std::string Command::usage() const { std::ostringstream oss; @@ -314,7 +379,7 @@ std::string Command::usage() const << " ModOrganizer.exe [options] [[command] [command-options]]\n" << "\n" << "Options:\n" - << options() << "\n"; + << visibleOptions() << "\n"; return oss.str(); } @@ -347,7 +412,7 @@ const std::vector<std::wstring>& Command::untouched() const } -po::options_description CrashDumpCommand::doOptions() const +po::options_description CrashDumpCommand::getVisibleOptions() const { po::options_description d; @@ -387,11 +452,6 @@ bool LaunchCommand::allow_unregistered() const return true; } -po::options_description LaunchCommand::doOptions() const -{ - return {}; -} - Command::Meta LaunchCommand::meta() const { return {"launch", "(internal, do not use)"}; @@ -463,14 +523,39 @@ LPCWSTR LaunchCommand::UntouchedCommandLineArguments( } -bool ExeCommand::allow_unregistered() const +std::string ExeCommand::getUsageLine() const { - return true; + return "[options] exe-name"; } -po::options_description ExeCommand::doOptions() const +po::options_description ExeCommand::getVisibleOptions() const { - return {}; + po::options_description d; + + d.add_options() + ("arguments,a", po::value<std::string>()->default_value(""), "override arguments") + ("cwd,c", po::value<std::string>()->default_value(""), "override working directory"); + + return d; +} + +po::options_description ExeCommand::getInternalOptions() const +{ + po::options_description d; + + d.add_options() + ("exe-name", po::value<std::string>()->required(), "executable name"); + + return d; +} + +po::positional_options_description ExeCommand::getPositional() const +{ + po::positional_options_description d; + + d.add("exe-name", 1); + + return d; } Command::Meta ExeCommand::meta() const @@ -480,16 +565,17 @@ Command::Meta ExeCommand::meta() const std::optional<int> ExeCommand::doRun() { - return {}; -} + const auto exe = vm()["exe-name"].as<std::string>(); + const auto args = vm()["arguments"].as<std::string>(); + const auto cwd = vm()["cwd"].as<std::string>(); -bool RunCommand::allow_unregistered() const -{ - return true; + + return 0; } -po::options_description RunCommand::doOptions() const + +po::options_description RunCommand::getOptions() const { return {}; } diff --git a/src/commandline.h b/src/commandline.h index f633518b..0e300327 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -17,8 +17,11 @@ public: std::string name() const; std::string description() const; + std::string usageLine() const; - po::options_description options() const; + po::options_description allOptions() const; + po::options_description visibleOptions() const; + po::positional_options_description positional() const; std::string usage() const; virtual bool allow_unregistered() const; @@ -34,7 +37,11 @@ protected: std::string name, description; }; - virtual po::options_description doOptions() const; + virtual std::string getUsageLine() const; + virtual po::options_description getVisibleOptions() const; + virtual po::options_description getInternalOptions() const; + virtual po::positional_options_description getPositional() const; + virtual Meta meta() const = 0; virtual std::optional<int> doRun() = 0; @@ -52,7 +59,7 @@ private: class CrashDumpCommand : public Command { protected: - po::options_description doOptions() const; + po::options_description getVisibleOptions() const override; Meta meta() const override; std::optional<int> doRun() override; }; @@ -76,7 +83,6 @@ public: bool allow_unregistered() const override; protected: - po::options_description doOptions() const; Meta meta() const override; std::optional<int> doRun() override; @@ -89,11 +95,11 @@ protected: class ExeCommand : public Command { -public: - bool allow_unregistered() const override; - protected: - po::options_description doOptions() const; + std::string getUsageLine() const override; + po::options_description getVisibleOptions() const override; + po::options_description getInternalOptions() const override; + po::positional_options_description getPositional() const override; Meta meta() const override; std::optional<int> doRun() override; }; @@ -101,11 +107,8 @@ protected: class RunCommand : public Command { -public: - bool allow_unregistered() const override; - protected: - po::options_description doOptions() const; + po::options_description getOptions() const; Meta meta() const override; std::optional<int> doRun() override; }; |
