Changeset View
Changeset View
Standalone View
Standalone View
src/util/system.cpp
Show First 20 Lines • Show All 290 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
/** | /** | ||||
* Interpret -nofoo as if the user supplied -foo=0. | * Interpret -nofoo as if the user supplied -foo=0. | ||||
* | * | ||||
* This method also tracks when the -no form was supplied, and if so, checks | * This method also tracks when the -no form was supplied, and if so, checks | ||||
* whether there was a double-negative (-nofoo=0 -> -foo=1). | * whether there was a double-negative (-nofoo=0 -> -foo=1). | ||||
* | * | ||||
* If there was not a double negative, it removes the "no" from the key, and | * If there was not a double negative, it removes the "no" from the key | ||||
* returns true, indicating the caller should clear the args vector to indicate | * and clears the args vector to indicate a negated option. | ||||
* a negated option. | |||||
* | * | ||||
* If there was a double negative, it removes "no" from the key, sets the value | * If there was a double negative, it removes "no" from the key, sets the | ||||
* to "1" and returns false. | * value to "1" and pushes the key and the updated value to the args vector. | ||||
* | * | ||||
* If there was no "no", it leaves key and value untouched and returns false. | * If there was no "no", it leaves key and value untouched and pushes them | ||||
* to the args vector. | |||||
* | * | ||||
* Where an option was negated can be later checked using the IsArgNegated() | * Where an option was negated can be later checked using the IsArgNegated() | ||||
* method. One use case for this is to have a way to disable options that are | * method. One use case for this is to have a way to disable options that are | ||||
* not normally boolean (e.g. using -nodebuglogfile to request that debug log | * not normally boolean (e.g. using -nodebuglogfile to request that debug log | ||||
* output is not sent to any file at all). | * output is not sent to any file at all). | ||||
*/ | */ | ||||
static bool InterpretNegatedOption(std::string &key, std::string &val) { | static void | ||||
InterpretOption(std::string key, std::string val, | |||||
std::map<std::string, std::vector<std::string>> &args) { | |||||
assert(key[0] == '-'); | assert(key[0] == '-'); | ||||
size_t option_index = key.find('.'); | size_t option_index = key.find('.'); | ||||
if (option_index == std::string::npos) { | if (option_index == std::string::npos) { | ||||
option_index = 1; | option_index = 1; | ||||
} else { | } else { | ||||
++option_index; | ++option_index; | ||||
} | } | ||||
if (key.substr(option_index, 2) == "no") { | if (key.substr(option_index, 2) == "no") { | ||||
bool bool_val = InterpretBool(val); | const bool bool_val = InterpretBool(val); | ||||
key.erase(option_index, 2); | key.erase(option_index, 2); | ||||
if (!bool_val) { | if (!bool_val) { | ||||
// Double negatives like -nofoo=0 are supported (but discouraged) | // Double negatives like -nofoo=0 are supported (but discouraged) | ||||
LogPrintf( | LogPrintf( | ||||
"Warning: parsed potentially confusing double-negative %s=%s\n", | "Warning: parsed potentially confusing double-negative %s=%s\n", | ||||
key, val); | key, val); | ||||
val = "1"; | val = "1"; | ||||
} else { | } else { | ||||
return true; | args[key].clear(); | ||||
return; | |||||
} | } | ||||
} | } | ||||
return false; | args[key].push_back(val); | ||||
} | } | ||||
ArgsManager::ArgsManager() | ArgsManager::ArgsManager() | ||||
: /* These options would cause cross-contamination if values for mainnet | : /* These options would cause cross-contamination if values for mainnet | ||||
* were used while running on regtest/testnet (or vice-versa). | * were used while running on regtest/testnet (or vice-versa). | ||||
* Setting them as section_only_args ensures that sharing a config file | * Setting them as section_only_args ensures that sharing a config file | ||||
* between mainnet and regtest/testnet won't cause problems due to these | * between mainnet and regtest/testnet won't cause problems due to these | ||||
* parameters by accident. */ | * parameters by accident. */ | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | for (int i = 1; i < argc; i++) { | ||||
// Check that the arg is known | // Check that the arg is known | ||||
if (!(IsSwitchChar(key[0]) && key.size() == 1)) { | if (!(IsSwitchChar(key[0]) && key.size() == 1)) { | ||||
if (!IsArgKnown(key)) { | if (!IsArgKnown(key)) { | ||||
error = strprintf("Invalid parameter %s", key.c_str()); | error = strprintf("Invalid parameter %s", key.c_str()); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// Check for -nofoo | InterpretOption(key, val, m_override_args); | ||||
if (InterpretNegatedOption(key, val)) { | |||||
m_override_args[key].clear(); | |||||
} else { | |||||
m_override_args[key].push_back(val); | |||||
} | |||||
} | } | ||||
// we do not allow -includeconf from command line, so we clear it here | // we do not allow -includeconf from command line, so we clear it here | ||||
auto it = m_override_args.find("-includeconf"); | auto it = m_override_args.find("-includeconf"); | ||||
if (it != m_override_args.end()) { | if (it != m_override_args.end()) { | ||||
if (it->second.size() > 0) { | if (it->second.size() > 0) { | ||||
for (const auto &ic : it->second) { | for (const auto &ic : it->second) { | ||||
error += "-includeconf cannot be used from commandline; " | error += "-includeconf cannot be used from commandline; " | ||||
▲ Show 20 Lines • Show All 489 Lines • ▼ Show 20 Lines | bool ArgsManager::ReadConfigStream(std::istream &stream, | ||||
bool ignore_invalid_keys) { | bool ignore_invalid_keys) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
std::vector<std::pair<std::string, std::string>> options; | std::vector<std::pair<std::string, std::string>> options; | ||||
if (!GetConfigOptions(stream, filepath, error, options, | if (!GetConfigOptions(stream, filepath, error, options, | ||||
m_config_sections)) { | m_config_sections)) { | ||||
return false; | return false; | ||||
} | } | ||||
for (const std::pair<std::string, std::string> &option : options) { | for (const std::pair<std::string, std::string> &option : options) { | ||||
std::string strKey = std::string("-") + option.first; | const std::string strKey = std::string("-") + option.first; | ||||
// Check that the arg is known | // Check that the arg is known | ||||
if (!IsArgKnown(strKey)) { | if (!IsArgKnown(strKey)) { | ||||
if (!ignore_invalid_keys) { | if (!ignore_invalid_keys) { | ||||
error = strprintf("Invalid configuration value %s", | error = strprintf("Invalid configuration value %s", | ||||
option.first.c_str()); | option.first.c_str()); | ||||
return false; | return false; | ||||
} else { | } else { | ||||
LogPrintf("Ignoring unknown configuration value %s\n", | LogPrintf("Ignoring unknown configuration value %s\n", | ||||
option.first); | option.first); | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
std::string strValue = option.second; | InterpretOption(strKey, option.second, m_config_args); | ||||
if (InterpretNegatedOption(strKey, strValue)) { | |||||
m_config_args[strKey].clear(); | |||||
} else { | |||||
m_config_args[strKey].push_back(strValue); | |||||
} | |||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool ArgsManager::ReadConfigFiles(std::string &error, | bool ArgsManager::ReadConfigFiles(std::string &error, | ||||
bool ignore_invalid_keys) { | bool ignore_invalid_keys) { | ||||
{ | { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
▲ Show 20 Lines • Show All 415 Lines • Show Last 20 Lines |