1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-04-29 12:13:52 +00:00

Add support for delimiter when parsing vector (#209)

This commit allows parsing any char separated list given by the user.
E.g app -a 1,2,3
std::vector<int> params;
app.add_option("-a", params, "Parse the params", ',');

Signed-off-by: Rafi Wiener <rafiw@mellanox.com>

add tests for delimiter parsing

Signed-off-by: Rafi Wiener <rafiw@mellanox.com>

Fixing style, adding docker version of clang-format
This commit is contained in:
Rafi Wiener 2019-02-06 16:15:31 +02:00 committed by Henry Schreiner
parent 598046c397
commit 048f968504
3 changed files with 123 additions and 9 deletions

View File

@ -417,14 +417,19 @@ class App {
template <typename T> template <typename T>
Option *add_option(std::string option_name, Option *add_option(std::string option_name,
std::vector<T> &variable, ///< The variable vector to set std::vector<T> &variable, ///< The variable vector to set
std::string description = "") { std::string description = "",
char delimiter = ' ') {
CLI::callback_t fun = [&variable](CLI::results_t res) { CLI::callback_t fun = [&variable, delimiter](CLI::results_t res) {
bool retval = true; bool retval = true;
variable.clear(); variable.clear();
for(const auto &a : res) { for(const auto &elem : res) {
variable.emplace_back(); for(const auto &var : CLI::detail::split(elem, delimiter)) {
retval &= detail::lexical_cast(a, variable.back()); if(!var.empty()) {
variable.emplace_back();
retval &= detail::lexical_cast(var, variable.back());
}
}
} }
return (!variable.empty()) && retval; return (!variable.empty()) && retval;
}; };
@ -439,14 +444,19 @@ class App {
Option *add_option(std::string option_name, Option *add_option(std::string option_name,
std::vector<T> &variable, ///< The variable vector to set std::vector<T> &variable, ///< The variable vector to set
std::string description, std::string description,
bool defaulted) { bool defaulted,
char delimiter = ' ') {
CLI::callback_t fun = [&variable](CLI::results_t res) { CLI::callback_t fun = [&variable, delimiter](CLI::results_t res) {
bool retval = true; bool retval = true;
variable.clear(); variable.clear();
for(const auto &a : res) { for(const auto &a : res) {
variable.emplace_back(); for(const auto &var : CLI::detail::split(a, delimiter)) {
retval &= detail::lexical_cast(a, variable.back()); if(!var.empty()) {
variable.emplace_back();
retval &= detail::lexical_cast(var, variable.back());
}
}
} }
return (!variable.empty()) && retval; return (!variable.empty()) && retval;
}; };

13
scripts/check_style_docker.sh Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env sh
# Also good but untagged: CLANG_FORMAT=unibeautify/clang-format
CLANG_FORMAT=saschpe/clang-format:5.0.1
set -evx
docker run -it ${CLANG_FORMAT} --version
docker run -it -v "$(pwd)":/workdir -w /workdir ${CLANG_FORMAT} -style=file -sort-includes -i $(git ls-files -- '*.cpp' '*.hpp')
git diff --exit-code --color
set +evx

View File

@ -1961,3 +1961,94 @@ TEST_F(TApp, BeforeRequirements) {
// args = {"-b", "-a", "extra"}; // args = {"-b", "-a", "extra"};
// EXPECT_THROW(run(), CLI::CallForHelp); // EXPECT_THROW(run(), CLI::CallForHelp);
} }
// #209
TEST_F(TApp, CustomUserSepParse) {
std::vector<int> vals = {1, 2, 3};
args = {"--idx", "1,2,3"};
auto opt = app.add_option("--idx", vals, "", ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2, 3}));
app.remove_option(opt);
app.add_option("--idx", vals, "", true, ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2, 3}));
}
// #209
TEST_F(TApp, DefaultUserSepParse) {
std::vector<int> vals = {1, 2, 3};
args = {"--idx", "1 2 3"};
auto opt = app.add_option("--idx", vals, "");
run();
EXPECT_EQ(vals, std::vector<int>({1, 2, 3}));
app.remove_option(opt);
app.add_option("--idx", vals, "", true);
run();
EXPECT_EQ(vals, std::vector<int>({1, 2, 3}));
}
// #209
TEST_F(TApp, BadUserSepParse) {
std::vector<int> vals;
app.add_option("--idx", vals, "");
args = {"--idx", "1,2,3"};
EXPECT_THROW(run(), CLI::ConversionError);
}
// #209
TEST_F(TApp, CustomUserSepParse2) {
std::vector<int> vals = {1, 2, 3};
args = {"--idx", "1,2,"};
auto opt = app.add_option("--idx", vals, "", ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2}));
app.remove_option(opt);
app.add_option("--idx", vals, "", true, ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2}));
}
// #209
TEST_F(TApp, CustomUserSepParse3) {
std::vector<int> vals = {1, 2, 3};
args = {"--idx",
"1",
","
"2"};
auto opt = app.add_option("--idx", vals, "", ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2}));
app.remove_option(opt);
app.add_option("--idx", vals, "", false, ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2}));
}
// #209
TEST_F(TApp, CustomUserSepParse4) {
std::vector<int> vals;
args = {"--idx", "1, 2"};
auto opt = app.add_option("--idx", vals, "", ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2}));
app.remove_option(opt);
app.add_option("--idx", vals, "", true, ',');
run();
EXPECT_EQ(vals, std::vector<int>({1, 2}));
}