-
Notifications
You must be signed in to change notification settings - Fork 67
A simple working demo? #49
Comments
This is what I have done for a first check: bool showHelp = true;
int width = 0;
std::string name;
bool doIt = false;
std::string command;
int main ( int argc, char** argv )
{
auto cli = clara::detail::Help(showHelp)
| clara::detail::Opt( width, "width" )["-w"]["--width"]("How wide should it be?")
| clara::detail::Opt( name, "name" )["-n"]["--name"]("By what name should I be known")
| clara::detail::Opt( doIt )["-d"]["--doit"]("Do the thing" )
| clara::detail::Arg( command, "command" )("which command to run").required();
auto result = cli.parse( clara::detail::Args( argc, argv ) );
if( !result )
{
std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
exit(1);
}
std::cerr << "Show Help:" << showHelp << std::endl;
std::cerr << "Width:" << width << std::endl;
std::cerr << "Name:" << name << std::endl;
std::cerr << "Doit:" << doIt << std::endl;
std::cerr << "Command:" << command << std::endl;
if ( showHelp )
std::cerr << cli << std::endl;
return 0;
} |
Can we verify if a parameter was provided or not? Except that if they have a default value or not? |
I tried this example and it seems to compile for me - I was wondering what I need to do pass the arguments to Catch ? |
@hassanfarid Sorry for the long delay, but I hadn't time to reply. I'm not the developer of Clara and I have no idea how to check this. My first thought was an invalid default value too. @abishekh I'm afraid I don't understand your question. The arguments passed to |
@hassanfarid if you bind to an optional variable ( |
@philsquared with I thought he want to have something like a "callback" (lamda) for the case the variable is written (not only changed) by Clara. But I'm not sure. ;-) ...IMO a very special requirement. |
@joede I'm afraid I'm not quite following. The only thing I can think of that you might mean here is that you want to be able to distinguish between values that were set to |
First of all, I am not the original poster of this question. This was only my interpretation of the problem. ;-) So we must wait until @hassanfarid clarifies the problem. int with = 100; // (1) the default value
std::optional<int> height = {}; // (2) without default
...
auto result = cli.parse( clara::detail::Args( argc, argv ) );
// variant (1)
if ( width != 100 )
// has been changed
// variant (2)
if ( height )
// has been changed
else
height = 50; // we must set the (useable) default value If you have a lot of parameters, the list of Update: just a fast thought. I don't know a use case for that, but a solution could be to allow to pass lambda's instead of variables to |
Sorry, it sounds obvious, now that that's what you meant :-) So you want to be able to specify a ("usable") default value in case it's not set on the CL, but also be able to tell, after the fact, if it was actually set on the CL? (and by "you" I mean @hassanfarid)? First, it might be worth pointing out that, rather than the height.value_or(50); Which is slightly less verbose, but I can understand is still not quite what is wanted. You want that default value to be set at, or close to, the original declaration. In which case I can only think of two ways - both of which are in user code (although, arguably, at least one could have out-of-the-box support to give you a leg up):
(*) to use a non- HTH |
WRT your update (which crossed with my last reply) - if I understand you correctly, you can "pass lambda's instead of variables to Opt()". e.g.: https://github.com/catchorg/Clara/blob/master/src/ClaraTests.cpp#L166 |
@philsquared thanks for your replies. Your reference to the test passing a lamba is interesting. I feared Clara couldn't determine a data type, so the lamba must convert the string parameter to the option itself. But i seems the parameter of the lamba is used in this case. Am I right? In this case I could update my example. Just to memorize it myself. ;-) |
That is correct (here's the code that deduces it): https://github.com/catchorg/Clara/blob/master/single_include/clara.hpp#L377 I appreciate this area of Clara is not really documented yet. |
OK, just to have it complete. Here is an updated example. Feel free to move it into a wiki page or so. // Small example of how to use Clara
//
// Save this snippet as `clara-sample.cpp` together with the simgle-header
// verion of Clara and call `g++` as shown below.
//
// g++ -Wall -std=c++11 -o clara-sample clara-sample.cpp
#include <string>
#include <iostream>
#include "clara.hpp"
// dont show the help by default. Use `-h or `-?` to enable it.
//
bool showHelp = false;
// this block of variables are changed by Clara with the corresponding options passed
// to the program.
//
int width = 0;
std::string name;
bool doIt = false;
std::string command;
// This is a special value which is set indirectly by an lamba function!
//
int index = 0;
int main ( int argc, char** argv )
{
auto cli = clara::detail::Help(showHelp)
| clara::detail::Opt( width, "width" )["-w"]["--width"]("How wide should it be?")
| clara::detail::Opt( name, "name" )["-n"]["--name"]("By what name should I be known")
| clara::detail::Opt( doIt )["-d"]["--doit"]("Do the thing" )
| clara::detail::Opt( [&]( int i )
{
if (i < 0 || i > 10)
return clara::detail::ParserResult::runtimeError("index must be between 0 and 10");
else {
index = i;
return clara::detail::ParserResult::ok( clara::detail::ParseResultType::Matched );
}
}, "index" )
["-i"]( "An index, which is an integer between 0 and 10, inclusive" )
| clara::detail::Arg( command, "command" )("which command to run").required();
auto result = cli.parse( clara::detail::Args( argc, argv ) );
if( !result )
{
std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
return 1;
}
if ( showHelp )
{
std::cerr << cli << std::endl;
return 0;
}
// show the results!
std::cerr << "Show Help:" << showHelp << std::endl;
std::cerr << "Index:" << index << std::endl;
std::cerr << "Width:" << width << std::endl;
std::cerr << "Name:" << name << std::endl;
std::cerr << "Doit:" << doIt << std::endl;
std::cerr << "Command:" << command << std::endl;
return 0;
} Thanks for your reference, but that is much more "modern C++" than I currently working with. ;-) I'm a long time "embedded C" coder and most C++ code I write is limited to GUI's written in FLTK or Qt5. But I'm currently look at it. Type traits and |
What is |
It tell's the parser that this option is "required". This means, the option must be passed to the application. |
Since this issue is currently a kind of only documentation, I report here my solution to parse an option that can be optional: #include "clara.hpp"
#include <cstdlib>
#include <iostream>
#include <optional>
using namespace clara;
struct Config
{
bool help = false;
bool gui = false;
std::optional<size_t> seed;
};
int main(int argc, char* argv[])
{
Config config;
// Create the command line parser
auto cli = Help(config.help)
| Opt(config.gui)["-g"]["--gui"]("open the gui")
| Opt([&](unsigned value) { config.seed = value; }, "seed")["-s"]["--seed"](
"use a specific seed for randomness");
// Parse the command line
if (auto result = cli.parse(Args(argc, argv)); !result) {
std::cout << "Error in command line: " << result.errorMessage() << std::endl;
exit(EXIT_FAILURE);
}
if (config.help) {
std::cout << cli;
exit(EXIT_SUCCESS);
}
// Initialize the seed
if (config.seed) {
// Use the seed
// ...
}
It requires C++17. |
Hello, is there a simple working demo here? With just include "clara.hpp", and a main function.
The text was updated successfully, but these errors were encountered: