Opened 15 years ago
Closed 12 years ago
#1132 closed Bugs (fixed)
zero_tokens doesn't work
Reported by: | Owned by: | Vladimir Prus | |
---|---|---|---|
Milestone: | Boost 1.36.0 | Component: | program_options |
Version: | Boost 1.34.1 | Severity: | Problem |
Keywords: | Cc: | bgreen@… |
Description
In the documentation for program_options, under the "Library Overview"/"Syntactic Information", the documentation appears to be incorrect.
For the following option description:
("verbose", value<string>()->zero_tokens(), "verbosity level")
It states that:
"the user may either provide a single token for the value, or no token at all."
I wrote a test program based on the options given in this section of the manual, and I get different behavior for the 'verbose' option. In fact, the actual behavior is almost intuitive: the option is unusable. No matter what you do, its an error. Seems natural since you're saying the option has a value associated with it, yet no tokens may be given to specify the value.
It also turns out that 'multitoken()' does not allow you to pass multiple tokens, but it does raise an exception if you specify anything after the first value, i.e.:
./a.out --email blah@blah me@somewhere exception: in option 'email': multiple values not allowed ./a.out --email blah@blah --help exception: in option 'email': multiple values not allowed
Here's my test program:
#include <boost/program_options.hpp> #include <string> #include <iostream> using namespace boost::program_options; using namespace std; int main(int argc,char *argv[]) { options_description desc; desc.add_options() ("help", "produce help message") ("compression", value<string>(), "compression level") ("verbose", value<string>()->zero_tokens(), "verbosity level") ("email", value<string>()->multitoken(), "email to send to") ; variables_map vm; try { store(parse_command_line(argc, argv, desc), vm); notify(vm); } catch (exception &e) { cout << "exception: " << e.what() << endl; return -1; } if (vm.count("help")) cout << desc << endl; if (vm.count("compression")) cout << "compression " << vm["compression"].as<string>() << endl; if (vm.count("verbose")) cout << "verbose " << vm["verbose"].as<string>() << endl; if (vm.count("email")) cout << "email " << vm["email"].as<string>() << endl; return 0; }
Change History (12)
comment:1 by , 15 years ago
follow-up: 3 comment:2 by , 15 years ago
For the record, using words like "mess" is not likely to get any fix sooner :-P
comment:3 by , 15 years ago
Replying to vladimir_prus:
For the record, using words like "mess" is not likely to get any fix sooner :-P
Don't mind, "mess" wasn't related to your work (which is excellent), but related to the situation ;-) But, do you know what's going wrong with zero_tokens() and multitokens()?
comment:4 by , 15 years ago
Type: | Support Requests → Bugs |
---|
comment:5 by , 14 years ago
Milestone: | To Be Determined → Boost 1.36.0 |
---|---|
Summary: | program_options documentation error. → zero_tokens clarification |
comment:6 by , 14 years ago
The bug (at least for zero_tokens) is still there - verified with 1.34 and 1.37.
comment:7 by , 14 years ago
Summary: | zero_tokens clarification → zero_tokens doesn't work |
---|
The simplest program to test with:
#include <boost/program_options.hpp> #include <iostream> #include <string> using namespace std; namespace po = boost::program_options; int main(int argc, char *argv[]) {
po::options_description desc("test"); desc.add_options()
("server", po::value<std::string>()->zero_tokens());
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
}
comment:8 by , 13 years ago
The problem with multitoken is still there in Boost 1.40 :-(
./a.out --email blah@blah me@somewhere exception: in option 'email': multiple values not allowed
I could use value<vector<string> >(), but this implies that the option can occur more than one time on command line which I don't want allow in my case.
zero_token() also broken, I always get:
exception: in option 'verbose': at least one value required
comment:9 by , 13 years ago
I looked a bit deeper to the zero_token() issue. I found out that there is implicit_value(...) function which can be used for this feature. If an option occurs without any further tokens and this option is allowed to stay without any arguments, then this implicit value is assign:
options_description desc; desc.add_options() ("verbose", value< int >()->implicit_value(1), "verbosity level") ;
Anyhow documentation has to be updated and maybe the zero_tokens() function needs to be removed. The multitoken() issue is still open.
Please comment. Thanks.
comment:10 by , 13 years ago
Another way how zero_tokens is used to good effect is the 'bool_switch' function:
BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>* bool_switch(bool* v) {
typed_value<bool>* r = new typed_value<bool>(v); r->default_value(0); r->zero_tokens();
return r;
}
This, together with validator for the bool types, allows to make --whatever be interpreted as 'true' value for 'whatever' option. Note this code:
BOOST_PROGRAM_OPTIONS_DECL void validate(any& v, const vector<string>& xs,
bool*, int)
{
check_first_occurrence(v); string s(get_single_string(xs, true));
The 'true' passed to 'get_single_string' means that if there are no tokens, the empty string should be returned -- which is then interpreted as true value.
Therefore, 'zero_tokens' makes sense exclusively when the validator for the type handles empty string or 'implied_value' is also specified. Seems like purely documentation bug to me, then.
comment:11 by , 12 years ago
I ran into this problem when reading the documentation for 1.45.0 and trying to compile/run the example code.
The resolution appears to be:
desc.add_options()
("help", "produce help message")
("compression", value<string>(), "compression level")
("verbose", value<string>()->implicit_value("0"), "verbosity level")
("email", value<vector<string>>()->multitoken(), "email to send to")
;
As mentioned in an earlier comment, the use of value<vector<string>>() for a multitoken() option means that the option can occur more than one time on the command line.
comment:12 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Can (still) verify this bug who seems to be rather old, because even in Boost 1.31.x I couldn't use the zero_tokens() option. I wrote an email to Vladimir Prus but never got an answer.
I hope this mess will be fixed in near future.