I have 2 use cases for program options library. I would say that they are fairly advanced but nevertheless typical ones: Due to severe time constraints I am going to describe just the first use case, which I think will highlight significant number of boost::program_options benefits and problems .
----------------- USE CASE ----------------------------- 1. Program options of Perforce version control "p4" client. p4 program options come from (in the order of descending priority) 1. Command line 2.standard input 3. config file 4. Windows registry 1. The command line has the general format: p4 [global-options] <command> [command-options] where global options are: -c client -d dir -G -H host -p port -P pass -s -u user -x file -C charset -L language -V -h and command-options depending on command. For example the command "submit" has the following possible options p4 [g-opts] submit [-r] [-s] [files] p4 [g-opts] submit [-r] -c changelist# p4 [g-opts] submit -i [-r] [-s] Please note, that "-c" option has semantic is different between global-options and command options 2. The arguments can be read directly from the standard input, in this case they should be separated by newline character. 3. The config file has the structure P4<KEYWORD>=value for example, instead of specifying option "-c myclient" in command line, user can write P4USER=myclient 4. The "most default" values are stored in Windows registry in format similar to config file. ----------------- END OF USE CASE ----------------------------- It seems to be important to support the handling of this syntax style, because: 1. It seems to be very "widespread", meaning the number of people, not necessarily the number of products. 2. It is structurally complicated enough to break the simplistic implementation. I will try to iteratively go through implementation, highlighting the problems and helpful features, soliciting library author feedback on the way. --------- IMPLEMENTATION (PSEUDOCODE) ROUND 1 ------------------ 1. Options storage variable_map go; // global_options or struct global_options { boost::optional<std::string> client; // Need optional boost::optional<std::string> dir; bool pythonize; bool show_version .... }; global_options go; or may be? lexical_map go; // idea of Aleksey Gurtovoy 2.Describe options global_options_desc.add_options() ( "c", parameters( "<client>", &go.client ), "some comments here" ) // Problem #1. // The first parameter is a mini-language. Usually C++ tends to avoid minilanguages. // For example: iostreams don't use "w+", "rw", "a", although iostreams are not always // the example of practices to follow. // Still, for users minilanguage might be unexpected here // Note: need to make sure that parameter can take optional<> or ( "c", parameters( "<client>" ), "some comments here" ) // store it in the ..._map later 3. Read - lowest priority first // 3.1. Read registry and config file // Problem #2 - the names in the registry and config file are not the same as the names given in options_description // actually it seems that the information in options description is primarily for command line, not for config files. // --- custom written --- mtn::copy( config_file( ".p4config" ), inserter( go ) ); // insert options in go (variables_map, or lexical_map) // --- end custom written --- // 3.2. Read command line // 3.2.1 Separate global options from command options options_and_arguments oa = parse_command_line(argc, argv, desc); // Problem #3: Would be nice if options_and_arguments was a sequence command_options_and_arguments = mtn::find_if( options_and_arguments, &is_argument ); global_options_and_arguments = mtn::iterator_range( options_and_arguments.begin(), command.begin() ); // 3.2.2. Find out whether I need to read a rest of arguments from standard input // Problem #4: Seems that it is too late to ask boost::program_options to do that // May be the arguments need to be read from stdin and the command line parsed again? // 3.2.3 Store global_options store( global_options_and_arguments , go, desc); or // Problem #5: need to check how to store into struct global_options {} // 3.2.4 What command? std::string command = *command_options_and_arguments.begin(); // 3.2.5 Route to module handling command modules[ command ].handle_command( command_options_and_arguments ); or modules[ command ].handle_command( slice( command_options_and_arguments, 1 ) ); //without command itself // 3.2.5 Handle command in module handle_command( command_options_and_arguments ) { // define options_descriptions store( command_options_and_arguments, desc, command_options ); } --------- END OF IMPLEMENTATION (PSEUDOCODE) ROUND 1 ------------------ Current problems: 1. Early draft - I might have a limited ubdrestanding of some questions (for example, composing usage strings from command registrar) 2. No STL conformity - boost::po objects and data structures are hard to operate with. 3. Need to see how additional storage is supported (lexical_map, non-container storage) 4. It doesn't seem that library can help with config files in this use case What is needed: 0 .More sleep :-) 1. Some ideas regarding 2,3,4 2. Produce a working implementation (make it an boost::program_options example - seems like a significant amount of work, may be not now?). TO REVIEW MANAGER: Would it be possible to extend the review period for boost::program_options at least to another weekend? Misha Bergal MetaCommunications Engineering _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost