[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
import toolset ;
toolset.using doxygen ;
boostbook program_option
: program_options.xml
: <implicit-dependency>autodoc
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
;
doxygen autodoc
: [ glob ../../../boost/program_options/*.hpp ] ;
###############################################################################
alias boostdoc
: program_options.xml
:
: <dependency>autodoc
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
[
<!ENTITY % entities SYSTEM "program_options.ent" >
%entities;
]>
<section>
<title>Acknowledgements</title>
<para>I'm very gratefull to all the people who helped with the development,
by discussion, fixes, and as users. It was pleasant
to see all that involvement, which made the library much better than it
would be otherwise.
</para>
<para>In the early stages, the library was affected by discussions with
Gennadiy Rozental, William Kempf and Alexander Okhotin.
</para>
<para>Hartmut Kaiser was the first person to try the library on his project
and send a number of suggestions and fixes.
</para>
<para>The formal review lead to numerous comments and enhancements. Pavol
Droba helped with the option description semantic. Gennadiy Rozental has
criticised many aspects of the library which caused various simplifications.
Pavel Vozenilek did carefull review of the implementation. A number of
comments were made by:
<itemizedlist>
<listitem><para>David Abrahams</para></listitem>
<listitem><para>Neal D. Becker</para></listitem>
<listitem><para>Misha Bergal</para></listitem>
<listitem><para>James Curran</para></listitem>
<listitem><para>Carl Daniel</para></listitem>
<listitem><para>Beman Dawes</para></listitem>
<listitem><para>Tanton Gibbs</para></listitem>
<listitem><para>Holger Grund</para></listitem>
<listitem><para>Hartmut Kaiser</para></listitem>
<listitem><para>Petr Kocmid</para></listitem>
<listitem><para>Baptiste Lepilleur</para></listitem>
<listitem><para>Marcelo E. Magallon</para></listitem>
<listitem><para>Chuck Messenger</para></listitem>
<listitem><para>John Torjo</para></listitem>
<listitem><para>Matthias Troyer</para></listitem>
</itemizedlist>
</para>
<para>Doug Gregor and Reece Dunn helped to resolve the issues with Boostbook
version of the documentation.
</para>
<para>Even after review, a number of people have helped with further development:
<itemizedlist>
<listitem><para>Rob Lievaart</para></listitem>
<listitem><para>Thorsten Ottosen</para></listitem>
<listitem><para>Joseph Wu</para></listitem>
<listitem><para>Ferdinand Prantl</para></listitem>
<listitem><para>Miro Jurisic</para></listitem>
<listitem><para>John Maddock</para></listitem>
<listitem><para>Janusz Piwowarski</para></listitem>
<listitem><para>Charles Brockman</para></listitem>
<listitem><para>Jonathan Wakely</para></listitem>
</itemizedlist>
</para>
</section>
<!--
Local Variables:
mode: xml
sgml-indent-data: t
sgml-parent-document: ("program_options.xml" "section")
sgml-set-face: t
End:
-->

View File

@@ -0,0 +1,43 @@
CLI (part of the Jarakta project)
http://jakarta.apache.org/commons/cli/index.html
This is Java library.
The interface seems to be similiar, except for data storage.
1. Instead of variables_map, the library can store the data
as Java system properties.
2. The class Option, which uses to describe the data, is also
used to keep the value. In contract, I keep them in separate
place. This facilitate using the same options description
for different data sources.
TODO: Need to check that Option.setType method does.
Werken.opt
http://sourceforge.net/projects/werken-opt/
This is a much simpler library then CLI, which
somewhat less features.
JArgs
http://jargs.sourceforge.net/
Another Java library. Has a fixed set of value types it can
handle.
Options (by Brad Appleton)
http://www.enteract.com/~bradapp/ftp/src/libs/C++/Options.html
This is very lean library. It does not provide argument validation,
and the only iterface is iteration over arguments. An interesting
iterface decision is using chars to identify presense of option's parameters.
This may be moved to my library (|, :, ?, *, +)
Cmdline (by Brad Appleton)
http://www.enteract.com/~bradapp/ftp/src/libs/C++/CmdLine.html
This library provides options validation and storage. Unfortunately
1. Only a fixed set of data types is supported.
2. It's intrusive -- one has to declare variable of "class ArgChar" or
something, and then extract data from there.

View File

@@ -0,0 +1,571 @@
<?xml version="1.0" standalone="yes"?>
<library-reference><header name="boost/program_options/cmdline.hpp">
<namespace name="boost">
<namespace name="program_options">
<namespace name="command_line_style">
<enum name="style_t"><enumvalue name="allow_long"><default>= 1</default><purpose>Allow "--long_name" style. </purpose></enumvalue><enumvalue name="allow_short"><default>= allow_long &lt;&lt; 1</default><purpose>Allow "-&lt;single character" style. </purpose></enumvalue><enumvalue name="allow_dash_for_short"><default>= allow_short &lt;&lt; 1</default><purpose>Allow "-" in short options. </purpose></enumvalue><enumvalue name="allow_slash_for_short"><default>= allow_dash_for_short &lt;&lt; 1</default><purpose>Allow "/" in short options. </purpose></enumvalue><enumvalue name="long_allow_adjacent"><default>= allow_slash_for_short &lt;&lt; 1</default><description><para>Allow option parameter in the same token for long option, like in --foo=10 </para></description></enumvalue><enumvalue name="long_allow_next"><default>= long_allow_adjacent &lt;&lt; 1</default><description><para>Allow option parameter in the next token for long options. </para></description></enumvalue><enumvalue name="short_allow_adjacent"><default>= long_allow_next &lt;&lt; 1</default><description><para>Allow option parameter in the same token for short options. </para></description></enumvalue><enumvalue name="short_allow_next"><default>= short_allow_adjacent &lt;&lt; 1</default><description><para>Allow option parameter in the next token for short options. </para></description></enumvalue><enumvalue name="allow_sticky"><default>= short_allow_next &lt;&lt; 1</default><description><para>Allow to merge several short options together, so that "-s -k" become "-sk". All of the options but last should accept no parameter. For example, if "-s" accept a parameter, then "k" will be taken as parameter, not another short option. Dos-style short options cannot be sticky. </para></description></enumvalue><enumvalue name="allow_guessing"><default>= allow_sticky &lt;&lt; 1</default><description><para>Allow abbreviated spellings for long options, if they unambiguously identify long option. No long option name should be prefix of other long option name if guessing is in effect. </para></description></enumvalue><enumvalue name="long_case_insensitive"><default>= allow_guessing &lt;&lt; 1</default><description><para>Ignore the difference in case for long options. </para></description></enumvalue><enumvalue name="short_case_insensitive"><default>= long_case_insensitive &lt;&lt; 1</default><description><para>Ignore the difference in case for short options. </para></description></enumvalue><enumvalue name="case_insensitive"><default>= (long_case_insensitive | short_case_insensitive)</default><description><para>Ignore the difference in case for all options. </para></description></enumvalue><enumvalue name="allow_long_disguise"><default>= short_case_insensitive &lt;&lt; 1</default><description><para>Allow long options with single option starting character, e.g <computeroutput>-foo=10</computeroutput> </para></description></enumvalue><enumvalue name="unix_style"><default>= (allow_short | short_allow_adjacent | short_allow_next
| allow_long | long_allow_adjacent | long_allow_next
| allow_sticky | allow_guessing
| allow_dash_for_short)</default><description><para>The more-or-less traditional unix style. </para></description></enumvalue><enumvalue name="default_style"><default>= unix_style</default><description><para>The default style. </para></description></enumvalue><description><para>Various possible styles of options.</para><para>There are "long" options, which start with "--" and "short", which start with either "-" or "/". Both kinds can be allowed or disallowed, see allow_long and allow_short. The allowed character for short options is also configurable.</para><para>Option's value can be specified in the same token as name ("--foo=bar"), or in the next token.</para><para>It's possible to introduce long options by the same character as short options, see allow_long_disguise.</para><para>Finally, guessing (specifying only prefix of option) and case insensitive processing are supported. </para></description></enum>
</namespace>
</namespace>
</namespace>
</header>
<header name="boost/program_options/config.hpp">
<macro name="BOOST_PROGRAM_OPTIONS_DECL"/>
</header>
<header name="boost/program_options/environment_iterator.hpp">
<namespace name="boost">
<class name="environment_iterator"><inherit access="public">boost::eof_iterator&lt; environment_iterator, std::pair&lt; std::string, std::string &gt; &gt;</inherit><method-group name="public member functions">
<method name="get"><type>void</type></method>
</method-group>
<constructor><parameter name="environment"><paramtype>char **</paramtype></parameter></constructor>
<constructor/>
</class></namespace>
</header>
<header name="boost/program_options/eof_iterator.hpp">
<namespace name="boost">
<class name="eof_iterator"><template>
<template-type-parameter name="Derived"/>
<template-type-parameter name="ValueType"/>
</template><inherit access="public">iterator_facade&lt; Derived, const ValueType, forward_traversal_tag &gt;</inherit><description><para>The '<classname alt="boost::eof_iterator">eof_iterator</classname>' class is useful for constructing forward iterators in cases where iterator extract data from some source and it's easy to detect 'eof' -- i.e. the situation where there's no data. One apparent example is reading lines from a file.</para><para>Implementing such iterators using 'iterator_facade' directly would require to create class with three core operation, a couple of constructors. When using '<classname alt="boost::eof_iterator">eof_iterator</classname>', the derived class should define only one method to get new value, plus a couple of constructors.</para><para>The basic idea is that iterator has 'eof' bit. Two iterators are equal only if both have their 'eof' bits set. The 'get' method either obtains the new value or sets the 'eof' bit.</para><para>Specifically, derived class should define:</para><para><orderedlist>
<listitem><para>A default constructor, which creates iterator with 'eof' bit set. The constructor body should call 'found_eof' method defined here.</para></listitem><listitem><para>Some other constructor. It should initialize some 'data pointer' used in iterator operation and then call 'get'.</para></listitem><listitem><para>The 'get' method. It should operate this way:<itemizedlist>
<listitem><para>look at some 'data pointer' to see if new element is available; if not, it should call 'found_eof'.</para></listitem><listitem><para>extract new element and store it at location returned by the 'value' method.</para></listitem><listitem><para>advance the data pointer.</para></listitem></itemizedlist>
</para></listitem></orderedlist>
</para><para>Essentially, the 'get' method has the functionality of both 'increment' and 'dereference'. It's very good for the cases where data extraction implicitly moves data pointer, like for stream operation. </para></description><method-group name="public member functions">
</method-group>
<constructor/>
<method-group name="protected member functions">
<method name="value"><type>ValueType &amp;</type><description><para>Returns the reference which should be used by derived class to store the next value. </para></description></method>
<method name="found_eof"><type>void</type><description><para>Should be called by derived class to indicate that it can't produce next element. </para></description></method>
</method-group>
<method-group name="private member functions">
<method name="increment"><type>void</type></method>
<method name="equal" cv="const"><type>bool</type><parameter name="other"><paramtype>const <classname>eof_iterator</classname> &amp;</paramtype></parameter></method>
<method name="dereference" cv="const"><type>const ValueType &amp;</type></method>
</method-group>
</class></namespace>
</header>
<header name="boost/program_options/errors.hpp">
<namespace name="boost">
<namespace name="program_options">
<class name="error"><inherit access="public">logic_error</inherit><description><para>Base class for all errors in the library. </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="xwhat"><paramtype>const std::string &amp;</paramtype></parameter></constructor>
</class><class name="too_many_positional_options_error"><inherit access="public">boost::program_options::error</inherit><description><para>Class thrown when there are too many positional options. This is a programming error. </para></description><method-group name="public member functions">
</method-group>
<constructor/>
</class><class name="invalid_command_line_style"><inherit access="public">boost::program_options::error</inherit><description><para>Class thrown when there are programming error related to style </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="msg"><paramtype>const std::string &amp;</paramtype></parameter></constructor>
</class><class name="reading_file"><inherit access="public">boost::program_options::error</inherit><description><para>Class thrown if config file can not be read </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="filename"><paramtype>const char *</paramtype></parameter></constructor>
</class><class name="error_with_option_name"><inherit access="public">boost::program_options::error</inherit><description><para>Base class for most exceptions in the library.</para><para>Substitutes the values for the parameter name placeholders in the template to create the human readable error message</para><para>Placeholders are surrounded by % signs: example% Poor man's version of boost::format</para><para>If a parameter name is absent, perform default substitutions instead so ugly placeholders are never left in-place.</para><para>Options are displayed in "canonical" form This is the most unambiguous form of the <emphasis>parsed</emphasis> option name and would correspond to option_description::format_name() i.e. what is shown by print_usage()</para><para>The "canonical" form depends on whether the option is specified in short or long form, using dashes or slashes or without a prefix (from a configuration file) </para></description><data-member name="m_error_template"><type>std::string</type><description><para>template with placeholders </para></description></data-member>
<method-group name="public member functions">
<method name="set_substitute"><type>void</type><parameter name="parameter_name"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="value"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Substitute parameter_name-&gt;value to create the error message from the error template </para></description></method>
<method name="set_substitute_default"><type>void</type><parameter name="parameter_name"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="from"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="to"><paramtype>const std::string &amp;</paramtype></parameter><description><para>If the parameter is missing, then make the from-&gt;to substitution instead </para></description></method>
<method name="add_context"><type>void</type><parameter name="option_name"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="original_token"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="option_style"><paramtype>int</paramtype></parameter><description><para>Add context to an exception </para></description></method>
<method name="set_prefix"><type>void</type><parameter name="option_style"><paramtype>int</paramtype></parameter></method>
<method name="set_option_name" specifiers="virtual"><type>void</type><parameter name="option_name"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Overridden in <classname alt="boost::program_options::error_with_no_option_name">error_with_no_option_name</classname> </para></description></method>
<method name="get_option_name" cv="const"><type>std::string</type></method>
<method name="set_original_token"><type>void</type><parameter name="original_token"><paramtype>const std::string &amp;</paramtype></parameter></method>
<method name="what" cv="const" specifiers="virtual"><type>const char *</type><description><para>Creates the error_message on the fly Currently a thin wrapper for substitute_placeholders() </para></description></method>
</method-group>
<constructor><parameter name="template_"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="option_name"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="original_token"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="option_style"><paramtype>int</paramtype><default>0</default></parameter></constructor>
<destructor><description><para>gcc says that throw specification on dtor is loosened without this line </para></description></destructor>
<method-group name="protected member functions">
<method name="substitute_placeholders" cv="const" specifiers="virtual"><type>void</type><parameter name="error_template"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Makes all substitutions using the template </para></description></method>
<method name="replace_token" cv="const"><type>void</type><parameter name="from"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="to"><paramtype>const std::string &amp;</paramtype></parameter></method>
<method name="get_canonical_option_name" cv="const"><type>std::string</type><description><para>Construct option name in accordance with the appropriate prefix style: i.e. long dash or short slash etc </para></description></method>
<method name="get_canonical_option_prefix" cv="const"><type>std::string</type></method>
</method-group>
</class><class name="multiple_values"><inherit access="public">boost::program_options::error_with_option_name</inherit><description><para>Class thrown when there are several option values, but user called a method which cannot return them all. </para></description><method-group name="public member functions">
</method-group>
<constructor/>
<destructor/>
</class><class name="multiple_occurrences"><inherit access="public">boost::program_options::error_with_option_name</inherit><description><para>Class thrown when there are several occurrences of an option, but user called a method which cannot return them all. </para></description><method-group name="public member functions">
</method-group>
<constructor/>
<destructor/>
</class><class name="required_option"><inherit access="public">boost::program_options::error_with_option_name</inherit><description><para>Class thrown when a required/mandatory option is missing </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="option_name"><paramtype>const std::string &amp;</paramtype></parameter></constructor>
<destructor/>
</class><class name="error_with_no_option_name"><inherit access="public">boost::program_options::error_with_option_name</inherit><description><para>Base class of unparsable options, when the desired option cannot be identified.</para><para>It makes no sense to have an option name, when we can't match an option to the parameter</para><para>Having this a part of the <classname alt="boost::program_options::error_with_option_name">error_with_option_name</classname> hierachy makes error handling a lot easier, even if the name indicates some sort of conceptual dissonance! </para></description><method-group name="public member functions">
<method name="set_option_name" specifiers="virtual"><type>void</type><parameter name=""><paramtype>const std::string &amp;</paramtype></parameter><description><para>Does NOT set option name, because no option name makes sense </para></description></method>
</method-group>
<constructor><parameter name="template_"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="original_token"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter></constructor>
<destructor/>
</class><class name="unknown_option"><inherit access="public">boost::program_options::error_with_no_option_name</inherit><description><para>Class thrown when option name is not recognized. </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="original_token"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter></constructor>
<destructor/>
</class><class name="ambiguous_option"><inherit access="public">boost::program_options::error_with_no_option_name</inherit><description><para>Class thrown when there's ambiguity amoung several possible options. </para></description><method-group name="public member functions">
<method name="alternatives" cv="const"><type>const std::vector&lt; std::string &gt; &amp;</type></method>
</method-group>
<constructor><parameter name="xalternatives"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter></constructor>
<destructor/>
<method-group name="protected member functions">
<method name="substitute_placeholders" cv="const" specifiers="virtual"><type>void</type><parameter name="error_template"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Makes all substitutions using the template </para></description></method>
</method-group>
</class><class name="invalid_syntax"><inherit access="public">boost::program_options::error_with_option_name</inherit><description><para>Class thrown when there's syntax error either for command line or config file options. See derived children for concrete classes. </para></description><enum name="kind_t"><enumvalue name="long_not_allowed"><default>= 30</default></enumvalue><enumvalue name="long_adjacent_not_allowed"/><enumvalue name="short_adjacent_not_allowed"/><enumvalue name="empty_adjacent_parameter"/><enumvalue name="missing_parameter"/><enumvalue name="extra_parameter"/><enumvalue name="unrecognized_line"/></enum>
<method-group name="public member functions">
<method name="kind" cv="const"><type>kind_t</type></method>
<method name="tokens" cv="const" specifiers="virtual"><type>std::string</type><description><para>Convenience functions for backwards compatibility </para></description></method>
</method-group>
<constructor><parameter name="kind"><paramtype>kind_t</paramtype></parameter><parameter name="option_name"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="original_token"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="option_style"><paramtype>int</paramtype><default>0</default></parameter></constructor>
<destructor/>
<method-group name="protected member functions">
<method name="get_template"><type>std::string</type><parameter name="kind"><paramtype>kind_t</paramtype></parameter><description><para>Used to convert kind_t to a related error text </para></description></method>
</method-group>
</class><class name="invalid_config_file_syntax"><inherit access="public">boost::program_options::invalid_syntax</inherit><method-group name="public member functions">
<method name="tokens" cv="const" specifiers="virtual"><type>std::string</type><description><para>Convenience functions for backwards compatibility </para></description></method>
</method-group>
<constructor><parameter name="invalid_line"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="kind"><paramtype>kind_t</paramtype></parameter></constructor>
<destructor/>
</class><class name="invalid_command_line_syntax"><inherit access="public">boost::program_options::invalid_syntax</inherit><description><para>Class thrown when there are syntax errors in given command line </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="kind"><paramtype>kind_t</paramtype></parameter><parameter name="option_name"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="original_token"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="option_style"><paramtype>int</paramtype><default>0</default></parameter></constructor>
<destructor/>
</class><class name="validation_error"><inherit access="public">boost::program_options::error_with_option_name</inherit><description><para>Class thrown when value of option is incorrect. </para></description><enum name="kind_t"><enumvalue name="multiple_values_not_allowed"><default>= 30</default></enumvalue><enumvalue name="at_least_one_value_required"/><enumvalue name="invalid_bool_value"/><enumvalue name="invalid_option_value"/><enumvalue name="invalid_option"/></enum>
<method-group name="public member functions">
</method-group>
<constructor><parameter name="kind"><paramtype>kind_t</paramtype></parameter><parameter name="option_name"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="original_token"><paramtype>const std::string &amp;</paramtype><default>""</default></parameter><parameter name="option_style"><paramtype>int</paramtype><default>0</default></parameter></constructor>
<destructor/>
<method-group name="protected member functions">
<method name="get_template"><type>std::string</type><parameter name="kind"><paramtype>kind_t</paramtype></parameter><description><para>Used to convert kind_t to a related error text </para></description></method>
</method-group>
</class><class name="invalid_option_value"><inherit access="public">boost::program_options::validation_error</inherit><description><para>Class thrown if there is an invalid option value given </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="value"><paramtype>const std::string &amp;</paramtype></parameter></constructor>
<constructor><parameter name="value"><paramtype>const std::wstring &amp;</paramtype></parameter></constructor>
</class><class name="invalid_bool_value"><inherit access="public">boost::program_options::validation_error</inherit><description><para>Class thrown if there is an invalid bool value given </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="value"><paramtype>const std::string &amp;</paramtype></parameter></constructor>
</class>
<function name="strip_prefixes"><type>std::string</type><parameter name="text"><paramtype>const std::string &amp;</paramtype></parameter></function>
</namespace>
</namespace>
</header>
<header name="boost/program_options/option.hpp">
<namespace name="boost">
<namespace name="program_options">
<class name="basic_option"><template>
<template-type-parameter name="charT"/>
</template><description><para>Option found in input source. Contains a key and a value. The key, in turn, can be a string (name of an option), or an integer (position in input source) -- in case no name is specified. The latter is only possible for command line. The template parameter specifies the type of char used for storing the option's value. </para></description><data-member name="string_key"><type>std::string</type><description><para>String key of this option. Intentionally independent of the template parameter. </para></description></data-member>
<data-member name="position_key"><type>int</type><description><para>Position key of this option. All options without an explicit name are sequentially numbered starting from 0. If an option has explicit name, 'position_key' is equal to -1. It is possible that both position_key and string_key is specified, in case name is implicitly added. </para></description></data-member>
<data-member name="value"><type>std::vector&lt; std::basic_string&lt; charT &gt; &gt;</type><description><para>Option's value </para></description></data-member>
<data-member name="original_tokens"><type>std::vector&lt; std::basic_string&lt; charT &gt; &gt;</type><description><para>The original unchanged tokens this option was created from. </para></description></data-member>
<data-member name="unregistered"><type>bool</type><description><para>True if option was not recognized. In that case, 'string_key' and 'value' are results of purely syntactic parsing of source. The original tokens can be recovered from the "original_tokens" member. </para></description></data-member>
<data-member name="case_insensitive"><type>bool</type><description><para>True if string_key has to be handled case insensitive. </para></description></data-member>
<method-group name="public member functions">
</method-group>
<constructor/>
<constructor><parameter name="xstring_key"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="xvalue"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter></constructor>
</class><typedef name="option"><type><classname>basic_option</classname>&lt; char &gt;</type></typedef>
<typedef name="woption"><type><classname>basic_option</classname>&lt; wchar_t &gt;</type></typedef>
</namespace>
</namespace>
</header>
<header name="boost/program_options/options_description.hpp">
<namespace name="boost">
<namespace name="program_options">
<class name="option_description"><description><para>Describes one possible command line/config file option. There are two kinds of properties of an option. First describe it syntactically and are used only to validate input. Second affect interpretation of the option, for example default value for it or function that should be called when the value is finally known. Routines which perform parsing never use second kind of properties -- they are side effect free. <para><emphasis role="bold">See Also:</emphasis><para><classname alt="boost::program_options::options_description">options_description</classname> </para></para>
</para></description><enum name="match_result"><enumvalue name="no_match"/><enumvalue name="full_match"/><enumvalue name="approximate_match"/></enum>
<method-group name="public member functions">
<method name="match" cv="const"><type>match_result</type><parameter name="option"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="approx"><paramtype>bool</paramtype></parameter><parameter name="long_ignore_case"><paramtype>bool</paramtype></parameter><parameter name="short_ignore_case"><paramtype>bool</paramtype></parameter><description><para>Given 'option', specified in the input source, returns 'true' if 'option' specifies *this. </para></description></method>
<method name="key" cv="const"><type>const std::string &amp;</type><parameter name="option"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Returns the key that should identify the option, in particular in the <classname alt="boost::program_options::variables_map">variables_map</classname> class. The 'option' parameter is the option spelling from the input source. If option name contains '*', returns 'option'. If long name was specified, it's the long name, otherwise it's a short name with prepended '-'. </para></description></method>
<method name="canonical_display_name" cv="const"><type>std::string</type><parameter name="canonical_option_style"><paramtype>int</paramtype><default>0</default></parameter><description><para>Returns the canonical name for the option description to enable the user to recognised a matching option. 1) For short options ('-', '/'), returns the short name prefixed. 2) For long options ('' / '-') returns the long name prefixed 3) All other cases, returns the long name (if present) or the short name, unprefixed. </para></description></method>
<method name="long_name" cv="const"><type>const std::string &amp;</type></method>
<method name="description" cv="const"><type>const std::string &amp;</type><purpose>Explanation of this option. </purpose></method>
<method name="semantic" cv="const"><type>shared_ptr&lt; const <classname>value_semantic</classname> &gt;</type><purpose>Semantic of option's value. </purpose></method>
<method name="format_name" cv="const"><type>std::string</type><purpose>Returns the option name, formatted suitably for usage message. </purpose></method>
<method name="format_parameter" cv="const"><type>std::string</type><description><para>Returns the parameter name and properties, formatted suitably for usage message. </para></description></method>
</method-group>
<constructor/>
<constructor><parameter name="name"><paramtype>const char *</paramtype></parameter><parameter name="s"><paramtype>const <classname>value_semantic</classname> *</paramtype></parameter><description><para>Initializes the object with the passed data.</para><para>Note: it would be nice to make the second parameter auto_ptr, to explicitly pass ownership. Unfortunately, it's often needed to create objects of types derived from '<classname alt="boost::program_options::value_semantic">value_semantic</classname>': <classname alt="boost::program_options::options_description">options_description</classname> d; d.add_options()("a", parameter&lt;int&gt;("n")-&gt;default_value(1)); Here, the static type returned by 'parameter' should be derived from <classname alt="boost::program_options::value_semantic">value_semantic</classname>.</para><para>Alas, derived-&gt;base conversion for auto_ptr does not really work, see <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf</ulink> <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#84">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#84</ulink></para><para>So, we have to use plain old pointers. Besides, users are not expected to use the constructor directly.</para><para>The 'name' parameter is interpreted by the following rules:<itemizedlist>
<listitem><para>if there's no "," character in 'name', it specifies long name</para></listitem><listitem><para>otherwise, the part before "," specifies long name and the part after -- short name. </para></listitem></itemizedlist>
</para></description></constructor>
<constructor><parameter name="name"><paramtype>const char *</paramtype></parameter><parameter name="s"><paramtype>const <classname>value_semantic</classname> *</paramtype></parameter><parameter name="description"><paramtype>const char *</paramtype></parameter><description><para>Initializes the class with the passed data. </para></description></constructor>
<destructor/>
<method-group name="private member functions">
<method name="set_name"><type><classname>option_description</classname> &amp;</type><parameter name="name"><paramtype>const char *</paramtype></parameter></method>
</method-group>
</class><class name="options_description_easy_init"><description><para>Class which provides convenient creation syntax to <classname alt="boost::program_options::option_description">option_description</classname>. </para></description><method-group name="public member functions">
<method name="operator()"><type><classname>options_description_easy_init</classname> &amp;</type><parameter name="name"><paramtype>const char *</paramtype></parameter><parameter name="description"><paramtype>const char *</paramtype></parameter></method>
<method name="operator()"><type><classname>options_description_easy_init</classname> &amp;</type><parameter name="name"><paramtype>const char *</paramtype></parameter><parameter name="s"><paramtype>const <classname>value_semantic</classname> *</paramtype></parameter></method>
<method name="operator()"><type><classname>options_description_easy_init</classname> &amp;</type><parameter name="name"><paramtype>const char *</paramtype></parameter><parameter name="s"><paramtype>const <classname>value_semantic</classname> *</paramtype></parameter><parameter name="description"><paramtype>const char *</paramtype></parameter></method>
</method-group>
<constructor><parameter name="owner"><paramtype><classname>options_description</classname> *</paramtype></parameter></constructor>
</class><class name="options_description"><description><para>A set of option descriptions. This provides convenient interface for adding new option (the add_options) method, and facilities to search for options by name.</para><para>See here for option adding interface discussion. <para><emphasis role="bold">See Also:</emphasis><para><classname alt="boost::program_options::option_description">option_description</classname> </para></para>
</para></description><data-member name="m_default_line_length" specifiers="static"><type>const unsigned</type></data-member>
<method-group name="public member functions">
<method name="add"><type>void</type><parameter name="desc"><paramtype>shared_ptr&lt; <classname>option_description</classname> &gt;</paramtype></parameter><description><para>Adds new variable description. Throws duplicate_variable_error if either short or long name matches that of already present one. </para></description></method>
<method name="add"><type><classname>options_description</classname> &amp;</type><parameter name="desc"><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><description><para>Adds a group of option description. This has the same effect as adding all option_descriptions in 'desc' individually, except that output operator will show a separate group. Returns *this. </para></description></method>
<method name="get_option_column_width" cv="const"><type>unsigned</type><description><para>Find the maximum width of the option column, including options in groups. </para></description></method>
<method name="add_options"><type><classname>options_description_easy_init</classname></type><description><para>Returns an object of implementation-defined type suitable for adding options to <classname alt="boost::program_options::options_description">options_description</classname>. The returned object will have overloaded operator() with parameter type matching '<classname alt="boost::program_options::option_description">option_description</classname>' constructors. Calling the operator will create new <classname alt="boost::program_options::option_description">option_description</classname> instance and add it. </para></description></method>
<method name="find" cv="const"><type>const <classname>option_description</classname> &amp;</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="approx"><paramtype>bool</paramtype></parameter><parameter name="long_ignore_case"><paramtype>bool</paramtype><default>false</default></parameter><parameter name="short_ignore_case"><paramtype>bool</paramtype><default>false</default></parameter></method>
<method name="find_nothrow" cv="const"><type>const <classname>option_description</classname> *</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="approx"><paramtype>bool</paramtype></parameter><parameter name="long_ignore_case"><paramtype>bool</paramtype><default>false</default></parameter><parameter name="short_ignore_case"><paramtype>bool</paramtype><default>false</default></parameter></method>
<method name="options" cv="const"><type>const std::vector&lt; shared_ptr&lt; <classname>option_description</classname> &gt; &gt; &amp;</type></method>
<method name="print" cv="const"><type>void</type><parameter name="os"><paramtype>std::ostream &amp;</paramtype></parameter><parameter name="width"><paramtype>unsigned</paramtype><default>0</default></parameter><description><para>Outputs 'desc' to the specified stream, calling 'f' to output each <classname alt="boost::program_options::option_description">option_description</classname> element. </para></description></method>
</method-group>
<constructor><parameter name="line_length"><paramtype>unsigned</paramtype><default>m_default_line_length</default></parameter><parameter name="min_description_length"><paramtype>unsigned</paramtype><default>m_default_line_length/2</default></parameter><description><para>Creates the instance. </para></description></constructor>
<constructor><parameter name="caption"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="line_length"><paramtype>unsigned</paramtype><default>m_default_line_length</default></parameter><parameter name="min_description_length"><paramtype>unsigned</paramtype><default>m_default_line_length/2</default></parameter><description><para>Creates the instance. The 'caption' parameter gives the name of this '<classname alt="boost::program_options::options_description">options_description</classname>' instance. Primarily useful for output. The 'description_length' specifies the number of columns that should be reserved for the description text; if the option text encroaches into this, then the description will start on the next line. </para></description></constructor>
<method-group name="friend functions">
<method name="operator&lt;&lt;"><type>friend BOOST_PROGRAM_OPTIONS_DECL std::ostream &amp;</type><parameter name="os"><paramtype>std::ostream &amp;</paramtype></parameter><parameter name="desc"><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><description><para>Produces a human readable output of 'desc', listing options, their descriptions and allowed parameters. Other <classname alt="boost::program_options::options_description">options_description</classname> instances previously passed to add will be output separately. </para></description></method>
</method-group>
</class><class name="duplicate_option_error"><inherit access="public">boost::program_options::error</inherit><description><para>Class thrown when duplicate option description is found. </para></description><method-group name="public member functions">
</method-group>
<constructor><parameter name="xwhat"><paramtype>const std::string &amp;</paramtype></parameter></constructor>
</class>
</namespace>
</namespace>
</header>
<header name="boost/program_options/parsers.hpp">
<namespace name="boost">
<namespace name="program_options">
<class-specialization name="basic_parsed_options"><template>
</template><specialization><template-arg>wchar_t</template-arg></specialization><description><para>Specialization of <classname alt="boost::program_options::basic_parsed_options">basic_parsed_options</classname> which:<itemizedlist>
<listitem><para>provides convenient conversion from <classname alt="boost::program_options::basic_parsed_options">basic_parsed_options&lt;char&gt;</classname></para></listitem><listitem><para>stores the passed char-based options for later use. </para></listitem></itemizedlist>
</para></description><data-member name="options"><type>std::vector&lt; <classname>basic_option</classname>&lt; wchar_t &gt; &gt;</type></data-member>
<data-member name="description"><type>const <classname>options_description</classname> *</type></data-member>
<data-member name="utf8_encoded_options"><type><classname>basic_parsed_options</classname>&lt; char &gt;</type><description><para>Stores UTF8 encoded options that were passed to constructor, to avoid reverse conversion in some cases. </para></description></data-member>
<data-member name="m_options_prefix"><type>int</type><description><para>Mainly used for the diagnostic messages in exceptions. The canonical option prefix for the parser which generated these results, depending on the settings for basic_command_line_parser::style() or cmdline::style(). In order of precedence of command_line_style enums: allow_long allow_long_disguise allow_dash_for_short allow_slash_for_short </para></description></data-member>
<method-group name="public member functions">
</method-group>
<constructor specifiers="explicit"><parameter name="po"><paramtype>const <classname>basic_parsed_options</classname>&lt; char &gt; &amp;</paramtype></parameter><description><para>Constructs wrapped options from options in UTF8 encoding. </para></description></constructor>
</class-specialization><class name="basic_command_line_parser"><template>
<template-type-parameter name="charT"/>
</template><inherit access="private">cmdline</inherit><description><para>Command line parser.</para><para>The class allows one to specify all the information needed for parsing and to parse the command line. It is primarily needed to emulate named function parameters -- a regular function with 5 parameters will be hard to use and creating overloads with a smaller number of parameters will be confusing.</para><para>For the most common case, the function parse_command_line is a better alternative.</para><para>There are two typedefs -- command_line_parser and wcommand_line_parser, for charT == char and charT == wchar_t cases. </para></description><method-group name="public member functions">
<method name="options"><type><classname>basic_command_line_parser</classname> &amp;</type><parameter name="desc"><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><description><para>Sets options descriptions to use. </para></description></method>
<method name="positional"><type><classname>basic_command_line_parser</classname> &amp;</type><parameter name="desc"><paramtype>const <classname>positional_options_description</classname> &amp;</paramtype></parameter><description><para>Sets positional options description to use. </para></description></method>
<method name="style"><type><classname>basic_command_line_parser</classname> &amp;</type><parameter name=""><paramtype>int</paramtype></parameter><description><para>Sets the command line style. </para></description></method>
<method name="extra_parser"><type><classname>basic_command_line_parser</classname> &amp;</type><parameter name=""><paramtype>ext_parser</paramtype></parameter><description><para>Sets the extra parsers. </para></description></method>
<method name="run"><type><classname>basic_parsed_options</classname>&lt; charT &gt;</type><description><para>Parses the options and returns the result of parsing. Throws on error. </para></description></method>
<method name="allow_unregistered"><type><classname>basic_command_line_parser</classname> &amp;</type><description><para>Specifies that unregistered options are allowed and should be passed though. For each command like token that looks like an option but does not contain a recognized name, an instance of basic_option&lt;charT&gt; will be added to result, with 'unrecognized' field set to 'true'. It's possible to collect all unrecognized options with the 'collect_unrecognized' funciton. </para></description></method>
<method name="extra_style_parser"><type><classname>basic_command_line_parser</classname> &amp;</type><parameter name="s"><paramtype>style_parser</paramtype></parameter></method>
</method-group>
<constructor><parameter name="args"><paramtype>const std::vector&lt; std::basic_string&lt; charT &gt; &gt; &amp;</paramtype></parameter><description><para>Creates a command line parser for the specified arguments list. The 'args' parameter should not include program name. </para></description></constructor>
<constructor><parameter name="argc"><paramtype>int</paramtype></parameter><parameter name="argv"><paramtype>const charT *const</paramtype></parameter><description><para>Creates a command line parser for the specified arguments list. The parameters should be the same as passed to 'main'. </para></description></constructor>
</class><enum name="collect_unrecognized_mode"><enumvalue name="include_positional"/><enumvalue name="exclude_positional"/><description><para>Controls if the 'collect_unregistered' function should include positional options, or not. </para></description></enum>
<typedef name="parsed_options"><type><classname>basic_parsed_options</classname>&lt; char &gt;</type></typedef>
<typedef name="wparsed_options"><type><classname>basic_parsed_options</classname>&lt; wchar_t &gt;</type></typedef>
<typedef name="ext_parser"><description><para>Augments <classname alt="boost::program_options::basic_parsed_options&lt; wchar_t &gt;">basic_parsed_options&lt;wchar_t&gt;</classname> with conversion from 'parsed_options' </para></description><type>function1&lt; std::pair&lt; std::string, std::string &gt;, const std::string &amp; &gt;</type></typedef>
<typedef name="command_line_parser"><type><classname>basic_command_line_parser</classname>&lt; char &gt;</type></typedef>
<typedef name="wcommand_line_parser"><type><classname>basic_command_line_parser</classname>&lt; wchar_t &gt;</type></typedef>
<function name="parse_command_line"><type><classname>basic_parsed_options</classname>&lt; charT &gt;</type><template>
<template-type-parameter name="charT"/>
</template><parameter name="argc"><paramtype>int</paramtype></parameter><parameter name="argv"><paramtype>const charT *const</paramtype></parameter><parameter name=""><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><parameter name="style"><paramtype>int</paramtype><default>0</default></parameter><parameter name="ext"><paramtype>function1&lt; std::pair&lt; std::string, std::string &gt;, const std::string &amp; &gt;</paramtype><default>ext_parser()</default></parameter><description><para>Creates instance of 'command_line_parser', passes parameters to it, and returns the result of calling the 'run' method. </para></description></function>
<function name="parse_config_file"><type>BOOST_PROGRAM_OPTIONS_DECL <classname>basic_parsed_options</classname>&lt; charT &gt;</type><template>
<template-type-parameter name="charT"/>
</template><parameter name=""><paramtype>std::basic_istream&lt; charT &gt; &amp;</paramtype></parameter><parameter name=""><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><parameter name="allow_unregistered"><paramtype>bool</paramtype><default>false</default></parameter><description><para>Parse a config file.</para><para>Read from given stream. </para></description></function>
<function name="parse_config_file"><type>BOOST_PROGRAM_OPTIONS_DECL <classname>basic_parsed_options</classname>&lt; charT &gt;</type><template>
<template-type-parameter name="charT"/>
</template><parameter name="filename"><paramtype>const char *</paramtype></parameter><parameter name=""><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><parameter name="allow_unregistered"><paramtype>bool</paramtype><default>false</default></parameter><description><para>Parse a config file.</para><para>Read from file with the given name. The character type is passed to the file stream. </para></description></function>
<function name="collect_unrecognized"><type>std::vector&lt; std::basic_string&lt; charT &gt; &gt;</type><template>
<template-type-parameter name="charT"/>
</template><parameter name="options"><paramtype>const std::vector&lt; <classname>basic_option</classname>&lt; charT &gt; &gt; &amp;</paramtype></parameter><parameter name="mode"><paramtype>enum collect_unrecognized_mode</paramtype></parameter><description><para>Collects the original tokens for all named options with 'unregistered' flag set. If 'mode' is 'include_positional' also collects all positional options. Returns the vector of origianl tokens for all collected options. </para></description></function>
<function name="parse_environment"><type>BOOST_PROGRAM_OPTIONS_DECL <classname>parsed_options</classname></type><parameter name=""><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><parameter name="name_mapper"><paramtype>const function1&lt; std::string, std::string &gt; &amp;</paramtype></parameter><description><para>Parse environment.</para><para>For each environment variable, the 'name_mapper' function is called to obtain the option name. If it returns empty string, the variable is ignored.</para><para>This is done since naming of environment variables is typically different from the naming of command line options. </para></description></function>
<function name="parse_environment"><type>BOOST_PROGRAM_OPTIONS_DECL <classname>parsed_options</classname></type><parameter name=""><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><parameter name="prefix"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Parse environment.</para><para>Takes all environment variables which start with 'prefix'. The option name is obtained from variable name by removing the prefix and converting the remaining string into lower case. </para></description></function>
<function name="parse_environment"><type>BOOST_PROGRAM_OPTIONS_DECL <classname>parsed_options</classname></type><parameter name=""><paramtype>const <classname>options_description</classname> &amp;</paramtype></parameter><parameter name="prefix"><paramtype>const char *</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. This function exists to resolve ambiguity between the two above functions when second argument is of 'char*' type. There's implicit conversion to both function1 and string. </para></description></function>
<overloaded-function name="split_unix"><signature><type>BOOST_PROGRAM_OPTIONS_DECL std::vector&lt; std::string &gt;</type><parameter name="cmdline"><paramtype>const std::string &amp;</paramtype></parameter><parameter name="seperator"><paramtype>const std::string &amp;</paramtype><default>" \t"</default></parameter><parameter name="quote"><paramtype>const std::string &amp;</paramtype><default>"'\""</default></parameter><parameter name="escape"><paramtype>const std::string &amp;</paramtype><default>"\\"</default></parameter></signature><signature><type>BOOST_PROGRAM_OPTIONS_DECL std::vector&lt; std::wstring &gt;</type><parameter name="cmdline"><paramtype>const std::wstring &amp;</paramtype></parameter><parameter name="seperator"><paramtype>const std::wstring &amp;</paramtype><default>L" \t"</default></parameter><parameter name="quote"><paramtype>const std::wstring &amp;</paramtype><default>L"'\""</default></parameter><parameter name="escape"><paramtype>const std::wstring &amp;</paramtype><default>L"\\"</default></parameter></signature><description><para>Splits a given string to a collection of single strings which can be passed to command_line_parser. The second parameter is used to specify a collection of possible seperator chars used for splitting. The seperator is defaulted to space " ". Splitting is done in a unix style way, with respect to quotes '"' and escape characters '\' </para></description></overloaded-function>
</namespace>
</namespace>
</header>
<header name="boost/program_options/positional_options.hpp">
<namespace name="boost">
<namespace name="program_options">
<class name="positional_options_description"><description><para>Describes positional options.</para><para>The class allows to guess option names for positional options, which are specified on the command line and are identified by the position. The class uses the information provided by the user to associate a name with every positional option, or tell that no name is known.</para><para>The primary assumption is that only the relative order of the positional options themselves matters, and that any interleaving ordinary options don't affect interpretation of positional options.</para><para>The user initializes the class by specifying that first N positional options should be given the name X1, following M options should be given the name X2 and so on. </para></description><method-group name="public member functions">
<method name="add"><type><classname>positional_options_description</classname> &amp;</type><parameter name="name"><paramtype>const char *</paramtype></parameter><parameter name="max_count"><paramtype>int</paramtype></parameter><description><para>Species that up to 'max_count' next positional options should be given the 'name'. The value of '-1' means 'unlimited'. No calls to 'add' can be made after call with 'max_value' equal to '-1'. </para></description></method>
<method name="max_total_count" cv="const"><type>unsigned</type><description><para>Returns the maximum number of positional options that can be present. Can return (numeric_limits&lt;unsigned&gt;::max)() to indicate unlimited number. </para></description></method>
<method name="name_for_position" cv="const"><type>const std::string &amp;</type><parameter name="position"><paramtype>unsigned</paramtype></parameter><description><para>Returns the name that should be associated with positional options at 'position'. Precondition: position &lt; max_total_count() </para></description></method>
</method-group>
<constructor/>
</class>
</namespace>
</namespace>
</header>
<header name="boost/program_options/value_semantic.hpp">
<namespace name="boost">
<namespace name="program_options">
<class name="value_semantic"><description><para>Class which specifies how the option's value is to be parsed and converted into C++ types. </para></description><method-group name="public member functions">
<method name="name" cv="const = 0" specifiers="virtual"><type>std::string</type><description><para>Returns the name of the option. The name is only meaningful for automatic help message. </para></description></method>
<method name="min_tokens" cv="const = 0" specifiers="virtual"><type>unsigned</type><description><para>The minimum number of tokens for this option that should be present on the command line. </para></description></method>
<method name="max_tokens" cv="const = 0" specifiers="virtual"><type>unsigned</type><description><para>The maximum number of tokens for this option that should be present on the command line. </para></description></method>
<method name="is_composing" cv="const = 0" specifiers="virtual"><type>bool</type><description><para>Returns true if values from different sources should be composed. Otherwise, value from the first source is used and values from other sources are discarded. </para></description></method>
<method name="is_required" cv="const = 0" specifiers="virtual"><type>bool</type><description><para>Returns true if value must be given. Non-optional value </para></description></method>
<method name="parse" cv="const = 0" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter><parameter name="utf8"><paramtype>bool</paramtype></parameter><description><para>Parses a group of tokens that specify a value of option. Stores the result in 'value_store', using whatever representation is desired. May be be called several times if value of the same option is specified more than once. </para></description></method>
<method name="apply_default" cv="const = 0" specifiers="virtual"><type>bool</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><description><para>Called to assign default value to 'value_store'. Returns true if default value is assigned, and false if no default value exists. </para></description></method>
<method name="notify" cv="const = 0" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>const boost::any &amp;</paramtype></parameter><description><para>Called when final value of an option is determined. </para></description></method>
</method-group>
<destructor/>
</class><class name="value_semantic_codecvt_helper"><template>
<template-type-parameter name="charT"/>
</template><description><para>Helper class which perform necessary character conversions in the 'parse' method and forwards the data further. </para></description></class><class-specialization name="value_semantic_codecvt_helper"><template>
</template><specialization><template-arg>char</template-arg></specialization><inherit access="public">boost::program_options::value_semantic</inherit><description><para>Helper conversion class for values that accept ascii strings as input. Overrides the 'parse' method and defines new 'xparse' method taking std::string. Depending on whether input to parse is ascii or UTF8, will pass it to xparse unmodified, or with UTF8-&gt;ascii conversion. </para></description><method-group name="private member functions">
<method name="parse" cv="const" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter><parameter name="utf8"><paramtype>bool</paramtype></parameter><description><para>Parses a group of tokens that specify a value of option. Stores the result in 'value_store', using whatever representation is desired. May be be called several times if value of the same option is specified more than once. </para></description></method>
</method-group>
<method-group name="protected member functions">
<method name="xparse" cv="const = 0" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter></method>
</method-group>
</class-specialization><class-specialization name="value_semantic_codecvt_helper"><template>
</template><specialization><template-arg>wchar_t</template-arg></specialization><inherit access="public">boost::program_options::value_semantic</inherit><description><para>Helper conversion class for values that accept ascii strings as input. Overrides the 'parse' method and defines new 'xparse' method taking std::wstring. Depending on whether input to parse is ascii or UTF8, will recode input to Unicode, or pass it unmodified. </para></description><method-group name="private member functions">
<method name="parse" cv="const" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter><parameter name="utf8"><paramtype>bool</paramtype></parameter><description><para>Parses a group of tokens that specify a value of option. Stores the result in 'value_store', using whatever representation is desired. May be be called several times if value of the same option is specified more than once. </para></description></method>
</method-group>
<method-group name="protected member functions">
<method name="xparse" cv="const = 0" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::wstring &gt; &amp;</paramtype></parameter></method>
</method-group>
</class-specialization><class name="untyped_value"><inherit access="public">boost::program_options::value_semantic_codecvt_helper&lt; char &gt;</inherit><description><para>Class which specifies a simple handling of a value: the value will have string type and only one token is allowed. </para></description><method-group name="public member functions">
<method name="name" cv="const" specifiers="virtual"><type>std::string</type><description><para>Returns the name of the option. The name is only meaningful for automatic help message. </para></description></method>
<method name="min_tokens" cv="const" specifiers="virtual"><type>unsigned</type><description><para>The minimum number of tokens for this option that should be present on the command line. </para></description></method>
<method name="max_tokens" cv="const" specifiers="virtual"><type>unsigned</type><description><para>The maximum number of tokens for this option that should be present on the command line. </para></description></method>
<method name="is_composing" cv="const" specifiers="virtual"><type>bool</type><description><para>Returns true if values from different sources should be composed. Otherwise, value from the first source is used and values from other sources are discarded. </para></description></method>
<method name="is_required" cv="const" specifiers="virtual"><type>bool</type><description><para>Returns true if value must be given. Non-optional value </para></description></method>
<method name="xparse" cv="const" specifiers="virtual"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::string &gt; &amp;</paramtype></parameter><description><para>If 'value_store' is already initialized, or new_tokens has more than one elements, throws. Otherwise, assigns the first string from 'new_tokens' to 'value_store', without any modifications. </para></description></method>
<method name="apply_default" cv="const" specifiers="virtual"><type>bool</type><parameter name=""><paramtype>boost::any &amp;</paramtype></parameter><description><para>Does nothing. </para></description></method>
<method name="notify" cv="const" specifiers="virtual"><type>void</type><parameter name=""><paramtype>const boost::any &amp;</paramtype></parameter><description><para>Does nothing. </para></description></method>
</method-group>
<constructor><parameter name="zero_tokens"><paramtype>bool</paramtype><default>false</default></parameter></constructor>
</class><class name="typed_value_base"><description><para>Base class for all option that have a fixed type, and are willing to announce this type to the outside world. Any 'value_semantics' for which you want to find out the type can be dynamic_cast-ed to <classname alt="boost::program_options::typed_value_base">typed_value_base</classname>. If conversion succeeds, the 'type' method can be called. </para></description><method-group name="public member functions">
<method name="value_type" cv="const = 0" specifiers="virtual"><type>const std::type_info &amp;</type></method>
</method-group>
<destructor/>
</class><class name="typed_value"><template>
<template-type-parameter name="T"/>
<template-type-parameter name="charT"><default>char</default></template-type-parameter>
</template><inherit access="public">boost::program_options::value_semantic_codecvt_helper&lt; charT &gt;</inherit><inherit access="public">boost::program_options::typed_value_base</inherit><description><para>Class which handles value of a specific type. </para></description><method-group name="public member functions">
<method name="default_value"><type><classname>typed_value</classname> *</type><parameter name="v"><paramtype>const T &amp;</paramtype></parameter><description><para>Specifies default value, which will be used if none is explicitly specified. The type 'T' should provide operator&lt;&lt; for ostream. </para></description></method>
<method name="default_value"><type><classname>typed_value</classname> *</type><parameter name="v"><paramtype>const T &amp;</paramtype></parameter><parameter name="textual"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Specifies default value, which will be used if none is explicitly specified. Unlike the above overload, the type 'T' need not provide operator&lt;&lt; for ostream, but textual representation of default value must be provided by the user. </para></description></method>
<method name="implicit_value"><type><classname>typed_value</classname> *</type><parameter name="v"><paramtype>const T &amp;</paramtype></parameter><description><para>Specifies an implicit value, which will be used if the option is given, but without an adjacent value. Using this implies that an explicit value is optional, </para></description></method>
<method name="value_name"><type><classname>typed_value</classname> *</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Specifies the name used to to the value in help message. </para></description></method>
<method name="implicit_value"><type><classname>typed_value</classname> *</type><parameter name="v"><paramtype>const T &amp;</paramtype></parameter><parameter name="textual"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Specifies an implicit value, which will be used if the option is given, but without an adjacent value. Using this implies that an explicit value is optional, but if given, must be strictly adjacent to the option, i.e.: '-ovalue' or 'option=value'. Giving '-o' or 'option' will cause the implicit value to be applied. Unlike the above overload, the type 'T' need not provide operator&lt;&lt; for ostream, but textual representation of default value must be provided by the user. </para></description></method>
<method name="notifier"><type><classname>typed_value</classname> *</type><parameter name="f"><paramtype>function1&lt; void, const T &amp; &gt;</paramtype></parameter><description><para>Specifies a function to be called when the final value is determined. </para></description></method>
<method name="composing"><type><classname>typed_value</classname> *</type><description><para>Specifies that the value is composing. See the 'is_composing' method for explanation. </para></description></method>
<method name="multitoken"><type><classname>typed_value</classname> *</type><description><para>Specifies that the value can span multiple tokens. </para></description></method>
<method name="zero_tokens"><type><classname>typed_value</classname> *</type><description><para>Specifies that no tokens may be provided as the value of this option, which means that only presense of the option is significant. For such option to be useful, either the 'validate' function should be specialized, or the 'implicit_value' method should be also used. In most cases, you can use the 'bool_switch' function instead of using this method. </para></description></method>
<method name="required"><type><classname>typed_value</classname> *</type><description><para>Specifies that the value must occur. </para></description></method>
<method name="name" cv="const"><type>std::string</type></method>
<method name="is_composing" cv="const"><type>bool</type></method>
<method name="min_tokens" cv="const"><type>unsigned</type></method>
<method name="max_tokens" cv="const"><type>unsigned</type></method>
<method name="is_required" cv="const"><type>bool</type></method>
<method name="xparse" cv="const"><type>void</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><parameter name="new_tokens"><paramtype>const std::vector&lt; std::basic_string&lt; charT &gt; &gt; &amp;</paramtype></parameter><description><para>Creates an instance of the 'validator' class and calls its operator() to perform the actual conversion. </para></description></method>
<method name="apply_default" cv="const" specifiers="virtual"><type>bool</type><parameter name="value_store"><paramtype>boost::any &amp;</paramtype></parameter><description><para>If default value was specified via previous call to 'default_value', stores that value into 'value_store'. Returns true if default value was stored. </para></description></method>
<method name="notify" cv="const"><type>void</type><parameter name="value_store"><paramtype>const boost::any &amp;</paramtype></parameter><description><para>If an address of variable to store value was specified when creating *this, stores the value there. Otherwise, does nothing. </para></description></method>
<method name="value_type" cv="const" specifiers="virtual"><type>const std::type_info &amp;</type></method>
</method-group>
<constructor><parameter name="store_to"><paramtype>T *</paramtype></parameter><description><para>Ctor. The 'store_to' parameter tells where to store the value when it's known. The parameter can be NULL. </para></description></constructor>
</class>
<overloaded-function name="value"><signature><type><classname>typed_value</classname>&lt; T &gt; *</type><template>
<template-type-parameter name="T"/>
</template></signature><signature><type><classname>typed_value</classname>&lt; T &gt; *</type><template>
<template-type-parameter name="T"/>
</template><parameter name="v"><paramtype>T *</paramtype></parameter></signature><description><para>Creates a typed_value&lt;T&gt; instance. This function is the primary method to create <classname alt="boost::program_options::value_semantic">value_semantic</classname> instance for a specific type, which can later be passed to '<classname alt="boost::program_options::option_description">option_description</classname>' constructor. The second overload is used when it's additionally desired to store the value of option into program variable. </para></description></overloaded-function>
<overloaded-function name="wvalue"><signature><type><classname>typed_value</classname>&lt; T, wchar_t &gt; *</type><template>
<template-type-parameter name="T"/>
</template></signature><signature><type><classname>typed_value</classname>&lt; T, wchar_t &gt; *</type><template>
<template-type-parameter name="T"/>
</template><parameter name="v"><paramtype>T *</paramtype></parameter></signature><description><para>Creates a typed_value&lt;T&gt; instance. This function is the primary method to create <classname alt="boost::program_options::value_semantic">value_semantic</classname> instance for a specific type, which can later be passed to '<classname alt="boost::program_options::option_description">option_description</classname>' constructor. </para></description></overloaded-function>
<overloaded-function name="bool_switch"><signature><type>BOOST_PROGRAM_OPTIONS_DECL <classname>typed_value</classname>&lt; bool &gt; *</type></signature><signature><type>BOOST_PROGRAM_OPTIONS_DECL <classname>typed_value</classname>&lt; bool &gt; *</type><parameter name="v"><paramtype>bool *</paramtype></parameter></signature><description><para>Works the same way as the 'value&lt;bool&gt;' function, but the created <classname alt="boost::program_options::value_semantic">value_semantic</classname> won't accept any explicit value. So, if the option is present on the command line, the value will be 'true'. </para></description></overloaded-function>
</namespace>
</namespace>
</header>
<header name="boost/program_options/variables_map.hpp">
<namespace name="boost">
<namespace name="program_options">
<class name="basic_parsed_options"><template>
<template-type-parameter name="charT"/>
</template><description><para>Results of parsing an input source. The primary use of this class is passing information from parsers component to value storage component. This class does not makes much sense itself. </para></description><method-group name="public member functions">
</method-group>
<constructor specifiers="explicit"><parameter name="xdescription"><paramtype>const <classname>options_description</classname> *</paramtype></parameter><parameter name="options_prefix"><paramtype>int</paramtype><default>0</default></parameter></constructor>
</class><class name="variable_value"><description><para>Class holding value of option. Contains details about how the value is set and allows to conveniently obtain the value. </para></description><method-group name="friend functions">
<method name="store"><type>friend BOOST_PROGRAM_OPTIONS_DECL void</type><parameter name="options"><paramtype>const <classname>basic_parsed_options</classname>&lt; char &gt; &amp;</paramtype></parameter><parameter name="m"><paramtype><classname>variables_map</classname> &amp;</paramtype></parameter><parameter name=""><paramtype>bool</paramtype></parameter><description><para>Stores in 'm' all options that are defined in 'options'. If 'm' already has a non-defaulted value of an option, that value is not changed, even if 'options' specify some value. </para></description></method>
</method-group>
<method-group name="public member functions">
<method name="as" cv="const"><type>const T &amp;</type><template>
<template-type-parameter name="T"/>
</template><description><para>If stored value if of type T, returns that value. Otherwise, throws boost::bad_any_cast exception. </para></description></method>
<method name="as"><type>T &amp;</type><template>
<template-type-parameter name="T"/>
</template><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method>
<method name="empty" cv="const"><type>bool</type><purpose>Returns true if no value is stored. </purpose></method>
<method name="defaulted" cv="const"><type>bool</type><description><para>Returns true if the value was not explicitly given, but has default value. </para></description></method>
<method name="value" cv="const"><type>const boost::any &amp;</type><description><para>Returns the contained value. </para></description></method>
<method name="value"><type>boost::any &amp;</type><description><para>Returns the contained value. </para></description></method>
</method-group>
<constructor/>
<constructor><parameter name="xv"><paramtype>const boost::any &amp;</paramtype></parameter><parameter name="xdefaulted"><paramtype>bool</paramtype></parameter></constructor>
</class><class name="abstract_variables_map"><description><para>Implements string-&gt;string mapping with convenient value casting facilities. </para></description><method-group name="public member functions">
<method name="operator[]" cv="const"><type>const <classname>variable_value</classname> &amp;</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Obtains the value of variable 'name', from *this and possibly from the chain of variable maps.</para><para><itemizedlist>
<listitem><para>if there's no value in *this.<itemizedlist>
<listitem><para>if there's next variable map, returns value from it</para></listitem><listitem><para>otherwise, returns empty value</para></listitem></itemizedlist>
</para></listitem><listitem><para>if there's defaulted value<itemizedlist>
<listitem><para>if there's next variable map, which has a non-defaulted value, return that</para></listitem><listitem><para>otherwise, return value from *this</para></listitem></itemizedlist>
</para></listitem><listitem><para>if there's a non-defaulted value, returns it. </para></listitem></itemizedlist>
</para></description></method>
<method name="next"><type>void</type><parameter name="next"><paramtype><classname>abstract_variables_map</classname> *</paramtype></parameter><description><para>Sets next variable map, which will be used to find variables not found in *this. </para></description></method>
</method-group>
<constructor/>
<constructor><parameter name="next"><paramtype>const <classname>abstract_variables_map</classname> *</paramtype></parameter></constructor>
<destructor/>
<method-group name="private member functions">
<method name="get" cv="const = 0" specifiers="virtual"><type>const <classname>variable_value</classname> &amp;</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Returns value of variable 'name' stored in *this, or empty value otherwise. </para></description></method>
</method-group>
</class><class name="variables_map"><inherit access="public">boost::program_options::abstract_variables_map</inherit><inherit access="public">std::map&lt; std::string, variable_value &gt;</inherit><description><para>Concrete variables map which store variables in real map.</para><para>This class is derived from std::map&lt;std::string, variable_value&gt;, so you can use all map operators to examine its content. </para></description><method-group name="public member functions">
<method name="operator[]" cv="const"><type>const <classname>variable_value</classname> &amp;</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter></method>
<method name="clear"><type>void</type></method>
<method name="notify"><type>void</type></method>
</method-group>
<constructor/>
<constructor><parameter name="next"><paramtype>const <classname>abstract_variables_map</classname> *</paramtype></parameter></constructor>
<method-group name="private member functions">
<method name="get" cv="const" specifiers="virtual"><type>const <classname>variable_value</classname> &amp;</type><parameter name="name"><paramtype>const std::string &amp;</paramtype></parameter><description><para>Implementation of abstract_variables_map::get which does 'find' in *this. </para></description></method>
</method-group>
<method-group name="friend functions">
<method name="store"><type>friend BOOST_PROGRAM_OPTIONS_DECL void</type><parameter name="options"><paramtype>const <classname>basic_parsed_options</classname>&lt; char &gt; &amp;</paramtype></parameter><parameter name="xm"><paramtype><classname>variables_map</classname> &amp;</paramtype></parameter><parameter name="utf8"><paramtype>bool</paramtype></parameter><description><para>Stores in 'm' all options that are defined in 'options'. If 'm' already has a non-defaulted value of an option, that value is not changed, even if 'options' specify some value. </para></description></method>
</method-group>
</class><function name="store"><type>BOOST_PROGRAM_OPTIONS_DECL void</type><parameter name="options"><paramtype>const <classname>basic_parsed_options</classname>&lt; char &gt; &amp;</paramtype></parameter><parameter name="m"><paramtype><classname>variables_map</classname> &amp;</paramtype></parameter><parameter name="utf8"><paramtype>bool</paramtype><default>false</default></parameter><description><para>Stores in 'm' all options that are defined in 'options'. If 'm' already has a non-defaulted value of an option, that value is not changed, even if 'options' specify some value. </para></description></function>
<function name="store"><type>BOOST_PROGRAM_OPTIONS_DECL void</type><parameter name="options"><paramtype>const <classname>basic_parsed_options</classname>&lt; wchar_t &gt; &amp;</paramtype></parameter><parameter name="m"><paramtype><classname>variables_map</classname> &amp;</paramtype></parameter><description><para>Stores in 'm' all options that are defined in 'options'. If 'm' already has a non-defaulted value of an option, that value is not changed, even if 'options' specify some value. This is wide character variant. </para></description></function>
<function name="notify"><type>BOOST_PROGRAM_OPTIONS_DECL void</type><parameter name="m"><paramtype><classname>variables_map</classname> &amp;</paramtype></parameter><description><para>Runs all 'notify' function for options in 'm'. </para></description></function>
</namespace>
</namespace>
</header>
<header name="boost/program_options/version.hpp">
<macro name="BOOST_PROGRAM_OPTIONS_VERSION"><description><para>The version of the source interface. The value will be incremented whenever a change is made which might cause compilation errors for existing code. </para></description></macro>
<macro name="BOOST_PROGRAM_OPTIONS_IMPLICIT_VALUE_NEXT_TOKEN"/>
</header>
</library-reference>

View File

@@ -0,0 +1,150 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
[
<!ENTITY % entities SYSTEM "program_options.ent" >
%entities;
]>
<section id="program_options.changes">
<title>Changes since formal review</title>
<para>During formal review, a large number of changes was suggested. To make
using the new version easier, the implemented changes are described
below.</para>
<para>Let's start with an example. The following is a typical code for the
reviewed version:<programlisting>
options_description desc;
desc.add_options()
("magic", parameter&lt;int&gt;("value"), "magic value for the program")
.default_value("43")
variables_map vm;
options_and_arguments oa1 = parse_command_line(ac, av, desc);
store(oa1, vm, desc)
variables_map vm2;
ifstream ifs("main.cfg");
options_and_arguments oa2 = parse_config_file(ifs, desc);
store(oa1, vm2, desc);
vm.next(&amp;vm2);
</programlisting>The code for the current version would look like:
<programlisting>
options_description desc;
desc.add_options()
("magic", value&lt;int&gt;()->default_value(43),
"magic value for the program")
variables_map vm;
store(parse_command_line(ac, av, desc), vm);
ifstream ifs("main.cfg");
store(parse_command_line(ifs, desc), vm);
notify(vm);
</programlisting>
</para>
<para>Let's examine all the changes in detail</para>
<section>
<title>Option description</title>
<itemizedlist>
<listitem>
<para>The <code>parameter</code> function was renamed to
<code>value</code>. Rationale: "paramater" is yet another term with no
clear definition, while "value" is already used everywhere in
docs.</para>
</listitem>
<listitem>
<para>The default value is specified in different place, and should
use the value of desired type, not string. Previous code was:
<programlisting>
("magic", parameter&lt;int&gt;("value")).default_value("43")
</programlisting>
and the new code is
<programlisting>
("magic", parameter&lt;int&gt;("value")->default_value(43));
</programlisting>
Rationale: the new way is less restrictive. At the same time, the
new design allows to implement other behaviour, like validation of
the value, which require knowledge of the value type.
</para>
</listitem>
<listitem>
<para>The number of token value can take on command line, which was
specified using character suffix appended to value name, is now
specified using more explicit member calls. Moreover, it's not longer
possible to specify the "value name".
For example:
<programlisting>("numbers", parameter&lt;int&gt;("n+"))</programlisting>
has became
<programlisting>("numbers", value&lt;int&gt;()->multitoken())</programlisting>
Rationale: such modifiers tend to make command line usage less
clear. There's no need to make evil things too easy to do.
The "value name" had only two roles: specifying modifiers, and
telling what to output in automated help. The first role has became
obsolete, and the second was questionable too. It was very unclear how
to decide on the best "value name", and eventually the selection was randon.
</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Parsers</title>
<itemizedlist>
<listitem>
<para>The <code>options_and_argument</code> class was removed.</para>
</listitem>
<listitem>
<para>The <code>cmdline</code> and <code>config_file</code> classes
were removed from the public interface. Various command line styles
are now declared in the <code>command_line_style</code> subnamespace.
</para>
</listitem>
<listitem>
<para>New function <code>parse_environment</code> was added.</para>
</listitem>
<listitem>
<para>Support for positional options was added</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Storage</title>
<itemizedlist>
<listitem>
<para>The <code>notify</code> function should be called after all
sources are stored in a <code>variales_map</code> instance. This is
done to property support priority of configuration sources.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<!--
Local Variables:
mode: xml
sgml-indent-data: t
sgml-parent-document: ("program_options.xml" "section")
sgml-set-face: t
End:
-->

View File

@@ -0,0 +1,213 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
[
<!ENTITY % entities SYSTEM "program_options.ent" >
%entities;
]>
<section id="program_options.design">
<title>Design Discussion</title>
<para>This section focuses on some of the design questions.
</para>
<section id="program_options.design.unicode">
<title>Unicode Support</title>
<para>Unicode support was one of the features specifically requested
during the formal review. Throughout this document "Unicode support" is
a synonym for "wchar_t" support, assuming that "wchar_t" always uses
Unicode encoding. Also, when talking about "ascii" (in lowercase) we'll
not mean strict 7-bit ASCII encoding, but rather "char" strings in local
8-bit encoding.
</para>
<para>
Generally, &quot;Unicode support&quot; can mean
many things, but for the program_options library it means that:
<itemizedlist>
<listitem>
<para>Each parser should accept either <code>char*</code>
or <code>wchar_t*</code>, correctly split the input into option
names and option values and return the data.
</para>
</listitem>
<listitem>
<para>For each option, it should be possible to specify whether the conversion
from string to value uses ascii or Unicode.
</para>
</listitem>
<listitem>
<para>The library guarantees that:
<itemizedlist>
<listitem>
<para>ascii input is passed to an ascii value without change
</para>
</listitem>
<listitem>
<para>Unicode input is passed to a Unicode value without change</para>
</listitem>
<listitem>
<para>ascii input passed to a Unicode value, and Unicode input
passed to an ascii value will be converted using a codecvt
facet (which may be specified by the user).
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
<para>The important point is that it's possible to have some "ascii
options" together with "Unicode options". There are two reasons for
this. First, for a given type you might not have the code to extract the
value from Unicode string and it's not good to require that such code be written.
Second, imagine a reusable library which has some options and exposes
options description in its interface. If <emphasis>all</emphasis>
options are either ascii or Unicode, and the library does not use any
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.
</para>
<para>Another important point is that ascii strings are passed though
without modification. In other words, it's not possible to just convert
ascii to Unicode and process the Unicode further. The problem is that the
default conversion mechanism -- the <code>codecvt</code> facet -- might
not work with 8-bit input without additional setup.
</para>
<para>The Unicode support outlined above is not complete. For example, we
don't support Unicode option names. Unicode support is hard and
requires a Boost-wide solution. Even comparing two arbitrary Unicode
strings is non-trivial. Finally, using Unicode in option names is
related to internationalization, which has it's own
complexities. E.g. if option names depend on current locale, then all
program parts and other parts which use the name must be
internationalized too.
</para>
<para>The primary question in implementing the Unicode support is whether
to use templates and <code>std::basic_string</code> or to use some
internal encoding and convert between internal and external encodings on
the interface boundaries.
</para>
<para>The choice, mostly, is between code size and execution
speed. A templated solution would either link library code into every
application that uses the library (thereby making shared library
impossible), or provide explicit instantiations in the shared library
(increasing its size). The solution based on internal encoding would
necessarily make conversions in a number of places and will be somewhat slower.
Since speed is generally not an issue for this library, the second
solution looks more attractive, but we'll take a closer look at
individual components.
</para>
<para>For the parsers component, we have three choices:
<itemizedlist>
<listitem>
<para>Use a fully templated implementation: given a string of a
certain type, a parser will return a &parsed_options; instance
with strings of the same type (i.e. the &parsed_options; class
will be templated).</para>
</listitem>
<listitem>
<para>Use internal encoding: same as above, but strings will be converted to and
from the internal encoding.</para>
</listitem>
<listitem>
<para>Use and partly expose the internal encoding: same as above,
but the strings in the &parsed_options; instance will be in the
internal encoding. This might avoid a conversion if
&parsed_options; instance is passed directly to other components,
but can be also dangerous or confusing for a user.
</para>
</listitem>
</itemizedlist>
</para>
<para>The second solution appears to be the best -- it does not increase
the code size much and is cleaner than the third. To avoid extra
conversions, the Unicode version of &parsed_options; can also store
strings in internal encoding.
</para>
<para>For the options descriptions component, we don't have much
choice. Since it's not desirable to have either all options use ascii or all
of them use Unicode, but rather have some ascii and some Unicode options, the
interface of the &value_semantic; must work with both. The only way is
to pass an additional flag telling if strings use ascii or internal encoding.
The instance of &value_semantic; can then convert into some
other encoding if needed.
</para>
<para>For the storage component, the only affected function is &store;.
For Unicode input, the &store; function should convert the value to the
internal encoding. It should also inform the &value_semantic; class
about the used encoding.
</para>
<para>Finally, what internal encoding should we use? The
alternatives are:
<code>std::wstring</code> (using UCS-4 encoding) and
<code>std::string</code> (using UTF-8 encoding). The difference between
alternatives is:
<itemizedlist>
<listitem>
<para>Speed: UTF-8 is a bit slower</para>
</listitem>
<listitem>
<para>Space: UTF-8 takes less space when input is ascii</para>
</listitem>
<listitem>
<para>Code size: UTF-8 requires additional conversion code. However,
it allows one to use existing parsers without converting them to
<code>std::wstring</code> and such conversion is likely to create a
number of new instantiations.
</para>
</listitem>
</itemizedlist>
There's no clear leader, but the last point seems important, so UTF-8
will be used.
</para>
<para>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:
<itemizedlist>
<listitem>
<para>We need to assume the character literals use ascii encoding
and that inputs use Unicode encoding.</para>
</listitem>
<listitem>
<para>A Unicode character (say '=') can be followed by 'composing
character' and the combination is not the same as just '=', so a
simple search for '=' might find the wrong character.
</para>
</listitem>
</itemizedlist>
Neither of these issues appear to be critical in practice, since ascii is
almost universal encoding and since composing characters following '=' (and
other characters with special meaning to the library) are not likely to appear.
</para>
</section>
</section>
<!--
Local Variables:
mode: xml
sgml-indent-data: t
sgml-parent-document: ("program_options.xml" "section")
sgml-set-face: t
End:
-->

View File

@@ -0,0 +1,19 @@
/** @page glossary Glosary
<dl>
<dt>Token</dt><dd>A single whitespace-separated part of
command line. In other words, an element of <tt>argv</tt> array.</dd>
<dt>Option</dt><dd>No definition yet. Options typically correspond to
(name, value) pair. Then can spawn several tokens.</dd>
<dt>Argument</dt><dd>No definition yet.</dd>
<dt>Command line element</dt><dd>A complete part of command line. May
be either option or argument.</dd>
<dt>Parameter</dt><dd>The syntantic element which specify value of the
option</dd>
</dl>
*/

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" standalone="yes"?>
<glossary>
<title>Glossary</title>
<glossentry>
<glossterm>Token</glossterm>
<glossdef>
<para>A single whitespace-separated part of
command line. In other words, an element of <code>argv</code> array.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Option</glossterm>
<glossdef>
<para>No definition yet. Options typically correspond to
(name, value) pair. Then can spawn several tokens.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Argument</glossterm>
<glossdef>
<para>No definition yet.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Command line element</glossterm>
<glossdef>
<para>A complete part of command line. May
be either option or argument.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Parameter</glossterm>
<glossdef>
<para>The syntactic element which specify value of an
option.
</para>
</glossdef>
</glossentry>
</glossary>

View File

@@ -0,0 +1,499 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
[
<!ENTITY % entities SYSTEM "program_options.ent" >
%entities;
]>
<section id="program_options.howto">
<title>How To</title>
<para>This section describes how the library can be used in specific
situations.</para>
<!--
validators
positional options
options groups/hidden options
-->
<section>
<title>Non-conventional Syntax</title>
<para>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.
</para>
<indexterm><primary>additional parser</primary></indexterm>
<para>For such cases, the library allows the user to provide an
<firstterm>additional parser</firstterm> -- a function which will be called on each
command line element, before any processing by the library. If the
additional parser recognises the syntax, it returns the option name and
value, which are used directly. The above example can be handled by the
following code:
</para>
<para>
<programlisting>
pair&lt;string, string&gt; reg_foo(const string&amp; s)
{
if (s.find("-f") == 0) {
if (s.substr(2, 3) == "no-")
return make_pair(s.substr(5), string("false"));
else
return make_pair(s.substr(2), string("true"));
} else {
return make_pair(string(), string());
}
}
</programlisting>
Here's the definition of the additional parser. When parsing the command
line, we pass the additional parser:
<programlisting>
store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo)
.run(), vm);
</programlisting>
The complete example can be found in the "example/custom_syntax.cpp"
file.
</para>
</section>
<section>
<title>Response Files</title>
<indexterm><primary>response files</primary></indexterm>
<para>Some operating system have very low limits of the command line
length. The common way to work around those limitations is using
<firstterm>response files</firstterm>. A response file is just a
configuration file which uses the same syntax as the command line. If
the command line specifies a name of response file to use, it's loaded
and parsed in addition to the command line. The library does not
provide direct support for response files, so you'll need to write some
extra code.
</para>
<para>
First, you need to define an option for the response file:
<programlisting>
("response-file", value&lt;string&gt;(),
"can be specified with '@name', too")
</programlisting>
</para>
<para>Second, you'll need an additional parser to support the standard syntax
for specifying response files: "@file":
<programlisting><![CDATA[
pair<string, string> at_option_parser(string const&s)
{
if ('@' == s[0])
return std::make_pair(string("response-file"), s.substr(1));
else
return pair<string, string>();
}
]]>
</programlisting>
</para>
<para>Finally, when the "response-file" option is found, you'll have to
load that file and pass it to the command line parser. This part is the
hardest. We'll use the Boost.Tokenizer library, which works but has some
limitations. You might also consider Boost.StringAlgo. The code is:
<programlisting><![CDATA[
if (vm.count("response-file")) {
// Load the file and tokenize it
ifstream ifs(vm["response-file"].as<string>().c_str());
if (!ifs) {
cout << "Could not open the response file\n";
return 1;
}
// Read the whole file into a string
stringstream ss;
ss << ifs.rdbuf();
// Split the file content
char_separator<char> sep(" \n\r");
std::string ResponsefileContents( ss.str() );
tokenizer<char_separator<char> > tok(ResponsefileContents, sep);
vector<string> 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);
}
]]>
</programlisting>
The complete example can be found in the "example/response_file.cpp"
file.
</para>
</section>
<section>
<title>Winmain Command Line</title>
<para>On the Windows operating system, GUI applications receive the
command line as a single string, not split into elements. For that reason,
the command line parser cannot be used directly. At least on some
compilers, it is possible to obtain
the split command line, but it's not clear if all compilers support the
same mechanism on all versions of the operating system. The
<code>split_winmain</code> function is a portable mechanism provided
by the library.</para>
<para>Here's an example of use:
<programlisting>
vector&lt;string&gt; args = split_winmain(lpCmdLine);
store(command_line_parser(args).options(desc).run(), vm);
</programlisting>
The <code>split_winmain</code> function is overloaded for <code>wchar_t</code> strings, so can
also be used in Unicode applications.
</para>
</section>
<section>
<title>Option Groups and Hidden Options</title>
<para>Having a single instance of the &options_description; class with all
the program's options can be problematic:
<itemizedlist>
<listitem>
<para>Some options make sense only for specific source, for example,
configuration files.</para>
</listitem>
<listitem>
<para>The user would prefer some structure in the generated help message.</para>
</listitem>
<listitem>
<para>Some options shouldn't appear in the generated help message at all.</para>
</listitem>
</itemizedlist>
</para>
<para>To solve the above issues, the library allows a programmer to create several
instances of the &options_description; class, which can be merged in
different combinations. The following example will define three groups of
options: command line specific, and two options group for specific program
modules, only one of which is shown in the generated help message.
</para>
<para>Each group is defined using standard syntax. However, you should
use reasonable names for each &options_description; instance:
<programlisting><![CDATA[
options_description general("General options");
general.add_options()
("help", "produce a help message")
("help-module", value<string>(),
"produce a help for a given module")
("version", "output the version number")
;
options_description gui("GUI options");
gui.add_options()
("display", value<string>(), "display to use")
;
options_description backend("Backend options");
backend.add_options()
("num-threads", value<int>(), "the initial number of threads")
;
]]></programlisting>
</para>
<para>After declaring options groups, we merge them in two
combinations. The first will include all options and be used for parsing. The
second will be used for the "--help" option.
<programlisting>
// Declare an options description instance which will include
// all the options
options_description all("Allowed options");
all.add(general).add(gui).add(backend);
// Declare an options description instance which will be shown
// to the user
options_description visible("Allowed options");
visible.add(general).add(gui);
</programlisting>
</para>
<para>What is left is to parse and handle the options:
<programlisting><![CDATA[
variables_map vm;
store(parse_command_line(ac, av, all), vm);
if (vm.count("help"))
{
cout << visible;
return 0;
}
if (vm.count("help-module")) {
const string& s = vm["help-module"].as<string>();
if (s == "gui") {
cout << gui;
} else if (s == "backend") {
cout << backend;
} else {
cout << "Unknown module '"
<< s << "' in the --help-module option\n";
return 1;
}
return 0;
}
if (vm.count("num-threads")) {
cout << "The 'num-threads' options was set to "
<< vm["num-threads"].as<int>() << "\n";
}
]]></programlisting>
When parsing the command line, all options are allowed. The "--help"
message, however, does not include the "Backend options" group -- the
options in that group are hidden. The user can explicitly force the
display of that options group by passing "--help-module backend"
option. The complete example can be found in the
"example/option_groups.cpp" file.
</para>
</section>
<section>
<title>Custom Validators</title>
<para>By default, the conversion of option's value from string into C++
type is done using iostreams, which sometimes is not convenient. The
library allows the user to customize the conversion for specific
classes. In order to do so, the user should provide suitable overload of
the <code>validate</code> function.
</para>
<para>
Let's first define a simple class:
<programlisting><![CDATA[
struct magic_number {
public:
magic_number(int n) : n(n) {}
int n;
};
]]></programlisting> and then overload the <code>validate</code> function:
<programlisting><![CDATA[
void validate(boost::any& v,
const std::vector<std::string>& values,
magic_number* target_type, int)
{
static regex r("\\d\\d\\d-(\\d\\d\\d)");
using namespace boost::program_options;
// Make sure no previous assignment to 'a' was made.
validators::check_first_occurrence(v);
// Extract the first string from 'values'. If there is more than
// 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
// int.
smatch match;
if (regex_match(s, match, r)) {
v = any(magic_number(lexical_cast<int>(match[1])));
} else {
throw validation_error(validation_error::invalid_option_value);
}
}
]]>
</programlisting>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 <code>magic_number</code> class. The second is the list of strings
found in the next occurrence of the option. The remaining two parameters
are needed to workaround the lack of partial template specialization and
partial function template ordering on some compilers.
</para>
<para>The function first checks that we don't try to assign to the same
option twice. Then it checks that only a single string was passed
in. Next the string is verified with the help of the Boost.Regex
library. If that test is passed, the parsed value is stored into the
<code>v</code> variable.
</para>
<para>The complete example can be found in the "example/regex.cpp" file.
</para>
</section>
<section>
<title>Unicode Support</title>
<para>To use the library with Unicode, you'd need to:
<itemizedlist>
<listitem>
<para>Use Unicode-aware parsers for Unicode input</para>
</listitem>
<listitem>
<para>Require Unicode support for options which need it</para>
</listitem>
</itemizedlist>
</para>
<para>Most of the parsers have Unicode versions. For example, the
&parse_command_line; function has an overload which takes
<code>wchar_t</code> strings, instead of ordinary <code>char</code>.
</para>
<para>Even if some of the parsers are Unicode-aware, it does not mean you
need to change definition of all the options. In fact, for many options,
like integer ones, it makes no sense. To make use of Unicode you'll need
<emphasis>some</emphasis> Unicode-aware options. They are different from
ordinary options in that they accept <code>wstring</code> input, and
process it using wide character streams. Creating an Unicode-aware option
is easy: just use the the <code>wvalue</code> function instead of the
regular <code>value</code>.
</para>
<para>When an ascii parser passes data to an ascii option, or a Unicode
parser passes data to a Unicode option, the data are not changed at
all. So, the ascii option will see a string in local 8-bit encoding, and
the Unicode option will see whatever string was passed as the Unicode
input.
</para>
<para>What happens when Unicode data is passed to an ascii option, and
vice versa? The library automatically performs the conversion from
Unicode to local 8-bit encoding. For example, if command line is in
ascii, but you use <code>wstring</code> options, then the ascii input
will be converted into Unicode.
</para>
<para>To perform the conversion, the library uses the <code>codecvt&lt;wchar_t,
char&gt;</code> locale facet from the global locale. If
you want to work with strings that use local 8-bit encoding (as opposed to
7-bit ascii subset), your application should start with:
<programlisting>
locale::global(locale(""));
</programlisting>
which would set up the conversion facet according to the user's selected
locale.
</para>
<para>It's wise to check the status of the C++ locale support on your
implementation, though. The quick test involves three steps:
<orderedlist>
<listitem>
<para>Go the the "test" directory and build the "test_convert" binary.</para>
</listitem>
<listitem>
<para>Set some non-ascii locale in the environment. On Linux, one can
run, for example: <screen>
$ export LC_CTYPE=ru_RU.KOI8-R
</screen>
</para>
</listitem>
<listitem>
<para>Run the "test_convert" binary with any non-ascii string in the
selected encoding as its parameter. If you see a list of Unicode codepoints,
everything's OK. Otherwise, locale support on your system might be
broken.</para>
</listitem>
</orderedlist>
</para>
</section>
<section>
<title>Allowing Unknown Options</title>
<para>Usually, the library throws an exception on unknown option names. This
behaviour can be changed. For example, only some part of your application uses
<libraryname>Program_options</libraryname>, and you wish to pass unrecognized options to another part of
the program, or even to another application.</para>
<para>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 <methodname alt="boost::program_options::basic_command_line_parser::allow_unregistered">allow_unregistered</methodname>
method of that class:
<programlisting>
parsed_options parsed =
command_line_parser(argc, argv).options(desc).allow_unregistered().run();
</programlisting>
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 <code>string_key</code> and <code>value</code> fields of the instance will contain results
of syntactic parsing of the token, the <code>unregistered</code> field will be set to <code>true</code>,
and the <code>original_tokens</code> field will contain the token as it appeared on the command line.
</para>
<para>If you want to pass the unrecognized options further, the
<functionname alt="boost::program_options::collect_unrecognized">collect_unrecognized</functionname> 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 handle positional options at all, you can use the function like this:
<programlisting>
vector&lt;string&gt; to_pass_further = collect_unrecognized(parsed.options, include_positional);
</programlisting>
</para>
</section>
<section>
<title>Testing Option Presence</title>
<para>Until now we have tested whether an option has been set using the
<methodname alt="boost::program_options::variables_map::count">count</methodname> method on the &variables_map;
class; as you are repeating the (string literal) name of the option this is prone to typos and/or errors
resulting from renaming the option in one place but not the other:
<programlisting><![CDATA[
po::options_description desc("Allowed options");
desc.add_options()
("compression", po::value<int>(), "set compression level")
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if (vm.count("compression")) {
cout << "Compression level was set to "
<< vm["compression"].as<int>() << ".\n";
} else {
cout << "Compression level was not set.\n";
}
]]>
</programlisting>
</para>
<para>Instead, you can use a variable of type <classname alt="boost::optional">boost::optional</classname>;
<libraryname>Program_options</libraryname> provides special support for <libraryname>Boost.Optional</libraryname>
such that if the user specifies the option the <classname alt="boost::optional">boost::optional</classname>
variable will be initialized to the appropriate value:
<programlisting><![CDATA[
po::options_description desc("Allowed options");
boost::optional<int> compression;
desc.add_options()
("compression", po::value(&compression), "set compression level")
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if (compression)) {
cout << "Compression level was set to " << *compression << ".\n";
} else {
cout << "Compression level was not set.\n";
}
]]>
</programlisting>
</para>
</section>
</section>
<!--
Local Variables:
mode: nxml
sgml-indent-data: t
sgml-parent-document: ("userman.xml" "chapter")
sgml-set-face: t
End:
-->

View File

@@ -0,0 +1,14 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../../doc/html/program_options.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="../../../doc/html/program_options.html">../../../doc/html/program_options.html</a>
&nbsp;<hr>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@@ -0,0 +1,652 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
[
<!ENTITY % entities SYSTEM "program_options.ent" >
%entities;
]>
<section id="program_options.overview">
<title>Library Overview</title>
<para>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.
</para>
<para>The library has three main components:
<itemizedlist>
<listitem>
<para>The options description component, which describes the allowed options
and what to do with the values of the options.
</para>
</listitem>
<listitem>
<para>The parsers component, which uses this information to find option names
and values in the input sources and return them.
</para>
</listitem>
<listitem>
<para>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.
</para>
</listitem>
</itemizedlist>
</para>
<para>To be a little more concrete, the <code>options_description</code>
class is from the options description component, the
<code>parse_command_line</code> function is from the parsers component, and the
<code>variables_map</code> class is from the storage component. </para>
<para>In the tutorial we've learned how those components can be used by the
<code>main</code> 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 <code>main</code>.
</para>
<para>
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.
</para>
<!--
<para>The design looks very simple and straight-forward, but it is worth
noting some important points:
<itemizedlist>
<listitem>
<para>The options description is not tied to specific source. Once
options are described, all parsers can use that description.</para>
</listitem>
<listitem>
<para>The parsers are intended to be fairly dumb. They just
split the input into (name, value) pairs, using strings to represent
names and values. No meaningful processing of values is done.
</para>
</listitem>
<listitem>
<para>The storage component is focused on storing options values. It
</para>
</listitem>
</itemizedlist>
</para>
-->
<section>
<title>Options Description Component</title>
<para>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;.
</para>
<para>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 <code>add</code> 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:
<programlisting>
options_description desc;
desc.add_options()
("help", "produce help")
("optimization", value&lt;int&gt;()->default_value(10), "optimization level")
;
</programlisting>
</para>
<para>The call to the <code>value</code> function creates an instance of
a class derived from the <code>value_semantic</code> class: <code>typed_value</code>.
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
<code>operator()</code> on the object returned by <code>add_options</code>
forward arguments to the constructor of the <code>option_description</code>
class and add the new instance.
</para>
<para>
Note that in addition to the
<code>value</code>, library provides the <code>bool_switch</code>
function, and user can write his own function which will return
other subclasses of <code>value_semantic</code> with
different behaviour. For the remainder of this section, we'll talk only
about the <code>value</code> function.
</para>
<para>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
(<code>std::vector&lt;std::string&gt;</code>). The semantic layer
is responsible for converting the value of the option into more usable C++
types.
</para>
<para>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: <screen>calc --expression=1 + 2/3</screen> because it's not
possible to parse <screen>1 + 2/3</screen> without knowing that it's a C
expression. With a little help from the user the task becomes trivial,
and the syntax clear: <screen>calc --expression="1 + 2/3"</screen>
</para>
<section>
<title>Syntactic Information</title>
<para>The syntactic information is provided by the
<classname>boost::program_options::options_description</classname> class
and some methods of the
<classname>boost::program_options::value_semantic</classname> class
and includes:
<itemizedlist>
<listitem>
<para>
name of the option, used to identify the option inside the
program,
</para>
</listitem>
<listitem>
<para>
description of the option, which can be presented to the user,
</para>
</listitem>
<listitem>
<para>
the allowed number of source tokens that comprise options's
value, which is used during parsing.
</para>
</listitem>
</itemizedlist>
</para>
<para>Consider the following example:
<programlisting>
options_description desc;
desc.add_options()
("help", "produce help message")
("compression", value&lt;string&gt;(), "compression level")
("verbose", value&lt;string&gt;()->implicit_value("0"), "verbosity level")
("email", value&lt;string&gt;()->multitoken(), "email to send to")
;
</programlisting>
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:
<screen>
test --help --compression 10 --verbose --email beadle@mars beadle2@mars
</screen>
</para>
<section>
<title>Description formatting</title>
<para>
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.
</para>
<para>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).
</para>
<para>You may specify additional indent for the first specified by
inserting spaces at the beginning of a paragraph. For example:
<programlisting>
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 ")
;
</programlisting>
will specify a four-space indent for the first line. The output will
look like:
<screen>
--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
</screen>
</para>
<para>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:
<programlisting>
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");
</programlisting>
will produce:
<screen>
--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
</screen>
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.
</para>
</section>
</section>
<section>
<title>Semantic Information</title>
<para>The semantic information is completely provided by the
<classname>boost::program_options::value_semantic</classname> class. For
example:
<programlisting>
options_description desc;
desc.add_options()
("compression", value&lt;int&gt;()->default_value(10), "compression level")
("email", value&lt; vector&lt;string&gt; &gt;()
->composing()->notifier(&amp;your_function), "email")
;
</programlisting>
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 <code>&amp;your_function</code>, passing the value of the
"email" option as argument.
</para>
</section>
<section>
<title>Positional Options</title>
<para>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 <firstterm>positional option</firstterm>,
which does not specify any name at all, for example:
<screen>
archiver --compression=9 /etc/passwd
</screen>
Here, the "/etc/passwd" element does not have any option name.
</para>
<para>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:
<screen>
archiver --compression=9 --input-file=/etc/passwd
</screen>
</para>
<para>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:
<programlisting>
positional_options_description pd; pd.add("input-file", 1);
</programlisting> specifies that for exactly one, first, positional
option the name will be "input-file".
</para>
<para>It's possible to specify that a number, or even all positional options, be
given the same name.
<programlisting>
positional_options_description pd;
pd.add("output-file", 2).add("input-file", -1);
</programlisting>
In the above example, the first two positional options will be associated
with name "output-file", and any others with the name "input-file".
</para>
<warning>
<para>The &positional_options_desc; class only specifies translation from
position to name, and the option name should still be registered with
an instance of the &options_description; class.</para>
</warning>
</section>
<!-- Note that the classes are not modified during parsing -->
</section>
<section>
<title>Parsers Component</title>
<para>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, <code>true</code>). So, the
parser checks that the value is specified when needed and not specified
when not needed, and returns new (name, value) pair.
</para>
<para>
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.
</para>
<para>
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.
<itemizedlist>
<listitem>
<para>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.
</para>
</listitem>
<listitem>
<para>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.
</para>
</listitem>
<listitem>
<para>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.
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section>
<title>Storage Component</title>
<para>The storage component is responsible for:
<itemizedlist>
<listitem>
<para>Storing the final values of an option into a special class and in
regular variables</para>
</listitem>
<listitem>
<para>Handling priorities among different sources.</para>
</listitem>
<listitem>
<para>Calling user-specified <code>notify</code> functions with the final
values of options.</para>
</listitem>
</itemizedlist>
</para>
<para>Let's consider an example:
<programlisting>
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
store(parse_config_file("example.cfg", desc), vm);
notify(vm);
</programlisting>
The <code>variables_map</code> class is used to store the option
values. The two calls to the <code>store</code> function add values
found on the command line and in the config file. Finally the call to
the <code>notify</code> function runs the user-specified notify
functions and stores the values into regular variables, if needed.
</para>
<para>The priority is handled in a simple way: the <code>store</code>
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.
</para>
<warning>
<para>Don't forget to call the <code>notify</code> function after you've
stored all parsed values.</para>
</warning>
</section>
<section>
<title>Specific parsers</title>
<section>
<title>Configuration file parser</title>
<para>The &parse_config_file; function implements parsing
of simple INI-like configuration files. Configuration file
syntax is line based:
</para>
<itemizedlist>
<listitem><para>A line in the form:</para>
<screen>
<replaceable>name</replaceable>=<replaceable>value</replaceable>
</screen>
<para>gives a value to an option.</para>
</listitem>
<listitem><para>A line in the form:</para>
<screen>
[<replaceable>section name</replaceable>]
</screen>
<para>introduces a new section in the configuration file.</para>
</listitem>
<listitem><para>The <literal>#</literal> character introduces a
comment that spans until the end of the line.</para>
</listitem>
</itemizedlist>
<para>The option names are relative to the section names, so
the following configuration file part:</para>
<screen>
[gui.accessibility]
visual_bell=yes
</screen>
<para>is equivalent to</para>
<screen>
gui.accessibility.visual_bell=yes
</screen>
</section>
<section>
<title>Environment variables parser</title>
<para><firstterm>Environment variables</firstterm> are string variables
which are available to all programs via the <code>getenv</code> 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
<filename>autoexec.bat</filename> file or (on recent versions) the
<filename>Control Panel/System/Advanced/Environment Variables</filename>
dialog, and on Unix &#x2014;, the <filename>/etc/profile</filename>,
<filename>~/.profile</filename> and <filename>~/.bash_profile</filename>
files. Because environment variables can be set for the entire system,
they are particularly suitable for options which apply to all programs.
</para>
<para>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.</para>
<para>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 <literal>proxy</literal> the environment variable might be called
<envar>BOOST_PROXY</envar>. 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 <literal>BOOST_</literal> as the prefix, and there are
two variables, <envar>CVSROOT</envar> and <envar>BOOST_PROXY</envar>, the
first variable will be ignored, and the second one will be converted to
option <literal>proxy</literal>.
</para>
<para>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 <code>std::string</code> and returning
<code>std::string</code>. 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.
</para>
</section>
</section>
<section>
<title>Annotated List of Symbols</title>
<para>The following table describes all the important symbols in the
library, for quick access.</para>
<informaltable pgwide="1">
<tgroup cols="2">
<colspec colname='c1'/>
<colspec colname='c2'/>
<thead>
<row>
<entry>Symbol</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry namest='c1' nameend='c2'>Options description component</entry>
</row>
<row>
<entry>&options_description;</entry>
<entry>describes a number of options</entry>
</row>
<row>
<entry>&value;</entry>
<entry>defines the option's value</entry>
</row>
<row>
<entry namest='c1' nameend='c2'>Parsers component</entry>
</row>
<row>
<entry>&parse_command_line;</entry>
<entry>parses command line (simpified interface)</entry>
</row>
<row>
<entry>&basic_command_line_parser;</entry>
<entry>parses command line (extended interface)</entry>
</row>
<row>
<entry>&parse_config_file;</entry>
<entry>parses config file</entry>
</row>
<row>
<entry>&parse_environment;</entry>
<entry>parses environment</entry>
</row>
<row>
<entry namest='c1' nameend='c2'>Storage component</entry>
</row>
<row>
<entry>&variables_map;</entry>
<entry>storage for option values</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</section>
<!--
Local Variables:
mode: nxml
sgml-indent-data: t
sgml-parent-document: ("program_options.xml" "section")
sgml-set-face: t
End:
-->

View File

@@ -0,0 +1,181 @@
Program options post-review development plan.
0. Convert all documentation to BoostBook format
1. (done)
Simplify and clarify interface.
It turns out that most users are interested in 'variables_map' class, so
it must be possible to use it directly, without even knowing about
'options_and_arguments'. The proposed interface is:
options_description desc;
....
variables_map vm;
load_from_command_line(vm, desc, argc, argv);
2. (done)
Better separation of syntaxic and semantic processing, as suggested by
Pavol Droba.
The problem with current 'option_description' interface is that the
'validator' and 'notifier' callbacks are not really usable by ordinary
users --- it's extender's interface. The current 'parameter' function uses
those callback to provide user-friendly semantic interface, but it's not
documented nor completely worked out.
In the new interface, the second parameter of 'option_description' ctor
will have two possibilities: just a string and a pointer to a new class
'value_descriptor'. When passed the latter, it will invoke the instance on
itself, and then delete the object. A function 'value' will be provided,
that will create value specific for a type.
Example
("magic", value<int>("n", &n)->default_value(10), "magic value").
The 'value' function will create instances of 'typed_value_descriptor'
type, with the following methods:
- default_value
- interpreter
- validator
- notifier
The 'option_description' class we'll have two attributes to support
semantic operation: 'generator', which will handle conversion from string
into value (including application of default value), and 'notifier'. Similiar
to the the current design, those attributes will be set by
'value_descriptor' instances.
Another function, "bool_switch" will create value descriptor for type bool,
with default value of false. The function is needed to avoid special-casing
'value' function on bool type, which was considered confusing (Neal D. Becker).
3. (done) Support for positional options.
Positional options will be treated uniformly with ordinary ones. User will
be able to specify that, for example, third positional option is to be
interpreted as option "output-file" with the same value.
The user interface will be simple: user will provide two instanes of
'options_description' to functions which parse command line. For example.
options_description desc;
desc.add_options()
("magic", "n", "magic value")
;
options_description pdesc;
pdesc.add_options()
("output-file", "n", "output file")
("input-files*", value< vector<string> >("n"), "files")
;
variables_map vm;
load_from_command_line(vm, desc, pdesc, argc, argv);
4. (done, except for registry)
Multiple sources improvement.
Need to implement support for registry/environment.
Also, must devise a way to handle different naming of option in
sources. Lastly, the storing of values into program variables should
become part of 'variables_map' interface.
5. Improve documentation.
Chuck Messenger:
"When code is given for an example program, after the code, give examples of
using the program, along with the expected output."
Pavol Droba:
"I would prefer a few chapters explaining various components of the
library, each followed by a reference."
Pavel Vozenilek:
> Documentation should contain list of compilers the library works on and
> also info whether MSVC 6 port is feasible or not.
>
> The non-Doxygen part of documentation can be also a bit expanded: e.g. I
> would welcome some high level overview of the algorithms and structures and
> info about expected CPU/memory consumption.
>
> Also info whether there are any internal limits (like option length) .
>
> Some examples may be bit more annotated, also contain what is expected
> output.
Syntax highligting.
Document "*" in option names
Automated tests for examples?
(new) Comments inside code snippets?
(new) Table of all symbols
6. (deferred)
Unicode support
- unicode in argv/argc
- Unicode in config files not supported
(
The difference between ASCII and unicode files is:
- big endian UTF16 starts with 2 bytes FE FF 9mandatory by Unicode
standard) - little endian UTF16 starts with FF FE
- UTF8 text starts with EF BB BF
Pavel Vozenilek
)
7. Config file improvements
- should have "allow_unregistered" for config_file.
- (done) bool options in config file do not work.
- "#" inside strings, in config files (Pavel Vozenilek)
8.
Cmdline improvements
- must be able to parse WinMain string
- support for response files
9. Other changes.
- (outdated) get_value -> value (Beman)
- (done) is "argv" const in std, or not? Adjust docs if not.
- variables_map::count_if, find_if (Tanton Gibbs)
- Works with exceptions disabled.
- (outdated) disallow empty name for the 'parameter' function
- check for prefixes if 'allow_guessing' is on
- check for duplicate declaration of options.
- test additional parser
- Show default values in help output
- Adaptive field width
- Mandatory options (2 votes (second Jonathan Graehl))
- (new) return vector from parsers by auto_ptr, not by value?
- (new) rename value_semantic into value_description
- (new) output for positional_options_description
- (new) variables_map should throw when value not found
- (important) decide where we check that the number of passed option
tokens is less than the allowed number. In parser or later?
- (important) what if the same option has different definitions?
- (new) We lost the ability to specify options_description instance
in call to 'store'. So now we can't store just subset of options.
Is it a problem?
- (new) Improve formatting of 'arg'.
- (new) revive real and regexp examples.
- (new) even more simpler syntax for assignent to var?
10. Uncertain
- Function to get program name
- Order of 'description' and 'value'.
11. (new) Look at all "TODO" comments.
(new) Check that all methods are documented.
12. Deferred
- setting a flag when option is found

View File

@@ -0,0 +1,162 @@
/** @mainpage Program options documentation
@section scope Scope
Briefly, the library should allow program developers to obtain
<em>program options</em>, i.e. (name,value) pairs from the user,
via conventional methods such as command line and config file.
Necessary facilities include:
- parse command line
- parse config files
- perform semantic validation on input, such as checking for correct
type of parameters, and storing values.
- combine all inputs together, so that all program options can
be obtained in one place.
@section goals Goals
The fundamental goals for this library were:
- it should be more convenient to use it than parse command line by hand,
even when the number of possible options is 2,
- all popular command line styles should be supported,
- "you pay for what you use" principle is important: simple utilities
need not be forced to depend on excessive amount of code.
- it must be possible to validate option values, convert them to required
types, and store either in program variables, or in data structures
maintained by the library.
- data from command line and config file should be usable together, and
alternative program option sources (such as registry) should be
possible.
@section design_overview Design overview
To meet the stated goals, the library uses a layered architecture.
-# At the bottom, there are two parser classes,
boost::program_options::cmdline and
boost::program_options::config_file.
They are responsible for syntax matters only and provide simple
iterator-like interface.
-# The boost::program_options::options_and_arguments holds the result of parsing command line or
config file. It is still concerned with syntax only and holds precisely
what is found on command line. There's a couple of associated parse
functions (
@ref parse_cmdline_func "1",
@ref parse_config_file_func "2"),
which relieve the user from the need to iterate over options
and arguments manually.
-# The class boost::program_options::options_description is a high-level
description of allowed
program options, which does not depend on concrete parser class. In
addition, it can be used to provide help message. There are parse
functions which return options_and_arguments given options_description.
-# The options_description class also has semantic responsibilities. It's
possible to specify validators for option, their default values, and the
like. There's a function boost::program_options::perform_semantic_actions,
which handles this information and returns a map of option values.
-# Finally, at the top, there boost::program_options::variables_map class.
It's possible to
store options in it, and obtain them later. Another feature is that
different variable_map instances can be linked together, so that both
command line and config file data is used. Additional option sources can
be added at this level.
@section futher_reading Futher reading
To get further information about the library, you might want to read
the documentation for the classes referenced above. Another possibility
is to look through the examples:
- @ref options_description "simple usage"
- @ref variables_map "parsing with validation and assignment to program variables"
- @ref multiple_sources "using command line and config file together"
- @ref custom_syntax "customized options syntax"
- @ref real_example "real example"
- @ref custom_validator "custom validator"
- @ref multiple_modules "possible approach for multi-module programs"
- @ref cmdline "low level cmdline parsing"
Finally, you might want the check out the @ref recipes "recipes" page.
*/
/** @page examples Examples
- @ref options_description "simple usage"
- @ref variables_map "parsing with validation and assignment to program variables"
- @ref multiple_sources "using command line and config file together"
- @ref custom_syntax "customized options syntax"
- @ref real_example "real example"
- @ref custom_validator "custom validator"
- @ref multiple_modules "possible approach for multi-module programs"
- @ref cmdline "low level cmdline parsing"
*/
/** @page options_description Options description
Example of quite a simple usage. Options are registered and the
command line is parsed. The user is responsible to interpreting the
option values. This also how automatic help message.
@include options_description.cpp
*/
/** @page variables_map Variables map
In this example, the <tt>parameter</tt> function is used to enable
validation of options (i.e. checking that they are of correct type).
The option values are also stored in program variables.
@include variables_map.cpp
*/
/** @page multiple_sources Multiple sources
It is possible for program options to come from different sources.
Here, the command line and a config file are used, and the values
specified in both are combined, with preferrence given to the
command line.
@include multiple_sources.cpp
*/
/** @page custom_syntax Custom syntax
Some applications use a custom syntax for the command line. In this
example, the gcc style of &quot;-fbar&quot;/&quot;-f&quot; is handled.
@include custom_syntax.cpp
*/
/** @page real_example A real example
Shows how to use custom option description class and custom formatter.
Also validates some option relationship.
@include real.cpp
*/
/** @page multiple_modules Multiple modules
Large programs are likely to have several modules which want to use
some options. One possible approach is show here.
@sa @ref recipe_multiple_modules
@include multiple_modules.cpp
*/
/** @page custom_validator Custom validator
It's possible to plug in arbitrary function for converting the string
value from the command line to the value used in your program. The
example below illustrates this.
@include regex.cpp
*/
/** @page cmdline The cmdline class
When validation or automatic help message are not needed, it's possible
to use low-level boost::program_options::cmdline class, like shown
in this example.
@include cmdline.cpp
*/

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!ENTITY positional_options_desc
"<classname alt='boost::program_options::positional_options_description'>positional_options_description</classname>">
<!ENTITY options_description
"<classname alt='boost::program_options::options_description'>options_description</classname>">
<!ENTITY option_description
"<classname alt='boost::program_options::option_description'>option_description</classname>">
<!ENTITY value_semantic
"<classname alt='boost::program_options::value_semantic'>value_semantic</classname>">
<!ENTITY parsed_options
"<classname alt='boost::program_options::parsed_options'>parsed_options</classname>">
<!ENTITY variables_map
"<classname alt='boost::program_options::variables_map'>variables_map</classname>">
<!ENTITY value
"<functionname alt='boost::program_options::value'>value</functionname>">
<!ENTITY parse_command_line
"<functionname
alt='boost::program_options::parse_command_line'>parse_command_line</functionname>">
<!ENTITY parse_config_file
"<functionname alt='boost::program_options::parse_config_file'>parse_config_file</functionname>">
<!ENTITY parse_environment
"<functionname alt='boost::program_options::parse_environment'>parse_environment</functionname>">
<!ENTITY store
"<functionname alt='boost::program_options::store'>store</functionname>">
<!ENTITY command_line_parser
"<classname alt='boost::program_options::command_line_parser'>command_line_parser</classname>">
<!ENTITY basic_command_line_parser
"<classname alt='boost::program_options::basic_command_line_parser'>basic_command_line_parser</classname>">
<!ENTITY basic_option
"<classname alt='boost::program_options::basic_option'>basic_option</classname>">

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<library
name="Program_options"
dirname="program_options" id="program_options"
last-revision="$Date$"
xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo>
<author>
<firstname>Vladimir</firstname>
<surname>Prus</surname>
</author>
<copyright>
<year>2002</year>
<year>2003</year>
<year>2004</year>
<holder>Vladimir Prus</holder>
</copyright>
<legalnotice>
<para>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <filename>LICENSE_1_0.txt</filename> or copy at
<ulink
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
</para>
</legalnotice>
<librarypurpose>
Facilities to obtain configuration data from command line, config files
and other sources</librarypurpose>
<librarycategory name="category:data-structures"></librarycategory>
</libraryinfo>
<title>Boost.Program_options</title>
<section>
<title>Introduction</title>
<para>The program_options library allows program developers to obtain
<emphasis>program options</emphasis>, that is (name, value) pairs from the user,
via conventional methods such as command line and config file.</para>
<para>Why would you use such a library, and why is it better than parsing
your command line by straightforward hand-written code?
<itemizedlist>
<listitem>
<para>It's easier. The syntax for declaring options is simple, and
the library itself is small. Things like conversion of option values to
desired type and storing into program variables are handled
automatically.
</para>
</listitem>
<listitem>
<para>Error reporting is better. All the problems with the command line are
reported, while hand-written code can just misparse the input. In
addition, the usage message can be automatically generated, to
avoid falling out of sync with the real list of options.</para>
</listitem>
<listitem>
<para>Options can be read from anywhere. Sooner or later the command
line will be not enough for your users, and you'll want config files
or maybe even environment variables. These can be added without significant
effort on your part.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Now let's see some examples of the library usage in the <xref
linkend="program_options.tutorial"/>.
</para>
</section>
<xi:include href="tutorial.xml"/>
<xi:include href="overview.xml"/>
<xi:include href="howto.xml"/>
<xi:include href="design.xml"/>
<xi:include href="acknowledgements.xml"/>
<xi:include href="autodoc.xml"/>
</library>

View File

@@ -0,0 +1,16 @@
Rename 'parameter' in option_description with something
better, e.g. 'value_specification'?
Approximate matching for variable_map access?
Should be able to stack validators?
Case with variables like this
'foo' = 10
'foo.bar' = 12
should become an error

View File

@@ -0,0 +1,12 @@
/** @page open_questions Open questions.
<ol>
<li> Shouldn't validators always use "C" locale?
<li> Shouldn't validator for intr check for different bases?
<li> Does anyone need "getop_option_description"?.
</ol>
*/

View File

@@ -0,0 +1,15 @@
We could either implement simple chaining for variable maps, or
implement generic composition classes. The former was choosen,
mostly because of simplicity.
There were two implementation approaches for multiple option
occurrences in options_and_arguments. First is store them
separately. The advantage is that it's easy to obtain all
occurrences before certain position on command line. The
disadvantage is that we cannot return a reference to
vector<vector<string> > in get_all_values. It was considered
that if support for position-dependent options is to be
added, then we're be mostly interested in occurrences of
a single option that were before some point. That's possible
with vector<vector<string> > storage.

View File

@@ -0,0 +1,95 @@
/** @page rationale Rationale
@section code_size Focus on code size
The program options library has two important properties:
- runtime performance is not important. After all, command line processing
is done only once, and the amount of data is small.
- code size matters. Since parsing command line is utility task, users
won't be glad to have lots of code linked to every binary which has
options.
For the above reasons, the the library is designed so that it can be easily
used as shared library, with minimum code on the side of main application.
In particular, templates are used only where necessary, for example for
validation of user-defined types. In other places, boost::function is
used to allow customization, but keep templates out of the public
interface.
@section string_vs_enums Strings vs. enums
In some places, the library uses strings to convey information that
could be represented by enumerations or values. For example,
the program_options::option_description class allows to add "?" to the
parameter name to specify that the parameter is optional. For another
example, while program_options::cmdline class allows to obtain the
index of option, it does not require to specify an index for each option,
and it's possible to tell options by their names.
Such interface appears to be much more usable. If we were using
enumeration for different properties of parameter, there would be
another argument to many functions, the need to type long, possible
qualified names, and little advantage.
That little advantage is that if you type a wrong enumeration name,
you'd get a compile error. If you type '!' instead of '?' after parameter
name, you'd get incorrect behaviour. However, such errors are deemed
rare.
@section char_vs_string const char* vs. std::string
Most of the interface uses const char* where std::string seems a natural
choice. The reason is that those functions are called many times: for
example to declare all options. They are typically called with string
literals, and implicit conversion to string appears to take a lot of
code space. Providing both std::string and const char* version would
considerably bloat the interface. Since passing std::string is considered
rare, only const char* versions are provided.
@section init_syntax Initialization syntax
The syntax used for creating options_description instance was designed to
be as easy as possible in the most common case. Consider:
@code
desc.add_options()
("verbose", "", "verbosity level")
("magic", "int", "magic value").notify(some_func)
;
@endcode
Here, most common properties of options: name, presense of parameter and
description, are specified very concisely, and additional properties can
be given quite naturally, too.
Another possibility would be:
@code
option_description d1(...), d2(...);
desc.add(d1 & d2);
@endcode
or
@code
option_description d1(...), d2(...);
desc = d1, d2;
@endcode
The drawback is the need to explicitly create new objects and give names
to them. The latter problem can be helped if objects are created inside
expressions:
@code
desc = option_description(...), option_description(...)
@endcode
but there's still extra typing.
@section help_handling Handling of --help
It was suggested by Gennadiy Rozental that occurrence of <tt>--help</tt>
on command line results in throwing an exception. Actually, the
&quot;special&quot; option must have been configurable. This was not
implemented, because applications might reasonable want to process
the rest of command line even of <tt>--help</tt> was seen. For example,
<tt>--verbose</tt> option can control how much help should be output,
or there may be several subcommand with different help screens.
*/

View File

@@ -0,0 +1,91 @@
/** @page recipes Recipes
Here, we'll give solution for some desires which seem common.
@section recipe_parameter_validation How to check for correct option value types and assign them?
There's the boost::program_options::parameter function. It
returns a object, which, if passed as the second parameter
to boost::program_options::option_description constructor,
establishes correct validation routine. A simple example
is
@code
options_description desc;
desc.add_options()
("foo", parameter<int>("arg"), "obscure option")
;
@endcode
If you pass an address of <tt>int</tt> variable as the second
parameter of the <tt>parameter</tt> function, that variable will
be assigned the options's value.
@sa @ref variables_map
@section recipe_lazy What if I don't want to declare any options?
I'm not sure this is good idea. In particular, mistyped options
will be silently ignored, leading to possible user surprises.
Futher, the boost::program_options::cmdline class was specially
designed to be very lightweight.
Anyway, there's a version of the parse_command_line function
which does not take an options_description instance. Also, the
cmdline class ctor accepts an 'allow_unregistered' parameter.
In both cases, all options will be allowed, and treated as if
they have optional parameter.
Note that with the default style,
@verbatim
--foo bar
@endverbatim
will be taken as option "foo" with value "bar", which is
probably not correct. You should disable option parameter in
the next token to avoid problems.
@sa boost::program_options::cmdline
@section recipe_multiple_modules I have several separate modules which must controlled by options. What am I to do?
There are several solutions.
@subsection sb1 Everything's global
You can create a single instance of the <tt>options_description</tt> class
somewhere near <tt>main</tt>. All the modules will export their own
options using other <tt>options_description</tt> instances which can
be added to the main one. After that, you'd parse command line and
config files. The parsing results will be stored in one variables_map,
which will be passed to all modules, which can work with their own
options.
@subsection sb2 Private option data
Assume one of the modules does not like to see irrelevant options.
For example, it outputs a configuration file for other program, and
irrelevant options will confuse that program.
It's possible to give the module only the options that it has
registered. First, the module provides an options_description instance
which is added to the global one. Second the command line is parsed
to produce an options_and_arguments instance. Lastly, the <tt>store</tt>
function is called. If passed the options_description instance previously
returned by the module, it will store only options specified in that
instance.
@sa @ref multiple_modules
@subsection sb3 Unique option names
The most general solution would be to give unique names to options
for different modules. One module will declare option "module1.server",
and another would declare "module2.internal_checks". Of course, there
can be global options like "verbosity", declared by <tt>main</tt> and
used by all modules.
This solution avoids all possible name clashes between modules. On
the other hand, longer option names can be less user-friendly. This
problem can be alleviated if module prefix is used only for less
common option, needed for fine-tuning.
*/

View File

@@ -0,0 +1,209 @@
From rogeeff@mail.com Fri Nov 16 19:57:49 2001
Received: from imap.cs.msu.su (imap.cs.msu.su [158.250.10.15])
by redsun.cs.msu.su (8.9.3/8.9.3) with ESMTP id TAA06515
for <ghost@redsun.cs.msu.su>; Fri, 16 Nov 2001 19:59:43 +0300 (MSK)
Received: from n15.groups.yahoo.com (n15.groups.yahoo.com [216.115.96.65])
by imap.cs.msu.su (8.11.6/8.11.6) with SMTP id fAGGtrd57869
for <ghost@cs.msu.su>; Fri, 16 Nov 2001 19:55:54 +0300 (MSK)
(envelope-from sentto-1234907-17382-1005929874-ghost=cs.msu.su@returns.groups.yahoo.com)
X-eGroups-Return: sentto-1234907-17382-1005929874-ghost=cs.msu.su@returns.groups.yahoo.com
Received: from [10.1.1.222] by n15.groups.yahoo.com with NNFMP; 16 Nov 2001 16:57:42 -0000
X-Sender: rogeeff@mail.com
X-Apparently-To: boost@yahoogroups.com
Received: (EGP: mail-8_0_0_1); 16 Nov 2001 16:57:53 -0000
Received: (qmail 2553 invoked from network); 16 Nov 2001 16:57:53 -0000
Received: from unknown (216.115.97.172)
by m4.grp.snv.yahoo.com with QMQP; 16 Nov 2001 16:57:53 -0000
Received: from unknown (HELO n6.groups.yahoo.com) (216.115.96.56)
by mta2.grp.snv.yahoo.com with SMTP; 16 Nov 2001 16:57:53 -0000
X-eGroups-Return: rogeeff@mail.com
Received: from [10.1.10.109] by n6.groups.yahoo.com with NNFMP; 16 Nov 2001 16:57:52 -0000
To: boost@yahoogroups.com
Message-ID: <9t3gid+hdf3@eGroups.com>
In-Reply-To: <E164iu4-00052e-00@zigzag.cs.msu.su>
User-Agent: eGroups-EW/0.82
X-Mailer: eGroups Message Poster
X-Originating-IP: 199.119.33.162
From: "Gennadiy E. Rozental" <rogeeff@mail.com>
X-Yahoo-Profile: rogeeff
MIME-Version: 1.0
Mailing-List: list boost@yahoogroups.com; contact boost-owner@yahoogroups.com
Delivered-To: mailing list boost@yahoogroups.com
Precedence: bulk
List-Unsubscribe: <mailto:boost-unsubscribe@yahoogroups.com>
Date: Fri, 16 Nov 2001 16:57:49 -0000
Reply-To: boost@yahoogroups.com
Subject: [boost] Re: arguments parsing, wildcard matcher
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII
Content-Length: 5662
Status: R
X-Status: N
--- In boost@y..., Vladimir Prus <ghost@c...> wrote:
>
> > Just a couple of classes I wrote that I wondered if anyone thought
> > any place in boost:
> >
> > arguments : simple command-line arguments and options parser:
> >
> > class arguments
> > {
> > public:
> > arguments(int argc, char* argv[]);
> >
> > bool has_option(const char* name) const;
> > bool get_option(const char* name, bool& value) const;
>
> > Any interest? Already proposed? Wasting my time?
>
> Actually, I'm already working on library with the same goals but
more
> elaborated. Moreover, it's almost finished. I planned to announce
it later,
> but have to do it now. My design goals were:
> - It should be resonable to use the library to parse as little as
2 command
> line options.
> - It must be extandable to privide any resonable handling
> - since command line is just a way to affect the program behaviour,
other
> ways to accomplish that must be provided, most notable is
configuration file
> - library should provide a way to store information from command
line and
> config file in a way allowing easy retrieval and using to change
configurable
> parameters of the program.
>
> The docs are available at:
> http://chronos.cs.msu.su/~ghost/projects/config_db/doc/index.html
>
> Let me know what you think.
Privet, Volodya.
Here what I am looking for to be supported by Command Line Argument
Framework directly or by means of easy extension:
1. command line argument formats
a. -<one letter key> <value>
b. -<one letter key><value>
c. -<key> <value>
d. -<option> - any length
e. /<key> <value> - and all other cases like a,b,c but with /
instead
g. --<key> <value>
h. -<key substring> <value>
An example: let say you expecting argument -osagent_port
then following argument lists should be valid:
-o 15000
-osa 15000
-osagent_port 15000
On the other hand it should perform validity checks. For example
if you also expect another argument -osagent_host. then first 2
argument list above should generate runtime error and 3d should
pass. Arguments integrity check should also be performed, i.e.
you should not allow for user to define 2 argument like this:
"-port"
"-port_type"
2. argument types
I should be able to explicitle specify expected argument type. For
example: std::string, int, double, option(bool). The framework should
perform value validation. For example 1.23 is not valid for int
argument. The framework should allow to use user-defined classes as
expected types for command-line argument. In other word. If I provide
you a class with predefined psecification framework should try to
generate object of argument class. Some simple extention you can
provide youself. For example, using following command line you should
be able to generate std::list<int>
-values 2 5 7 8
and using following command line you should be able to generate
std::list<std::string>
-files_to_test test1.td test2.td test3.td test4.td
and using following command line user should be able to provide
argument class A to generate std::list<A>
struct A{
std::string key;
int value;
};
-parameters_mapping name1 4 name5 7 name6 8 name9 1123
3. argument storage.
a. Framework should be able to generate and store arguments
internally. In this case framework in responsable for memory.
b. Framework should be able to generate and store argument into the
user-bound location. In this case user in responsable for memory.
4. arguments can have default values
5. arguments can be optional and required. The framework should
automatically check presence of of all required arguments.
6. argument value access
a. if user passed storage location - he will be able to get value
from there
b. by name and type. If any of them is incorrect - error. The same
rules aplied here as in 1.h if argument matching algorithm allows
substrings.
c. is_present check - to be able to check presence of optional
arguments.
7. usage line.
The framework should be able to generate a using line given a
difinition of all feilds. To support this you will probably need
argument description as one of the command line argument
constructor's argument. Thr framework should be able to configured to
use different usage line. If command line contain predefined keyword
(-help or /? for example) framework should print usage message.
8. Framework Error
If any of the following condition occures during command line
processing the framework should generate an error and print a usage
line:
a. invalid aargument
b. ambiguous argument
c. invalid value for the argument
d. absence of required argument
e. framework meet -help (of any other predefined keyword)
Invalid name or type should generate exception during value access.
Here my view on the problem.
Regards,
Gennadiy.
P.S. Did you look into Brat Appleton's work? It seems to be close to
what you are doing.
>
> Concerning your proposal, I can mark two points, apart from it's
been a
> subset of mine:
> 1. It uses get_options(const char* name, type& value) methods,
which are not
> extendable (and the similar thing is used in KConfig class in
KDE....) What I
> propose is
> variables_map vm .....
> int i = vm["magic"].as<int>()
> FontName fn = vm["font"].as<FontName>()
> 2. You propose wildcard expansions. This is good. But it is easy to
add it to
> any existing command line parsing library.
>
> - Volodya
Info: http://www.boost.org Unsubscribe: <mailto:boost-unsubscribe@yahoogroups.com>
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

View File

@@ -0,0 +1,238 @@
Say that variables_map is actually derived from std::map.
Make parse_config_file("foo.cfg", desc) work.
Document handling of positional options which depends on precedding options.
I.e scanning the parsed options and creating new variables_map when we see
a positional option. (Email from Tony).
> My instinctive reaction is to provide both via an options argument to
> split_command_line (a name that would now be more appropriate). But I
> haven't devoted much time to thinking this through, so I may be wrong. :-)
>
> In any event, the tokenization isn't much fun. I'd expect the library to
> provide a convenient mechanism for parsing a response file.
> Similarly, is there some easy to use hook for customizing the "arg" to
> indicate the type of the data (similar to how the textual representation
> of the default argument can be changed, e.g.
> value<Infile>(&forests_file)->default_value(default_in,"STDIN"), so that
> I could get something like: "-f filename (=STDIN) :" instead of "-f
> arg (=STDIN) :"?
> A minor nit pick, with option groups (chained options_description), the
> colons for the same group align but not across groups.
There's another possibility:
value<type>(&variable, "filename")->......
something like that was in the pre-review version, with the difference that the value name was also used to specify flags, e.g "filename?" would mean the value is optional.
Should we also store the name specified on the command line in basic_option,
so that validation_error can mention the *specified* option name?
The config file is a bit different from command line. E.g. 'bool_switch' can't
be specified in the config file. Further, it's not possible to specify a list
of values in config file. For example, you can't write
include=a,b,c,d
(or some other separator). You need:
include=a
...
include=d
> I often find it beneficial to start a log file, by tracing all options
> in effect. Thus, it would be nice if one could iterate over all values
> in a variable_map and get a string representation of all values. Perhaps
> as an iterator range to the original string that was parsed into the
> value in the first place. Using as<string> delegates to boost::any and
> only succeeds if the value is indeed a string (a design decision I can
> only applaud, btw), so I'm out of luck there.
UML diagram?
src/cmdline.cpp: function strncmp_nocase():
> maybe it can be replaced by something from string_algorithms
> library. AFAIK the library should be in 1.32.
> 24. the documentation may contain info what source files are needed
> for which feature or whether they need to be included always all.
The program_options.reference.html may contain one-liner
overview for every header and every class/typedef/function
listed here - just for quick browsing and overview.
> > > 5. Maybe more overcommented code examples can be added into
> > > docs, each exploring single feature of library.
> > >
> > > Some people learn mostly from such examples.
> > >
> > > Later note: definitely would be useful, IMO.
> >
> > Maybe. Do you have specific ideas what the examples can be about?
>
> One tiny example concentrating on one feature as short/long options,
> multiple sources, hidden options, positional options, INI handling etc.
> Something what user can skim over and cut/paste into app.
> I would prefer that all occurrences of ASCII be capitalized. It is the
> abbreviation of the name of the Standard. You may show it in lower case,
> though, to distinguish "char strings in local 8-bit encoding" from the
> Standard but it may confuse some readers. I can't think of a good
> alternative right now.
> [By the way, "positional options" _desperately_ needs an entry in the
> glossary. It's the most mystifying term in the library.]
> If not already stated, you should note that all options must appear in the
> options description layer (or class or object). No options may make their
> first appearance in the runtime configuration file, for instance. The
> library doesn't like surprises. (I bring this up because other
> initialization libraries allow an option to be declared in the
> configuration file alone. The file reader stores the option and parses it
> to determine its type, for example, Boolean, double, integer or string.)
-----------
> "In the simplest case, the name is explicitly specified, which allows the
> program to decide if such an option is known."
>
> or
>
> "In the simplest case, the name is explicitly specified and the program
> decides that the option is known."
> (This paragraph is a bit hard to read. Maybe when I understand the library
> better I can suggest some wording which flows more smoothly.)
Maybe some explanation can help. Most of the time, input source contains both
the name of option and the value, for example, --foo=10. In this case, we
just lookup the option name, decide we know this option, and process it.
In one specific case -- positional command line options, we don't have
explicit name. For example:
my_prog 1 2 3
so more complex logic is necessary.
> Rather than clutter up this list it might be better for the word "sources"
> to be a link to another part of the document which lists the sources and
> the order of precedence.
Style of 'screen' in docs.
> Perhaps you should include some sample output to show correct and incorrect
> locale support or include a link to somewhere else in Boost where the
> reader can find more information. I wouldn't know a Unicode if it came up
> and bit me on the ankle.
> "Common cases are when the value is explicitly specified by the user, and
> when the value cannot be specified by the user, but the presense of the
> option implies some value (for example, <code>true</code>). So, the parser
> checks that the value is specified when needed and not specified when not
> needed, and returns new (name, value) pair."
>
> This wording is quite stiff and I can't decipher it, especially the "not
> specified when not needed" phrase. Can you rewrite this?
> While I'm thinking about it, can you add the "Last revised..." line at the
> bottom of each HTML page as it is on program_options.html or it that
> governed by an xsl file?
> If it doesn't already exist, there should be something in the tutorial to
> explicitly define the steps required prior to the use of a configuration
> variable as:
> 1. declaration
> 2. addition or composition
> 3. storage or insertion
> 4. notification.
> I think a few lines should be added to aid the library user with the test
> programs. You could place them here in howto.xml or elsewhere or in a new
> section entirely. Users will want to know if their compiler is known to
> work with the library and should be directed to the Boost Compiler Status
> Tables page (\status\compiler_status.html or similar) or directly to the
> Compiler Status Summary (http://boost.sourceforge.net/regression-logs/).
> Many users will want to run the test programs on their own computer. Your
> documentation should answer these questions:
> Which libraries must be linked to build the programs? (Dynamic? Static?)
> Are there any other special considerations or any compiler switches to be
> set? For those without a full Boost package, which other Boost libraries
> are "included" by the test programs and, therefore, must be available?
Basically, it's assumed that test programs with be run with Boost.Build.
Maybe it's worth noting that if a user wants to compiler them himself,
he should link the program_options library.
> If you decide to make a separate section to describe the implementation of
> the test programs, you might move the "test_convert" paragraphs starting at
> line 379 of howto.xml there and put a referring link in its place.
> I thought there was a bit of correspondence on one of the Boost mailing
> lists concerning the inability of program_options to show the stored
> variables 'en masse' but I can't find it now. You should include that in
> the documentation. Most users will be searching for a method to verify that
> command line and configuration file values were actually stored in place of
> the default values, for instance. You could put in a line or two stating
> that there is no one function which will send the entire database to a file
> for later review. (I think it had something to do with the fact that
> program_options doesn't "know" the type of each option.) I think it will
> acquire the status of a Frequently-Asked Question.)
> > Agreed. Though it's no FAQ section yet.... maybe, I can add this to howto
>
> section, though a question without full solution is not good.
>
> For the time being, those who want to know if such a display function
> exists will have their question answered and the reason for it. I suppose
> that the library user could insert a series of statements in his program
> immediately after the "notify" function which would write each known option
> to a file for later examination. Some people may use a number of "assert"
> statements instead. They would only come into play in the debug mode.
More visibility for bool_switch.
> BTW: I thought of one other comment. One of the things I missed a little
> in the documentation is a description of the config file format, as well
> as what can be achieved with the po::command_line_style::style_t enum. I
> think most users will need this information sooner or later. A few
> examples would be fine... But then again time is such a precious thing
> Does the library supports sections in config files
> What about the combination of (if some user-settable switch is thrown,
> but not by default):
>
> * allowing unknown options -- these are considered positional parameters
> * rearranging the argument list such that all positional parameters
> are moved to the end
>
> This way:
>
> program --unknown 42 --known-flag --known-arg value
>
> is handled as if it were (in standard UNIX command-line-ese):
>
> program --known-flag --known-arg value -- --unknown 42

View File

@@ -0,0 +1,353 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
[
<!ENTITY % entities SYSTEM "program_options.ent" >
%entities;
]>
<section id="program_options.tutorial">
<title>Tutorial</title>
<para>In this section, we'll take a look at the most common usage scenarios
of the program_options library, starting with the simplest one. The examples
show only the interesting code parts, but the complete programs can be found
in the "BOOST_ROOT/libs/program_options/example" directory. Through all the
examples, we'll assume that the following namespace alias is in effect:
<programlisting>namespace po = boost::program_options;</programlisting>
</para>
<section>
<title>Getting Started</title>
<para>The first example is the simplest possible: it only handles two
options. Here's the source code (the full program is in
"example/first.cpp"):
<programlisting>
// Declare the supported options.
po::options_description desc(&quot;Allowed options&quot;);
desc.add_options()
(&quot;help&quot;, &quot;produce help message&quot;)
(&quot;compression&quot;, po::value&lt;int&gt;(), &quot;set compression level&quot;)
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if (vm.count(&quot;help&quot;)) {
cout &lt;&lt; desc &lt;&lt; &quot;\n&quot;;
return 1;
}
if (vm.count(&quot;compression&quot;)) {
cout &lt;&lt; &quot;Compression level was set to &quot;
&lt;&lt; vm[&quot;compression&quot;].as&lt;int&gt;() &lt;&lt; &quot;.\n&quot;;
} else {
cout &lt;&lt; &quot;Compression level was not set.\n&quot;;
}
</programlisting>
</para>
<para>We start by declaring all allowed options using the
&options_description; class. The <code>add_options</code> method of that
class returns a special proxy object that defines
<code>operator()</code>. Calls to that operator actually declare
options. The parameters are option name, information about value, and option
description. In this example, the first option has no value, and the second
one has a value of type <code>int</code>.
</para>
<para>After that, an object of class <code>variables_map</code> is
declared. That class is intended to store values of options, and can store
values of arbitrary types. Next, the calls to <code>store</code>,
<code>parse_command_line</code> and <code>notify</code> functions cause
<code>vm</code> to contain all the options found on the command
line.</para>
<para>And now, finally, we can use the options as we like. The
<code>variables_map</code> class can be used just like
<code>std::map</code>, except that values stored there must be retrieved
with the <code>as</code> method shown above. (If the type specified in the
call to the <code>as</code> method is different from the actually stored
type, an exception is thrown.)
</para>
<para>It's now a good time to try compiling the code yourself, but if
you're not yet ready, here's an example session:
<screen>
$ <userinput>bin/gcc/debug/first</userinput>
Compression level was not set.
$ <userinput>bin/gcc/debug/first --help</userinput>
Allowed options:
--help : produce help message
--compression arg : set compression level
$ <userinput>bin/gcc/debug/first --compression 10</userinput>
Compression level was set to 10.
</screen>
</para>
</section>
<section>
<title>Option Details</title>
<para>An option value, surely, can have other types than <code>int</code>, and
can have other interesting properties, which we'll discuss right now. The
complete version of the code snipped below can be found in
<filename>example/options_description.cpp</filename>.</para>
<para>Imagine we're writing a compiler. It should take the optimization
level, a number of include paths, and a number of input files, and perform some
interesting work. Let's describe the options:
<programlisting>
int opt;
po::options_description desc(&quot;Allowed options&quot;);
desc.add_options()
(&quot;help&quot;, &quot;produce help message&quot;)
(&quot;optimization&quot;, po::value&lt;int&gt;(&amp;opt)-&gt;default_value(10),
&quot;optimization level&quot;)
(&quot;include-path,I&quot;, po::value&lt; vector&lt;string&gt; &gt;(),
&quot;include path&quot;)
(&quot;input-file&quot;, po::value&lt; vector&lt;string&gt; &gt;(), &quot;input file&quot;)
;
</programlisting>
</para>
<para>The <literal>"help"</literal> option should be familiar from
the previous example. It's a good idea to have this option in all cases.
</para>
<para>The <literal>"optimization"</literal> option shows two new features. First, we specify
the address of the variable(<code>&amp;opt</code>). After storing values, that
variable will have the value of the option. Second, we specify a default
value of 10, which will be used if no value is specified by the user.
</para>
<para>The <literal>"include-path"</literal> option is an example of the
only case where the interface of the <code>options_description</code>
class serves only one
source -- the command line. Users typically like to use short option names
for common options, and the "include-path,I" name specifies that short
option name is "I". So, both "--include-path" and "-I" can be used.
</para>
<para>Note also that the type of the <literal>"include-path"</literal>
option is <type>std::vector</type>. The library provides special
support for vectors -- it will be possible to specify the option several
times, and all specified values will be collected in one vector.
</para>
<para>The "input-file" option specifies the list of files to
process. That's okay for a start, but, of course, writing something like:
<screen>
<userinput>compiler --input-file=a.cpp</userinput>
</screen>
is a little non-standard, compared with
<screen>
<userinput>compiler a.cpp</userinput>
</screen>
We'll address this in a moment.
</para>
<para>
The command line tokens which have no option name, as above, are
called "positional options" by this library. They can be handled
too. With a little help from the user, the library can decide that "a.cpp"
really means the same as "--input-file=a.cpp". Here's the additional code
we need:
<programlisting>
po::positional_options_description p;
p.add(&quot;input-file&quot;, -1);
po::variables_map vm;
po::store(po::command_line_parser(ac, av).
options(desc).positional(p).run(), vm);
po::notify(vm);
</programlisting>
</para>
<para>
The first two lines say that all positional options should be translated
into "input-file" options. Also note that we use the
&command_line_parser; class to parse the command
line, not the &parse_command_line;
function. The latter is a convenient wrapper for simple cases, but now we
need to pass additional information.
</para>
<para>By now, all options are described and parsed. We'll save ourselves the
trouble of implementing the rest of the compiler logic and only print the
options:
<programlisting>
if (vm.count(&quot;include-path&quot;))
{
cout &lt;&lt; &quot;Include paths are: &quot;
&lt;&lt; vm[&quot;include-path&quot;].as&lt; vector&lt;string&gt; &gt;() &lt;&lt; &quot;\n&quot;;
}
if (vm.count(&quot;input-file&quot;))
{
cout &lt;&lt; &quot;Input files are: &quot;
&lt;&lt; vm[&quot;input-file&quot;].as&lt; vector&lt;string&gt; &gt;() &lt;&lt; &quot;\n&quot;;
}
cout &lt;&lt; &quot;Optimization level is &quot; &lt;&lt; opt &lt;&lt; &quot;\n&quot;;
</programlisting>
</para>
<para>Here's an example session:
<screen>
$ <userinput>bin/gcc/debug/options_description --help</userinput>
Usage: options_description [options]
Allowed options:
--help : produce help message
--optimization arg : optimization level
-I [ --include-path ] arg : include path
--input-file arg : input file
$ <userinput>bin/gcc/debug/options_description</userinput>
Optimization level is 10
$ <userinput>bin/gcc/debug/options_description --optimization 4 -I foo a.cpp</userinput>
Include paths are: foo
Input files are: a.cpp
Optimization level is 4
</screen>
</para>
<para>
Oops, there's a slight problem. It's still possible to specify the
"--input-file" option, and usage message says so, which can be confusing
for the user. It would be nice to hide this information, but let's wait
for the next example.
</para>
</section>
<section>
<title>Multiple Sources</title>
<para>It's quite likely that specifying all options to our compiler on the
command line will annoy users. What if a user installs a new library and
wants to always pass an additional command line element? What if he has
made some choices which should be applied on every run? It's desirable to
create a config file with common settings which will be used together with
the command line.
</para>
<para>Of course, there will be a need to combine the values from command
line and config file. For example, the optimization level specified on the
command line should override the value from the config file. On the other
hand, include paths should be combined.
</para>
<para>Let's see the code now. The complete program is in
"examples/multiple_sources.cpp". The option definition has two interesting
details. First, we declare several instances of the
<code>options_description</code> class. The reason is that, in general,
not all options are alike. Some options, like "input-file" above, should
not be presented in an automatic help message. Some options make sense only
in the config file. Finally, it's nice to have some structure in the help message,
not just a long list of options. Let's declare several option groups:
<programlisting>
// Declare a group of options that will be
// allowed only on command line
po::options_description generic(&quot;Generic options&quot;);
generic.add_options()
(&quot;version,v&quot;, &quot;print version string&quot;)
(&quot;help&quot;, &quot;produce help message&quot;)
;
// Declare a group of options that will be
// allowed both on command line and in
// config file
po::options_description config(&quot;Configuration&quot;);
config.add_options()
(&quot;optimization&quot;, po::value&lt;int&gt;(&amp;opt)-&gt;default_value(10),
&quot;optimization level&quot;)
(&quot;include-path,I&quot;,
po::value&lt; vector&lt;string&gt; &gt;()-&gt;composing(),
&quot;include path&quot;)
;
// Hidden options, will be allowed both on command line and
// in config file, but will not be shown to the user.
po::options_description hidden(&quot;Hidden options&quot;);
hidden.add_options()
(&quot;input-file&quot;, po::value&lt; vector&lt;string&gt; &gt;(), &quot;input file&quot;)
;
</programlisting>
Note the call to the <code>composing</code> method in the declaration of the
"include-path" option. It tells the library that values from different sources
should be composed together, as we'll see shortly.
</para>
<para>
The <code>add</code> method of the <code>options_description</code>
class can be used to further group the options:
<programlisting>
po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);
po::options_description config_file_options;
config_file_options.add(config).add(hidden);
po::options_description visible(&quot;Allowed options&quot;);
visible.add(generic).add(config);
</programlisting>
</para>
<para>The parsing and storing of values follows the usual pattern, except that
we additionally call <functionname>parse_config_file</functionname>, and
call the &store; function twice. But what
happens if the same value is specified both on the command line and in
config file? Usually, the value stored first is preferred. This is what
happens for the "--optimization" option. For "composing" options, like
"include-file", the values are merged.
</para>
<para>Here's an example session:
<screen>
$ <userinput>bin/gcc/debug/multiple_sources</userinput>
Include paths are: /opt
Optimization level is 1
$ <userinput>bin/gcc/debug/multiple_sources --help</userinput>
Allows options:
Generic options:
-v [ --version ] : print version string
--help : produce help message
Configuration:
--optimization n : optimization level
-I [ --include-path ] path : include path
$ <userinput>bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp</userinput>
Include paths are: foo /opt
Input files are: a.cpp b.cpp
Optimization level is 4
</screen>
The first invocation uses values from the configuration file. The second
invocation also uses values from command line. As we see, the include
paths on the command line and in the configuration file are merged,
while optimization is taken from the command line.
</para>
</section>
</section>
<!--
Local Variables:
mode: nxml
sgml-indent-data: t
sgml-parent-document: ("program_options.xml" "section")
sgml-set-face: t
End:
-->