Boost logo

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