diff --git a/src/util.h b/src/util.h --- a/src/util.h +++ b/src/util.h @@ -120,21 +120,33 @@ RPC, GUI, COMMANDS, - REGISTER_COMMANDS + REGISTER_COMMANDS, + + // Always the last option to avoid printing these in the help + HIDDEN, }; class ArgsManager { protected: friend class ArgsManagerHelper; + struct Arg { + std::string m_help_param; + std::string m_help_text; + bool m_debug_only; + + Arg(const std::string &help_param, const std::string &help_text, + bool debug_only) + : m_help_param(help_param), m_help_text(help_text), + m_debug_only(debug_only){}; + }; + mutable CCriticalSection cs_args; std::map> m_override_args; std::map> m_config_args; std::string m_network; std::set m_network_only_args; - std::map, - std::pair> - m_available_args; + std::map> m_available_args; void ReadConfigStream(std::istream &stream); diff --git a/src/util.cpp b/src/util.cpp --- a/src/util.cpp +++ b/src/util.cpp @@ -624,10 +624,18 @@ void ArgsManager::AddArg(const std::string &name, const std::string &help, const bool debug_only, const OptionsCategory &cat) { - std::pair key(cat, name); - assert(m_available_args.count(key) == 0); - m_available_args.emplace(key, - std::pair(help, debug_only)); + // Split arg name from its help param + size_t eq_index = name.find('='); + if (eq_index == std::string::npos) { + eq_index = name.size(); + } + + std::map &arg_map = m_available_args[cat]; + auto ret = arg_map.emplace( + name.substr(0, eq_index), + Arg(name.substr(eq_index, name.size() - eq_index), help, debug_only)); + // Make sure an insertion actually happened. + assert(ret.second); } void ArgsManager::ClearArg(const std::string &strArg) { @@ -639,42 +647,70 @@ std::string ArgsManager::GetHelpMessage() { const bool show_debug = gArgs.GetBoolArg("-help-debug", false); - std::string usage = HelpMessageGroup(_("Options:")); - - OptionsCategory last_cat = OptionsCategory::OPTIONS; - for (auto &arg : m_available_args) { - if (arg.first.first != last_cat) { - last_cat = arg.first.first; - if (last_cat == OptionsCategory::CONNECTION) { - usage += HelpMessageGroup(_("Connection options:")); - } else if (last_cat == OptionsCategory::ZMQ) { - usage += HelpMessageGroup(_("ZeroMQ notification options:")); - } else if (last_cat == OptionsCategory::DEBUG_TEST) { - usage += HelpMessageGroup(_("Debugging/Testing options:")); - } else if (last_cat == OptionsCategory::NODE_RELAY) { - usage += HelpMessageGroup(_("Node relay options:")); - } else if (last_cat == OptionsCategory::BLOCK_CREATION) { - usage += HelpMessageGroup(_("Block creation options:")); - } else if (last_cat == OptionsCategory::RPC) { - usage += HelpMessageGroup(_("RPC server options:")); - } else if (last_cat == OptionsCategory::WALLET) { - usage += HelpMessageGroup(_("Wallet options:")); - } else if (last_cat == OptionsCategory::WALLET_DEBUG_TEST && - show_debug) { - usage += - HelpMessageGroup(_("Wallet debugging/testing options:")); - } else if (last_cat == OptionsCategory::CHAINPARAMS) { - usage += HelpMessageGroup(_("Chain selection options:")); - } else if (last_cat == OptionsCategory::GUI) { - usage += HelpMessageGroup(_("UI Options:")); - } else if (last_cat == OptionsCategory::COMMANDS) { - usage += HelpMessageGroup(_("Commands:")); - } else if (last_cat == OptionsCategory::REGISTER_COMMANDS) { - usage += HelpMessageGroup(_("Register Commands:")); - } + std::string usage = ""; + for (const auto &arg_map : m_available_args) { + switch (arg_map.first) { + case OptionsCategory::OPTIONS: + usage += HelpMessageGroup("Options:"); + break; + case OptionsCategory::CONNECTION: + usage += HelpMessageGroup("Connection options:"); + break; + case OptionsCategory::ZMQ: + usage += HelpMessageGroup("ZeroMQ notification options:"); + break; + case OptionsCategory::DEBUG_TEST: + usage += HelpMessageGroup("Debugging/Testing options:"); + break; + case OptionsCategory::NODE_RELAY: + usage += HelpMessageGroup("Node relay options:"); + break; + case OptionsCategory::BLOCK_CREATION: + usage += HelpMessageGroup("Block creation options:"); + break; + case OptionsCategory::RPC: + usage += HelpMessageGroup("RPC server options:"); + break; + case OptionsCategory::WALLET: + usage += HelpMessageGroup("Wallet options:"); + break; + case OptionsCategory::WALLET_DEBUG_TEST: + if (show_debug) { + usage += + HelpMessageGroup("Wallet debugging/testing options:"); + } + break; + case OptionsCategory::CHAINPARAMS: + usage += HelpMessageGroup("Chain selection options:"); + break; + case OptionsCategory::GUI: + usage += HelpMessageGroup("UI Options:"); + break; + case OptionsCategory::COMMANDS: + usage += HelpMessageGroup("Commands:"); + break; + case OptionsCategory::REGISTER_COMMANDS: + usage += HelpMessageGroup("Register Commands:"); + break; + default: + break; + } + + // When we get to the hidden options, stop + if (arg_map.first == OptionsCategory::HIDDEN) { + break; } - if (show_debug || !arg.second.second) { - usage += HelpMessageOpt(arg.first.second, arg.second.first); + + for (const auto &arg : arg_map.second) { + if (show_debug || !arg.second.m_debug_only) { + std::string name; + if (arg.second.m_help_param.empty()) { + name = arg.first; + } else { + name = arg.first + arg.second.m_help_param; + } + usage += HelpMessageOpt(name, arg.second.m_help_text); + } } } return usage;