Boost logo

Boost Users :

From: Vladimir Prus (vladimir_at_[hidden])
Date: 2008-08-26 00:37:16


Allen Cronce wrote:

> fs::path inPath;
>
> po::options_description desc("Allowed options");
> desc.add_options()
> ("in,i", po::value<fs::path>(&inPath), "Input file or directory
> <pathname>")

> If I call the above with the following parameters, it works:
>
> --in "my_file"
>
> Input path = "my_file"
>
> But if I call it with a path that has a space in it, I get an error:
>
> --in "my file"
>
> Exception error: in option 'in': invalid option value 'my file'
>
> I know that I can work around the problem by loading the path into an
> interim string first, then use the string to initialize a path object.
> But unless I'm missing something, I would have thought that
> iteroperability between boost.program-options and boost.filesystem
> should be more seamless. It seems very common to want to load options
> into path objects.

I am not aware of boost.program_options has any special support for
boost::filesystem::path, which suggests that processing of this option
goes via generic path:

    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));
        }
    }

and the error message you get is 'what()' of invalid_option_value. In other
words, it appears that lexical_cast from a string with spaces into
boost::filesystem::path does not work. And it clear why:

    template< class Path >
    std::basic_istream< typename Path::string_type::value_type,
      typename Path::string_type::traits_type > &
      operator>>
      ( std::basic_istream< typename Path::string_type::value_type,
      typename Path::string_type::traits_type >& is, Path & ph )
    {
      typename Path::string_type str;
      is >> str;
      ph = str;
      return is;
    }

Extractor operator for string stops on whitespace. The fix, IMO, is
to special case conversion to boost::filesystem::path in lexical_cast,
just like it's already done for conversion to string.

Beman, what do you think?

- Volodya


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