![]() |
Boost Users : |
From: François Duranleau (duranlef_at_[hidden])
Date: 2005-11-02 12:40:55
On Mon, 31 Oct 2005 boost_at_[hidden] wrote:
> Hello,
>
> I'm new to the boost::program_options library and tried to use it for a
> command pattern based software. The program is launched with the
> following commandline:
>
>> program command [Options] <Files>
>
> The program can use different output formatters with
> --formatter={XML|binary|text}. Every command and formatter specify their
> own set of options.
>
> I first tried to collect all options form the commands and formatters
> and parse the command line only once. This lead to the problem, that due
> to the different positional options information the commandline parser
> always threw an exception due to wrong command line formatting.
>
> Since I couldn't find a way to add mutliple optional option groups to
> the parser, I moved the parsing code into my command base class and
> query the derived commands for the different required information, like:
>
> class Command
> {
> public:
> vritual options_description GetOptionsDescription ();
> virtual options_description GetHiddenOptionsDescription ();
> virtual positional_program_options GetPositionalProgramOptions ();
>
> virtual Run (variables_map const & vm) = 0;
> int Execute (std::vector<std:.string> args)
> {
> options_description desc;
> descr.add (GetOptionsDescription ()).add (GetHiddenOptionsDescription
> ());
>
> variables_map vm;
> store(command_line_parser(args)
> .options(desc).
> .positional(GetPositionalProgramOptions ())
> .run(), vm);
> notify(vm);
>
> Run (vm);
> }
>
> }
>
> The execute function is called form the program main after the "command"
> has been stripped from the commandline and the concrete command was
> created by the factory.
> So far so good. This works for the different commands, but not for the
> formatters.
>
> 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?
>
> I know, that there is the notify mechanism, but this only works after
> the commandline has been successfully parsed. And also the custom
> parsers do not solve my problem.
>
> Any idea how to solve this issue?
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);
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.
-- François Duranleau LIGUM, Université de Montréal "Voyager, c'est essayer de revenir avec quelques préjugés en moins." - Jean-Daniel Lafond
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net