diff --git a/src/common/args.cpp b/src/common/args.cpp index 3ffa4d3f105..5c8589cf440 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -483,29 +483,33 @@ std::string SettingToString(const common::SettingsValue& value, const std::strin return SettingToString(value).value_or(strDefault); } -int64_t ArgsManager::GetIntArg(const std::string& strArg, int64_t nDefault) const +template +Int ArgsManager::GetArg(const std::string& strArg, Int nDefault) const { - return GetIntArg(strArg).value_or(nDefault); + return GetArg(strArg).value_or(nDefault); } -std::optional ArgsManager::GetIntArg(const std::string& strArg) const +template +std::optional ArgsManager::GetArg(const std::string& strArg) const { const common::SettingsValue value = GetSetting(strArg); - return SettingToInt(value); + return SettingTo(value); } -std::optional SettingToInt(const common::SettingsValue& value) +template +std::optional SettingTo(const common::SettingsValue& value) { if (value.isNull()) return std::nullopt; if (value.isFalse()) return 0; if (value.isTrue()) return 1; - if (value.isNum()) return value.getInt(); - return LocaleIndependentAtoi(value.get_str()); + if (value.isNum()) return value.getInt(); + return LocaleIndependentAtoi(value.get_str()); } -int64_t SettingToInt(const common::SettingsValue& value, int64_t nDefault) +template +Int SettingTo(const common::SettingsValue& value, Int nDefault) { - return SettingToInt(value).value_or(nDefault); + return SettingTo(value).value_or(nDefault); } bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const @@ -531,6 +535,23 @@ bool SettingToBool(const common::SettingsValue& value, bool fDefault) return SettingToBool(value).value_or(fDefault); } +#define INSTANTIATE_INT_TYPE(Type) \ + template Type ArgsManager::GetArg(const std::string&, Type) const; \ + template std::optional ArgsManager::GetArg(const std::string&) const; \ + template Type SettingTo(const common::SettingsValue&, Type); \ + template std::optional SettingTo(const common::SettingsValue&) + +INSTANTIATE_INT_TYPE(int8_t); +INSTANTIATE_INT_TYPE(uint8_t); +INSTANTIATE_INT_TYPE(int16_t); +INSTANTIATE_INT_TYPE(uint16_t); +INSTANTIATE_INT_TYPE(int32_t); +INSTANTIATE_INT_TYPE(uint32_t); +INSTANTIATE_INT_TYPE(int64_t); +INSTANTIATE_INT_TYPE(uint64_t); + +#undef INSTANTIATE_INT_TYPE + bool ArgsManager::SoftSetArg(const std::string& strArg, const std::string& strValue) { LOCK(cs_args); diff --git a/src/common/args.h b/src/common/args.h index 1b9233ec75c..ea4e173bf72 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -89,8 +90,11 @@ struct SectionInfo { std::string SettingToString(const common::SettingsValue&, const std::string&); std::optional SettingToString(const common::SettingsValue&); -int64_t SettingToInt(const common::SettingsValue&, int64_t); -std::optional SettingToInt(const common::SettingsValue&); +template +Int SettingTo(const common::SettingsValue&, Int); + +template +std::optional SettingTo(const common::SettingsValue&); bool SettingToBool(const common::SettingsValue&, bool); std::optional SettingToBool(const common::SettingsValue&); @@ -293,8 +297,14 @@ protected: * @param nDefault (e.g. 1) * @return command-line argument (0 if invalid number) or default value */ - int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const; - std::optional GetIntArg(const std::string& strArg) const; + template + Int GetArg(const std::string& strArg, Int nDefault) const; + + template + std::optional GetArg(const std::string& strArg) const; + + int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const { return GetArg(strArg, nDefault); } + std::optional GetIntArg(const std::string& strArg) const { return GetArg(strArg); } /** * Return boolean argument or default value diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 671e119642f..7af0896c0bf 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -410,8 +410,8 @@ bool InitHTTPServer(const util::SignalInterrupt& interrupt) } LogDebug(BCLog::HTTP, "Initialized HTTP server\n"); - g_max_queue_depth = std::max((long)gArgs.GetIntArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L); - LogDebug(BCLog::HTTP, "set work queue of depth %d\n", g_max_queue_depth); + g_max_queue_depth = std::max(gArgs.GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1); + LogDebug(BCLog::HTTP, "set work queue of depth %d", g_max_queue_depth); // transfer ownership to eventBase/HTTP via .release() eventBase = base_ctr.release(); @@ -431,8 +431,8 @@ static std::thread g_thread_http; void StartHTTPServer() { - int rpcThreads = std::max((long)gArgs.GetIntArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); - LogInfo("Starting HTTP server with %d worker threads\n", rpcThreads); + int rpcThreads = std::max(gArgs.GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1); + LogInfo("Starting HTTP server with %d worker threads", rpcThreads); g_threadpool_http.Start(rpcThreads); g_thread_http = std::thread(ThreadHTTP, eventBase); } diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 3d876a8f63b..cfbc350f091 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -88,14 +88,14 @@ static common::SettingsValue PruneSetting(bool prune_enabled, int prune_size_gb) static bool PruneEnabled(const common::SettingsValue& prune_setting) { // -prune=1 setting is manual pruning mode, so disabled for purposes of the gui - return SettingToInt(prune_setting, 0) > 1; + return SettingTo(prune_setting, 0) > 1; } //! Get pruning size value to show in GUI from bitcoin -prune setting. If //! pruning is not enabled, just show default recommended pruning size (2GB). static int PruneSizeGB(const common::SettingsValue& prune_setting) { - int value = SettingToInt(prune_setting, 0); + int value = SettingTo(prune_setting, 0); return value > 1 ? PruneMiBtoGB(value) : DEFAULT_PRUNE_TARGET_GB; } @@ -469,9 +469,9 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con suffix.empty() ? getOption(option, "-prev") : DEFAULT_PRUNE_TARGET_GB; case DatabaseCache: - return qlonglong(SettingToInt(setting(), DEFAULT_DB_CACHE >> 20)); + return qlonglong(SettingTo(setting(), DEFAULT_DB_CACHE >> 20)); case ThreadsScriptVerif: - return qlonglong(SettingToInt(setting(), DEFAULT_SCRIPTCHECK_THREADS)); + return qlonglong(SettingTo(setting(), DEFAULT_SCRIPTCHECK_THREADS)); case Listen: return SettingToBool(setting(), DEFAULT_LISTEN); case Server: diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index ee369272370..ec17fe39971 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -247,26 +247,41 @@ BOOST_AUTO_TEST_CASE(intarg) const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); SetupArgs(local_args, {foo, bar}); + ResetArgs(local_args, ""); + BOOST_CHECK(!local_args.GetArg("-foo").has_value()); + BOOST_CHECK(!local_args.GetArg("-bar").has_value()); BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 11), 11); BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 0), 0); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{222}), 222); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{0}), 0); ResetArgs(local_args, "-foo -bar"); + BOOST_CHECK_EQUAL(local_args.GetArg("-foo"), 0); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar"), 0); BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 11), 0); - BOOST_CHECK_EQUAL(local_args.GetIntArg("-bar", 11), 0); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{222}), 0); // Check under-/overflow behavior. ResetArgs(local_args, "-foo=-9223372036854775809 -bar=9223372036854775808"); + BOOST_CHECK_EQUAL(local_args.GetArg("-foo"), std::numeric_limits::min()); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar"), std::numeric_limits::max()); BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 0), std::numeric_limits::min()); BOOST_CHECK_EQUAL(local_args.GetIntArg("-bar", 0), std::numeric_limits::max()); + BOOST_CHECK_EQUAL(local_args.GetArg("-foo", uint8_t{0}), std::numeric_limits::min()); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{0}), std::numeric_limits::max()); ResetArgs(local_args, "-foo=11 -bar=12"); + BOOST_CHECK_EQUAL(local_args.GetArg("-foo"), 11); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar"), 12); BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 0), 11); - BOOST_CHECK_EQUAL(local_args.GetIntArg("-bar", 11), 12); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{11}), 12); ResetArgs(local_args, "-foo=NaN -bar=NotANumber"); + BOOST_CHECK_EQUAL(local_args.GetArg("-foo"), 0); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar"), 0); BOOST_CHECK_EQUAL(local_args.GetIntArg("-foo", 1), 0); - BOOST_CHECK_EQUAL(local_args.GetIntArg("-bar", 11), 0); + BOOST_CHECK_EQUAL(local_args.GetArg("-bar", uint8_t{11}), 0); } BOOST_AUTO_TEST_CASE(patharg)