Boost logo

Boost :

From: Gary Powell (Gary.Powell_at_[hidden])
Date: 2001-05-11 12:41:01


>>
> Oh I see. I was assuming the POSIX way: double dashes for longopts, single
> dashes for shortopts. I'd personally prefer that approach, for the
> following
> reasons (in order of appearance):
>
> 1.
> The possibility for combining several shortopts in one argument. Think
> "diff -Naur".
<<
Ok.

>>
> 2.
> It's pretty common to have short forms for all the most important options.
> Specifying them all seperately is tedious and bloats the help output.
> In a clean program, you will have to make them all explicit because
> otherwise they couldn't be used in scripts and thelike (anywhere their
> usage
> is hardcoded) or adding a new opt with the same first letter will
> instantly
> ambiguate the short form and break the script.
<<
Makes sense.

>>
> 3.
> Actually the programmers interface doesn't suffer all too much. You
> basically
> have three forms of the register function:
>
> reg(handler, descr, short_chr, long_name); // full-blown
> // for convenience
> reg(handler, descr, short_chr);
> reg(handler, descr, long_name);
<<
Ok.

>>
> 4.
> POSIX-compliance is important to (virtually) all UNIX applications while
> Windows-apps at least wouldn't suffer from it. ;)
<<
No window's app's programmers just suffer anyway ;>

>>
> > Sometimes its best just to post interface questions and not worry about
> the
> > implementation until you have that nailed down. (Witness all the math
> > constant discussions and revisions.)
>
> Alright, so here's the outer interface's synopsis:
>
> class option_processor {
> public:
> // argname: Symbolic name for the argument to be used in the help.
> // "" means try to guess from desc, use "ARG" if ambiguous
> template<class H> reg(H hdlr, string desc, char chr, string name,
> string argname = "");
> // convenience
> template<class H> reg(H hdlr, string desc, char chr);
> template<class H> reg(H hdlr, string desc, string name);
>
> string info() const; // return the help listing
>
> void operator()(int* argc, char** argv[]);
> };
<<
Would it be worth parameterizing on the charType like this?

template<class charType, class charTraits = std::character_traits<charType>
>
class basic_option_processor {
public:
   template<class H>
   reg(H hdlr, basic_string<charType, charTraits> desc ,charType shortFlag,
       basic_string<charType, charTraits> LongName,
       basic_string<charType, charTraits> argName = "");

  // etc...
};

typedef basic_option_procesor<char> option_processor;
typedef basic_option_procesor<wchar> woption_processor;

>>
> I have to rework the handler objects again, considering using a boost
> callback type, so I won't go into detail. Right now I have convenience
> functions for their creation:
>
> // creates a no-argument handler
> handler(void (*func)());
> template<class F> noarg_handler(F func); // special case for function
> objects
> // creates a mandatory-arg handler
> template<class F> handler(F func);
> // creates a optional-arg handler supplying a default to its function if
> // no argument is given.
> template<class F> handler(F func, F::argument_type def);
>
> But I'm suspecting this is a less-than-optimal solution. Especially the
> special case for non-arg function objects. Ugh.
>
> I think the problem that lead me to all this was that I wanted to relieve
> the
> programmer from processing a string argument, so I needed a functor that
> does
> the conversion from string to the function's argument type. Any
> suggestions
> welcome.
<<
A question comes to mind and that is how to you control the parsing? As in
does each handler tell the parser how much of the line it just ate?

Also formatting of the help string, do you embed <cr>'s?

-gary-

gary.powell_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk