Skip to content

Commit e9fd366

Browse files
committed
refactor: Remove null setting check in GetSetting()
Also rename the "result_complete" variable in GetSettingsList() to "done" to be more consistent with GetSetting(). This change doesn't affect current behavior but could be useful in the future to support dynamically changing settings at runtime and adding new settings sources, because it lets high priority sources reset settings back to default (see test). By removing a special case for null, this change also helps merge code treat settings values more like black boxes, and interfere less with settings parsing and retrieval.
1 parent cba2710 commit e9fd366

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

src/test/settings_tests.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ BOOST_AUTO_TEST_CASE(Simple)
4545
CheckValues(settings2, R"("val2")", R"(["val2","val3"])");
4646
}
4747

48+
// Confirm that a high priority setting overrides a lower priority setting even
49+
// if the high priority setting is null. This behavior is useful for a high
50+
// priority setting source to be able to effectively reset any setting back to
51+
// its default value.
52+
BOOST_AUTO_TEST_CASE(NullOverride)
53+
{
54+
util::Settings settings;
55+
settings.command_line_options["name"].push_back("value");
56+
BOOST_CHECK_EQUAL(R"("value")", GetSetting(settings, "section", "name", false, false).write().c_str());
57+
settings.forced_settings["name"] = {};
58+
BOOST_CHECK_EQUAL(R"(null)", GetSetting(settings, "section", "name", false, false).write().c_str());
59+
}
60+
4861
// Test different ways settings can be merged, and verify results. This test can
4962
// be used to confirm that updates to settings code don't change behavior
5063
// unintentionally.

src/util/settings.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ SettingsValue GetSetting(const Settings& settings,
5656
bool get_chain_name)
5757
{
5858
SettingsValue result;
59+
bool done = false; // Done merging any more settings sources.
5960
MergeSettings(settings, section, name, [&](SettingsSpan span, Source source) {
6061
// Weird behavior preserved for backwards compatibility: Apply negated
6162
// setting even if non-negated setting would be ignored. A negated
@@ -79,6 +80,8 @@ SettingsValue GetSetting(const Settings& settings,
7980
// negated values, or at least warn they are ignored.
8081
const bool skip_negated_command_line = get_chain_name;
8182

83+
if (done) return;
84+
8285
// Ignore settings in default config section if requested.
8386
if (ignore_default_section_config && source == Source::CONFIG_FILE_DEFAULT_SECTION &&
8487
!never_ignore_negated_setting) {
@@ -88,13 +91,12 @@ SettingsValue GetSetting(const Settings& settings,
8891
// Skip negated command line settings.
8992
if (skip_negated_command_line && span.last_negated()) return;
9093

91-
// Stick with highest priority value, keeping result if already set.
92-
if (!result.isNull()) return;
93-
9494
if (!span.empty()) {
9595
result = reverse_precedence ? span.begin()[0] : span.end()[-1];
96+
done = true;
9697
} else if (span.last_negated()) {
9798
result = false;
99+
done = true;
98100
}
99101
});
100102
return result;
@@ -106,7 +108,7 @@ std::vector<SettingsValue> GetSettingsList(const Settings& settings,
106108
bool ignore_default_section_config)
107109
{
108110
std::vector<SettingsValue> result;
109-
bool result_complete = false;
111+
bool done = false; // Done merging any more settings sources.
110112
bool prev_negated_empty = false;
111113
MergeSettings(settings, section, name, [&](SettingsSpan span, Source source) {
112114
// Weird behavior preserved for backwards compatibility: Apply config
@@ -125,7 +127,7 @@ std::vector<SettingsValue> GetSettingsList(const Settings& settings,
125127

126128
// Add new settings to the result if isn't already complete, or if the
127129
// values are zombies.
128-
if (!result_complete || add_zombie_config_values) {
130+
if (!done || add_zombie_config_values) {
129131
for (const auto& value : span) {
130132
if (value.isArray()) {
131133
result.insert(result.end(), value.getValues().begin(), value.getValues().end());
@@ -136,8 +138,8 @@ std::vector<SettingsValue> GetSettingsList(const Settings& settings,
136138
}
137139

138140
// If a setting was negated, or if a setting was forced, set
139-
// result_complete to true to ignore any later lower priority settings.
140-
result_complete |= span.negated() > 0 || source == Source::FORCED;
141+
// done to true to ignore any later lower priority settings.
142+
done |= span.negated() > 0 || source == Source::FORCED;
141143

142144
// Update the negated and empty state used for the zombie values check.
143145
prev_negated_empty |= span.last_negated() && result.empty();

0 commit comments

Comments
 (0)