Commit d8a529ea authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'topic/config-parsing'

parents abcf0df4 26a7221c
......@@ -209,7 +209,7 @@ private:
config_option_set& options_;
settings& cfg_;
std::string current_key;
std::string current_key_;
std::vector<error> warnings_;
};
......
......@@ -266,7 +266,7 @@ void read_ini(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
transition(init, " \t\n")
fsm_epsilon(read_ini_comment(ps, consumer), init, ';')
transition(start_section, '[')
fsm_epsilon_if(tmp == "global", read_ini_section(ps, begin_section()), init)
fsm_epsilon_if(tmp == "global", read_ini_section(ps, begin_section()), return_to_global)
}
// Read the section key after reading an '['.
state(start_section) {
......@@ -281,7 +281,10 @@ void read_ini(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
// Wait for the closing ']', preceded by any number of whitespaces.
state(close_section) {
transition(close_section, " \t")
fsm_transition(read_ini_section(ps, begin_section()), init, ']')
fsm_transition(read_ini_section(ps, begin_section()), return_to_global, ']')
}
unstable_state(return_to_global) {
epsilon(init, any_char, tmp = "global")
}
fin();
}
......
......@@ -310,7 +310,13 @@ actor_system_config& actor_system_config::set_impl(string_view name,
return set_impl("middleman.app-identifiers", std::move(value));
}
auto opt = custom_options_.qualified_name_lookup(name);
if (opt != nullptr && opt->check(value) == none) {
if (opt == nullptr) {
std::cerr << "*** failed to set config parameter " << name
<< ": invalid name" << std::endl;
} else if (auto err = opt->check(value)) {
std::cerr << "*** failed to set config parameter " << name << ": "
<< to_string(err) << std::endl;
} else {
opt->store(value);
auto category = opt->category();
auto& dict = category == "global" ? content
......
......@@ -42,7 +42,6 @@ ini_list_consumer abstract_ini_consumer::begin_list() {
return {this};
}
// -- map_consumer -------------------------------------------------------------
ini_map_consumer::ini_map_consumer(abstract_ini_consumer* parent)
......@@ -156,23 +155,28 @@ ini_consumer* ini_category_consumer::dparent() {
ini_consumer::ini_consumer(config_option_set& options, settings& cfg)
: options_(options),
cfg_(cfg),
current_key("global") {
current_key_("global") {
// nop
}
ini_category_consumer ini_consumer::begin_map() {
return {this, current_key};
return {this, current_key_};
}
void ini_consumer::key(std::string name) {
current_key = std::move(name);
current_key_ = std::move(name);
}
void ini_consumer::value_impl(config_value&& x) {
using dict_type = config_value::dictionary;
auto dict = get_if<dict_type>(&x);
if (current_key != "global") {
auto& dst = cfg_.emplace(current_key, dict_type{}).first->second;
if (dict == nullptr) {
warnings_.emplace_back(make_error(pec::type_mismatch,
"expected a dictionary at top level"));
return;
}
if (current_key_ != "global") {
auto& dst = cfg_.emplace(current_key_, dict_type{}).first->second;
if (dict != nullptr && !dict->empty() && holds_alternative<dict_type>(dst)) {
auto& dst_dict = get<dict_type>(dst);
// We need to "merge" values into the destination, because it can already
......@@ -181,9 +185,19 @@ void ini_consumer::value_impl(config_value&& x) {
dst_dict.insert_or_assign(entry.first, std::move(entry.second));
}
} else {
for (auto& entry : *dict)
std::string prev_key;
swap(current_key_, prev_key);
for (auto& entry : *dict) {
if (holds_alternative<dict_type>(entry.second)) {
// Recurse into top-level maps.
current_key_ = std::move(entry.first);
value_impl(std::move(entry.second));
} else {
cfg_.insert_or_assign(entry.first, std::move(entry.second));
}
}
swap(prev_key, current_key_);
}
}
} // namespace detail
......
......@@ -46,15 +46,15 @@ impl = 'foo';some atom
const char test_ini2[] = R"(
is_server = true
port = 4242
nodes = ["sun", "venus"]
logger = {
file-name = "foobar.ini"
}
port = 4242
scheduler = {
timing = 2us,
impl = 'foo'
}
nodes = ["sun", "venus"]
)";
struct fixture {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment