|  | Home | Libraries | People | FAQ | More | 
In the tutorial section, we saw several examples of library usage. Here we will describe the overall library design including the primary components and their function.
The library has three main components:
The options description component, which describes the allowed options and what to do with the values of the options.
The parsers component, which uses this information to find option names and values in the input sources and return them.
The storage component, which provides the interface to access the value of an option. It also converts the string representation of values that parsers return into desired C++ types.
To be a little more concrete, the options_description
  class is from the options description component, the
  parse_command_line function is from the parsers component, and the
  variables_map class is from the storage component. 
In the tutorial we've learned how those components can be used by the
    main function to parse the command line and config
    file. Before going into the details of each component, a few notes about
    the world outside of main.
  
For that outside world, the storage component is the most important. It provides a class which stores all option values and that class can be freely passed around your program to modules which need access to the options. All the other components can be used only in the place where the actual parsing is the done. However, it might also make sense for the individual program modules to describe their options and pass them to the main module, which will merge all options. Of course, this is only important when the number of options is large and declaring them in one place becomes troublesome.
The options description component has three main classes:
      option_description, value_semantic and options_description. The
      first two together describe a single option. The option_description
      class contains the option's name, description and a pointer to value_semantic,
      which, in turn, knows the type of the option's value and can parse the value,
      apply the default value, and so on. The options_description class is a
      container for instances of option_description.
    
For almost every library, those classes could be created in a
      conventional way: that is, you'd create new options using constructors and
      then call the add method of options_description. However,
      that's overly verbose for declaring 20 or 30 options. This concern led
      to creation of the syntax that you've already seen:
options_description desc;
desc.add_options()
    ("help", "produce help")
    ("optimization", value<int>()->default_value(10), "optimization level")
    ;
The call to the value function creates an instance of
      a class derived from the value_semantic class: typed_value.
      That class contains the code to parse
      values of a specific type, and contains a number of methods which can be
      called by the user to specify additional information. (This
      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.
    
      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
      different behaviour. For the remainder of this section, we'll talk only
      about the value function.
    
The information about an option is divided into syntactic and
      semantic. Syntactic information includes the name of the option and the
      number of tokens which can be used to specify the value. This
      information is used by parsers to group tokens into (name, value) pairs,
      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.
    
This separation is an important part of library design. The parsers use only the syntactic layer, which takes away some of the freedom to use overly complex structures. For example, it's not easy to parse syntax like:
calc --expression=1 + 2/3
because it's not possible to parse
1 + 2/3
without knowing that it's a C expression. With a little help from the user the task becomes trivial, and the syntax clear:
calc --expression="1 + 2/3"
The syntactic information is provided by the
        boost::program_options::options_description class
        and some methods of the
        boost::program_options::value_semantic class
        and includes:
        
name of the option, used to identify the option inside the program,
description of the option, which can be presented to the user,
the allowed number of source tokens that comprise options's value, which is used during parsing.
Consider the following example:
options_description desc;
desc.add_options()
    ("help", "produce help message")
    ("compression", value<string>(), "compression level")
    ("verbose", value<string>()->implicit_value("0"), "verbosity level")
    ("email", value<string>()->multitoken(), "email to send to")
    ;
      
For the first parameter, we specify only the name and the description. No value can be specified in the parsed source. For the first option, the user must specify a value, using a single token. For the third option, the user may either provide a single token for the value, or no token at all. For the last option, the value can span several tokens. For example, the following command line is OK:
          test --help --compression 10 --verbose --email beadle@mars beadle2@mars
      
Sometimes the description can get rather long, for example, when several option's values need separate documentation. Below we describe some simple formatting mechanisms you can use.
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 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:
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:
  --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
        
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:
options.add_options()
      ("well_formated", "As you can see this is a very well formatted
option description.\n"
                        "You can do this for example:\n\n"
                        "Values:\n"
                        "  Value1: \tdoes this and that, bla bla bla bla
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");
        
will produce:
  --well_formated       As you can see this is a
                        very well formatted
                        option description.
                        You can do this for
                        example:
                        Values:
                          Value1: does this and
                                  that, bla bla
                                  bla bla bla bla
                                  bla bla bla bla
                                  bla bla bla bla
                                  bla
                          Value2: does something
                                  else, bla bla
                                  bla bla bla bla
                                  bla bla bla bla
                                  bla bla bla bla
                                  bla
                            This paragraph has a
                        first line indent only,
                        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, otherwise an exception of type program_options::error is thrown. Finally, the tabulator is ignored if it is not on the first line of the paragraph or is on the last possible position of the first line.
The semantic information is completely provided by the
        boost::program_options::value_semantic class. For
        example:
options_description desc;
desc.add_options()
    ("compression", value<int>()->default_value(10), "compression level")
    ("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.
      
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, which does not specify any name at all, for example:
          archiver --compression=9 /etc/passwd
        
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 options, so that the above command line can be interpreted the same way as:
          archiver --compression=9 --input-file=/etc/passwd
        
The positional_options_description 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:
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.
positional_options_description pd;
pd.add("output-file", 2).add("input-file", -1);
In the above example, the first two positional options will be associated with name "output-file", and any others with the name "input-file".
| ![[Warning]](../../../doc/src/images/warning.png) | Warning | 
|---|---|
| The  | 
The parsers component splits input sources into (name, value) pairs.
      Each parser looks for possible options and consults the options
      description component to determine if the option is known and how its value
      is specified. In the simplest case, the name is explicitly specified,
      which allows the library to decide if such option is known. If it is known, the
      value_semantic instance determines how the value is specified. (If
      it is not known, an exception is thrown.) Common
      cases are when the value is explicitly specified by the user, and when
      the value cannot be specified by the user, but the presence of the
      option implies some value (for example, true). So, the
      parser checks that the value is specified when needed and not specified
      when not needed, and returns new (name, value) pair.
    
      To invoke a parser you typically call a function, passing the options
      description and command line or config file or something else.
      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.
    
There are three exceptions to the above model -- all related to traditional usage of the command line. While they require some support from the options description component, the additional complexity is tolerable.
The name specified on the command line may be different from the option name -- it's common to provide a "short option name" alias to a longer name. It's also common to allow an abbreviated name to be specified on the command line.
Sometimes it's desirable to specify value as several tokens. For example, an option "--email-recipient" may be followed by several emails, each as a separate command line token. This behaviour is supported, though it can lead to parsing ambiguities and is not enabled by default.
The command line may contain positional options -- elements which don't have any name. The command line parser provides a mechanism to guess names for such options, as we've seen in the tutorial.
The storage component is responsible for:
Storing the final values of an option into a special class and in regular variables
Handling priorities among different sources.
Calling user-specified notify functions with the final
         values of options.
Let's consider an example:
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
store(parse_config_file("example.cfg", desc), vm);
notify(vm);
      The variables_map class is used to store the option
      values. The two calls to the store function add values
      found on the command line and in the config file. Finally the call to
      the notify function runs the user-specified notify
      functions and stores the values into regular variables, if needed.
    
The priority is handled in a simple way: the store
      function will not change the value of an option if it's already
      assigned. In this case, if the command line specifies the value for an
      option, any value in the config file is ignored.
    
| ![[Warning]](../../../doc/src/images/warning.png) | Warning | 
|---|---|
| Don't forget to call the  | 
The parse_config_file function implements parsing
      of simple INI-like configuration files. Configuration file
      syntax is line based:
      
A line in the form:
name=value
gives a value to an option.
A line in the form:
[section name]
        
introduces a new section in the configuration file.
The # character introduces a
        comment that spans until the end of the line.
The option names are relative to the section names, so the following configuration file part:
[gui.accessibility]
visual_bell=yes
      
is equivalent to
gui.accessibility.visual_bell=yes
      
When the option "gui.accessibility.visual_bell" has been added to the options
options_description desc;
desc.add_options()
    ("gui.accessibility.visual_bell", value<string>(), "flash screen for bell")
    ;
    
Environment variables are string variables
      which are available to all programs via the getenv function
      of C runtime library. The operating system allows to set initial values
      for a given user, and the values can be further changed on the command
      line.  For example, on Windows one can use the
      autoexec.bat file or (on recent versions) the
      Control Panel/System/Advanced/Environment Variables
      dialog, and on Unix —, the /etc/profile,
      ~/.profile and ~/.bash_profile
      files. Because environment variables can be set for the entire system,
      they are particularly suitable for options which apply to all programs.
      
The environment variables can be parsed with the
      parse_environment function. The function have several overloaded
      versions. The first parameter is always an options_description
      instance, and the second specifies what variables must be processed, and
      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
      variables. Also, while option names are most likely in lower case,
      environment variables conventionally use upper case. So, for an option
      name proxy the environment variable might be called
      BOOST_PROXY. During parsing, we need to perform reverse
      conversion of the names. This is accomplished by passing the choosen
      prefix as the second parameter of the parse_environment function.
      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.
      
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
      std::string. That function will be called for each
      environment variable and should return either the name of the option, or
      empty string if the variable should be ignored. An example showing this
      method can be found in "example/env_options.cpp".
      
Everything that is passed in on the command line, as an environmental variable, or in a config file is a string. For values that need to be used as a non-string type, the value in the variables_map will attempt to convert it to the correct type.
Integers and floating point values are converted using Boost's lexical_cast. It will accept integer values such as "41" or "-42". It will accept floating point numbers such as "51.1", "-52.1", "53.1234567890" (as a double), "54", "55.", ".56", "57.1e5", "58.1E5", ".591e5", "60.1e-5", "-61.1e5", "-62.1e-5", etc. Unfortunately, hex, octal, and binary representations that are available in C++ literals are not supported by lexical_cast, and thus will not work with program_options.
Booleans a special in that there are multiple ways to come at them. 
    Similar to another value type, it can be specified as ("my-option",
    value<bool>()), and then set as:
example --my-option=true
    
However, more typical is that boolean values are set by the simple
    presence of a switch. This is enabled by bool_switch as in 
    ("other-option", bool_switch()). This will cause the value to
    default to false and it will become true if the switch is found:
example --other-switch
    
When a boolean does take a parameter, there are several options. Those that evaluate to true in C++ are: "true", "yes", "on", "1". Those that evaluate to false in C++ are: "false", "no", "off", "0". In addition, when reading from a config file, the option name with an equal sign and no value after it will also evaluate to true.
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 | 
| value | defines the option's value | 
| Parsers component | |
| parse_command_line | parses command line (simpified interface) | 
| basic_command_line_parser | parses command line (extended interface) | 
| parse_config_file | parses config file | 
| parse_environment | parses environment | 
| Storage component | |
| variables_map | storage for option values |