Questions about using program_options
I have a project that's currently doing manual command-line parsing, then using a suite of classes I developed to read from multiple formats of configuration files. In looking at boost libraries, I see that boost::program_options might be something worth using. The first question I have is "what config file formats does it use/ want" ? I'm still reading all of the docs, so this may become clear, but. The next question is, since this is one of the non-header-only libraries, how hard would it be to pull segments out of the boost distribution to ship with my suite of programs and build it along- side? Just to get the program_options component. (Though, as a side note, I'm also using Loki::SharedPtr in my project, so if that could be converted to boost::shared_ptr it might be less complicated. Then again, I'm using some of the more complicated features of SharedPtr, so it's not clear to me that boost::shared_ptr is adequate, which is why I didn't choose it in the first place.) Thanks... Any advice on taking portions of the boost code and bundling it into another source package would be appreciated. - Chris
Hello Chris, CR> The first question I have is "what config file formats does it CR> use/ want" ? I'm still reading all of the docs, so this may become CR> clear, but. The format is similar to windows INI files. I.e. key=value strings optionally grouped into sections. Also it may contain comments in lines that begin from #. Actual format is defined by the function common_config_file_iterator::get. If you provide your own implementation of basic_config_file_iterator you will be able to parse your own config file format. CR> The next question is, since this is one of the non-header-only CR> libraries, how hard would it be to pull segments out of the boost CR> distribution to ship with my suite of programs and build it along- CR> side? Just to get the program_options component. This is very easy. There is tool called bcp (acronym from boost copy), which you may use to copy only a single boost package. It automaticaly searches for all dependency and creates a working copy of several boost sub-libraries along with build files and documentation. I personally don't like program_options. -- -- Vyacheslav Andrejev -- System Architect, Optech International, Inc.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Chris Ross wrote:
I have a project that's currently doing manual command-line parsing, then using a suite of classes I developed to read from multiple formats of configuration files. In looking at boost libraries, I see that boost::program_options might be something worth using.
The first question I have is "what config file formats does it use/ want" ? I'm still reading all of the docs, so this may become clear, but.
The next question is, since this is one of the non-header-only libraries, how hard would it be to pull segments out of the boost distribution to ship with my suite of programs and build it along- side? Just to get the program_options component.
(Though, as a side note, I'm also using Loki::SharedPtr in my project, so if that could be converted to boost::shared_ptr it might be less complicated. Then again, I'm using some of the more complicated features of SharedPtr, so it's not clear to me that boost::shared_ptr is adequate, which is why I didn't choose it in the first place.)
Thanks... Any advice on taking portions of the boost code and bundling it into another source package would be appreciated.
- Chris _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I use the boost::program_options as it is halfway there to providing something I've written from scratch in most other languages - a reusable PropertyCatalog. My C++ implementation is wrapped around boost::program_options which provides functions like the following: bool PropertyCatalog::getBooleanProperty(string key, bool defaultValue) { bool retval = defaultValue; if (vm.count(key)) { try { retval = vm[key].as<bool>(); } catch (...) { retval = defaultValue; } } return retval; } So anywhere in my code I can do, for example: if (PropertyCatalog::getBooleanProperty("testapp.profile",false)) { profile.append(currentStatus); } The actual command-line or INI file parsing is done by the boost::program_options library - I have merely wrapped it in something I am used to... -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFIN0X4/X5Z5iyVCbERArmdAJsFoogqdFuLD+bFc55E0uIZcr0wtACfUJq6 HO1HUYpMX63mWGwv1cq5xmw= =dlGM -----END PGP SIGNATURE-----
Hi! Rupert Bruce schrieb:
So anywhere in my code I can do, for example: if (PropertyCatalog::getBooleanProperty("testapp.profile",false)) { profile.append(currentStatus); }
Which has a design flaw, I think. I just got rid of a lot of such function calls in a project I'm working at. The flaw: do not keep configuration default values distributed in the code. What if the default value needs to change? It does commonly change for directory paths. If you now tell me to always write the correct value into the config file, then I wouldn't need any default value at all and I could just remove them. And if you need different default values for the same key in different places, then you simply need also different keys. I now have "getConfig" calls without defaults in the call. Frank
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Frank Birbacher wrote:
Hi!
Rupert Bruce schrieb:
So anywhere in my code I can do, for example: if (PropertyCatalog::getBooleanProperty("testapp.profile",false)) { profile.append(currentStatus); }
Which has a design flaw, I think. I just got rid of a lot of such function calls in a project I'm working at. The flaw: do not keep configuration default values distributed in the code. What if the default value needs to change? It does commonly change for directory paths. If you now tell me to always write the correct value into the config file, then I wouldn't need any default value at all and I could just remove them. And if you need different default values for the same key in different places, then you simply need also different keys.
I now have "getConfig" calls without defaults in the call.
Frank
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Personally, I like the defaults (I typically replace a hard-coded value in the code with a call to PropertyCatalog so the default is obvious). One advantage of Polymorphism is that I don't need to specify a default: PropertyCatalog::getBooleanProperty("testapp.profile") As you mention, file paths are a common default that changes - one that I frequently have to override on the command line is the path to the config file itself. One benefit of boost::program_options is that I have that flexibility. This is from a test case with no properties: int main(int argc, char *argv[]) { PropertyCatalog::populate(argc, argv); string log_config_file=PropertyCatalog::getStringProperty("config.logging", "../config/log4cxx.properties"); log4cxx::PropertyConfigurator::configure(LOG4CXX_FILE(log_config_file)); if (PropertyCatalog::isDefined("help")) { PropertyCatalog::logPropertyCatalog(); } return UnitTest::RunAllTests(); } void PropertyCatalog::populate(int argc, char **argv) { options_description general("General options"); general.add_options() ("help", "produce a help message") ("config", value<string>(),"override the default config file name") ("version", "output the version number"); string defaultConfigFileName = static_cast<string>(argv[0])+".properties"; string config_file=PropertyCatalog::getStringProperty("config", defaultConfigFileName); options_description cmdline_options; cmdline_options.add(general); options_description config_file_options; config_file_options.add(general); //class variable 'visible' holds the set of option_descriptions that the user //may want to have listed via logPropertyCatalog() visible.add(general); store(parse_command_line(argc, argv, cmdline_options), vm); //load the config file ifstream ifs(config_file.c_str()); store(parse_config_file(ifs, config_file_options), vm); notify(vm); } -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFIOC5D/X5Z5iyVCbERAoHPAJ9/p/GNwuLHpZh2yBiqlyp+WbrEaQCdFMIZ yvAtqhEkkaRRrB7ojhSe9Lw= =Pu8n -----END PGP SIGNATURE-----
participants (4)
-
Chris Ross
-
Frank Birbacher
-
Rupert Bruce
-
Vyacheslav E. Andrejev