Commit d8a529ea authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'topic/config-parsing'

parents abcf0df4 26a7221c
...@@ -209,7 +209,7 @@ private: ...@@ -209,7 +209,7 @@ private:
config_option_set& options_; config_option_set& options_;
settings& cfg_; settings& cfg_;
std::string current_key; std::string current_key_;
std::vector<error> warnings_; std::vector<error> warnings_;
}; };
......
...@@ -266,7 +266,7 @@ void read_ini(state<Iterator, Sentinel>& ps, Consumer&& consumer) { ...@@ -266,7 +266,7 @@ void read_ini(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
transition(init, " \t\n") transition(init, " \t\n")
fsm_epsilon(read_ini_comment(ps, consumer), init, ';') fsm_epsilon(read_ini_comment(ps, consumer), init, ';')
transition(start_section, '[') 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 '['. // Read the section key after reading an '['.
state(start_section) { state(start_section) {
...@@ -281,7 +281,10 @@ void read_ini(state<Iterator, Sentinel>& ps, Consumer&& consumer) { ...@@ -281,7 +281,10 @@ void read_ini(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
// Wait for the closing ']', preceded by any number of whitespaces. // Wait for the closing ']', preceded by any number of whitespaces.
state(close_section) { state(close_section) {
transition(close_section, " \t") 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(); fin();
} }
......
...@@ -310,7 +310,13 @@ actor_system_config& actor_system_config::set_impl(string_view name, ...@@ -310,7 +310,13 @@ actor_system_config& actor_system_config::set_impl(string_view name,
return set_impl("middleman.app-identifiers", std::move(value)); return set_impl("middleman.app-identifiers", std::move(value));
} }
auto opt = custom_options_.qualified_name_lookup(name); 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); opt->store(value);
auto category = opt->category(); auto category = opt->category();
auto& dict = category == "global" ? content auto& dict = category == "global" ? content
......
...@@ -42,7 +42,6 @@ ini_list_consumer abstract_ini_consumer::begin_list() { ...@@ -42,7 +42,6 @@ ini_list_consumer abstract_ini_consumer::begin_list() {
return {this}; return {this};
} }
// -- map_consumer ------------------------------------------------------------- // -- map_consumer -------------------------------------------------------------
ini_map_consumer::ini_map_consumer(abstract_ini_consumer* parent) ini_map_consumer::ini_map_consumer(abstract_ini_consumer* parent)
...@@ -156,23 +155,28 @@ ini_consumer* ini_category_consumer::dparent() { ...@@ -156,23 +155,28 @@ ini_consumer* ini_category_consumer::dparent() {
ini_consumer::ini_consumer(config_option_set& options, settings& cfg) ini_consumer::ini_consumer(config_option_set& options, settings& cfg)
: options_(options), : options_(options),
cfg_(cfg), cfg_(cfg),
current_key("global") { current_key_("global") {
// nop // nop
} }
ini_category_consumer ini_consumer::begin_map() { ini_category_consumer ini_consumer::begin_map() {
return {this, current_key}; return {this, current_key_};
} }
void ini_consumer::key(std::string name) { 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) { void ini_consumer::value_impl(config_value&& x) {
using dict_type = config_value::dictionary; using dict_type = config_value::dictionary;
auto dict = get_if<dict_type>(&x); auto dict = get_if<dict_type>(&x);
if (current_key != "global") { if (dict == nullptr) {
auto& dst = cfg_.emplace(current_key, dict_type{}).first->second; 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)) { if (dict != nullptr && !dict->empty() && holds_alternative<dict_type>(dst)) {
auto& dst_dict = get<dict_type>(dst); auto& dst_dict = get<dict_type>(dst);
// We need to "merge" values into the destination, because it can already // We need to "merge" values into the destination, because it can already
...@@ -181,8 +185,18 @@ void ini_consumer::value_impl(config_value&& x) { ...@@ -181,8 +185,18 @@ void ini_consumer::value_impl(config_value&& x) {
dst_dict.insert_or_assign(entry.first, std::move(entry.second)); dst_dict.insert_or_assign(entry.first, std::move(entry.second));
} }
} else { } else {
for (auto& entry : *dict) std::string prev_key;
cfg_.insert_or_assign(entry.first, std::move(entry.second)); 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_);
} }
} }
......
...@@ -46,15 +46,15 @@ impl = 'foo';some atom ...@@ -46,15 +46,15 @@ impl = 'foo';some atom
const char test_ini2[] = R"( const char test_ini2[] = R"(
is_server = true is_server = true
port = 4242
nodes = ["sun", "venus"]
logger = { logger = {
file-name = "foobar.ini" file-name = "foobar.ini"
} }
port = 4242
scheduler = { scheduler = {
timing = 2us, timing = 2us,
impl = 'foo' impl = 'foo'
} }
nodes = ["sun", "venus"]
)"; )";
struct fixture { 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