diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 538fe592b8309d..9b2c88786d76e3 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1159,16 +1159,21 @@ static void SetGenerateToAddressArgs(const std::string& address, std::vector GetCommandArgs() { + std::optional command = gArgs.GetCommand(); + + // Return command args if command is present, otherwise return an empty vector + if (command.has_value()) { + return command->args; + } + return {}; // Return an empty vector +} + static int CommandLineRPC(int argc, char *argv[]) { std::string strPrint; int nRet = 0; try { - // Skip switches - while (argc > 1 && IsSwitchChar(argv[1][0])) { - argc--; - argv++; - } std::string rpcPass; if (gArgs.GetBoolArg("-stdinrpcpass", false)) { NO_STDIN_ECHO(); @@ -1184,7 +1189,7 @@ static int CommandLineRPC(int argc, char *argv[]) } gArgs.ForceSetArg("-rpcpassword", rpcPass); } - std::vector args = std::vector(&argv[1], &argv[argc]); + std::vector args = GetCommandArgs(); if (gArgs.GetBoolArg("-stdinwalletpassphrase", false)) { NO_STDIN_ECHO(); std::string walletPass; diff --git a/src/common/args.cpp b/src/common/args.cpp index f59d2b8f0fcd10..67d9ba035e3303 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -176,6 +176,43 @@ void ArgsManager::SelectConfigNetwork(const std::string& network) m_network = network; } +bool ArgsManager::ProcessOptionKey(std::string& key, std::optional& val, std::string& error) { + + // Transform --foo to -foo + if (key.length() > 1 && key[1] == '-') + key.erase(0, 1); + + // Transform -foo to foo + key.erase(0, 1); + + KeyInfo keyinfo = InterpretKey(key); + std::optional flags = GetArgFlags('-' + keyinfo.name); + + // Unknown command line options and command line options with dot characters + // (which are returned from InterpretKey with nonempty section strings)are not valid. + if (!flags || !keyinfo.section.empty()) { + error = strprintf("Invalid parameter %s", key); + return false; + } + + std::optional value = InterpretValue(keyinfo, val ? &*val : nullptr, *flags, error); + if (!value) return false; + + // Store the option + m_settings.command_line_options[keyinfo.name].push_back(*value); + // or we could update it to avoid having multiple values for an option + // but some args mgr tests would break cos we are changing current behaviour, i'd leave it as is... + //if (auto it = m_settings.command_line_options.find(keyinfo.name); it != m_settings.command_line_options.end()) { + // Key exists, update the value (overwrite the previous value) + //it->second[0] = *value; // Update the first (or only) entry + //} else { + // Key doesn't exist, add a new entry + //m_settings.command_line_options[keyinfo.name].push_back(*value); + //} + + return true; +} + bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::string& error) { LOCK(cs_args); @@ -217,32 +254,27 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin m_command.push_back(key); while (++i < argc) { // The remaining args are command args - m_command.emplace_back(argv[i]); + if (argv[i][0] == '-') { + // except it starts with dash "-" then will check if it's a valid option + key = argv[i]; + val.reset(); + is_index = key.find('='); + if (is_index != std::string::npos) { + val = key.substr(is_index + 1); + key.erase(is_index); + } + if (!ProcessOptionKey(key, val, error)) { + return false; + } + } else { + m_command.emplace_back(argv[i]); + } } break; } - - // Transform --foo to -foo - if (key.length() > 1 && key[1] == '-') - key.erase(0, 1); - - // Transform -foo to foo - key.erase(0, 1); - KeyInfo keyinfo = InterpretKey(key); - std::optional flags = GetArgFlags('-' + keyinfo.name); - - // Unknown command line options and command line options with dot - // characters (which are returned from InterpretKey with nonempty - // section strings) are not valid. - if (!flags || !keyinfo.section.empty()) { - error = strprintf("Invalid parameter %s", argv[i]); + if (!ProcessOptionKey(key, val, error)) { return false; } - - std::optional value = InterpretValue(keyinfo, val ? &*val : nullptr, *flags, error); - if (!value) return false; - - m_settings.command_line_options[keyinfo.name].push_back(*value); } // we do not allow -includeconf from command line, only -noincludeconf diff --git a/src/common/args.h b/src/common/args.h index 8d9daf5f65d869..7db644922b0f76 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -444,6 +444,8 @@ class ArgsManager const std::string& prefix, const std::string& section, const std::map>& args) const; + + bool ProcessOptionKey(std::string& key, std::optional& val, std::string& error); }; extern ArgsManager gArgs;