Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251BOOST_CHECK(test.ParseParameters(2, argv, error));252BOOST_CHECK_EQUAL(error, "");254argv[1] = "-unregistered";255BOOST_CHECK(!test.ParseParameters(2, argv, error));256BOOST_CHECK_EQUAL(error, "Invalid parameter -unregistered");258// Make sure registered parameters prefixed with a chain type trigger errors.259// (Previously, they were accepted and ignored.)260argv[1] = "-test.registered";261BOOST_CHECK(!test.ParseParameters(2, argv, error));262BOOST_CHECK_EQUAL(error, "Invalid parameter -test.registered");263}265static void TestParse(const std::string& str, bool expected_bool, int64_t expected_int)266{267TestArgsManager test;268test.SetupArgs({{"-value", ArgsManager::ALLOW_ANY}});269std::string arg = "-value=" + str;270const char* argv[] = {"ignored", arg.c_str()};271std::string error;272BOOST_CHECK(test.ParseParameters(2, argv, error));273BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), expected_bool);274BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), expected_bool);275BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99998), expected_int);276BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99999), expected_int);277}279// Test bool and int parsing.280BOOST_AUTO_TEST_CASE(util_ArgParsing)281{282// Some of these cases could be ambiguous or surprising to users, and might283// be worth triggering errors or warnings in the future. But for now basic284// test coverage is useful to avoid breaking backwards compatibility285// unintentionally.286TestParse("", true, 0);287TestParse(" ", false, 0);288TestParse("0", false, 0);289TestParse("0 ", false, 0);290TestParse(" 0", false, 0);291TestParse("+0", false, 0);292TestParse("-0", false, 0);293TestParse("5", true, 5);294TestParse("5 ", true, 5);295TestParse(" 5", true, 5);296TestParse("+5", true, 5);297TestParse("-5", true, -5);298TestParse("0 5", false, 0);299TestParse("5 0", true, 5);300TestParse("050", true, 50);301TestParse("0.", false, 0);302TestParse("5.", true, 5);303TestParse("0.0", false, 0);304TestParse("0.5", false, 0);305TestParse("5.0", true, 5);306TestParse("5.5", true, 5);307TestParse("x", false, 0);308TestParse("x0", false, 0);309TestParse("x5", false, 0);310TestParse("0x", false, 0);311TestParse("5x", true, 5);312TestParse("0x5", false, 0);313TestParse("false", false, 0);314TestParse("true", false, 0);315TestParse("yes", false, 0);316TestParse("no", false, 0);317}319BOOST_AUTO_TEST_CASE(util_GetBoolArg)320{321TestArgsManager testArgs;322const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);323const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);324const auto c = std::make_pair("-c", ArgsManager::ALLOW_ANY);325const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);326const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);327const auto f = std::make_pair("-f", ArgsManager::ALLOW_ANY);329const char *argv_test[] = {330"ignored", "-a", "-nob", "-c=0", "-d=1", "-e=false", "-f=true"};331std::string error;332testArgs.SetupArgs({a, b, c, d, e, f});333BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));335// Each letter should be set.336for (const char opt : "abcdef")337BOOST_CHECK(testArgs.IsArgSet({'-', opt}) || !opt);339// Nothing else should be in the map340testArgs.LockSettings([&](const common::Settings& s) {341BOOST_CHECK(s.command_line_options.size() == 6);342BOOST_CHECK(s.ro_config.empty());343});345// The -no prefix should get stripped on the way in.346BOOST_CHECK(!testArgs.IsArgSet("-nob"));348// The -b option is flagged as negated, and nothing else is349BOOST_CHECK(testArgs.IsArgNegated("-b"));350BOOST_CHECK(!testArgs.IsArgNegated("-a"));352// Check expected values.353BOOST_CHECK(testArgs.GetBoolArg("-a", false) == true);354BOOST_CHECK(testArgs.GetBoolArg("-b", true) == false);355BOOST_CHECK(testArgs.GetBoolArg("-c", true) == false);356BOOST_CHECK(testArgs.GetBoolArg("-d", false) == true);357BOOST_CHECK(testArgs.GetBoolArg("-e", true) == false);358BOOST_CHECK(testArgs.GetBoolArg("-f", true) == false);359}361BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)362{363// Test some awful edge cases that hopefully no user will ever exercise.364TestArgsManager testArgs;366// Params test367const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY);368const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);369const char *argv_test[] = {"ignored", "-nofoo", "-foo", "-nobar=0"};370testArgs.SetupArgs({foo, bar});371std::string error;372BOOST_CHECK(testArgs.ParseParameters(4, argv_test, error));374// This was passed twice, second one overrides the negative setting.375BOOST_CHECK(!testArgs.IsArgNegated("-foo"));376BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "");378// A double negative is a positive, and not marked as negated.379BOOST_CHECK(!testArgs.IsArgNegated("-bar"));380BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");382// Config test383const char *conf_test = "nofoo=1\nfoo=1\nnobar=0\n";384BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));385testArgs.ReadConfigString(conf_test);387// This was passed twice, second one overrides the negative setting,388// and the value.389BOOST_CHECK(!testArgs.IsArgNegated("-foo"));390BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "1");392// A double negative is a positive, and does not count as negated.393BOOST_CHECK(!testArgs.IsArgNegated("-bar"));394BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "1");396// Combined test397const char *combo_test_args[] = {"ignored", "-nofoo", "-bar"};398const char *combo_test_conf = "foo=1\nnobar=1\n";399BOOST_CHECK(testArgs.ParseParameters(3, combo_test_args, error));400testArgs.ReadConfigString(combo_test_conf);402// Command line overrides, but doesn't erase old setting403BOOST_CHECK(testArgs.IsArgNegated("-foo"));404BOOST_CHECK(testArgs.GetArg("-foo", "xxx") == "0");405BOOST_CHECK(testArgs.GetArgs("-foo").size() == 0);407// Command line overrides, but doesn't erase old setting408BOOST_CHECK(!testArgs.IsArgNegated("-bar"));409BOOST_CHECK(testArgs.GetArg("-bar", "xxx") == "");410BOOST_REQUIRE(testArgs.GetArgs("-bar").size() == 1);411BOOST_CHECK(testArgs.GetArgs("-bar").front() == "");412}414BOOST_AUTO_TEST_CASE(util_ReadConfigStream)415{416const char *str_config =417"a=\n"418"b=1\n"419"ccc=argument\n"420"ccc=multiple\n"421"d=e\n"422"nofff=1\n"423"noggg=0\n"424"h=1\n"425"noh=1\n"426"noi=1\n"427"i=1\n"428"sec1.ccc=extend1\n"429"\n"430"[sec1]\n"431"ccc=extend2\n"432"d=eee\n"433"h=1\n"434"[sec2]\n"435"ccc=extend3\n"436"iii=2\n";438TestArgsManager test_args;439const auto a = std::make_pair("-a", ArgsManager::ALLOW_ANY);440const auto b = std::make_pair("-b", ArgsManager::ALLOW_ANY);441const auto ccc = std::make_pair("-ccc", ArgsManager::ALLOW_ANY);442const auto d = std::make_pair("-d", ArgsManager::ALLOW_ANY);443const auto e = std::make_pair("-e", ArgsManager::ALLOW_ANY);444const auto fff = std::make_pair("-fff", ArgsManager::ALLOW_ANY);445const auto ggg = std::make_pair("-ggg", ArgsManager::ALLOW_ANY);446const auto h = std::make_pair("-h", ArgsManager::ALLOW_ANY);447const auto i = std::make_pair("-i", ArgsManager::ALLOW_ANY);448const auto iii = std::make_pair("-iii", ArgsManager::ALLOW_ANY);449test_args.SetupArgs({a, b, ccc, d, e, fff, ggg, h, i, iii});451test_args.ReadConfigString(str_config);452// expectation: a, b, ccc, d, fff, ggg, h, i end up in map453// so do sec1.ccc, sec1.d, sec1.h, sec2.ccc, sec2.iii455test_args.LockSettings([&](const common::Settings& s) {456BOOST_CHECK(s.command_line_options.empty());457BOOST_CHECK(s.ro_config.size() == 3);458BOOST_CHECK(s.ro_config.at("").size() == 8);459BOOST_CHECK(s.ro_config.at("sec1").size() == 3);460BOOST_CHECK(s.ro_config.at("sec2").size() == 2);462BOOST_CHECK(s.ro_config.at("").contains("a"));463BOOST_CHECK(s.ro_config.at("").contains("b"));464BOOST_CHECK(s.ro_config.at("").contains("ccc"));465BOOST_CHECK(s.ro_config.at("").contains("d"));466BOOST_CHECK(s.ro_config.at("").contains("fff"));467BOOST_CHECK(s.ro_config.at("").contains("ggg"));468BOOST_CHECK(s.ro_config.at("").contains("h"));469BOOST_CHECK(s.ro_config.at("").contains("i"));470BOOST_CHECK(s.ro_config.at("sec1").contains("ccc"));471BOOST_CHECK(s.ro_config.at("sec1").contains("h"));472BOOST_CHECK(s.ro_config.at("sec2").contains("ccc"));473BOOST_CHECK(s.ro_config.at("sec2").contains("iii"));474});476BOOST_CHECK(test_args.IsArgSet("-a"));477BOOST_CHECK(test_args.IsArgSet("-b"));478BOOST_CHECK(test_args.IsArgSet("-ccc"));479BOOST_CHECK(test_args.IsArgSet("-d"));480BOOST_CHECK(test_args.IsArgSet("-fff"));481BOOST_CHECK(test_args.IsArgSet("-ggg"));482BOOST_CHECK(test_args.IsArgSet("-h"));483BOOST_CHECK(test_args.IsArgSet("-i"));484BOOST_CHECK(!test_args.IsArgSet("-zzz"));485BOOST_CHECK(!test_args.IsArgSet("-iii"));487BOOST_CHECK_EQUAL(test_args.GetArg("-a", "xxx"), "");488BOOST_CHECK_EQUAL(test_args.GetArg("-b", "xxx"), "1");489BOOST_CHECK_EQUAL(test_args.GetArg("-ccc", "xxx"), "argument");490BOOST_CHECK_EQUAL(test_args.GetArg("-d", "xxx"), "e");491BOOST_CHECK_EQUAL(test_args.GetArg("-fff", "xxx"), "0");492BOOST_CHECK_EQUAL(test_args.GetArg("-ggg", "xxx"), "1");493BOOST_CHECK_EQUAL(test_args.GetArg("-h", "xxx"), "0");494BOOST_CHECK_EQUAL(test_args.GetArg("-i", "xxx"), "1");495BOOST_CHECK_EQUAL(test_args.GetArg("-zzz", "xxx"), "xxx");496BOOST_CHECK_EQUAL(test_args.GetArg("-iii", "xxx"), "xxx");498for (const bool def : {false, true}) {499BOOST_CHECK(test_args.GetBoolArg("-a", def));500BOOST_CHECK(test_args.GetBoolArg("-b", def));
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.