tutorial.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <?xml version="1.0" standalone="yes"?>
  2. <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
  3. "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"
  4. [
  5. <!ENTITY % entities SYSTEM "program_options.ent" >
  6. %entities;
  7. ]>
  8. <section id="program_options.tutorial">
  9. <title>Tutorial</title>
  10. <para>In this section, we'll take a look at the most common usage scenarios
  11. of the program_options library, starting with the simplest one. The examples
  12. show only the interesting code parts, but the complete programs can be found
  13. in the "BOOST_ROOT/libs/program_options/example" directory. Through all the
  14. examples, we'll assume that the following namespace alias is in effect:
  15. <programlisting>namespace po = boost::program_options;</programlisting>
  16. </para>
  17. <section>
  18. <title>Getting Started</title>
  19. <para>The first example is the simplest possible: it only handles two
  20. options. Here's the source code (the full program is in
  21. "example/first.cpp"):
  22. <programlisting>
  23. // Declare the supported options.
  24. po::options_description desc(&quot;Allowed options&quot;);
  25. desc.add_options()
  26. (&quot;help&quot;, &quot;produce help message&quot;)
  27. (&quot;compression&quot;, po::value&lt;int&gt;(), &quot;set compression level&quot;)
  28. ;
  29. po::variables_map vm;
  30. po::store(po::parse_command_line(ac, av, desc), vm);
  31. po::notify(vm);
  32. if (vm.count(&quot;help&quot;)) {
  33. cout &lt;&lt; desc &lt;&lt; &quot;\n&quot;;
  34. return 1;
  35. }
  36. if (vm.count(&quot;compression&quot;)) {
  37. cout &lt;&lt; &quot;Compression level was set to &quot;
  38. &lt;&lt; vm[&quot;compression&quot;].as&lt;int&gt;() &lt;&lt; &quot;.\n&quot;;
  39. } else {
  40. cout &lt;&lt; &quot;Compression level was not set.\n&quot;;
  41. }
  42. </programlisting>
  43. </para>
  44. <para>We start by declaring all allowed options using the
  45. &options_description; class. The <code>add_options</code> method of that
  46. class returns a special proxy object that defines
  47. <code>operator()</code>. Calls to that operator actually declare
  48. options. The parameters are option name, information about value, and option
  49. description. In this example, the first option has no value, and the second
  50. one has a value of type <code>int</code>.
  51. </para>
  52. <para>After that, an object of class <code>variables_map</code> is
  53. declared. That class is intended to store values of options, and can store
  54. values of arbitrary types. Next, the calls to <code>store</code>,
  55. <code>parse_command_line</code> and <code>notify</code> functions cause
  56. <code>vm</code> to contain all the options found on the command
  57. line.</para>
  58. <para>And now, finally, we can use the options as we like. The
  59. <code>variables_map</code> class can be used just like
  60. <code>std::map</code>, except that values stored there must be retrieved
  61. with the <code>as</code> method shown above. (If the type specified in the
  62. call to the <code>as</code> method is different from the actually stored
  63. type, an exception is thrown.)
  64. </para>
  65. <para>It's now a good time to try compiling the code yourself, but if
  66. you're not yet ready, here's an example session:
  67. <screen>
  68. $ <userinput>bin/gcc/debug/first</userinput>
  69. Compression level was not set.
  70. $ <userinput>bin/gcc/debug/first --help</userinput>
  71. Allowed options:
  72. --help : produce help message
  73. --compression arg : set compression level
  74. $ <userinput>bin/gcc/debug/first --compression 10</userinput>
  75. Compression level was set to 10.
  76. </screen>
  77. </para>
  78. </section>
  79. <section>
  80. <title>Option Details</title>
  81. <para>An option value, surely, can have other types than <code>int</code>, and
  82. can have other interesting properties, which we'll discuss right now. The
  83. complete version of the code snipped below can be found in
  84. <filename>example/options_description.cpp</filename>.</para>
  85. <para>Imagine we're writing a compiler. It should take the optimization
  86. level, a number of include paths, and a number of input files, and perform some
  87. interesting work. Let's describe the options:
  88. <programlisting>
  89. int opt;
  90. po::options_description desc(&quot;Allowed options&quot;);
  91. desc.add_options()
  92. (&quot;help&quot;, &quot;produce help message&quot;)
  93. (&quot;optimization&quot;, po::value&lt;int&gt;(&amp;opt)-&gt;default_value(10),
  94. &quot;optimization level&quot;)
  95. (&quot;include-path,I&quot;, po::value&lt; vector&lt;string&gt; &gt;(),
  96. &quot;include path&quot;)
  97. (&quot;input-file&quot;, po::value&lt; vector&lt;string&gt; &gt;(), &quot;input file&quot;)
  98. ;
  99. </programlisting>
  100. </para>
  101. <para>The <literal>"help"</literal> option should be familiar from
  102. the previous example. It's a good idea to have this option in all cases.
  103. </para>
  104. <para>The <literal>"optimization"</literal> option shows two new features. First, we specify
  105. the address of the variable(<code>&amp;opt</code>). After storing values, that
  106. variable will have the value of the option. Second, we specify a default
  107. value of 10, which will be used if no value is specified by the user.
  108. </para>
  109. <para>The <literal>"include-path"</literal> option is an example of the
  110. only case where the interface of the <code>options_description</code>
  111. class serves only one
  112. source -- the command line. Users typically like to use short option names
  113. for common options, and the "include-path,I" name specifies that short
  114. option name is "I". So, both "--include-path" and "-I" can be used.
  115. </para>
  116. <para>Note also that the type of the <literal>"include-path"</literal>
  117. option is <type>std::vector</type>. The library provides special
  118. support for vectors -- it will be possible to specify the option several
  119. times, and all specified values will be collected in one vector.
  120. </para>
  121. <para>The "input-file" option specifies the list of files to
  122. process. That's okay for a start, but, of course, writing something like:
  123. <screen>
  124. <userinput>compiler --input-file=a.cpp</userinput>
  125. </screen>
  126. is a little non-standard, compared with
  127. <screen>
  128. <userinput>compiler a.cpp</userinput>
  129. </screen>
  130. We'll address this in a moment.
  131. </para>
  132. <para>
  133. The command line tokens which have no option name, as above, are
  134. called "positional options" by this library. They can be handled
  135. too. With a little help from the user, the library can decide that "a.cpp"
  136. really means the same as "--input-file=a.cpp". Here's the additional code
  137. we need:
  138. <programlisting>
  139. po::positional_options_description p;
  140. p.add(&quot;input-file&quot;, -1);
  141. po::variables_map vm;
  142. po::store(po::command_line_parser(ac, av).
  143. options(desc).positional(p).run(), vm);
  144. po::notify(vm);
  145. </programlisting>
  146. </para>
  147. <para>
  148. The first two lines say that all positional options should be translated
  149. into "input-file" options. Also note that we use the
  150. &command_line_parser; class to parse the command
  151. line, not the &parse_command_line;
  152. function. The latter is a convenient wrapper for simple cases, but now we
  153. need to pass additional information.
  154. </para>
  155. <para>By now, all options are described and parsed. We'll save ourselves the
  156. trouble of implementing the rest of the compiler logic and only print the
  157. options:
  158. <programlisting>
  159. if (vm.count(&quot;include-path&quot;))
  160. {
  161. cout &lt;&lt; &quot;Include paths are: &quot;
  162. &lt;&lt; vm[&quot;include-path&quot;].as&lt; vector&lt;string&gt; &gt;() &lt;&lt; &quot;\n&quot;;
  163. }
  164. if (vm.count(&quot;input-file&quot;))
  165. {
  166. cout &lt;&lt; &quot;Input files are: &quot;
  167. &lt;&lt; vm[&quot;input-file&quot;].as&lt; vector&lt;string&gt; &gt;() &lt;&lt; &quot;\n&quot;;
  168. }
  169. cout &lt;&lt; &quot;Optimization level is &quot; &lt;&lt; opt &lt;&lt; &quot;\n&quot;;
  170. </programlisting>
  171. </para>
  172. <para>Here's an example session:
  173. <screen>
  174. $ <userinput>bin/gcc/debug/options_description --help</userinput>
  175. Usage: options_description [options]
  176. Allowed options:
  177. --help : produce help message
  178. --optimization arg : optimization level
  179. -I [ --include-path ] arg : include path
  180. --input-file arg : input file
  181. $ <userinput>bin/gcc/debug/options_description</userinput>
  182. Optimization level is 10
  183. $ <userinput>bin/gcc/debug/options_description --optimization 4 -I foo -I another/path --include-path third/include/path a.cpp b.cpp</userinput>
  184. Include paths are: foo another/path third/include/path
  185. Input files are: a.cpp b.cpp
  186. Optimization level is 4
  187. </screen>
  188. </para>
  189. <para>
  190. Oops, there's a slight problem. It's still possible to specify the
  191. "--input-file" option, and usage message says so, which can be confusing
  192. for the user. It would be nice to hide this information, but let's wait
  193. for the next example.
  194. </para>
  195. </section>
  196. <section>
  197. <title>Multiple Sources</title>
  198. <para>It's quite likely that specifying all options to our compiler on the
  199. command line will annoy users. What if a user installs a new library and
  200. wants to always pass an additional command line element? What if he has
  201. made some choices which should be applied on every run? It's desirable to
  202. create a config file with common settings which will be used together with
  203. the command line.
  204. </para>
  205. <para>Of course, there will be a need to combine the values from command
  206. line and config file. For example, the optimization level specified on the
  207. command line should override the value from the config file. On the other
  208. hand, include paths should be combined.
  209. </para>
  210. <para>Let's see the code now. The complete program is in
  211. "examples/multiple_sources.cpp". The option definition has two interesting
  212. details. First, we declare several instances of the
  213. <code>options_description</code> class. The reason is that, in general,
  214. not all options are alike. Some options, like "input-file" above, should
  215. not be presented in an automatic help message. Some options make sense only
  216. in the config file. Finally, it's nice to have some structure in the help message,
  217. not just a long list of options. Let's declare several option groups:
  218. <programlisting>
  219. // Declare a group of options that will be
  220. // allowed only on command line
  221. po::options_description generic(&quot;Generic options&quot;);
  222. generic.add_options()
  223. (&quot;version,v&quot;, &quot;print version string&quot;)
  224. (&quot;help&quot;, &quot;produce help message&quot;)
  225. ;
  226. // Declare a group of options that will be
  227. // allowed both on command line and in
  228. // config file
  229. po::options_description config(&quot;Configuration&quot;);
  230. config.add_options()
  231. (&quot;optimization&quot;, po::value&lt;int&gt;(&amp;opt)-&gt;default_value(10),
  232. &quot;optimization level&quot;)
  233. (&quot;include-path,I&quot;,
  234. po::value&lt; vector&lt;string&gt; &gt;()-&gt;composing(),
  235. &quot;include path&quot;)
  236. ;
  237. // Hidden options, will be allowed both on command line and
  238. // in config file, but will not be shown to the user.
  239. po::options_description hidden(&quot;Hidden options&quot;);
  240. hidden.add_options()
  241. (&quot;input-file&quot;, po::value&lt; vector&lt;string&gt; &gt;(), &quot;input file&quot;)
  242. ;
  243. </programlisting>
  244. Note the call to the <code>composing</code> method in the declaration of the
  245. "include-path" option. It tells the library that values from different sources
  246. should be composed together, as we'll see shortly.
  247. </para>
  248. <para>
  249. The <code>add</code> method of the <code>options_description</code>
  250. class can be used to further group the options:
  251. <programlisting>
  252. po::options_description cmdline_options;
  253. cmdline_options.add(generic).add(config).add(hidden);
  254. po::options_description config_file_options;
  255. config_file_options.add(config).add(hidden);
  256. po::options_description visible(&quot;Allowed options&quot;);
  257. visible.add(generic).add(config);
  258. </programlisting>
  259. </para>
  260. <para>The parsing and storing of values follows the usual pattern, except that
  261. we additionally call <functionname>parse_config_file</functionname>, and
  262. call the &store; function twice. But what
  263. happens if the same value is specified both on the command line and in
  264. config file? Usually, the value stored first is preferred. This is what
  265. happens for the "--optimization" option. For "composing" options, like
  266. "include-file", the values are merged.
  267. </para>
  268. <para>Here's an example session:
  269. <screen>
  270. $ <userinput>bin/gcc/debug/multiple_sources</userinput>
  271. Include paths are: /opt
  272. Optimization level is 1
  273. $ <userinput>bin/gcc/debug/multiple_sources --help</userinput>
  274. Allows options:
  275. Generic options:
  276. -v [ --version ] : print version string
  277. --help : produce help message
  278. Configuration:
  279. --optimization n : optimization level
  280. -I [ --include-path ] path : include path
  281. $ <userinput>bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp</userinput>
  282. Include paths are: foo /opt
  283. Input files are: a.cpp b.cpp
  284. Optimization level is 4
  285. </screen>
  286. The first invocation uses values from the configuration file. The second
  287. invocation also uses values from command line. As we see, the include
  288. paths on the command line and in the configuration file are merged,
  289. while optimization is taken from the command line.
  290. </para>
  291. </section>
  292. </section>
  293. <!--
  294. Local Variables:
  295. mode: nxml
  296. sgml-indent-data: t
  297. sgml-parent-document: ("program_options.xml" "section")
  298. sgml-set-face: t
  299. End:
  300. -->