$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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);
}