Comments (2)
Yes, but you'd need a custom validator for the options, because normal validating groups wouldn't work in this case (because --open or --close can both be omitted, meaning they'd pass validation if neither was specified, but if --now is specified, exactly one of them is required. Doing this with nested groups would make the validation of one group need to change based on the state of the other, which isn't possible out of the box with the current design). And because of the way that the group validation is implemented, you'd have to unfortunately rely on the order of the group's children to cleanly identify what is being done (because the validator is moved into the group, and must be specified before the flags are, so you couldn't have the validator as a function object that maintains a reference to its flags without some terrible hackery like placement new). Here's a functioning example:
#include <iostream>
#include "args.hxx"
bool OpenCloseNowValidator(const args::Group &group) {
const args::Base *now = group.Children()[0];
const args::Base *open = group.Children()[1];
const args::Base *close = group.Children()[2];
if (open->Matched() && close->Matched()) {
return false;
}
if (now->Matched() && !(open->Matched() || close->Matched())) {
return false;
}
return true;
}
int main(int argc, char **argv)
{
args::ArgumentParser parser("This is a test program.");
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
args::Group nowgroup(parser, "", OpenCloseNowValidator);
args::Flag now(nowgroup, "now", "The now flag, needs --open or --close", {'n', "now"});
args::Flag open(nowgroup, "open", "The open flag, mutually exclusive with --close", {'o', "open"});
args::Flag close(nowgroup, "close", "The close flag, mutually exclusive with --open", {'c', "close"});
try {
parser.ParseCLI(argc, argv);
}
catch (const args::ValidationError &e)
{
std::cerr << "Illegal options specified!" << std::endl;
return 1;
}
catch (const args::Help&)
{
std::cout << parser;
return 0;
}
catch (const args::ParseError& e)
{
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}
And it in action:
$ ./test -h
./test {OPTIONS}
This is a test program.
OPTIONS:
-h, --help Display this help menu
-n, --now The now flag, needs --open or --close
-o, --open The open flag, mutually exclusive with
--close
-c, --close The close flag, mutually exclusive with
--open
$ ./test -o
$ ./test -c
$ ./test -on
$ ./test -cn
$ ./test -oc
Illegal options specified!
$ ./test -n
Illegal options specified!
$ ./test -noc
Illegal options specified!
Unfortunately, the current API makes it impossible to give good messages with validation, either with the custom validators or with the inbuilt ones. In a future major release, this may be reeled back so that validators don't just return true or false, but actually throw exceptions when failing validation, and group nesting will probably be made illegal, requiring that any complex validation demands that the end programmer implement it themselves, if I get back into major feature development of this library sufficient enough to make a major release like that. I'd have to also consider a way for group validation to better access its children, as order-dependent validation in this case presents a painful case for code management, as reordering variables could easily break validation.
Anyway, I hope this is sufficient enough for your use.
from args.
In case someone needs this, one solution can be to treat the boolean return values of the arguments like integers and add them up together:
args::Flag arg_myarg1(/* ... */);
args::Flag arg_myarg2(/* ... */);
args::Flag arg_myarg3(/* ... */);
/* ... */
if (arg_myarg1 + arg_myarg2 + arg_myarg3 /* ... */ > 1) {
// error
}
from args.
Related Issues (20)
- Doesn't save error messages properly when built with `ARGS_NOEXCEPT` HOT 6
- pkg-config file is broken when CMAKE_INSTALL_{INCLUDE,LIB}DIR is absolute HOT 1
- find_package(args REQUIRED) doesn't set args_VERSION HOT 3
- [6.4.3 regression] Installs pkgconfig into the root HOT 3
- Regression: Help string lists `{OPTIONS}` after positional arguments HOT 4
- Detect console/terminal width HOT 2
- 6.4.5: Tests fail HOT 1
- configure of a client project fails: An argument named "TRUE" appears in a conditional statement. HOT 1
- cmake doesn't define args_INCLUDE_DIRS HOT 2
- How to parse keyword-based arguments? HOT 1
- Supplying the same argument twice doesn't cause error HOT 1
- Missing argument doesn't throw exception HOT 1
- Add macros to get version HOT 1
- From where did you obtained catch.hpp HOT 2
- Cannot pass negative values to NargsValueFlag<double> HOT 3
- short options not parsed when longprefix is empty HOT 2
- -v flag seems to trigger an args::Help exception HOT 5
- Tag 2.6.4 has PATCH = 3 in args.hxx HOT 1
- use dd-style fail to get '\' in linux HOT 3
- Parse arguments from single string. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from args.