Merge #15335: Fix lack of warning of unrecognized section names

1a7ba84e11 Fix lack of warning of unrecognized section names (Akio Nakamura)

Pull request description:

  In #14708, It was introduced that to warn when unrecognized section names are exist in the config file.
  But ```m_config_sections.clear()```  in ```ArgsManager::ReadConfigStream()``` is called every time when reading each configuration file, so it can warn about only last reading file if ```includeconf``` exists.

  This PR fix lack of warning by collecting all section names by moving ```m_config_sections.clear()```  to ```ArgsManager::ReadConfigFiles()``` .
  Also add a test code to confirm this situation.

Tree-SHA512: 26aa0cbe3e4ae2e58cbe73d4492ee5cf465fd4c3e5df2c8ca7e282b627df9e637267af1e3816386b1dc6db2398b31936925ce0e432219fec3a9b3398f01e3e65
This commit is contained in:
MarcoFalke
2019-03-02 09:59:09 -05:00
5 changed files with 38 additions and 26 deletions

View File

@@ -353,8 +353,7 @@ const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
return unsuitables;
}
const std::set<std::string> ArgsManager::GetUnrecognizedSections() const
const std::list<SectionInfo> ArgsManager::GetUnrecognizedSections() const
{
// Section names to be recognized in the config file.
static const std::set<std::string> available_sections{
@@ -362,14 +361,11 @@ const std::set<std::string> ArgsManager::GetUnrecognizedSections() const
CBaseChainParams::TESTNET,
CBaseChainParams::MAIN
};
std::set<std::string> diff;
LOCK(cs_args);
std::set_difference(
m_config_sections.begin(), m_config_sections.end(),
available_sections.begin(), available_sections.end(),
std::inserter(diff, diff.end()));
return diff;
std::list<SectionInfo> unrecognized = m_config_sections;
unrecognized.remove_if([](const SectionInfo& appeared){ return available_sections.find(appeared.m_name) != available_sections.end(); });
return unrecognized;
}
void ArgsManager::SelectConfigNetwork(const std::string& network)
@@ -793,7 +789,7 @@ static std::string TrimString(const std::string& str, const std::string& pattern
return str.substr(front, end - front + 1);
}
static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::set<std::string>& sections)
static bool GetConfigOptions(std::istream& stream, const std::string& filepath, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::list<SectionInfo>& sections)
{
std::string str, prefix;
std::string::size_type pos;
@@ -809,7 +805,7 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
if (!str.empty()) {
if (*str.begin() == '[' && *str.rbegin() == ']') {
const std::string section = str.substr(1, str.size() - 2);
sections.insert(section);
sections.emplace_back(SectionInfo{section, filepath, linenr});
prefix = section + '.';
} else if (*str.begin() == '-') {
error = strprintf("parse error on line %i: %s, options in configuration file must be specified without leading -", linenr, str);
@@ -822,8 +818,8 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
return false;
}
options.emplace_back(name, value);
if ((pos = name.rfind('.')) != std::string::npos) {
sections.insert(name.substr(0, pos));
if ((pos = name.rfind('.')) != std::string::npos && prefix.length() <= pos) {
sections.emplace_back(SectionInfo{name.substr(0, pos), filepath, linenr});
}
} else {
error = strprintf("parse error on line %i: %s", linenr, str);
@@ -838,12 +834,11 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
return true;
}
bool ArgsManager::ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys)
bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys)
{
LOCK(cs_args);
std::vector<std::pair<std::string, std::string>> options;
m_config_sections.clear();
if (!GetConfigOptions(stream, error, options, m_config_sections)) {
if (!GetConfigOptions(stream, filepath, error, options, m_config_sections)) {
return false;
}
for (const std::pair<std::string, std::string>& option : options) {
@@ -874,6 +869,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
{
LOCK(cs_args);
m_config_args.clear();
m_config_sections.clear();
}
const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME);
@@ -881,7 +877,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
// ok to not have a config file
if (stream.good()) {
if (!ReadConfigStream(stream, error, ignore_invalid_keys)) {
if (!ReadConfigStream(stream, confPath, error, ignore_invalid_keys)) {
return false;
}
// if there is an -includeconf in the override args, but it is empty, that means the user
@@ -912,7 +908,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
for (const std::string& to_include : includeconf) {
fsbridge::ifstream include_config(GetConfigFile(to_include));
if (include_config.good()) {
if (!ReadConfigStream(include_config, error, ignore_invalid_keys)) {
if (!ReadConfigStream(include_config, to_include, error, ignore_invalid_keys)) {
return false;
}
LogPrintf("Included configuration file %s\n", to_include.c_str());