Boost logo

Boost Users :

Subject: Re: [Boost-users] program_option parsing error
From: Marek Skalický (mskalick_at_[hidden])
Date: 2015-09-30 05:58:22


Vladimir Prus píše v Út 29. 09. 2015 v 22:36 +0300:
> On 29-Sep-15 3:00 PM, Marek Skalický wrote:
> > Vladimir Prus píše v Čt 24. 09. 2015 v 12:13 +0300:
> >> Hi Marek,
> >>
> >> On 23-Sep-15 4:41 PM, Marek Skalický wrote:
> >>> Hello everyone,
> >>> I have a question about program_option library.
> >>>
> >>> If I have argv=["binaryname", "--port", "5"] and port have set
> >>> default_value=6 and implicit_value=7 what should be the value of port
> >>> after parsing argv?
> >>
> >> It should be 5.
> >>
> >> default_value does not matter because the --port option is provided
> >> implicit_value does not matter because the --port option includes a value explicitly
> >
> > Thanks.
> >
> >>
> >>> I am asking because this test
> >>> https://github.com/mongodb/mongo/blob/0481c958daeb2969800511e7475dc66986fa9ed5/src/mongo/util/options_parser/options_parser_test.cpp#L753 is failing with boost 1.59 (with boost 1.58 it is passing). Does someone please know what changed in this new version?
> >>
> >> Does this issue reproduces when using program_options directly? The code above appears to use classes that are
> >> similar, but not the same.
> >
> > I separated boost code. However, this code still fails:
> > "
> > namespace po = boost::program_options;
> >
> > po::options_description boostOptions;
> > po::positional_options_description boostPositionalOptions;
> >
> > std::vector<const char*> argv_buffer;
> > argv_buffer.push_back("binaryname");
> > argv_buffer.push_back("--port");
> > argv_buffer.push_back("5");
> > int argc = argv_buffer.size();
> >
> > int style = (((po::command_line_style::unix_style ^
> > po::command_line_style::allow_guessing) |
> > po::command_line_style::allow_long_disguise) ^
> > po::command_line_style::allow_sticky);
> >
> > std::auto_ptr<po::typed_value<std::string> >
> > boostTypeBuilder(po::value<std::string>());
> > boostTypeBuilder->implicit_value("7");
> >
> > std::auto_ptr<po::value_semantic> boostType;
> > boostType = boostTypeBuilder;
> >
> > boostOptions.add_options()("port", boostType.release(), "Port");
> > po::command_line_parser(argc, (argc > 0 ? &argv_buffer[0] : NULL)).
> > options(boostOptions).
> > positional(boostPositionalOptions).
> > style(style);.
> > run();
> > "
> >
> > What is wrong? Or is this a bug in Boost?
>
> When I try your example, I get the too_many_positional_options_error exception, and it actually seems to be documented
> behavior:
>
> typed_value * implicit_value(const T & v);
> Specifies an implicit value, which will be used if the option is given, but without an adjacent value. Using
> this implies that an explicit value is optional, but if given, must be strictly adjacent to the option, i.e.:
> '-ovalue' or '--option=value'. Giving '-o' or '--option' will cause the implicit value to be applied.
>
> In other words, implicit value is applied here because --port does not have an explicit adjacent value, and then
> "5" becomes a superfluous token and result in an error. The documentation say the same in 1.58, and even in 1.50.
>
> The code however, was recently changed, here:
>
> https://github.com/boostorg/program_options/commit/88dea3c6fdea8c9ea894911897b1770599c383e4
> https://github.com/boostorg/program_options/pull/8
>
> Guess arguments can be made either way how we should handle this. What would you think?

Thank you. That is what I asked for. It makes sens. So now I know that
the error is in the MongoDB test, so I can fix it.

The changes explains that with 1.58 code above works.

Thank you and have a nice day,
Marek

>
>
> - Volodya
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net