Opened 17 years ago

Closed 14 years ago

Last modified 12 years ago

#469 closed Bugs (fixed)

multitoken broken

Reported by: rutavibaja Owned by: Vladimir Prus
Milestone: To Be Determined Component: program_options
Version: Boost 1.38.0 Severity: Showstopper
Keywords: Cc:

Description

Due to the changes in the parser, multitoken is broken 
in program_options [boost 1.33]. Looking at the code it 
is relatively clear why - the parser is too "greedy" and 
eats up all the options following the multitoken one 
without checking when to stop (for example, it should 
stop once it encounters another option/switch).

If this functionality is to be deprecated as hinted in 
some mails on the mailing list, it should be removed 
from the public interface. If not, I guess it should be 
fixed :)

The way to test it is to have a multitoken switch appear 
_in the middle_ of the command line (definitely not at 
the end) which should then simply eat all options to the 
right of it.

Change History (6)

comment:1 by nobody, 16 years ago

Logged In: NO 

I have encounter the same problems. I need input multiple multitoken. The program options 1.33 does not work in the mutitoken, if it use in the middle of command line. Does anyone have fixed this bug?

comment:2 by Vladimir Prus, 15 years ago

Milestone: Boost 1.35.0
Severity: Problem
Summary: multitoken broken in program_options 1.33multitoken broken

Confirmed as a problem. The solution to be decided.

comment:3 by anonymous, 15 years ago

Given the following program_options description:

std::vector<std::string> multiItems;

program_description desc;
desc.add_options()
    ("multi", value<>(&multiItems)->multitoken(), "...");
....

Would we expect the command line: "myProgram --multi foo bar" to add two entries (foo and bar) into 'multiItems'?

It currently (1.34) doesn't; bar gets lost. I can understand that this could be tricky, especially if positional options are also being used.

If multitoken was never designed for this purpose, then currently the way to achieve the desired effect is to overload 'validate'. However, this is only necessary because of the use of 'lexical_cast' in the current validate implementations.

To illustrate:

typedef std::pair<int int> PairOfInts;
PairOfInts pairOfInts;

program_description desc;
desc.add_options()
    ("pair", value<>(&pairOfInts), "...");
....

With command line: "myProgram --pair 1 2":

The current 'validate' code will stream (via lexical_cast) the string "1 2" into lexical_stream, then stream it out to the value type, i.e. the std::pair.

The problem there is that the stream-out of the string will only take the "1" part, so when it attempts to stream it back in, only one value is presented.

If we had provided a stream operator for our pair:

std::istream& operator>>(std::istream &a_istr, PairOfInts &a_pair)
{
    a_istr >> a_pair.first >> a_pair.second;
    return a_istr;
}

Then an exception would fire trying to get the second value.

The 'validate' code has a vector of strings, but only the first entry is filled.

If the current (detail/value_semantic.hpp) validate code:

template<class T, class charT>
void validate(boost::any& v, 
              const std::vector< std::basic_string<charT> >& xs, 
              T*, long)
{
    validators::check_first_occurrence(v);
    std::basic_string<charT> s(validators::get_single_string(xs));
    try {
        v = any(lexical_cast<T>(s));
    }
    catch(const bad_lexical_cast&) {
        boost::throw_exception(invalid_option_value(s));
    }
}

Was adjusted to not use lexical_cast, e.g.:

template<class T, class charT>
void validate(boost::any& v, 
              const std::vector< std::basic_string<charT> >& xs, 
              T*, long)
{
    validators::check_first_occurrence(v);
    std::basic_string<charT> s(validators::get_single_string(xs));
    std::istringstream istr(s);
    T value;
    if (!(istr >> value)
    {
        boost::throw_exception(invalid_option_value(s));
    }
    v = value;
}

Then more complex types could be supported just by providing the stream-in operator, rather than overloaded 'validate's (that seem to have to go in namespace boost, too).

comment:4 by anonymous, 14 years ago

Component: configprogram_options
Milestone: Boost 1.36.0To Be Determined
Severity: ProblemShowstopper
Status: assignednew
Version: NoneBoost 1.38.0

This multitoken bug has been broken and reported as a bug for 4 years now and not addressed. Is the author/supported not planning on ever fixing it? I'm stuck on boost 1.32 just because of this one bug.

comment:5 by Vladimir Prus, 14 years ago

Resolution: Nonefixed
Status: newclosed

(In [52154]) When processing value multitoken options, don't eat futher options. Fixes #469.

comment:6 by Vladimir Prus, 14 years ago

(In [52210]) Merge from release: When processing value multitoken options, don't eat futher options. Fixes #469.

Note: See TracTickets for help on using tickets.