Commit ba142d68 authored by Dominik Charousset's avatar Dominik Charousset

Clear target variables before parsing

parent ed22184f
...@@ -638,6 +638,7 @@ public: ...@@ -638,6 +638,7 @@ public:
CAF_HAS_MEMBER_TRAIT(size); CAF_HAS_MEMBER_TRAIT(size);
CAF_HAS_MEMBER_TRAIT(data); CAF_HAS_MEMBER_TRAIT(data);
CAF_HAS_MEMBER_TRAIT(clear);
/// Checks whether F is convertible to either `std::function<void (T&)>` /// Checks whether F is convertible to either `std::function<void (T&)>`
/// or `std::function<void (const T&)>`. /// or `std::function<void (const T&)>`.
......
...@@ -52,12 +52,25 @@ config_value get_impl(const void* ptr) { ...@@ -52,12 +52,25 @@ config_value get_impl(const void* ptr) {
return config_value{trait::convert(*reinterpret_cast<const T*>(ptr))}; return config_value{trait::convert(*reinterpret_cast<const T*>(ptr))};
} }
template <class T>
typename std::enable_if<detail::has_clear_member<T>::value>::type
clear_before_parsing(T& xs) {
xs.clear();
}
template <class T>
typename std::enable_if<!detail::has_clear_member<T>::value>::type
clear_before_parsing(T&) {
// nop
}
template <class T> template <class T>
expected<config_value> parse_impl(T* ptr, string_view str) { expected<config_value> parse_impl(T* ptr, string_view str) {
if (!ptr) { if (!ptr) {
T tmp; T tmp;
return parse_impl(&tmp, str); return parse_impl(&tmp, str);
} }
clear_before_parsing(*ptr);
using trait = select_config_value_access_t<T>; using trait = select_config_value_access_t<T>;
string_parser_state ps{str.begin(), str.end()}; string_parser_state ps{str.begin(), str.end()};
trait::parse_cli(ps, *ptr, top_level_cli_parsing); trait::parse_cli(ps, *ptr, top_level_cli_parsing);
......
...@@ -170,16 +170,25 @@ CAF_TEST(flat CLI parsing with nested categories) { ...@@ -170,16 +170,25 @@ CAF_TEST(flat CLI parsing with nested categories) {
CAF_TEST(square brackets are optional on the command line) { CAF_TEST(square brackets are optional on the command line) {
using int_list = std::vector<int>; using int_list = std::vector<int>;
opts.add<int_list>("global", "bar,b", "some list"); opts.add<int_list>("global", "value,v", "some list");
CAF_CHECK_EQUAL(read<int_list>({"--bar=[1])"}), int_list({1})); CAF_CHECK_EQUAL(read<int_list>({"--value=[1]"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=[1,])"}), int_list({1})); CAF_CHECK_EQUAL(read<int_list>({"--value=[1,]"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=[ 1 , ])"}), int_list({1})); CAF_CHECK_EQUAL(read<int_list>({"--value=[ 1 , ]"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=[1,2])"}), int_list({1, 2})); CAF_CHECK_EQUAL(read<int_list>({"--value=[1,2]"}), int_list({1, 2}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=[1, 2, 3])"}), int_list({1, 2, 3})); CAF_CHECK_EQUAL(read<int_list>({"--value=[1, 2, 3]"}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=[1, 2, 3, ])"}), int_list({1, 2, 3})); CAF_CHECK_EQUAL(read<int_list>({"--value=[1, 2, 3, ]"}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=1)"}), int_list({1})); CAF_CHECK_EQUAL(read<int_list>({"--value=1"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=1,2,3)"}), int_list({1, 2, 3})); CAF_CHECK_EQUAL(read<int_list>({"--value=1,2,3"}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"--bar=1, 2 , 3 , )"}), int_list({1, 2, 3})); CAF_CHECK_EQUAL(read<int_list>({"--value=1, 2 , 3 , "}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "[1]"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "[1,]"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "[ 1 , ]"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "[1,2]"}), int_list({1, 2}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "[1, 2, 3]"}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "[1, 2, 3, ]"}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "1"}), int_list({1}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "1,2,3"}), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>({"-v", "1, 2 , 3 , "}), int_list({1, 2, 3}));
} }
#define SUBTEST(msg) \ #define SUBTEST(msg) \
...@@ -200,7 +209,7 @@ CAF_TEST(CLI arguments override defaults) { ...@@ -200,7 +209,7 @@ CAF_TEST(CLI arguments override defaults) {
ints = int_list{1, 2, 3}; ints = int_list{1, 2, 3};
cfg["bar"] = config_value{ints}; cfg["bar"] = config_value{ints};
CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({1, 2, 3})); CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>(cfg, {"--bar=[10, 20, 30])"}), none); CAF_CHECK_EQUAL(read<int_list>(cfg, {"--bar=[10, 20, 30]"}), none);
CAF_CHECK_EQUAL(ints, int_list({10, 20, 30})); CAF_CHECK_EQUAL(ints, int_list({10, 20, 30}));
CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({10, 20, 30})); CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({10, 20, 30}));
CAF_MESSAGE("test string lists"); CAF_MESSAGE("test string lists");
...@@ -208,7 +217,7 @@ CAF_TEST(CLI arguments override defaults) { ...@@ -208,7 +217,7 @@ CAF_TEST(CLI arguments override defaults) {
cfg["foo"] = config_value{strings}; cfg["foo"] = config_value{strings};
CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"), CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"),
string_list({"one", "two", "three"})); string_list({"one", "two", "three"}));
CAF_CHECK_EQUAL(read<string_list>(cfg, {"--foo=[hello, world])"}), none); CAF_CHECK_EQUAL(read<string_list>(cfg, {"--foo=[hello, world]"}), none);
CAF_CHECK_EQUAL(strings, string_list({"hello", "world"})); CAF_CHECK_EQUAL(strings, string_list({"hello", "world"}));
CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"), CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"),
string_list({"hello", "world"})); string_list({"hello", "world"}));
...@@ -221,13 +230,13 @@ CAF_TEST(CLI arguments override defaults) { ...@@ -221,13 +230,13 @@ CAF_TEST(CLI arguments override defaults) {
CAF_MESSAGE("test integer lists"); CAF_MESSAGE("test integer lists");
cfg["bar"] = config_value{int_list{1, 2, 3}}; cfg["bar"] = config_value{int_list{1, 2, 3}};
CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({1, 2, 3})); CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({1, 2, 3}));
CAF_CHECK_EQUAL(read<int_list>(cfg, {"--bar=[10, 20, 30])"}), none); CAF_CHECK_EQUAL(read<int_list>(cfg, {"--bar=[10, 20, 30]"}), none);
CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({10, 20, 30})); CAF_CHECK_EQUAL(get<int_list>(cfg, "bar"), int_list({10, 20, 30}));
CAF_MESSAGE("test string lists"); CAF_MESSAGE("test string lists");
cfg["foo"] = config_value{string_list{"one", "two", "three"}}; cfg["foo"] = config_value{string_list{"one", "two", "three"}};
CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"), CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"),
string_list({"one", "two", "three"})); string_list({"one", "two", "three"}));
CAF_CHECK_EQUAL(read<string_list>(cfg, {"--foo=[hello, world])"}), none); CAF_CHECK_EQUAL(read<string_list>(cfg, {"--foo=[hello, world]"}), none);
CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"), CAF_CHECK_EQUAL(get<string_list>(cfg, "foo"),
string_list({"hello", "world"})); string_list({"hello", "world"}));
} }
......
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