François Duranleau schrieb:
How can I parse the command line dynamically? E.g. if I encounter the "--formatter=xml" argument, a new XMLFormatter is created and the options description from this formatter are added to list of valid options?
How about using extra_parser ? You could so something like (assuming that there is a global variable 'desc' containing :
struct select_formatter_options { options_descrition* opts ;
select_formmatter_options( options_description& opts ) : opts( opts ) {}
pair< string , string > operator () ( const string& arg ) { if ( opt == "--formatter=xml" ) { formatter = new XMLFormatter ; opts->add( formatter.options() ) ; } // else if etc.
// The rest of the parsing can be done by the library return pair< string , string >() ; } } ;
And then you do this:
variables_map vm; store(command_line_parser(args) .options(desc). .positional( GetPositionalProgramOptions () ) .extra_parser( select_formatter_options( desc ) ) .run(), vm); notify(vm);
After writing the eMail I thought about this, too, but had no idea how to get a hand on the embedded "m_desc" object of detail::cmdline. I somehow expected that this class used a private copy of the options_description.. I have checked the code and all copies that are used within the parser and cmdline are actually pointers to the provided desc object. So I gave it a fast try and your idea seems to work. There is just the question, wether it is safe to modify the "desc" object while actually using it within the cmdline. The only thing I don't like with this idea, is that you bypass all other style_parsers. So you have to code for all possible styles that are already handled by the different cmdline parsers and that can be customized wether the are used or not. Wouldn't it be better, if the the cmdline class calls a user provided function directly after an option has been parsed.
I have no idea if this can really work though. And there is at least one caveat: the option "--formatter=whatever" can only have this form, not "--formatter whatever" or a short form "-f whatever" (but could be "-fwhatever" with the appropriate adjustment above). You can prevent the short option version, but Boost.Program_options allows the long option to be used with multiple tokens (e.g. "--formatter whatever"). You could reinforce that though by testing, after you call notify above, if the option was set, but if no formatter has been created.
There is a way around this, if you do not use the "easy" version of the parser. If you use the detail::cmdline class you can set an additional style_parser, that will receive the complete rest of the command line. With this style_parser you are able to parse the form "--formatter whatever". You just have to remove the arguments you parsed from the provided commandline in the end. Thanks for the info Dirk