Comments (3)
You could achieve that by separating the definitions of the commands and options from the parsing control flow logic:
auto opts = (
option("-a"),
option("-b"),
option("-c")
);
auto cmds = (
command("cmd1")
| command("cmd2")
| command("cmd3")
| command("cmd4")
);
auto cli = ( (cmds, opts) | opts ); // <--
from clipp.
This would be probably good enough for me, but I cannot make it work. Here is a testing code to reproduce the behavior:
#include <iostream>
#include <string>
#include <clipp.h>
int main(int argc, char *argv[])
{
using namespace clipp;
//variables storing the parsing result; initialized with their default values
enum class mode { cmd1, cmd2, cmd3 };
mode selected = mode::cmd1;
std::string input;
int verb = 0;
auto cli_cmds = (
(command("cmd1").set(selected, mode::cmd1).doc("command 1") \
| command("find").set(selected, mode::cmd2).doc("command 2") \
| command("help").set(selected, mode::cmd3).doc("command 3")));
auto cli_opts = (
option("-i", "--input") & value("data", input) % "testing input",
(option("-v", "--verb").set(verb, 1) & opt_value("level", verb)) % "verbosity"
);
auto cli = ((cli_cmds, cli_opts) | cli_opts);
if (parse(argc, argv, cli)) {
switch (selected) {
case mode::cmd1:
case mode::cmd2:
case mode::cmd3:
std::cout << "selected: " << static_cast<int>(selected) << '\n';
std::cout << "input: " << input << '\n';
std::cout << "verb: " << verb << '\n';
}
}
else {
std::cout << usage_lines(cli, "tester") << '\n';
}
return 0;
}
If I do not give any command on the CL, the parsing fails. Changing the processing to the original idea works however:
if (parse(argc, argv, (cli_cmds, cli_opts))) {
switch (selected) {
case mode::cmd1:
case mode::cmd2:
case mode::cmd3:
std::cout << "selected: " << static_cast<int>(selected) << '\n';
std::cout << "input: " << input << '\n';
std::cout << "verb: " << verb << '\n';
}
}
else {
if (parse(argc, argv, cli_opts)) {
std::cout << "selected: " << static_cast<int>(mode::cmd1) << '\n';
std::cout << "input: " << input << '\n';
std::cout << "verb: " << verb << '\n';
}
std::cout << usage_lines(cli, "tester") << '\n';
}
return 0;
from clipp.
FWIW I accidentally figured out the situation when it works as you proposed. Here is a streamlined testcase:
int main(int argc, char *argv[])
{
using namespace clipp;
enum class mode { cmd1, cmd2 };
mode selected = mode::cmd1;
std::string name;
std::string opt1;
auto cli_cmds = (
command("cmd1").set(selected, mode::cmd1).doc("command 1")
| command("cmd2").set(selected, mode::cmd2).doc("command 2"));
auto cli_args = value("name", name) % "pos. arg. name";
auto cli_opts = (option("-o", "--option") & value("option", opt1)) % "option";
//auto cli_nocmd = (cli_args, cli_opts);
auto cli_nocmd = cli_opts;
auto cli = ((cli_cmds, cli_nocmd) | cli_nocmd);
if (parse(argc, argv, cli)) {
switch (selected) {
case mode::cmd1:
case mode::cmd2:
std::cout << "selected: " << static_cast<int>(selected) << '\n';
std::cout << "option: " << opt1 << '\n';
std::cout << "name: " << name << '\n';
}
}
else {
std::cout << "Usage:\n" << usage_lines(cli, "tester") << '\n';
}
return 0;
}
Basically the CLI definition has two parts: cli_cmds
which contains commands, and cli_nocmd
which is the rest. The rest can differ as will be explained below. Then I use:
auto cli = ((cli_cmds, cli_nocmd) | cli_nocmd);
to define the "composite" definition to also accept a command line without any command (i.e. using "default" command).
The code as presented above does not work. Running the executable without any arguments does not get parsed properly (as "no command & no option").
However if I add additional positional argument name
into "no commands" definition (currently commented out) and run the code, it starts working as expected. I.e. running it with only the positional argument gets parsed correctly.
It seems that if there is no argument on the command line and no required argument in cli_nocmd
definition the whole cli_nocmd
part gets ignored and the parsing fails.
Can it be qualified as a bug?
from clipp.
Related Issues (20)
- Problem with option_value having the same prefix as a command HOT 1
- Weird problem with order of elements in the cli spec HOT 1
- Parse failing on otherwise valid arguments HOT 1
- Repeatable required option fails to parse with one value
- Repeatable required option parses incorrectly.
- How to repeat repeatable values.
- Wide string support?
- Parse bug with option and value within command
- Included Windows.h causes std::min bug
- CMakeLists.txt is not included in the release package HOT 1
- Compiler error when compiling with MSVC & C++20 HOT 4
- Parse error for float/double with leading dot
- Case insensitive matching
- documentation formatting wrong for groups with only value options HOT 1
- Is this repo still alive? Update: yes HOT 4
- Multiple commands problem - use one_of instead of | HOT 2
- help is never sets to true and required makes all invalid
- any_other() records the wrong argument
- Is the project still maintained? HOT 2
- How to hide optional params in `usage_lines`
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 clipp.