CLI11
CLI11 copied to clipboard
Cannot choose group based on flag
#include <CLI/CLI.hpp>
int main(int argc, char **argv) {
CLI::App app{"App"};
int a, b;
bool other;
auto ogroup_a = app.add_option_group("a_group", "do a");
ogroup_a->add_option("a", a, "option a")->required();
auto ogroup_b = app.add_option_group("b_group", "do other");
ogroup_b->add_option("-o", other, "do other thing")->required();
ogroup_b->add_option("b", b, "option b")->required();
app.require_option(1);
CLI11_PARSE(app, argc, argv);
}
I want to be able to run either this:
a.out 1
or this:
a.out -o 2
But if I try to run the second one I get
b is required
Run with --help for more information.
#include <CLI/CLI.hpp>
int main(int argc, char **argv) {
CLI::App app{"App"};
int a, b;
auto ogroup = app.add_option_group("subgroup", "do a");
ogroup->add_option("a", a, "option a");
ogroup->add_option("-o", b, "do other thing");
ogroup->require_option(1,1); // specify exactly one option from the group must be selected
CLI11_PARSE(app, argc, argv);
}
I think this will do what you want
The way you had it before was just grouping so both were required as if they were members of the app directly.
That doesn't do the same thing. I realize I made a mistake in the example. It should have been
#include <CLI/CLI.hpp>
int main(int argc, char **argv) {
CLI::App app{"App"};
int a, b;
bool other;
auto ogroup_a = app.add_option_group("a_group", "do a");
ogroup_a->add_option("a", a, "option a")->required();
auto ogroup_b = app.add_option_group("b_group", "do other");
ogroup_b->add_flag("-o", other, "do other thing")->required();
ogroup_b->add_option("b", b, "option b")->required();
app.require_option(1);
CLI11_PARSE(app, argc, argv);
}
And the error is:
> ./a.out -o 2
Exactly 1 option from [,[Option Group: a_group],[Option Group: b_group]] is required and 2 were given
Run with --help for more information.
Ok so
int main(int argc, const char *argv[]) {
CLI::App app{"App"};
int a{0}, b{0};
bool other{false};
auto ogroup_a = app.add_option_group("a_group", "do a");
ogroup_a->enabled_by_default();
ogroup_a->add_option("a", a, "option a")->required();
auto triggerGroup = app.add_option_group("trigger", "trigger for group b");
auto oflag = triggerGroup->add_flag("-o", other, "do other thing");
auto ogroup_b = app.add_option_group("b_group", "do other");
ogroup_b->add_option("b", b, "option b")->required();
ogroup_b->disabled_by_default();
triggerGroup->preparse_callback([ogroup_a, ogroup_b](std::size_t) {
ogroup_b->disabled(false);
ogroup_a->disabled();
});
CLI11_PARSE(app, argc, argv);
if(other) {
std::cout << "selected other b=" << b << std::endl;
} else {
std::cout << "selected a =" << a << std::endl;
}
}
will produce
> ./a.out -o 2
selected other b=2
> ./a.out 1
selected a =1
if you want to disallow something like
> ./a.out 1 -o 2
selected other b=2
Then you need to add this line
ogroup_a->preparse_callback([triggerGroup](std::size_t) {
triggerGroup->disabled();
});
Then
> ./a.out 1 -o 2
The following arguments were not expected: 2 -o
Run with --help for more information.