[program_options] Proposed feature to provide option namespace prefixing

Hi! I'm a developer on the Drizzle project, and we're currently replacing the home-grown getopt wrapper we inherited from the MySQL codebase with Boost.Program_options. So far, we're thrilled and it's going great, so thanks! We've focused on the client utilities to start, but as we're coming up on the server, we have an issue that we have an internal solution for, but which seems like it might be something that could be more generally useful, so I thought I'd mention it here, and if there is any interest, I can work up a proper code submission. The situation has to do with plugin modules and option names. In our current system, we enforce an option name prefix that matches the module name. For instance, if you are the InnoDB plugin author, you would declare an option named "buffer_pool_size" which would be presented to the user as "--innodb_buffer_pool_size", and the server/plugin registration handles prepending the module name to the option name for you. (you cannot choose to not do this) For those following along at home, you'll notice the _ we're using for the concatenation - we're happy changing that to be a "." so that the program_options config file sections will work in a sensible way. Our approach to doing this with Boost.Program_options at the moment is to wrap options_description_easy_init in a class. Something like: class DRIZZLED_API options_context { const std::string &module_name; po::options_description_easy_init &po_options; std::string prepend_name(const char *name); public: options_context(const std::string &module_name_in, po::options_description_easy_init &po_options_in); options_context& operator()(const char* name, const char* description) { std::string new_name(module_name); new_name.push_back('.'); new_name.append(name); po_options(new_name.c_str(), description); return *this; } ... }; Then in server plugin registration, a context is created around the real program_options and is is handed to the plugin module: module.register_options(options_context(module.get_name(), commandline_options.add_options()); It seems like a possibly nicer or more integrated approach would be something that would look like this: module.register_options(commandline_options.add_options(module.get_name()); And given the mapping of config file sections to name-dotted prefixes, it seems like it wouldn't be a ridiculous addition. Is anybody interested in me reworking what we end up with to be usable or applicable back to the Boost core? Thanks! Monty

Monty Taylor wrote:
Our approach to doing this with Boost.Program_options at the moment is to wrap options_description_easy_init in a class. Something like:
class DRIZZLED_API options_context { const std::string &module_name; po::options_description_easy_init &po_options;
std::string prepend_name(const char *name);
public:
options_context(const std::string &module_name_in, po::options_description_easy_init &po_options_in);
options_context& operator()(const char* name, const char* description) { std::string new_name(module_name); new_name.push_back('.'); new_name.append(name); po_options(new_name.c_str(), description); return *this; } ... };
Then in server plugin registration, a context is created around the real program_options and is is handed to the plugin module:
module.register_options(options_context(module.get_name(), commandline_options.add_options());
It seems like a possibly nicer or more integrated approach would be something that would look like this:
module.register_options(commandline_options.add_options(module.get_name());
And given the mapping of config file sections to name-dotted prefixes, it seems like it wouldn't be a ridiculous addition.
Is anybody interested in me reworking what we end up with to be usable or applicable back to the Boost core?
Hi Monty, it seems that what you propose can be accomplished by adding a new member to option_description_easy_init, and then doing string concatenation in the three operator() methods? It seems pretty reasonable thing to do, and I'll be happy to integrate patches to that effect. The only concern is that you simplify definition of options, however, it seems that access to options still have to use fully qualified names. Or do you have solution for that as well? Thanks, Volodya
Thanks! Monty _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 06/12/2010 01:20 AM, Vladimir Prus wrote:
Monty Taylor wrote:
Our approach to doing this with Boost.Program_options at the moment is to wrap options_description_easy_init in a class. Something like:
class DRIZZLED_API options_context { const std::string &module_name; po::options_description_easy_init &po_options;
std::string prepend_name(const char *name);
public:
options_context(const std::string &module_name_in, po::options_description_easy_init &po_options_in);
options_context& operator()(const char* name, const char* description) { std::string new_name(module_name); new_name.push_back('.'); new_name.append(name); po_options(new_name.c_str(), description); return *this; } ... };
Then in server plugin registration, a context is created around the real program_options and is is handed to the plugin module:
module.register_options(options_context(module.get_name(), commandline_options.add_options());
It seems like a possibly nicer or more integrated approach would be something that would look like this:
module.register_options(commandline_options.add_options(module.get_name());
And given the mapping of config file sections to name-dotted prefixes, it seems like it wouldn't be a ridiculous addition.
Is anybody interested in me reworking what we end up with to be usable or applicable back to the Boost core?
Hi Monty,
it seems that what you propose can be accomplished by adding a new member to option_description_easy_init, and then doing string concatenation in the three operator() methods? It seems pretty reasonable thing to do, and I'll be happy to integrate patches to that effect.
Fantastic. I'll work some up for you.
The only concern is that you simplify definition of options, however, it seems that access to options still have to use fully qualified names. Or do you have solution for that as well?
I don't have a solution to that, but you're right, I should really come up with one. I guess my first concern was simply to prevent module authors from accidentally breaking namespace rules - but their code will certainly make more internal sense if they can access options using the same short names. Will think about it... Monty

Monty Taylor <mordred <at> inaugust.com> writes:
On 06/12/2010 01:20 AM, Vladimir Prus wrote:
Monty Taylor wrote:
It seems like a possibly nicer or more integrated approach would be something that would look like this:
module.register_options(commandline_options.add_options(module.get_name
());
Is anybody interested in me reworking what we end up with to be usable or applicable back to the Boost core?
This sounds similar to something we're doing, where the first argument on the command-line decides the mode of the program. We wanted the convenience of being able to use a single configuration file, but also the convenience of not having "section." prefixes on the command- line. E.g. ##### #/config.ini [mode_1] opt1=... opt2=... optFoo=... [mode_2] opt1=... opt2=... optBar=... #### theProgram mode_1 config.ini theProgram mode_1 opt1=value theProgram mode_1 config.ini opt2=override theProgram mode_2 optFoo=value // error: option not available for mode_2 At the moment we have a (simple, but a bit hacky) solution of prepending the mode onto the command arguments, so +1 for anything that moves code out of our base into the library ;-)
The only concern is that you simplify definition of options, however, it seems that access to options still have to use fully qualified names. Or do you have solution for that as well?
I don't have a solution to that, but you're right, I should really come up with one. I guess my first concern was simply to prevent module authors from accidentally breaking namespace rules - but their code will certainly make more internal sense if they can access options using the same short names.
Is this a case of being able to 'bind' the variables_map to a domain, too?
participants (3)
-
Chard
-
Monty Taylor
-
Vladimir Prus