|
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