cxxopts
cxxopts copied to clipboard
short option ignores an argument
I have code (simplified):
cxxopts::Options opts("jobsrv", "Job Server");
opts.add_options()
("w,dump-data", "write data to <filename>.json", cxxopts::value<string>()->implicit_value("default_filename"), "filename")
("f,file", "file to process (e.g. /dir1/a.txt)", cxxopts::value<vector<string>>())
;
opts.parse_positional(vector<string>{ "f" });
opts.positional_help("[<file>...]");
auto cmdline = opts.parse(argc, argv);
...
if (cmdline.count("w"))
{
string job_name = cmdline["w"].as<string>();
...
... now if I run my binary like this:
<binary> --dump-job=newfile
then job_name
contains newfile
and all is dandy.
... but if I run it like this:
<binary> --dump-job newfile
or
<binary> -w newfile
then job_name
contains default_filename
(and newfile
ends up in positional arguments).
... and if I run it like this:
<binary> -w=newfile
it complains with Argument '-w=newfile' starts with a - but has incorrect syntax
.
Did I miss something when definition my options?
The reason that newfile
ends up in positional arguments is because --dump-job has an implicit parameter. There were a few issues previously with confusion about implicit parameters and assumptions about where the arguments should go, and that seemed like the clearest way to solve it.
For the short option, I think if you write -wnewfile
you will get what you want.
Hmm... What is the best way to deal with this situation? get rid of implicit parameter?
For the short option, I think if you write -wnewfile you will get what you want.
Nope, fails with same exception
Ok I remember now, you have to use the long option with =
.
OK. So it is a bug. But it has a work-around. I would like to try to fix it.
The problem is that with an implicit value, when you write --option
by itself, you get the option set with its implicit value. So the parser can't tell whether to consume the next argument as the option value or to make it a positional argument. There was a previous bug where someone was writing --option value
and expecting value
to be a positional parameter.
So, this is design-level problem -- I guess you need to provide stricter definition of implicit value
and how it gets handled in presence of positional options.
May be it makes sense to provide strict definition of command line
(BNF grammar?) and build your object model based on it? Will probably lead to significant overhaul of the library as well as usage of some parser framework (smth like Boost Spirit only without boost dependency?)
As for workaround -- it seems for me it is the best to remove implicit value. Am I right?