Boost logo

Boost Users :

From: David Greene (greened_at_[hidden])
Date: 2006-02-14 21:56:52


I'm starting to use boost::program_options and am not having much
luck:

>>-home-> ./options_test
Got debug value default
Got option default
Segmentation fault (core dumped)

>>-home-> ./options_test --help
free(): invalid pointer 0x8fb06f8!
free(): invalid pointer 0x8fafcd0!
Got debug value default
Got option default
Segmentation fault (core dumped)

>>-home-> ./options_test --help --debug io
free(): invalid pointer 0x8a83ec0!
free(): invalid pointer 0x8a83ed0!
free(): invalid pointer 0x8a83ec8!
free(): invalid pointer 0x8a84a38!
Segmentation fault (core dumped)

At first I thought it might be a problem with the -mt version as
my larger application is threaded. But I compiled the testcase
attached below as a single-threaded application and it still fails
in the same ways.

I'm not sure if my use of vector<string> is correct. The documentation
is confusing on this point. In

http://boost.sourceforge.net/doc/html/program_options/overview.html

one example with the "email" option uses multitoken with "string"
and another uses "combining" with "vector<string>." Is it not
possible to have a combining and multitoken option value? What's
the correct value type to use if I want the multiple tokens for
the "debug" option to appear as separate items in a vector (or
other sequence)? Or do I have to stuff them in a single string
and manually parse them out later?

                        -Dave

------------------------
#include <boost/bind.hpp>
#include <boost/program_options.hpp>
//#include <boost/filesystem/operations.hpp>
//#include <boost/filesystem/fstream.hpp>

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>

std::ostream &operator<<(std::ostream &out,
                         const std::vector<std::string> &value);

std::ostream &operator<<(std::ostream &out,
                         const std::vector<std::string> &value)
{
   std::copy(value.begin(), value.end(),
             std::ostream_iterator<std::string>(out, " "));
   return(out);
}

namespace test {
   namespace opt = boost::program_options;
   //namespace fs = boost::filesystem;

   static void validate_debug_options(const opt::options_description
                                      &debug,
                                      const std::vector<std::string>
                                      &value)
   {
      std::cout << "Got debug value " << value << std::endl;
      for(std::vector<std::string>::const_iterator i = value.begin();
          i != value.end();
          ++i) {
         std::cout << "Got option " << *i << std::endl;
      }
   }

   void process_options(int argc, char **argv)
   {
      opt::options_description help("Help options");
      opt::options_description debug("Debug options");
      opt::options_description cmdline_options;
      opt::options_description cfgfile_options;

      help.add_options()
         ("help", "This help message");

      typedef std::vector<std::string> option_vector;
      option_vector default_debug_flags;
      default_debug_flags.push_back("default");

      debug.add_options()
         ("debug,d",
          opt::value<std::vector<std::string> >()->
          // For some reason can't find operator<< declared above
          default_value(default_debug_flags, "default")->
          composing()->
          multitoken()->
          notifier(boost::bind(validate_debug_options,
                               boost::ref(debug), _1)),
          "Debug flags:\n\n"
          " foo: \tDo something\n"
          " bar: \tDo something else\n"
          " baz: \tDon't do anything\n");

      cmdline_options.add(help).add(debug);
      cfgfile_options.add(debug);

      opt::variables_map vm;
      opt::store(opt::parse_command_line(argc, argv, cmdline_options), vm);

// fs::ifstream config_file("./opt.cfg");

// if (config_file) {
// opt::store(opt::parse_config_file(config_file,
                    cfgfile_options), vm);
// }

      opt::notify(vm);
   }
}

int main(int argc, char **argv)
{
   test::process_options(argc, argv);

   return(0);
}


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