diff --git a/src/httprpc.cpp b/src/httprpc.cpp --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -86,9 +86,9 @@ std::string strUser = strUserPass.substr(0, strUserPass.find(":")); std::string strPass = strUserPass.substr(strUserPass.find(":") + 1); - if (mapMultiArgs.count("-rpcauth") > 0) { + if (gArgs.IsArgSet("-rpcauth")) { // Search for multi-user login/pass "rpcauth" from config - for (const std::string &strRPCAuth : mapMultiArgs.at("-rpcauth")) { + for (const std::string &strRPCAuth : gArgs.GetArgs("-rpcauth")) { std::vector vFields; boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); if (vFields.size() != 3) { diff --git a/src/httpserver.cpp b/src/httpserver.cpp --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -180,9 +180,8 @@ rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv6 localhost. rpc_allow_subnets.push_back(CSubNet(localv6)); - if (mapMultiArgs.count("-rpcallowip")) { - const std::vector &vAllow = mapMultiArgs.at("-rpcallowip"); - for (std::string strAllow : vAllow) { + if (gArgs.IsArgSet("-rpcallowip")) { + for (const std::string &strAllow : gArgs.GetArgs("-rpcallowip")) { CSubNet subnet; LookupSubNet(strAllow.c_str(), subnet); if (!subnet.IsValid()) { @@ -315,14 +314,12 @@ "-rpcallowip was not specified, refusing to allow " "everyone to connect\n"); } - } else if (mapMultiArgs.count("-rpcbind")) { + } else if (gArgs.IsArgSet("-rpcbind")) { // Specific bind address. - const std::vector &vbind = mapMultiArgs.at("-rpcbind"); - for (std::vector::const_iterator i = vbind.begin(); - i != vbind.end(); ++i) { + for (const std::string &strRPCBind : gArgs.GetArgs("-rpcbind")) { int port = defaultPort; std::string host; - SplitHostPort(*i, port, host); + SplitHostPort(strRPCBind, port, host); endpoints.push_back(std::make_pair(host, port)); } } else { diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -1094,8 +1094,7 @@ __func__); } - if (mapMultiArgs.count("-connect") && - mapMultiArgs.at("-connect").size() > 0) { + if (gArgs.IsArgSet("-connect")) { // when only connecting to trusted nodes, do not seed via DNS, or listen // by default. if (SoftSetBoolArg("-dnsseed", false)) @@ -1290,10 +1289,9 @@ // Make sure enough file descriptors are available int nBind = std::max( - (mapMultiArgs.count("-bind") ? mapMultiArgs.at("-bind").size() : 0) + - (mapMultiArgs.count("-whitebind") - ? mapMultiArgs.at("-whitebind").size() - : 0), + (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) + + (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() + : 0), size_t(1)); nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); @@ -1313,22 +1311,21 @@ std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections); - if (nMaxConnections < nUserMaxConnections) + if (nMaxConnections < nUserMaxConnections) { InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, " "because of system limitations."), nUserMaxConnections, nMaxConnections)); + } // Step 3: parameter-to-internal-flags - - if (mapMultiArgs.count("-debug")) { + if (gArgs.IsArgSet("-debug")) { // Special-case: if -debug=0/-nodebug is set, turn off debugging // messages - const std::vector &categories = mapMultiArgs.at("-debug"); - if (!(GetBoolArg("-nodebug", false) || - find(categories.begin(), categories.end(), std::string("0")) != - categories.end())) { + const std::vector &categories = gArgs.GetArgs("-debug"); + if (find(categories.begin(), categories.end(), std::string("0")) == + categories.end()) { for (const auto &cat : categories) { - uint32_t flag; + uint32_t flag = 0; if (!GetLogCategory(&flag, &cat)) { InitWarning(strprintf( _("Unsupported logging category %s.\n"), cat)); @@ -1537,17 +1534,16 @@ nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); - if (mapMultiArgs.count("-bip9params")) { + if (gArgs.IsArgSet("-bip9params")) { // Allow overriding BIP9 parameters for testing if (!chainparams.MineBlocksOnDemand()) { return InitError( "BIP9 parameters may only be overridden on regtest."); } - const std::vector &deployments = - mapMultiArgs.at("-bip9params"); - for (auto i : deployments) { + for (const std::string &strDeployment : gArgs.GetArgs("-bip9params")) { std::vector vDeploymentParams; - boost::split(vDeploymentParams, i, boost::is_any_of(":")); + boost::split(vDeploymentParams, strDeployment, + boost::is_any_of(":")); if (vDeploymentParams.size() != 3) { return InitError("BIP9 parameters malformed, expecting " "deployment:start:end"); @@ -1730,9 +1726,9 @@ RegisterValidationInterface(peerLogic.get()); RegisterNodeSignals(GetNodeSignals()); - if (mapMultiArgs.count("-onlynet")) { + if (gArgs.IsArgSet("-onlynet")) { std::set nets; - for (const std::string &snet : mapMultiArgs.at("-onlynet")) { + for (const std::string &snet : gArgs.GetArgs("-onlynet")) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf( @@ -1745,8 +1741,8 @@ } } - if (mapMultiArgs.count("-whitelist")) { - for (const std::string &net : mapMultiArgs.at("-whitelist")) { + if (gArgs.IsArgSet("-whitelist")) { + for (const std::string &net : gArgs.GetArgs("-whitelist")) { CSubNet subnet; LookupSubNet(net.c_str(), subnet); if (!subnet.IsValid()) @@ -1807,8 +1803,8 @@ if (fListen) { bool fBound = false; - if (mapMultiArgs.count("-bind")) { - for (const std::string &strBind : mapMultiArgs.at("-bind")) { + if (gArgs.IsArgSet("-bind")) { + for (const std::string &strBind : gArgs.GetArgs("-bind")) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) { @@ -1818,8 +1814,8 @@ Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } } - if (mapMultiArgs.count("-whitebind")) { - for (const std::string &strBind : mapMultiArgs.at("-whitebind")) { + if (gArgs.IsArgSet("-whitebind")) { + for (const std::string &strBind : gArgs.GetArgs("-whitebind")) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, 0, false)) { return InitError(ResolveErrMsg("whitebind", strBind)); @@ -1833,7 +1829,7 @@ (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); } } - if (!mapMultiArgs.count("-bind") && !mapMultiArgs.count("-whitebind")) { + if (!gArgs.IsArgSet("-bind") && !gArgs.IsArgSet("-whitebind")) { struct in_addr inaddr_any; inaddr_any.s_addr = INADDR_ANY; fBound |= @@ -1847,8 +1843,8 @@ } } - if (mapMultiArgs.count("-externalip")) { - for (const std::string &strAddr : mapMultiArgs.at("-externalip")) { + if (gArgs.IsArgSet("-externalip")) { + for (const std::string &strAddr : gArgs.GetArgs("-externalip")) { CService addrLocal; if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && @@ -1860,8 +1856,8 @@ } } - if (mapMultiArgs.count("-seednode")) { - for (const std::string &strDest : mapMultiArgs.at("-seednode")) { + if (gArgs.IsArgSet("-seednode")) { + for (const std::string &strDest : gArgs.GetArgs("-seednode")) { connman.AddOneShot(strDest); } } @@ -2127,12 +2123,13 @@ fHaveGenesis = true; } - if (IsArgSet("-blocknotify")) + if (IsArgSet("-blocknotify")) { uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); + } std::vector vImportFiles; - if (mapMultiArgs.count("-loadblock")) { - for (const std::string &strFile : mapMultiArgs.at("-loadblock")) { + if (gArgs.IsArgSet("-loadblock")) { + for (const std::string &strFile : gArgs.GetArgs("-loadblock")) { vImportFiles.push_back(strFile); } } diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -1749,11 +1749,10 @@ void CConnman::ThreadOpenConnections() { // Connect to specific addresses - if (mapMultiArgs.count("-connect") && - mapMultiArgs.at("-connect").size() > 0) { + if (gArgs.IsArgSet("-connect") && gArgs.GetArgs("-connect").size() > 0) { for (int64_t nLoop = 0;; nLoop++) { ProcessOneShot(); - for (const std::string &strAddr : mapMultiArgs.at("-connect")) { + for (const std::string &strAddr : gArgs.GetArgs("-connect")) { CAddress addr(CService(), NODE_NONE); OpenNetworkConnection(addr, false, nullptr, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { @@ -1988,8 +1987,8 @@ void CConnman::ThreadOpenAddedConnections() { { LOCK(cs_vAddedNodes); - if (mapMultiArgs.count("-addnode")) { - vAddedNodes = mapMultiArgs.at("-addnode"); + if (gArgs.IsArgSet("-addnode")) { + vAddedNodes = gArgs.GetArgs("-addnode"); } } @@ -2454,9 +2453,8 @@ &CConnman::ThreadOpenAddedConnections, this))); // Initiate outbound connections unless connect=0 - if (!mapMultiArgs.count("-connect") || - mapMultiArgs.at("-connect").size() != 1 || - mapMultiArgs.at("-connect")[0] != "0") { + if (!gArgs.IsArgSet("-connect") || gArgs.GetArgs("-connect").size() != 1 || + gArgs.GetArgs("-connect")[0] != "0") { threadOpenConnections = std::thread(&TraceThread>, "opencon", std::function( @@ -3027,8 +3025,8 @@ uacomments.push_back("EB" + eb); // sanitize comments per BIP-0014, format user agent and check total size - if (mapMultiArgs.count("-uacomment")) { - for (const std::string &cmt : mapMultiArgs.at("-uacomment")) { + if (gArgs.IsArgSet("-uacomment")) { + for (const std::string &cmt : gArgs.GetArgs("-uacomment")) { if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) { LogPrintf( "User Agent comment (%s) contains unsafe characters. " diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -16,8 +16,6 @@ #include -extern std::map mapArgs; - BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_criticalsection) { @@ -102,52 +100,69 @@ "Fri, 30 Sep 2011 23:36:17 +0000"); } +class TestArgsManager : public ArgsManager { +public: + std::map &GetMapArgs() { return mapArgs; }; + const std::map> &GetMapMultiArgs() { + return mapMultiArgs; + }; +}; + BOOST_AUTO_TEST_CASE(util_ParseParameters) { + TestArgsManager testArgs; const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"}; - ParseParameters(0, (char **)argv_test); - BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + testArgs.ParseParameters(0, (char **)argv_test); + BOOST_CHECK(testArgs.GetMapArgs().empty() && + testArgs.GetMapMultiArgs().empty()); - ParseParameters(1, (char **)argv_test); - BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + testArgs.ParseParameters(1, (char **)argv_test); + BOOST_CHECK(testArgs.GetMapArgs().empty() && + testArgs.GetMapMultiArgs().empty()); - ParseParameters(5, (char **)argv_test); + testArgs.ParseParameters(5, (char **)argv_test); // expectation: -ignored is ignored (program name argument), // -a, -b and -ccc end up in map, -d ignored because it is after // a non-option argument (non-GNU option parsing) - BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); - BOOST_CHECK(IsArgSet("-a") && IsArgSet("-b") && IsArgSet("-ccc") && - !IsArgSet("f") && !IsArgSet("-d")); - BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && - mapMultiArgs.count("-ccc") && !mapMultiArgs.count("f") && - !mapMultiArgs.count("-d")); - - BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); - BOOST_CHECK(mapMultiArgs.at("-ccc").size() == 2); + BOOST_CHECK(testArgs.GetMapArgs().size() == 3 && + testArgs.GetMapMultiArgs().size() == 3); + BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && + testArgs.IsArgSet("-ccc") && !testArgs.IsArgSet("f") && + !testArgs.IsArgSet("-d")); + BOOST_CHECK(testArgs.GetMapMultiArgs().count("-a") && + testArgs.GetMapMultiArgs().count("-b") && + testArgs.GetMapMultiArgs().count("-ccc") && + !testArgs.GetMapMultiArgs().count("f") && + !testArgs.GetMapMultiArgs().count("-d")); + + BOOST_CHECK(testArgs.GetMapArgs()["-a"] == "" && + testArgs.GetMapArgs()["-ccc"] == "multiple"); + BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2); } BOOST_AUTO_TEST_CASE(util_GetArg) { - mapArgs.clear(); - mapArgs["strtest1"] = "string..."; + TestArgsManager testArgs; + testArgs.GetMapArgs().clear(); + testArgs.GetMapArgs()["strtest1"] = "string..."; // strtest2 undefined on purpose - mapArgs["inttest1"] = "12345"; - mapArgs["inttest2"] = "81985529216486895"; + testArgs.GetMapArgs()["inttest1"] = "12345"; + testArgs.GetMapArgs()["inttest2"] = "81985529216486895"; // inttest3 undefined on purpose - mapArgs["booltest1"] = ""; + testArgs.GetMapArgs()["booltest1"] = ""; // booltest2 undefined on purpose - mapArgs["booltest3"] = "0"; - mapArgs["booltest4"] = "1"; - - BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string..."); - BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default"); - BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345); - BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL); - BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1); - BOOST_CHECK_EQUAL(GetBoolArg("booltest1", false), true); - BOOST_CHECK_EQUAL(GetBoolArg("booltest2", false), false); - BOOST_CHECK_EQUAL(GetBoolArg("booltest3", false), false); - BOOST_CHECK_EQUAL(GetBoolArg("booltest4", false), true); + testArgs.GetMapArgs()["booltest3"] = "0"; + testArgs.GetMapArgs()["booltest4"] = "1"; + + BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string..."); + BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default"); + BOOST_CHECK_EQUAL(testArgs.GetArg("inttest1", -1), 12345); + BOOST_CHECK_EQUAL(testArgs.GetArg("inttest2", -1), 81985529216486895LL); + BOOST_CHECK_EQUAL(testArgs.GetArg("inttest3", -1), -1); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true); } BOOST_AUTO_TEST_CASE(util_FormatMoney) { diff --git a/src/util.h b/src/util.h --- a/src/util.h +++ b/src/util.h @@ -16,6 +16,7 @@ #include "compat.h" #include "fs.h" +#include "sync.h" #include "tinyformat.h" #include "utiltime.h" @@ -40,7 +41,6 @@ boost::signals2::signal Translate; }; -extern const std::map> &mapMultiArgs; extern bool fPrintToConsole; extern bool fPrintToDebugLog; @@ -128,7 +128,6 @@ } void PrintExceptionContinue(const std::exception *pex, const char *pszThread); -void ParseParameters(int argc, const char *const argv[]); void FileCommit(FILE *file); bool TruncateFile(FILE *file, unsigned int length); int RaiseFileDescriptorLimit(int nMinFD); @@ -143,7 +142,6 @@ fs::path GetPidFile(); void CreatePidFile(const fs::path &path, pid_t pid); #endif -void ReadConfigFile(const std::string &confPath); #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif @@ -159,67 +157,132 @@ #endif } -/** - * Return true if the given argument has been manually set. - * - * @param strArg Argument to get (e.g. "-foo") - * @return true if the argument has been set - */ -bool IsArgSet(const std::string &strArg); +class ArgsManager { +protected: + CCriticalSection cs_args; + std::map mapArgs; + std::map> mapMultiArgs; -/** - * Return string argument or default value. - * - * @param strArg Argument to get (e.g. "-foo") - * @param default (e.g. "1") - * @return command-line argument or default value - */ -std::string GetArg(const std::string &strArg, const std::string &strDefault); +public: + void ParseParameters(int argc, const char *const argv[]); + void ReadConfigFile(const std::string &confPath); + std::vector GetArgs(const std::string &strArg); + + /** + * Return true if the given argument has been manually set. + * + * @param strArg Argument to get (e.g. "-foo") + * @return true if the argument has been set + */ + bool IsArgSet(const std::string &strArg); + + /** + * Return string argument or default value. + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. "1") + * @return command-line argument or default value + */ + std::string GetArg(const std::string &strArg, + const std::string &strDefault); + + /** + * Return integer argument or default value. + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. 1) + * @return command-line argument (0 if invalid number) or default value + */ + int64_t GetArg(const std::string &strArg, int64_t nDefault); + + /** + * Return boolean argument or default value. + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (true or false) + * @return command-line argument or default value + */ + bool GetBoolArg(const std::string &strArg, bool fDefault); + + /** + * Set an argument if it doesn't already have a value. + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ + bool SoftSetArg(const std::string &strArg, const std::string &strValue); + + /** + * Set a boolean argument if it doesn't already have a value. + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ + bool SoftSetBoolArg(const std::string &strArg, bool fValue); + + // Forces a arg setting, used only in testing + void ForceSetArg(const std::string &strArg, const std::string &strValue); + + // Forces a multi arg setting, used only in testing + void ForceSetMultiArg(const std::string &strArg, + const std::string &strValue); + + // Remove an arg setting, used only in testing + void ClearArg(const std::string &strArg); +}; -/** - * Return integer argument or default value. - * - * @param strArg Argument to get (e.g. "-foo") - * @param default (e.g. 1) - * @return command-line argument (0 if invalid number) or default value - */ -int64_t GetArg(const std::string &strArg, int64_t nDefault); +extern ArgsManager gArgs; -/** - * Return boolean argument or default value. - * - * @param strArg Argument to get (e.g. "-foo") - * @param default (true or false) - * @return command-line argument or default value - */ -bool GetBoolArg(const std::string &strArg, bool fDefault); +// wrappers using the global ArgsManager: +static inline void ParseParameters(int argc, const char *const argv[]) { + gArgs.ParseParameters(argc, argv); +} -/** - * Set an argument if it doesn't already have a value. - * - * @param strArg Argument to set (e.g. "-foo") - * @param strValue Value (e.g. "1") - * @return true if argument gets set, false if it already had a value - */ -bool SoftSetArg(const std::string &strArg, const std::string &strValue); +static inline void ReadConfigFile(const std::string &confPath) { + gArgs.ReadConfigFile(confPath); +} -/** - * Set a boolean argument if it doesn't already have a value. - * - * @param strArg Argument to set (e.g. "-foo") - * @param fValue Value (e.g. false) - * @return true if argument gets set, false if it already had a value - */ -bool SoftSetBoolArg(const std::string &strArg, bool fValue); +static inline bool SoftSetArg(const std::string &strArg, + const std::string &strValue) { + return gArgs.SoftSetArg(strArg, strValue); +} + +static inline void ForceSetArg(const std::string &strArg, + const std::string &strValue) { + gArgs.ForceSetArg(strArg, strValue); +} + +static inline void ForceSetMultiArg(const std::string &strArg, + const std::string &strValue) { + gArgs.ForceSetMultiArg(strArg, strValue); +} -// Forces a arg setting, used only in testing -void ForceSetArg(const std::string &strArg, const std::string &strValue); +static inline void ClearArg(const std::string &strArg) { + gArgs.ClearArg(strArg); +} -// Forces a multi arg setting, used only in testing -void ForceSetMultiArg(const std::string &strArg, const std::string &strValue); +static inline bool IsArgSet(const std::string &strArg) { + return gArgs.IsArgSet(strArg); +} -// Remove an arg setting, used only in testing -void ClearArg(const std::string &strArg); +static inline std::string GetArg(const std::string &strArg, + const std::string &strDefault) { + return gArgs.GetArg(strArg, strDefault); +} + +static inline int64_t GetArg(const std::string &strArg, int64_t nDefault) { + return gArgs.GetArg(strArg, nDefault); +} + +static inline bool GetBoolArg(const std::string &strArg, bool fDefault) { + return gArgs.GetBoolArg(strArg, fDefault); +} + +static inline bool SoftSetBoolArg(const std::string &strArg, bool fValue) { + return gArgs.SoftSetBoolArg(strArg, fValue); +} /** * Format a string to be used as group of options in help messages. diff --git a/src/util.cpp b/src/util.cpp --- a/src/util.cpp +++ b/src/util.cpp @@ -13,7 +13,6 @@ #include "fs.h" #include "random.h" #include "serialize.h" -#include "sync.h" #include "utilstrencodings.h" #include "utiltime.h" @@ -91,11 +90,7 @@ const char *const BITCOIN_CONF_FILENAME = "bitcoin.conf"; const char *const BITCOIN_PID_FILENAME = "bitcoind.pid"; -CCriticalSection cs_args; -std::map mapArgs; -static std::map> _mapMultiArgs; -const std::map> &mapMultiArgs = - _mapMultiArgs; +ArgsManager gArgs; bool fPrintToConsole = false; bool fPrintToDebugLog = true; @@ -362,10 +357,10 @@ } } -void ParseParameters(int argc, const char *const argv[]) { +void ArgsManager::ParseParameters(int argc, const char *const argv[]) { LOCK(cs_args); mapArgs.clear(); - _mapMultiArgs.clear(); + mapMultiArgs.clear(); for (int i = 1; i < argc; i++) { std::string str(argv[i]); @@ -388,50 +383,61 @@ InterpretNegativeSetting(str, strValue); mapArgs[str] = strValue; - _mapMultiArgs[str].push_back(strValue); + mapMultiArgs[str].push_back(strValue); } } -bool IsArgSet(const std::string &strArg) { +std::vector ArgsManager::GetArgs(const std::string &strArg) { + LOCK(cs_args); + return mapMultiArgs.at(strArg); +} + +bool ArgsManager::IsArgSet(const std::string &strArg) { LOCK(cs_args); return mapArgs.count(strArg); } -std::string GetArg(const std::string &strArg, const std::string &strDefault) { +std::string ArgsManager::GetArg(const std::string &strArg, + const std::string &strDefault) { LOCK(cs_args); if (mapArgs.count(strArg)) return mapArgs[strArg]; return strDefault; } -int64_t GetArg(const std::string &strArg, int64_t nDefault) { +int64_t ArgsManager::GetArg(const std::string &strArg, int64_t nDefault) { LOCK(cs_args); if (mapArgs.count(strArg)) return atoi64(mapArgs[strArg]); return nDefault; } -bool GetBoolArg(const std::string &strArg, bool fDefault) { +bool ArgsManager::GetBoolArg(const std::string &strArg, bool fDefault) { LOCK(cs_args); if (mapArgs.count(strArg)) return InterpretBool(mapArgs[strArg]); return fDefault; } -bool SoftSetArg(const std::string &strArg, const std::string &strValue) { +bool ArgsManager::SoftSetArg(const std::string &strArg, + const std::string &strValue) { LOCK(cs_args); - if (mapArgs.count(strArg)) return false; - mapArgs[strArg] = strValue; + if (mapArgs.count(strArg)) { + return false; + } + ForceSetArg(strArg, strValue); return true; } -bool SoftSetBoolArg(const std::string &strArg, bool fValue) { +bool ArgsManager::SoftSetBoolArg(const std::string &strArg, bool fValue) { if (fValue) return SoftSetArg(strArg, std::string("1")); else return SoftSetArg(strArg, std::string("0")); } -void ForceSetArg(const std::string &strArg, const std::string &strValue) { +void ArgsManager::ForceSetArg(const std::string &strArg, + const std::string &strValue) { LOCK(cs_args); mapArgs[strArg] = strValue; + mapMultiArgs[strArg].push_back(strValue); } /** @@ -439,12 +445,16 @@ * so we should not worry about element uniqueness and * integrity of mapMultiArgs data structure */ -void ForceSetMultiArg(const std::string &strArg, const std::string &strValue) { +void ArgsManager::ForceSetMultiArg(const std::string &strArg, + const std::string &strValue) { LOCK(cs_args); - _mapMultiArgs[strArg].push_back(strValue); + if (mapArgs.count(strArg) == 0) { + mapArgs[strArg] = strValue; + } + mapMultiArgs[strArg].push_back(strValue); } -void ClearArg(const std::string &strArg) { +void ArgsManager::ClearArg(const std::string &strArg) { LOCK(cs_args); mapArgs.erase(strArg); } @@ -557,7 +567,7 @@ return pathConfigFile; } -void ReadConfigFile(const std::string &confPath) { +void ArgsManager::ReadConfigFile(const std::string &confPath) { fs::ifstream streamConfig(GetConfigFile(confPath)); // No bitcoin.conf file is OK @@ -577,8 +587,10 @@ std::string strKey = std::string("-") + it->string_key; std::string strValue = it->value[0]; InterpretNegativeSetting(strKey, strValue); - if (mapArgs.count(strKey) == 0) mapArgs[strKey] = strValue; - _mapMultiArgs[strKey].push_back(strValue); + if (mapArgs.count(strKey) == 0) { + mapArgs[strKey] = strValue; + } + mapMultiArgs[strKey].push_back(strValue); } } // If datadir is changed in .conf file: