Unverified Commit 018144ed authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #831

Fix nested categories in config options
parents cfc1e1d6 7dbb23de
...@@ -115,6 +115,19 @@ std::string config_option_set::help_text(bool global_only) const { ...@@ -115,6 +115,19 @@ std::string config_option_set::help_text(bool global_only) const {
return std::move(builder.result); return std::move(builder.result);
} }
namespace {
settings& select_entry(settings& config, string_view key){
auto sep = key.find('.');
if (sep == string_view::npos)
return config[key].as_dictionary();
auto prefix = key.substr(0, sep);
auto suffix = key.substr(sep + 1);
return select_entry(config[prefix].as_dictionary(), suffix);
}
} // namespace
auto config_option_set::parse(settings& config, argument_iterator first, auto config_option_set::parse(settings& config, argument_iterator first,
argument_iterator last) const argument_iterator last) const
-> std::pair<pec, argument_iterator> { -> std::pair<pec, argument_iterator> {
...@@ -128,8 +141,7 @@ auto config_option_set::parse(settings& config, argument_iterator first, ...@@ -128,8 +141,7 @@ auto config_option_set::parse(settings& config, argument_iterator first,
auto opt_name = opt.long_name(); auto opt_name = opt.long_name();
auto opt_ctg = opt.category(); auto opt_ctg = opt.category();
// Try inserting a new submap into the config or fill existing one. // Try inserting a new submap into the config or fill existing one.
auto& entry = opt_ctg == "global" ? config auto& entry = opt_ctg == "global" ? config : select_entry(config, opt_ctg);
: config[opt_ctg].as_dictionary();
// Flags only consume the current element. // Flags only consume the current element.
if (opt.is_flag()) { if (opt.is_flag()) {
if (arg_begin != arg_end) if (arg_begin != arg_end)
...@@ -223,17 +235,17 @@ config_option_set::parse(settings& config, ...@@ -223,17 +235,17 @@ config_option_set::parse(settings& config,
} }
config_option_set::option_pointer config_option_set::option_pointer
config_option_set::cli_long_name_lookup(string_view name) const { config_option_set::cli_long_name_lookup(string_view input) const {
// We accept "caf#" prefixes for backward compatibility, but ignore them. // We accept "caf#" prefixes for backward compatibility, but ignore them.
size_t offset = name.compare(0, 4, "caf#") != 0 ? 0u : 4u; auto name = input.substr(input.compare(0, 4, "caf#") != 0 ? 0u : 4u);
// Extract category and long name. // Extract category and long name.
string_view category; string_view category;
string_view long_name; string_view long_name;
auto sep = name.find('.', offset); auto sep = name.find_last_of('.');
if (sep == string::npos) { if (sep == string::npos) {
long_name = name.substr(offset); long_name = name;
} else { } else {
category = name.substr(offset, sep); category = name.substr(0, sep);
long_name = name.substr(sep + 1); long_name = name.substr(sep + 1);
} }
// Scan all options for a match. // Scan all options for a match.
......
...@@ -190,3 +190,12 @@ CAF_TEST(flat CLI parsing) { ...@@ -190,3 +190,12 @@ CAF_TEST(flat CLI parsing) {
CAF_CHECK_EQUAL(x.full_name(), "foo.bar"); CAF_CHECK_EQUAL(x.full_name(), "foo.bar");
CAF_CHECK_EQUAL(x.has_flat_cli_name(), true); CAF_CHECK_EQUAL(x.has_flat_cli_name(), true);
} }
CAF_TEST(flat CLI parsing with nested categories) {
auto x = make_config_option<std::string>("?foo.goo", "bar,b", "test option");
CAF_CHECK_EQUAL(x.category(), "foo.goo");
CAF_CHECK_EQUAL(x.long_name(), "bar");
CAF_CHECK_EQUAL(x.short_names(), "b");
CAF_CHECK_EQUAL(x.full_name(), "foo.goo.bar");
CAF_CHECK_EQUAL(x.has_flat_cli_name(), true);
}
...@@ -151,4 +151,13 @@ CAF_TEST(flat CLI options) { ...@@ -151,4 +151,13 @@ CAF_TEST(flat CLI options) {
CAF_CHECK_EQUAL(read<std::string>({"--foo.bar=foobar"}), "foobar"); CAF_CHECK_EQUAL(read<std::string>({"--foo.bar=foobar"}), "foobar");
} }
CAF_TEST(flat CLI parsing with nested categories) {
key = "foo.goo.bar";
opts.add<std::string>("?foo.goo", "bar,b", "some value");
CAF_CHECK(opts.begin()->has_flat_cli_name());
CAF_CHECK_EQUAL(read<std::string>({"-b", "foobar"}), "foobar");
CAF_CHECK_EQUAL(read<std::string>({"--bar=foobar"}), "foobar");
CAF_CHECK_EQUAL(read<std::string>({"--foo.goo.bar=foobar"}), "foobar");
}
CAF_TEST_FIXTURE_SCOPE_END() CAF_TEST_FIXTURE_SCOPE_END()
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