diff --git a/doc/design.xml b/doc/design.xml index 3051e5e..0881500 100644 --- a/doc/design.xml +++ b/doc/design.xml @@ -22,7 +22,7 @@ not mean strict 7-bit ASCII encoding, but rather "char" strings in local 8-bit encoding. - + Generally, "Unicode support" can mean many things, but for the program_options library it means that: @@ -54,7 +54,7 @@ passed to an ascii value will be converted using a codecvt facet (which may be specified by the user). - + @@ -68,8 +68,8 @@ Second, imagine a reusable library which has some options and exposes options description in its interface. If all options are either ascii or Unicode, and the library does not use any - Unicode strings, then the author will likely to use ascii options, which - would make the library unusable inside Unicode + Unicode strings, then the author is likely to use ascii options, making + the library unusable inside Unicode applications. Essentially, it would be necessary to provide two versions of the library -- ascii and Unicode. @@ -94,7 +94,7 @@ The primary question in implementing the Unicode support is whether to use templates and std::basic_string or to use some internal encoding and convert between internal and external encodings on - the interface boundaries. + the interface boundaries. The choice, mostly, is between code size and execution @@ -171,14 +171,14 @@ number of new instantiations. - + There's no clear leader, but the last point seems important, so UTF-8 - will be used. + will be used. - Choosing the UTF-8 encoding allows the use of existing parsers, - because 7-bit ascii characters retain their values in UTF-8, + Choosing the UTF-8 encoding allows the use of existing parsers, + because 7-bit ascii characters retain their values in UTF-8, so searching for 7-bit strings is simple. However, there are two subtle issues: @@ -197,16 +197,16 @@ almost universal encoding and since composing characters following '=' (and other characters with special meaning to the library) are not likely to appear. - + - +
Non-conventional Syntax - + Sometimes, standard command line syntaxes are not enough. For example, the gcc compiler has "-frtti" and -fno-rtti" options, and this syntax is not directly supported. @@ -57,14 +57,14 @@ store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo) .run(), vm); The complete example can be found in the "example/custom_syntax.cpp" - file. + file.
Response Files - response files + response files Some operating system have very low limits of the command line length. The common way to work around those limitations is using @@ -79,7 +79,7 @@ store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo) First, you need to define an option for the response file: -("response-file", value<string>(), +("response-file", value<string>(), "can be specified with '@name', too") @@ -120,14 +120,14 @@ if (vm.count("response-file")) { vector args; copy(tok.begin(), tok.end(), back_inserter(args)); // Parse the file and store the options - store(command_line_parser(args).options(desc).run(), vm); + store(command_line_parser(args).options(desc).run(), vm); } ]]> The complete example can be found in the "example/response_file.cpp" - file. + file. - +
@@ -146,7 +146,7 @@ if (vm.count("response-file")) { vector<string> args = split_winmain(lpCmdLine); store(command_line_parser(args).options(desc).run(), vm); - + The split_winmain function is overloaded for wchar_t strings, so can also be used in Unicode applications. @@ -223,7 +223,7 @@ visible.add(general).add(gui); variables_map vm; store(parse_command_line(ac, av, all), vm); -if (vm.count("help")) +if (vm.count("help")) { cout << visible; return 0; @@ -235,7 +235,7 @@ if (vm.count("help-module")) { } else if (s == "backend") { cout << backend; } else { - cout << "Unknown module '" + cout << "Unknown module '" << s << "' in the --help-module option\n"; return 1; } @@ -243,8 +243,8 @@ if (vm.count("help-module")) { } if (vm.count("num-threads")) { cout << "The 'num-threads' options was set to " - << vm["num-threads"].as() << "\n"; -} + << vm["num-threads"].as() << "\n"; +} ]]> When parsing the command line, all options are allowed. The "--help" message, however, does not include the "Backend options" group -- the @@ -253,7 +253,7 @@ if (vm.count("num-threads")) { option. The complete example can be found in the "example/option_groups.cpp" file. - +
@@ -276,7 +276,7 @@ public: }; ]]> and then overload the validate function: & values, magic_number* target_type, int) { @@ -290,16 +290,16 @@ void validate(boost::any& v, // one string, it's an error, and exception will be thrown. const string& s = validators::get_single_string(values); - // Do regex match and convert the interesting part to + // Do regex match and convert the interesting part to // int. smatch match; if (regex_match(s, match, r)) { v = any(magic_number(lexical_cast(match[1]))); } else { throw validation_error(validation_error::invalid_option_value); - } + } } -]]> +]]> The function takes four parameters. The first is the storage for the value, and in this case is either empty or contains an instance of the magic_number class. The second is the list of strings @@ -372,7 +372,7 @@ void validate(boost::any& v, locale::global(locale("")); which would set up the conversion facet according to the user's selected - locale. + locale. It's wise to check the status of the C++ locale support on your @@ -382,7 +382,7 @@ locale::global(locale("")); Go the the "test" directory and build the "test_convert" binary. - Set some non-ascii locale in the environmemt. On Linux, one can + Set some non-ascii locale in the environment. On Linux, one can run, for example: $ export LC_CTYPE=ru_RU.KOI8-R @@ -402,37 +402,37 @@ $ export LC_CTYPE=ru_RU.KOI8-R
Allowing Unknown Options - Usually, the library throws an exception on unknown option names. This - behaviour can be changed. For example, only some part of your application uses + Usually, the library throws an exception on unknown option names. This + behaviour can be changed. For example, only some part of your application uses Program_options, and you wish to pass unrecognized options to another part of the program, or even to another application. - To allow unregistered options on the command line, you need to use + To allow unregistered options on the command line, you need to use the &basic_command_line_parser; class for parsing (not &parse_command_line;) - and call the allow_unregistered + and call the allow_unregistered method of that class: -parsed_options parsed = - command_line_parser(argc, argv).options(desc).allow_unregistered().run(); +parsed_options parsed = + command_line_parser(argc, argv).options(desc).allow_unregistered().run(); - - For each token that looks like an option, but does not have a known name, - an instance of &basic_option; will be added to the result. - The string_key and value fields of the instance will contain results + + For each token that looks like an option, but does not have a known name, + an instance of &basic_option; will be added to the result. + The string_key and value fields of the instance will contain results of syntactic parsing of the token, the unregistered field will be set to true, and the original_tokens field will contain the token as it appeared on the command line. - If you want to pass the unrecognized options further, the + If you want to pass the unrecognized options further, the collect_unrecognized function can be used. The function will collect original tokens for all unrecognized values, and optionally, all found positional options. - Say, if your code handles a few options, but does not handles positional options at all, you can use the function like this: + Say, if your code handles a few options, but does not handle positional options at all, you can use the function like this: vector<string> to_pass_further = collect_unrecognized(parsed.options, include_positional); - - - + + +
diff --git a/doc/overview.xml b/doc/overview.xml index dcfbaf4..f7de296 100644 --- a/doc/overview.xml +++ b/doc/overview.xml @@ -22,7 +22,7 @@ The parsers component, which uses this information to find option names - and values in the input sources and return them. + and values in the input sources and return them. @@ -72,10 +72,10 @@
- The storage component is focused on storing options values. It + The storage component is focused on storing options values. It - + @@ -105,7 +105,7 @@ desc.add_options() ("help", "produce help") ("optimization", value<int>()->default_value(10), "optimization level") ; - + The call to the value function creates an instance of @@ -116,14 +116,14 @@ desc.add_options() essentially emulates named parameters of the constructor.) Calls to operator() on the object returned by add_options forward arguments to the constructor of the option_description - class and add the new instance. + class and add the new instance. Note that in addition to the value, library provides the bool_switch function, and user can write his own function which will return - other subclasses of value_semantic with + other subclasses of value_semantic with different behaviour. For the remainder of this section, we'll talk only about the value function. @@ -135,7 +135,7 @@ desc.add_options() where value is just a vector of strings (std::vector<std::string>). The semantic layer is responsible for converting the value of the option into more usable C++ - types. + types. This separation is an important part of library design. The parsers @@ -153,7 +153,7 @@ desc.add_options() boost::program_options::options_description class and some methods of the boost::program_options::value_semantic class - and includes: + and includes: @@ -193,7 +193,7 @@ desc.add_options() span several tokens. For example, the following command line is OK: test --help --compression 10 --verbose --email beadle@mars beadle2@mars - +
@@ -208,18 +208,18 @@ desc.add_options() The description string has one or more paragraphs, separated by the newline character ('\n'). When an option is output, the library will compute the indentation for options's description. Each of the - paragraph is output as a separate line with that intentation. If + paragraph is output as a separate line with that intentation. If a paragraph does not fit on one line it is spanned over multiple lines (which will have the same indentation). You may specify additional indent for the first specified by - inserting spaces at the beginning of a paragraph. For example: + inserting spaces at the beginning of a paragraph. For example: options.add_options() ("help", " A long help msg a long help msg a long help msg a long help msg a long help msg a long help msg a long help msg a long help msg ") - ; + ; will specify a four-space indent for the first line. The output will look like: @@ -230,14 +230,14 @@ msg a long help msg a long help msg a long help msg a long help msg ") help msg a long help msg a long help msg a long help msg - + For the case where line is wrapped, you can want an additional indent for wrapped text. This can be done by inserting a tabulator character ('\t') at the desired position. For - example: + example: options.add_options() ("well_formated", "As you can see this is a very well formatted @@ -249,7 +249,7 @@ bla bla bla bla bla bla bla bla bla bla bla\n" " Value2: \tdoes something else, bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla\n\n" " This paragraph has a first line indent only, -bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla"); +bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla"); will produce: @@ -280,20 +280,20 @@ bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla"); bla bla bla The tab character is removed before output. Only one tabulator per - paragraph is allowed, otherwisee an exception of type + paragraph is allowed, otherwise an exception of type program_options::error is thrown. Finally, the tabulator is ignored if - it's is not on the first line of the paragraph or is on the last + it is not on the first line of the paragraph or is on the last possible position of the first line.
- +
Semantic Information - - The semantic information is completely provided by the + + The semantic information is completely provided by the boost::program_options::value_semantic class. For example: @@ -303,18 +303,18 @@ desc.add_options() ("email", value< vector<string> >() ->composing()->notifier(&your_function), "email") ; - + These declarations specify that default value of the first option is 10, that the second option can appear several times and all instances should be merged, and that after parsing is done, the library will call function &your_function, passing the value of the - "email" option as argument. + "email" option as argument.
- +
Positional Options - + Our definition of option as (name, value) pairs is simple and useful, but in one special case of the command line, there's a problem. A command line can include a positional option, @@ -324,7 +324,7 @@ desc.add_options() Here, the "/etc/passwd" element does not have any option name. - + One solution is to ask the user to extract positional options himself and process them as he likes. However, there's a nicer approach -- provide a method to automatically assign the names for positional @@ -334,7 +334,7 @@ desc.add_options() archiver --compression=9 --input-file=/etc/passwd - + The &positional_options_desc; class allows the command line parser to assign the names. The class specifies how many positional options are allowed, and for each allowed option, specifies the name. For example: @@ -343,7 +343,7 @@ positional_options_description pd; pd.add("input-file", 1); specifies that for exactly one, first, positional option the name will be "input-file". - + It's possible to specify that a number, or even all positional options, be given the same name. @@ -360,11 +360,11 @@ pd.add("output-file", 2).add("input-file", -1); an instance of the &options_description; class. - +
- + - +
@@ -390,7 +390,7 @@ pd.add("output-file", 2).add("input-file", -1); The results of parsing are returned as an instance of the &parsed_options; class. Typically, that object is passed directly to the storage component. However, it also can be used directly, or undergo some additional - processing. + processing. @@ -422,8 +422,8 @@ pd.add("output-file", 2).add("input-file", -1); - - + +
@@ -512,7 +512,7 @@ visual_bell=yes gui.accessibility.visual_bell=yes - +
@@ -538,7 +538,7 @@ gui.accessibility.visual_bell=yes what option names must correspond to it. To describe the second parameter we need to consider naming conventions for environment variables. - + If you have an option that should be specified via environment variable, you need make up the variable's name. To avoid name clashes, we suggest that you use a sufficiently unique prefix for environment @@ -551,9 +551,9 @@ gui.accessibility.visual_bell=yes Say, if you pass BOOST_ as the prefix, and there are two variables, CVSROOT and BOOST_PROXY, the first variable will be ignored, and the second one will be converted to - option proxy. + option proxy. - + The above logic is sufficient in many cases, but it is also possible to pass, as the second parameter of the &parse_environment; function, any function taking a std::string and returning @@ -561,35 +561,35 @@ gui.accessibility.visual_bell=yes environment variable and should return either the name of the option, or empty string if the variable should be ignored. - +
Annotated List of Symbols - + The following table describes all the important symbols in the library, for quick access. - + - + - - + + Symbol Description - + - - + + Options description component - + &options_description; describes a number of options @@ -599,10 +599,10 @@ gui.accessibility.visual_bell=yes defines the option's value - + Parsers component - + &parse_command_line; parses command line (simpified interface) @@ -624,7 +624,7 @@ gui.accessibility.visual_bell=yes parses environment - + Storage component @@ -632,20 +632,20 @@ gui.accessibility.visual_bell=yes &variables_map; storage for option values - + - + - +
- +