Hi Dan,
Haven't tried something like you want, but maybe the below info on
what's going on helps.
Fristly, about sections in config files:
foo.expDays in the config file would be:
[foo]
expDays
So all variables in the config file would have foo. prepended.
Then, the store method only read the specified source and puts what it
finds in the varMap. Notify processes this further, e.g. telling you
about unknown options that it thus can't deal with, and also pushing
the variable to the address of a variable in your program as you
requested it to.
Right now, you should have both an foo.expDays and an expDays in the
variable map. I dont think there are any guarantees on in which order
they'll be written to your variables. You might try making both
variables have the same name (so not foo.expDays, but just expDays in
the config file) and see what happens then, what gets overwritten.
Hope some of this is useful,
Best,
Dee
On Tue, Nov 1, 2011 at 02:31, Gruhn, Dan
Greetings,
I would like to have a parameter "expire-days" that has a default and can be set via the command line
--expire-days|-e <days>
and a config file
[foo] expire-days = <days>
It would be most elegant to be able to specify things like this (notice the automatic storage to the expireDays variable):
namespace bpo = boost::program_options; int expireDays = 30; bpo::options_description desc("Allowed options"); desc.add_options() ("expire-days,e", bpo::value<int>(&expireDays)->default_value(expireDays), "Number of days before files expire") ;
bpo::options_description configFileDesc; configFileDesc.add_options() ("foo.expire-days", bpo::value<int>(&expireDays), "") ;
bpo::variables_map varMap;
try { // Attempt to parse the configuration file. std::ifstream cfg("/tmp/all.cfg"); if (cfg.is_open()) { std::cout << "Opened /tmp/all.cfg" << std::endl; static const bool allowUnregistered = true; bpo::store(bpo::parse_config_file(cfg , configFileDesc, allowUnregistered), varMap); } // Parse the command line bpo::store(bpo::parse_command_line(argc, argv, desc), varMap);
bpo::notify(varMap); } std::cout << "Expire days: " << expireDays << std::endl;
My code may be strange but I am trying to find the right order and combination of adding options, parsing, storing, and notifying that gives the command line priority over the config file which in turn has priority over the 30 day default. Oddly enough, it doesn't seem to make much difference which order I use, the config file seems to have precedence This is not what I expected so perhaps I'm doing something wrong but I can't find it.
I know that I can accomplish this via extra code on my part, but I'm trying to come up with a general scheme that would work for multiple programs with multiple variables using a common config file and the simpler the better. The documentation mentions using sections in config files but doesn't give much detail. Can anyone help me here or at least describe for me which of add_options, parse_*, store, and notify does the following:
1) Sets the default value 2) Marks that a value has been set from the command line/config file. 3) Actually does the store to the given variable. 4) What does notify do?
I've tried (and continue to try) looking through the code but am having problems find the right place examine. I'll take pointers in that area as well.
This does not seem like an exotic use case. Has anyone else accomplished this or something like it?
As always, any help of any kind will be greatly appreciated.
Dan
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users