diff options
| author | Mikaƫl Capelle <capelle.mikael@gmail.com> | 2023-07-09 17:36:03 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-09 17:36:03 +0200 |
| commit | ef94aee28464039672b277243a0181ae93550d6c (patch) | |
| tree | 0575a68af5f154e9d6d0738edbaefb16a11d6f5c /src/commandline.cpp | |
| parent | 7d6cb8528d20e36a4cee822263865ee2f7f32481 (diff) | |
| parent | 3de050e9c03e553f7ae3f780f6bd080a30ae123e (diff) | |
Merge pull request #1839 from Holt59/ci/initial-gh-action-for-build
Clang-Format + Github Workflow
Diffstat (limited to 'src/commandline.cpp')
| -rw-r--r-- | src/commandline.cpp | 343 |
1 files changed, 132 insertions, 211 deletions
diff --git a/src/commandline.cpp b/src/commandline.cpp index f64ff7cb..9082d710 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -1,11 +1,11 @@ #include "commandline.h" #include "env.h" -#include "organizercore.h" #include "instancemanager.h" -#include "multiprocess.h" #include "loglist.h" -#include "shared/util.h" +#include "multiprocess.h" +#include "organizercore.h" #include "shared/appconfig.h" +#include "shared/util.h" #include <log.h> #include <report.h> @@ -14,19 +14,18 @@ namespace cl using namespace MOBase; -std::string pad_right(std::string s, std::size_t n, char c=' ') +std::string pad_right(std::string s, std::size_t n, char c = ' ') { if (s.size() < n) - s.append(n - s.size() , c); + s.append(n - s.size(), c); return s; } // formats the list of pairs in two columns // -std::string table( - const std::vector<std::pair<std::string, std::string>>& v, - std::size_t indent, std::size_t spacing) +std::string table(const std::vector<std::pair<std::string, std::string>>& v, + std::size_t indent, std::size_t spacing) { std::size_t longest = 0; @@ -35,40 +34,28 @@ std::string table( std::string s; - for (auto&& p : v) - { + for (auto&& p : v) { if (!s.empty()) s += "\n"; - s += - std::string(indent, ' ') + - pad_right(p.first, longest) + " " + - std::string(spacing, ' ') + - p.second; + s += std::string(indent, ' ') + pad_right(p.first, longest) + " " + + std::string(spacing, ' ') + p.second; } return s; - } - -CommandLine::CommandLine() - : m_command(nullptr) +CommandLine::CommandLine() : m_command(nullptr) { createOptions(); - add< - RunCommand, - ReloadPluginCommand, - RefreshCommand, - CrashDumpCommand, - LaunchCommand>(); + add<RunCommand, ReloadPluginCommand, RefreshCommand, CrashDumpCommand, + LaunchCommand>(); } std::optional<int> CommandLine::process(const std::wstring& line) { - try - { + try { auto args = po::split_winmain(line); if (!args.empty()) { // remove program name @@ -79,18 +66,16 @@ std::optional<int> CommandLine::process(const std::wstring& line) // command name, but not the rest, which will be collected below auto parsed = po::wcommand_line_parser(args) - .options(m_allOptions) - .positional(m_positional) - .allow_unregistered() - .run(); + .options(m_allOptions) + .positional(m_positional) + .allow_unregistered() + .run(); po::store(parsed, m_vm); po::notify(m_vm); // collect options past the command name - auto opts = po::collect_unrecognized( - parsed.options, po::include_positional); - + auto opts = po::collect_unrecognized(parsed.options, po::include_positional); if (m_vm.count("command")) { // there's a word as the first argument; this may be a command name or @@ -106,8 +91,7 @@ std::optional<int> CommandLine::process(const std::wstring& line) // remove the command name itself opts.erase(opts.begin()); - try - { + try { // legacy commands handle their own parsing, such as 'launch'; don't // attempt to parse anything here if (!c->legacy()) { @@ -140,14 +124,10 @@ std::optional<int> CommandLine::process(const std::wstring& line) m_command = c.get(); return runEarly(); - } - catch(po::error& e) - { + } catch (po::error& e) { env::Console console; - std::cerr - << e.what() << "\n" - << usage(c.get()) << "\n"; + std::cerr << e.what() << "\n" << usage(c.get()) << "\n"; return 1; } @@ -155,7 +135,6 @@ std::optional<int> CommandLine::process(const std::wstring& line) } } - // the first word on the command line is not a valid command, try the other // stuff; this is used in setupCore() below when called from // MOApplication::doOneRun() @@ -167,7 +146,6 @@ std::optional<int> CommandLine::process(const std::wstring& line) return 0; } - if (!opts.empty()) { const auto qs = QString::fromStdWString(opts[0]); @@ -202,14 +180,10 @@ std::optional<int> CommandLine::process(const std::wstring& line) } return {}; - } - catch(po::error& e) - { + } catch (po::error& e) { env::Console console; - std::cerr - << e.what() << "\n" - << usage() << "\n"; + std::cerr << e.what() << "\n" << usage() << "\n"; return 1; } @@ -250,7 +224,7 @@ std::optional<int> CommandLine::runPostApplication(MOApplication& a) if (m_vm.count("instance") && m_vm["instance"].as<std::string>() == "") { env::Console c; - if (auto i=InstanceManager::singleton().currentInstance()) { + if (auto i = InstanceManager::singleton().currentInstance()) { std::cout << i->displayName().toStdString() << "\n"; } else { std::cout << "no instance configured\n"; @@ -283,13 +257,12 @@ std::optional<int> CommandLine::runPostOrganizer(OrganizerCore& core) // make sure MO doesn't exit even if locking is disabled, ForceWait and // PreventExit will do that core.processRunner() - .setFromShortcut(m_shortcut) - .setWaitForCompletion(ProcessRunner::ForCommandLine, UILocker::PreventExit) - .run(); + .setFromShortcut(m_shortcut) + .setWaitForCompletion(ProcessRunner::ForCommandLine, UILocker::PreventExit) + .run(); return 0; - } - catch (std::exception&) { + } catch (std::exception&) { // user was already warned return 1; } @@ -301,23 +274,19 @@ std::optional<int> CommandLine::runPostOrganizer(OrganizerCore& core) const QString exeName = *m_executable; log::debug("starting {} from command line", exeName); - try - { + try { // pass the remaining parameters to the binary // // make sure MO doesn't exit even if locking is disabled, ForceWait and // PreventExit will do that core.processRunner() - .setFromFileOrExecutable(exeName, m_untouched) - .setWaitForCompletion(ProcessRunner::ForCommandLine, UILocker::PreventExit) - .run(); + .setFromFileOrExecutable(exeName, m_untouched) + .setWaitForCompletion(ProcessRunner::ForCommandLine, UILocker::PreventExit) + .run(); return 0; - } - catch (const std::exception &e) - { - reportError( - QObject::tr("failed to start application: %1").arg(e.what())); + } catch (const std::exception& e) { + reportError(QObject::tr("failed to start application: %1").arg(e.what())); return 1; } } else if (m_command) { @@ -331,42 +300,31 @@ void CommandLine::clear() { m_vm.clear(); m_shortcut = {}; - m_nxmLink = {}; + m_nxmLink = {}; } void CommandLine::createOptions() { - m_visibleOptions.add_options() - ("help", - "show this message") - - ("multiple", - "allow multiple MO processes to run; see below") + m_visibleOptions.add_options()("help", "show this message") - ("pick", - "show the select instance dialog on startup") + ("multiple", "allow multiple MO processes to run; see below") - ("logs", - "duplicates the logs to stdout") + ("pick", "show the select instance dialog on startup") - ("instance,i", - po::value<std::string>()->implicit_value(""), - "use the given instance (defaults to last used)") + ("logs", "duplicates the logs to stdout") - ("profile,p", - po::value<std::string>(), - "use the given profile (defaults to last used)"); + ("instance,i", po::value<std::string>()->implicit_value(""), + "use the given instance (defaults to last used)") + ("profile,p", po::value<std::string>(), + "use the given profile (defaults to last used)"); po::options_description options; - options.add_options() - ("command", po::value<std::string>(), "command") - ("subargs", po::value<std::vector<std::string> >(), "args"); + options.add_options()("command", po::value<std::string>(), "command")( + "subargs", po::value<std::vector<std::string>>(), "args"); // one command name, followed by any arguments for that command - m_positional - .add("command", 1) - .add("subargs", -1); + m_positional.add("command", 1).add("subargs", -1); m_allOptions.add(m_visibleOptions); m_allOptions.add(options); @@ -376,27 +334,22 @@ std::string CommandLine::usage(const Command* c) const { std::ostringstream oss; - oss - << "\n" - << "Usage:\n"; + oss << "\n" + << "Usage:\n"; if (c) { - oss - << " ModOrganizer.exe [global-options] " << c->usageLine() << "\n\n"; + oss << " ModOrganizer.exe [global-options] " << c->usageLine() << "\n\n"; const std::string more = c->moreInfo(); if (!more.empty()) { oss << more << "\n\n"; } - oss - << "Command options:\n" - << c->visibleOptions() << "\n"; + oss << "Command options:\n" << c->visibleOptions() << "\n"; } else { - oss - << " ModOrganizer.exe [options] [[command] [command-options]]\n" - << "\n" - << "Commands:\n"; + oss << " ModOrganizer.exe [options] [[command] [command-options]]\n" + << "\n" + << "Commands:\n"; // name and description for all commands std::vector<std::pair<std::string, std::string>> v; @@ -409,14 +362,11 @@ std::string CommandLine::usage(const Command* c) const v.push_back({c->name(), c->description()}); } - oss - << table(v, 2, 4) << "\n" - << "\n"; + oss << table(v, 2, 4) << "\n" + << "\n"; } - oss - << "Global options:\n" - << m_visibleOptions << "\n"; + oss << "Global options:\n" << m_visibleOptions << "\n"; // show the more text unless this is usage for a specific command if (!c) { @@ -480,32 +430,29 @@ const QStringList& CommandLine::untouched() const std::string CommandLine::more() const { - return - "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 these:\n" - " \n" - " 1) Never have multiple MO processes running that manage the same\n" - " game instance.\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_ MO processes as soon as multiple\n" - " processes become unnecessary."; + return "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 these:\n" + " \n" + " 1) Never have multiple MO processes running that manage the same\n" + " game instance.\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_ MO processes as soon as multiple\n" + " processes become unnecessary."; } - Command::Meta::Meta(std::string n, std::string d, std::string u, std::string m) - : name(n), description(d), usage(u), more(m) -{ -} + : name(n), description(d), usage(u), more(m) +{} std::string Command::name() const { @@ -541,8 +488,7 @@ po::options_description Command::visibleOptions() const { po::options_description d(getVisibleOptions()); - d.add_options() - ("help", "shows this message"); + d.add_options()("help", "shows this message"); return d; } @@ -575,13 +521,11 @@ po::positional_options_description Command::getPositional() const return {}; } -void Command::set( - const std::wstring& originalLine, - po::variables_map vm, - std::vector<std::wstring> untouched) +void Command::set(const std::wstring& originalLine, po::variables_map vm, + std::vector<std::wstring> untouched) { - m_original = originalLine; - m_vm = vm; + m_original = originalLine; + m_vm = vm; m_untouched = untouched; } @@ -625,25 +569,20 @@ const std::vector<std::wstring>& Command::untouched() const return m_untouched; } - po::options_description CrashDumpCommand::getVisibleOptions() const { po::options_description d; - d.add_options() - ("type", po::value<std::string>()->default_value("mini"), "mini|data|full"); + d.add_options()("type", po::value<std::string>()->default_value("mini"), + "mini|data|full"); return d; } Command::Meta CrashDumpCommand::meta() const { - return { - "crashdump", - "writes a crashdump for a running process of MO", - "[options]", - "" - }; + return {"crashdump", "writes a crashdump for a running process of MO", "[options]", + ""}; } std::optional<int> CrashDumpCommand::runEarly() @@ -651,7 +590,7 @@ std::optional<int> CrashDumpCommand::runEarly() env::Console console; const auto typeString = vm()["type"].as<std::string>(); - const auto type = env::coreDumpTypeFromString(typeString); + const auto type = env::coreDumpTypeFromString(typeString); // dump const auto b = env::coredumpOther(type); @@ -665,7 +604,6 @@ std::optional<int> CrashDumpCommand::runEarly() return (b ? 0 : 1); } - Command::Meta LaunchCommand::meta() const { return {"launch", "(internal, do not use)", "", ""}; @@ -691,14 +629,15 @@ std::optional<int> LaunchCommand::runEarly() int LaunchCommand::SpawnWaitProcess(LPCWSTR workingDirectory, LPCWSTR commandLine) { - PROCESS_INFORMATION pi{ 0 }; - STARTUPINFO si{ 0 }; - si.cb = sizeof(si); + PROCESS_INFORMATION pi{0}; + STARTUPINFO si{0}; + si.cb = sizeof(si); std::wstring commandLineCopy = commandLine; - if (!CreateProcessW(NULL, &commandLineCopy[0], NULL, NULL, FALSE, 0, NULL, workingDirectory, &si, &pi)) { - // A bit of a problem where to log the error message here, at least this way you can get the message - // using a either DebugView or a live debugger: + if (!CreateProcessW(NULL, &commandLineCopy[0], NULL, NULL, FALSE, 0, NULL, + workingDirectory, &si, &pi)) { + // A bit of a problem where to log the error message here, at least this way you can + // get the message using a either DebugView or a live debugger: std::wostringstream ost; ost << L"CreateProcess failed: " << commandLine << ", " << GetLastError(); OutputDebugStringW(ost.str().c_str()); @@ -714,15 +653,15 @@ int LaunchCommand::SpawnWaitProcess(LPCWSTR workingDirectory, LPCWSTR commandLin return static_cast<int>(exitCode); } -// Parses the first parseArgCount arguments of the current process command line and returns -// them in parsedArgs, the rest of the command line is returned untouched. -LPCWSTR LaunchCommand::UntouchedCommandLineArguments( - int parseArgCount, std::vector<std::wstring>& parsedArgs) +// Parses the first parseArgCount arguments of the current process command line and +// returns them in parsedArgs, the rest of the command line is returned untouched. +LPCWSTR +LaunchCommand::UntouchedCommandLineArguments(int parseArgCount, + std::vector<std::wstring>& parsedArgs) { LPCWSTR cmd = GetCommandLineW(); - LPCWSTR arg = nullptr; // to skip executable name - for (; parseArgCount >= 0 && *cmd; ++cmd) - { + LPCWSTR arg = nullptr; // to skip executable name + for (; parseArgCount >= 0 && *cmd; ++cmd) { if (*cmd == '"') { int escaped = 0; for (++cmd; *cmd && (*cmd != '"' || escaped % 2 != 0); ++cmd) @@ -730,8 +669,8 @@ LPCWSTR LaunchCommand::UntouchedCommandLineArguments( } if (*cmd == ' ') { if (arg) - if (cmd-1 > arg && *arg == '"' && *(cmd-1) == '"') - parsedArgs.push_back(std::wstring(arg+1, cmd-1)); + if (cmd - 1 > arg && *arg == '"' && *(cmd - 1) == '"') + parsedArgs.push_back(std::wstring(arg + 1, cmd - 1)); else parsedArgs.push_back(std::wstring(arg, cmd)); arg = cmd + 1; @@ -741,29 +680,25 @@ LPCWSTR LaunchCommand::UntouchedCommandLineArguments( return cmd; } - Command::Meta RunCommand::meta() const { - return { - "run", - "runs a program, file or a configured executable", - "[options] NAME", + return {"run", "runs a program, file or a configured executable", "[options] NAME", - "Runs a program or a file with the virtual filesystem. If NAME is a path\n" - "to a non-executable file, the program that is associated with the file\n" - "extension is run instead. With -e, NAME must refer to the name of an\n" - "executable in the instance (for example, \"SKSE\")." - }; + "Runs a program or a file with the virtual filesystem. If NAME is a path\n" + "to a non-executable file, the program that is associated with the file\n" + "extension is run instead. With -e, NAME must refer to the name of an\n" + "executable in the instance (for example, \"SKSE\")."}; } po::options_description RunCommand::getVisibleOptions() const { po::options_description d; - d.add_options() - ("executable,e", po::value<bool>()->default_value(false)->zero_tokens(), "the name is a configured executable name") - ("arguments,a", po::value<std::string>(), "override arguments") - ("cwd,c", po::value<std::string>(), "override working directory"); + d.add_options()("executable,e", + po::value<bool>()->default_value(false)->zero_tokens(), + "the name is a configured executable name")( + "arguments,a", po::value<std::string>(), "override arguments")( + "cwd,c", po::value<std::string>(), "override working directory"); return d; } @@ -772,8 +707,8 @@ po::options_description RunCommand::getInternalOptions() const { po::options_description d; - d.add_options() - ("NAME", po::value<std::string>()->required(), "program or executable name"); + d.add_options()("NAME", po::value<std::string>()->required(), + "program or executable name"); return d; } @@ -796,8 +731,7 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core) { const auto program = QString::fromStdString(vm()["NAME"].as<std::string>()); - try - { + try { // make sure MO doesn't exit even if locking is disabled, ForceWait and // PreventExit will do that auto p = core.processRunner(); @@ -814,9 +748,9 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core) if (itor == exes.end()) { // not found reportError( - QObject::tr("Executable '%1' not found in instance '%2'.") - .arg(program) - .arg(InstanceManager::singleton().currentInstance()->displayName())); + QObject::tr("Executable '%1' not found in instance '%2'.") + .arg(program) + .arg(InstanceManager::singleton().currentInstance()->displayName())); return 1; } @@ -840,40 +774,33 @@ std::optional<int> RunCommand::runPostOrganizer(OrganizerCore& core) const auto r = p.run(); if (r == ProcessRunner::Error) { reportError( - QObject::tr("Failed to run '%1'. The logs might have more information.").arg(program)); + QObject::tr("Failed to run '%1'. The logs might have more information.") + .arg(program)); return 1; } return 0; - } - catch (const std::exception &e) { + } catch (const std::exception& e) { reportError( - QObject::tr("Failed to run '%1'. The logs might have more information. %2") - .arg(program).arg(e.what())); + QObject::tr("Failed to run '%1'. The logs might have more information. %2") + .arg(program) + .arg(e.what())); return 1; } } - - Command::Meta ReloadPluginCommand::meta() const { - return { - "reload-plugin", - "reloads the given plugin", - "PLUGIN", - "" - }; + return {"reload-plugin", "reloads the given plugin", "PLUGIN", ""}; } po::options_description ReloadPluginCommand::getInternalOptions() const { po::options_description d; - d.add_options() - ("PLUGIN", po::value<std::string>()->required(), "plugin name"); + d.add_options()("PLUGIN", po::value<std::string>()->required(), "plugin name"); return d; } @@ -896,10 +823,9 @@ std::optional<int> ReloadPluginCommand::runPostOrganizer(OrganizerCore& core) { const QString name = QString::fromStdString(vm()["PLUGIN"].as<std::string>()); - QString filepath = QDir( - qApp->applicationDirPath() + "/" + - ToQString(AppConfig::pluginPath())) - .absoluteFilePath(name); + QString filepath = + QDir(qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath())) + .absoluteFilePath(name); log::debug("reloading plugin from {}", filepath); core.pluginContainer().reloadPlugin(filepath); @@ -907,14 +833,9 @@ std::optional<int> ReloadPluginCommand::runPostOrganizer(OrganizerCore& core) return {}; } - Command::Meta RefreshCommand::meta() const { - return { - "refresh", - "refreshes MO (same as F5)", - "", "" - }; + return {"refresh", "refreshes MO (same as F5)", "", ""}; } bool RefreshCommand::canForwardToPrimary() const @@ -928,4 +849,4 @@ std::optional<int> RefreshCommand::runPostOrganizer(OrganizerCore& core) return {}; } -} // namespace +} // namespace cl |
