17 CONFIG_FILE_NETWORK_SECTION,
18 CONFIG_FILE_DEFAULT_SECTION
26 template <
typename Fn>
27 static void MergeSettings(
const Settings& settings,
const std::string& section,
const std::string&
name, Fn&& fn)
42 if (!section.empty()) {
44 if (
auto* values =
FindKey(*map, name)) {
45 fn(
SettingsSpan(*values), Source::CONFIG_FILE_NETWORK_SECTION);
51 if (
auto* values =
FindKey(*map, name)) {
52 fn(
SettingsSpan(*values), Source::CONFIG_FILE_DEFAULT_SECTION);
58 bool ReadSettings(
const fs::path& path, std::map<std::string, SettingsValue>& values, std::vector<std::string>& errors)
65 if (!file.is_open())
return true;
68 if (!in.
read(std::string{std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()})) {
69 errors.emplace_back(
strprintf(
"Unable to parse settings file %s", path.string()));
74 errors.emplace_back(
strprintf(
"Failed reading settings file %s", path.string()));
80 errors.emplace_back(
strprintf(
"Found non-object value %s in settings file %s", in.
write(), path.string()));
84 const std::vector<std::string>& in_keys = in.
getKeys();
85 const std::vector<SettingsValue>& in_values = in.
getValues();
86 for (
size_t i = 0; i < in_keys.size(); ++i) {
87 auto inserted = values.emplace(in_keys[i], in_values[i]);
88 if (!inserted.second) {
89 errors.emplace_back(
strprintf(
"Found duplicate key %s in settings file %s", in_keys[i], path.string()));
92 return errors.empty();
96 const std::map<std::string, SettingsValue>& values,
97 std::vector<std::string>& errors)
100 for (
const auto& value : values) {
101 out.
__pushKV(value.first, value.second);
106 errors.emplace_back(
strprintf(
"Error: Unable to open settings file %s for writing", path.string()));
109 file << out.
write( 1, 4) << std::endl;
115 const std::string& section,
116 const std::string&
name,
117 bool ignore_default_section_config,
127 const bool never_ignore_negated_setting = span.
last_negated();
134 const bool reverse_precedence =
135 (source == Source::CONFIG_FILE_NETWORK_SECTION || source == Source::CONFIG_FILE_DEFAULT_SECTION) &&
143 const bool skip_negated_command_line = get_chain_name;
148 if (ignore_default_section_config && source == Source::CONFIG_FILE_DEFAULT_SECTION &&
149 !never_ignore_negated_setting) {
154 if (skip_negated_command_line && span.
last_negated())
return;
157 result = reverse_precedence ? span.
begin()[0] : span.
end()[-1];
168 const std::string& section,
169 const std::string&
name,
170 bool ignore_default_section_config)
172 std::vector<SettingsValue> result;
174 bool prev_negated_empty =
false;
183 const bool add_zombie_config_values =
184 (source == Source::CONFIG_FILE_NETWORK_SECTION || source == Source::CONFIG_FILE_DEFAULT_SECTION) &&
188 if (ignore_default_section_config && source == Source::CONFIG_FILE_DEFAULT_SECTION)
return;
192 if (!done || add_zombie_config_values) {
193 for (
const auto& value : span) {
194 if (value.isArray()) {
195 result.insert(result.end(), value.getValues().begin(), value.getValues().end());
197 result.push_back(value);
204 done |= span.
negated() > 0 || source == Source::FORCED;
207 prev_negated_empty |= span.
last_negated() && result.empty();
214 bool has_default_section_setting =
false;
215 bool has_other_setting =
false;
217 if (span.
empty())
return;
218 else if (source == Source::CONFIG_FILE_DEFAULT_SECTION) has_default_section_setting =
true;
219 else has_other_setting =
true;
224 return has_default_section_setting && !has_other_setting;
234 for (
size_t i = size; i > 0; --i) {
235 if (data[i - 1].isFalse())
return i;
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
bool OnlyHasDefaultSectionSetting(const Settings &settings, const std::string §ion, const std::string &name)
Return true if a setting is set in the default config file section, and not overridden by a higher pr...
bool read(const char *raw, size_t len)
const std::vector< UniValue > & getValues() const
SettingsValue GetSetting(const Settings &settings, const std::string §ion, const std::string &name, bool ignore_default_section_config, bool get_chain_name)
Get settings value from combined sources: forced settings, command line arguments, runtime read-write settings, and the read-only config file.
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
std::vector< SettingsValue > GetSettingsList(const Settings &settings, const std::string §ion, const std::string &name, bool ignore_default_section_config)
Get combined setting value similar to GetSetting(), except if setting was specified multiple times...
bool WriteSettings(const fs::path &path, const std::map< std::string, SettingsValue > &values, std::vector< std::string > &errors)
Write settings file.
size_t negated() const
Number of negated values.
std::map< std::string, std::vector< SettingsValue > > command_line_options
Map of setting name to list of command line values.
Accessor for list of settings that skips negated values when iterated over.
bool empty() const
True if there are any non-negated values.
std::map< std::string, std::map< std::string, std::vector< SettingsValue > > > ro_config
Map of config section name and setting name to list of config file values.
const SettingsValue * end() const
Pointer to end of values.
const SettingsValue * begin() const
Pointer to first non-negated value.
const std::vector< std::string > & getKeys() const
std::map< std::string, SettingsValue > forced_settings
Map of setting name to forced setting value.
void __pushKV(const std::string &key, const UniValue &val)
bool last_negated() const
True if the last value is negated.
bool ReadSettings(const fs::path &path, std::map< std::string, SettingsValue > &values, std::vector< std::string > &errors)
Read settings file.