summaryrefslogtreecommitdiff
path: root/doc/html/program_options/tutorial.html
blob: 2208f81049edf05e31bd0ed79936159fef55762a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Tutorial</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../program_options.html" title="Chapter&#160;22.&#160;Boost.Program_options">
<link rel="prev" href="../program_options.html" title="Chapter&#160;22.&#160;Boost.Program_options">
<link rel="next" href="overview.html" title="Library Overview">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../program_options.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../program_options.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="overview.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="program_options.tutorial"></a>Tutorial</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="tutorial.html#idm45555218472112">Getting Started</a></span></dt>
<dt><span class="section"><a href="tutorial.html#idm45555218453872">Option Details</a></span></dt>
<dt><span class="section"><a href="tutorial.html#idm45555218427440">Multiple Sources</a></span></dt>
</dl></div>
<p>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:
</p>
<pre class="programlisting">namespace po = boost::program_options;</pre>
<p>
  </p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm45555218472112"></a>Getting Started</h3></div></div></div>
<p>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"):

</p>
<pre class="programlisting">
// Declare the supported options.
po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("compression", po::value&lt;int&gt;(), "set compression level")
;

po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);    

if (vm.count("help")) {
    cout &lt;&lt; desc &lt;&lt; "\n";
    return 1;
}

if (vm.count("compression")) {
    cout &lt;&lt; "Compression level was set to " 
 &lt;&lt; vm["compression"].as&lt;int&gt;() &lt;&lt; ".\n";
} else {
    cout &lt;&lt; "Compression level was not set.\n";
}
</pre>
<p>
  </p>
<p>We start by declaring all allowed options using the
    <code class="computeroutput"><a class="link" href="../boost/program_options/options_description.html" title="Class options_description">options_description</a></code> class. The <code class="computeroutput">add_options</code> method of that
    class returns a special proxy object that defines
    <code class="computeroutput">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 class="computeroutput">int</code>.
  </p>
<p>After that, an object of class <code class="computeroutput">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 class="computeroutput">store</code>,
    <code class="computeroutput">parse_command_line</code> and <code class="computeroutput">notify</code> functions cause
    <code class="computeroutput">vm</code> to contain all the options found on the command
    line.</p>
<p>And now, finally, we can use the options as we like. The
    <code class="computeroutput">variables_map</code> class can be used just like
    <code class="computeroutput">std::map</code>, except that values stored there must be retrieved
    with the <code class="computeroutput">as</code> method shown above. (If the type specified in the
    call to the <code class="computeroutput">as</code> method is different from the actually stored
    type, an exception is thrown.)
  </p>
<p>It's now a good time to try compiling the code yourself, but if
    you're not yet ready, here's an example session:
</p>
<pre class="screen">
$ <strong class="userinput"><code>bin/gcc/debug/first</code></strong>
Compression level was not set.
$ <strong class="userinput"><code>bin/gcc/debug/first --help</code></strong>
Allowed options:
  --help                 : produce help message
  --compression arg      : set compression level
$ <strong class="userinput"><code>bin/gcc/debug/first --compression 10</code></strong>
Compression level was set to 10.
    </pre>
<p>
  </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm45555218453872"></a>Option Details</h3></div></div></div>
<p>An option value, surely, can have other types than <code class="computeroutput">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
  <code class="filename">example/options_description.cpp</code>.</p>
<p>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:
    </p>
<pre class="programlisting">
int opt;
po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("optimization", po::value&lt;int&gt;(&amp;opt)-&gt;default_value(10), 
  "optimization level")
    ("include-path,I", po::value&lt; vector&lt;string&gt; &gt;(), 
  "include path")
    ("input-file", po::value&lt; vector&lt;string&gt; &gt;(), "input file")
;
</pre>
<p>
  </p>
<p>The <code class="literal">"help"</code> option should be familiar from 
  the previous example. It's a good idea to have this option in all cases.
  </p>
<p>The <code class="literal">"optimization"</code> option shows two new features. First, we specify
    the address of the variable(<code class="computeroutput">&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.
  </p>
<p>The <code class="literal">"include-path"</code> option is an example of the 
  only case where the interface of the <code class="computeroutput">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.
  </p>
<p>Note also that the type of the <code class="literal">"include-path"</code>
  option is <span class="type">std::vector</span>. 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.  
  </p>
<p>The "input-file" option specifies the list of files to
    process. That's okay for a start, but, of course, writing something like:
    </p>
<pre class="screen">
<strong class="userinput"><code>compiler --input-file=a.cpp</code></strong>
    </pre>
<p>
    is a little non-standard, compared with
    </p>
<pre class="screen">
<strong class="userinput"><code>compiler a.cpp</code></strong>
    </pre>
<p>
    We'll address this in a moment.
  </p>
<p>
    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:
    </p>
<pre class="programlisting">
po::positional_options_description p;
p.add("input-file", -1);

po::variables_map vm;
po::store(po::command_line_parser(ac, av).
          options(desc).positional(p).run(), vm);
po::notify(vm);
    </pre>
<p>    
  </p>
<p>
    The first two lines say that all positional options should be translated
    into "input-file" options. Also note that we use the
    <code class="computeroutput"><a class="link" href="reference.html#boost.program_options.command_line_parser">command_line_parser</a></code> class to parse the command
    line, not the <code class="computeroutput"><a class="link" href="../boost/program_options/parse_command_line.html" title="Function template parse_command_line">parse_command_line</a></code>
    function. The latter is a convenient wrapper for simple cases, but now we
    need to pass additional information.
  </p>
<p>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:
    </p>
<pre class="programlisting">
if (vm.count("include-path"))
{
    cout &lt;&lt; "Include paths are: " 
         &lt;&lt; vm["include-path"].as&lt; vector&lt;string&gt; &gt;() &lt;&lt; "\n";
}

if (vm.count("input-file"))
{
    cout &lt;&lt; "Input files are: " 
         &lt;&lt; vm["input-file"].as&lt; vector&lt;string&gt; &gt;() &lt;&lt; "\n";
}

cout &lt;&lt; "Optimization level is " &lt;&lt; opt &lt;&lt; "\n";                
</pre>
<p>
  </p>
<p>Here's an example session:
    </p>
<pre class="screen">
$ <strong class="userinput"><code>bin/gcc/debug/options_description --help</code></strong>
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
$ <strong class="userinput"><code>bin/gcc/debug/options_description</code></strong>
Optimization level is 10
$ <strong class="userinput"><code>bin/gcc/debug/options_description --optimization 4 -I foo a.cpp</code></strong>
Include paths are: foo
Input files are: a.cpp
Optimization level is 4
</pre>
<p>
  </p>
<p>
    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.
  </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm45555218427440"></a>Multiple Sources</h3></div></div></div>
<p>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.
    </p>
<p>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.
    </p>
<p>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 class="computeroutput">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:
      </p>
<pre class="programlisting">
// Declare a group of options that will be 
// allowed only on command line
po::options_description generic("Generic options");
generic.add_options()
    ("version,v", "print version string")
    ("help", "produce help message")    
    ;
    
// Declare a group of options that will be 
// allowed both on command line and in
// config file
po::options_description config("Configuration");
config.add_options()
    ("optimization", po::value&lt;int&gt;(&amp;opt)-&gt;default_value(10), 
          "optimization level")
    ("include-path,I", 
         po::value&lt; vector&lt;string&gt; &gt;()-&gt;composing(), 
         "include path")
    ;

// 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("Hidden options");
hidden.add_options()
    ("input-file", po::value&lt; vector&lt;string&gt; &gt;(), "input file")
    ;        
</pre>
<p>
      Note the call to the <code class="computeroutput">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.
    </p>
<p>    
      The <code class="computeroutput">add</code> method of the <code class="computeroutput">options_description</code>
      class can be used to further group the options:
      </p>
<pre class="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("Allowed options");
visible.add(generic).add(config);
      </pre>
<p>
    </p>
<p>The parsing and storing of values follows the usual pattern, except that
      we additionally call <code class="computeroutput">parse_config_file</code>, and
      call the <code class="computeroutput"><a class="link" href="../boost/program_options/store_idm45507045051456.html" title="Function store">store</a></code> 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.
    </p>
<p>Here's an example session:
</p>
<pre class="screen">
$ <strong class="userinput"><code>bin/gcc/debug/multiple_sources</code></strong>
Include paths are: /opt
Optimization level is 1
$ <strong class="userinput"><code>bin/gcc/debug/multiple_sources --help</code></strong>
Allows options:

Generic options:
  -v [ --version ]       : print version string
  --help                 : produce help message

Configuration:
  --optimization n       : optimization level
  -I [ --include-path ] path : include path

$ <strong class="userinput"><code>bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp</code></strong>
Include paths are: foo /opt
Input files are: a.cpp b.cpp
Optimization level is 4
</pre>
<p>
      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.
    </p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2004 Vladimir Prus<p>Distributed under the Boost Software License, Version 1.0.
      (See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at 
      <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../program_options.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../program_options.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="overview.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>