>> > 2. Layered design. > > IMO All of my > > concerns are unfortunate consequences of the way you designed your > > library. IMO there should be one typed storage for the parsed > arguments > > (instead of 3 like you have) linked with formal parameters description.
> You are not correct. There are two storage mechanism for parsed data. > First > ('options_and_arguments') stores *only* strings. Second > ('variables_map') > stores typed values. So, there's one typed storage. 1. You store something inside class cmdline 2. You store strings in options_and_arguments 3. You store typed values in variables_map In my opinion 2 places are redundant. You should only have one. > > Plus second layer managing composition of parameter originated by > > different sources. > That's 'variables_map'. But variables map is part of first layer, it's store typed arguments. And it almost does not have any functionality I expect to see on this second layer dedicated to combinind parameters from different sources. > >> > b. Force same style for all parameters in command line (I could >not >>> > define /h --my_long_param) >>> >>> Do you need it in practice? >> >> Why not. Maybe different modules require parameters in different >style. > >I feel this to be artifical example, and would not be surprised if no >user >of program_options will ever want it. And if it wants... custom parsers >can be used. But this is part of functionaly you supply out of the box. And now i need ot rewrite it. You keep repeating: "use custom parser". I wonder why would I need this framework then. >>> desc.add_options() >>> // first argument is options name >>> // second argument is parameter name >>> // third argument is description >>> ("output", "file", "output file") >>> .... >>> ; >>> >>> This means that one comment line is added for first argument, and >then >>> you can very conveniently specify option name. >> >> Poor maintenance programmer looked on this code and spread hands >puzzled: >> What is option name and what is parameter name???? Which one should I >use >> to identify argument? Where the value assigned? What is default value? > >Sorry, but this kind of questions can be answered only in docs. Sorry. But this is not good enough for me. In my terms above would look like this: parameter<std::string>( "output" ) << place_to( output_file_name ) << default_value( "/tmp/abc" ) << description( "output file name" ) You do not need to know anything in addition about how parser works. Moreover it's unifies and easily extendable to adopt different modifers. >> class cmdline access methods: >> option_name() >> option_index() >> raw_option_name(); >> option_value(); >> option_values(); >> argument(); >> arguments(); >> >> You obviously struggle from need to provide on one hand container >> interface, on the other iterator one. >> Plus instead of N methods returning >> properties of option there should be one that returns foe example >'option' >> structure. >... which 'option' structure would contain the same set of methods? >Let's >consider the needs of 'cmdline' clients. You have > cmdline cmd(....); > while(++cmd) { > if (cmd.at_option()) { > ... > } > } > >With iterators, that would become > > for(cmdline_iterator i(...), e; i != e; ++i) { > if (i->is_option()) { > > >Wait! Again, what's 'value_type'. Some imaginary 'option_or_argument' >class? >boost::variant? boost::any? Yep, that would be an interator, but you >gain >nothing. It will be only input iterator, and with such a specialized >'value_type', that to use that iterator, you need to known that you're >dealing with command line --- there's no place for genericity. > >I'd probably buy your argument if you'd say that one can devise class >'option' and make command line parser, config file parser and something >else parser iterator, with 'option' as the value type. That would be >nice, >but it can't be done. cmdline has addition 'raw_option_name' member >function, and config_file cannot return arguments. The interfaces are a >bit >different. In my design I provide rnadom access iterator to the storage of parsed arguments of type cla::argument. And I could use whatever generic algorithm I like with it. Why does anybody need raw_option_name()? Also it's beyond my understanding why we need at_option, at_argument. May be it's because I still could not get what meaning you use for these terms in this context. I parsed argc/argv, stored typed argument. Now I only need ot get the value out of argument I identifued somehow (by name, or index, or order - whatever) > my_prog --service name=>Repository ... > > Here parameter name is service name, separator is string "=>", value is > 'Repository'. > Nope. It's not supported by cmdline class. And you would not be able to support it within the bounds of your design. >> > 9. Multi-pass parsing support > If that's not sufficient (which I doubt), I can think of a more general > solution. Basically, 'cmdline' class can allow unregistered options. > With > a bit of tweaking, it can return unparsed tokens. There is a solution. But it's not trivial. And not in a bound ot your current design. >> If you're use error codes, you'd have >> to check it after calling each function. > > No. I would not. In majority of the cases I do not bother whether any > intermediate step fails, parsing or validation fails. Whatever happened > during CLA declaration, parsing and validation I just want to get a > notification about an error during CLA parsing procedure and have and > access to the error message. IOW it would look like this: > > > cla::parser p; > > p << parameter<int>( "name" ) > > .... > > if( ! p.parse(argc,argv) ) { > > cout << p.error_msg() << endl; > > p.usage(); > > return 1; > > } > > I don't see here handling of response files or config files... if you > were > to add it, would you write the same "if" block a couple of times? I may have several if spatements: if( cla_parser.parse(...) ) ... if( config_file.parse(...) ) ... ... It's not worse than several catch clauses. Try/catch seems redundant when used right aroung the function that throw an exception. >> > Moreover in many interfaces library assumes existence on long name, >> > short >> > name, which may not be the case even with name based parameter >> > identification. >> >> I don't understand what you mean here. > > > I may not have long name, but only short one, like with old getopt > had. > It's not a problem. You'd still use the long name for identification > purposes, but disable long names in command line. I don't get it. What long name would I use if it only have short name. > > I may not have short name but only long one, like the style I am > > personally prefer. > What's problem with this case? It's supported out-of-box. What would you return when user call short name method? >> > 15. External parsers support. > > I do not want to store parsed values inside the parser at all. Instead > I > > want to register for every parameter callback function. > That's another example I don't see any use for. What will those callback > functions do. Can you given some more details why it might be needed? Let say I have method set_trace_level that manage tracing level for you application. What I need is in my terms look like this: parameter<int>( "trace_level" ) << default_value( 0 ) << handler( set_trace_level ) << description( "specifies the trace level for the application" ) Now when argc/argv parsed argument value is not stored into list of parsed argument. Instead handler function call and parsed value passed. I may have different parsers for all my parameters. > - Volodya Gennadiy. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost