Reputation: 6806
Using boost 1_55, I have a bool_switch() option, which is defined as:
bpo::options_description opts;
opts->add_options()
("foo", bpo::bool_switch(), "Enable foo.");
opts_map = new bpo::variables_map;
And it is parsed on the command line by:
bpo::store(bpo::parse_command_line(argc, argv, opts), *opts_map);
And also parsed in a config file by:
ifstream ifs("foo.conf");
if (ifs.good()) {
bpo::store(bpo::parse_config_file(ifs, opts), *opts_map);
close(ifs);
}
The trouble is that it works fine on the command line by either specifying --foo
or not, but it is always false
(with second.defaulted() == true
) when I put it in the config file. I have tried the following in the config file:
foo
foo=true
foo=1
Other types of options (e.g. bpo::value<ANYTYPE>()
with or without composing()
) work fine both on the command line and also in the config file, only bool_switch()
options are not working.
Any idea what I'm doing wrong? Or can you not use bool_switch()
options with parse_config_file()
?
EDIT:
A workaround is to use a value()
type with default_value()
and implicit_value()
:
opts->AddOptions()("foo", bpo::value<bool>()->default_value(false)->implicit_value(true), "Enable foo.");
Upvotes: 3
Views: 2062
Reputation: 21
I'm currently using Boost 1.58 and support for boolean switch options in a config file works just fine.
Config file (config.cfg):
log=ON
Code:
#include <fstream>
#include <boost/program_options.hpp>
#include <iostream>
namespace prog_opts = boost::program_options;
//Notified function
void option_verbose(bool opt) {
std::cout << "Log ";
if (opt)
std::cout << "ON";
else
std::cout << "OFF";
std::cout << "\n";
}
int main (int argc, char* argv[]) {
prog_opts::options_description general("Options");
general.add_options()
("log", prog_opts::bool_switch()->notifier(&option_verbose), "logging")
;
// Assign the CLI args to the map
prog_opts::variables_map cli_map;
const prog_opts::basic_parsed_options< char >& cliopts = prog_opts::command_line_parser(argc, argv).options(general).run();
prog_opts::store(cliopts , cli_map);
// Get options from config
std::ifstream infile("config.cfg", std::ifstream::in);
store(parse_config_file(infile, general), cli_map);
notify(cli_map);
}
From using this, it appears that the behavior is:
In the example code with log=ON in the config file, the option will always be ON. With it set to OFF, the option will only be enabled when running your application with the option --log.
Hope this helps.
Upvotes: 2
Reputation: 24174
I don't think what you're trying to do is presently allowed. Vladimir, the author of the program options library states
I've changed bool_switch so that it does not accept any arguments. This also solves the problem with "arg (=0)" output.
There's one possible problem. For command line, we most likely don't want explicit value for bools. But in config file, the value is always present. This is the only case I know where single options description for command line and other sources is problematic -- if you describe an option with bool_switch, it can't be specified in config file.
Let's see if that's a problem.
Note that this statement is nearly 10 years old, but I couldn't find any evidence it's no longer true when inspecting the source code in 1.55.
Upvotes: 1