Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/doc/html/program_options/howto.html @ 12

Last change on this file since 12 was 12, checked in by landauf, 18 years ago

added boost

File size: 19.7 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4<title>How To</title>
5<link rel="stylesheet" href="../boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.69.1">
7<link rel="start" href="../index.html" title="The Boost C++ Libraries">
8<link rel="up" href="../program_options.html" title="Chapter 7. Boost.Program_options">
9<link rel="prev" href="overview.html" title="Library Overview">
10<link rel="next" href="design.html" title="Design Discussion">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%">
14<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td>
15<td align="center"><a href="../../../index.htm">Home</a></td>
16<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="../../../people/people.htm">People</a></td>
18<td align="center"><a href="../../../more/faq.htm">FAQ</a></td>
19<td align="center"><a href="../../../more/index.htm">More</a></td>
20</table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="overview.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../program_options.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="design.html"><img src="../images/next.png" alt="Next"></a>
24</div>
25<div class="section" lang="en">
26<div class="titlepage"><div><div><h3 class="title">
27<a name="program_options.howto"></a>How To</h3></div></div></div>
28<div class="toc"><dl>
29<dt><span class="section"><a href="howto.html#id2715843">Non-conventional Syntax</a></span></dt>
30<dt><span class="section"><a href="howto.html#id2715898">Response Files</a></span></dt>
31<dt><span class="section"><a href="howto.html#id2715975">Winmain Command Line</a></span></dt>
32<dt><span class="section"><a href="howto.html#id2716014">Option Groups and Hidden Options</a></span></dt>
33<dt><span class="section"><a href="howto.html#id2716150">Custom Validators</a></span></dt>
34<dt><span class="section"><a href="howto.html#id2716238">Unicode Support</a></span></dt>
35<dt><span class="section"><a href="howto.html#id2716386">Allowing Unknown Options</a></span></dt>
36</dl></div>
37<p>This section describes how the library can be used in specific
38  situations.</p>
39<div class="section" lang="en">
40<div class="titlepage"><div><div><h4 class="title">
41<a name="id2715843"></a>Non-conventional Syntax</h4></div></div></div>
42<p>Sometimes, standard command line syntaxes are not enough. For
43    example, the gcc compiler has "-frtti" and -fno-rtti" options, and this
44    syntax is not directly supported.
45    </p>
46<a class="indexterm" name="id2715851"></a><p>For such cases, the library allows the user to provide an
47    <em class="firstterm">additional parser</em> -- a function which will be called on each
48    command line element, before any processing by the library. If the
49    additional parser recognises the syntax, it returns the option name and
50    value, which are used directly. The above example can be handled by the
51    following code:
52    </p>
53<pre class="programlisting">
54pair&lt;string, string&gt; reg_foo(const string&amp; s)
55{
56    if (s.find("-f") == 0) {
57        if (s.substr(2, 3) == "no-")
58            return make_pair(s.substr(5), string("false"));
59        else
60            return make_pair(s.substr(2), string("true"));
61    } else {
62        return make_pair(string(), string());
63    }
64}
65</pre>
66<p>
67      Here's the definition of the additional parser. When parsing the command
68      line, we pass the additional parser:
69</p>
70<pre class="programlisting">
71store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo)
72        .run(), vm);
73</pre>
74<p>
75      The complete example can be found in the "example/custom_syntax.cpp"
76      file.               
77    </p>
78</div>
79<div class="section" lang="en">
80<div class="titlepage"><div><div><h4 class="title">
81<a name="id2715898"></a>Response Files</h4></div></div></div>
82<a class="indexterm" name="id2715902"></a><p>Some operating system have very low limits of the command line
83      length. The common way to work around those limitations is using
84      <em class="firstterm">response files</em>.  A response file is just a
85      configuration file which uses the same syntax as the command line. If
86      the command line specifies a name of response file to use, it's loaded
87      and parsed in addition to the command line.  The library does not
88      provide direct support for response files, so you'll need to write some
89      extra code.
90    </p>
91<p>
92      First, you need to define an option for the response file:
93</p>
94<pre class="programlisting">
95("response-file", value&lt;string&gt;(),
96     "can be specified with '@name', too")
97</pre>
98<p>Second, you'll need an additional parser to support the standard syntax
99    for specifying response files: "@file":
100</p>
101<pre class="programlisting">
102pair&lt;string, string&gt; at_option_parser(string const&amp;s)
103{
104    if ('@' == s[0])
105        return std::make_pair(string("response-file"), s.substr(1));
106    else
107        return pair&lt;string, string&gt;();
108}
109
110</pre>
111<p>Finally, when the "response-file" option is found, you'll have to
112    load that file and pass it to the command line parser. This part is the
113    hardest. We'll use the Boost.Tokenizer library, which works but has some
114    limitations. You might also consider Boost.StringAlgo. The code is:
115</p>
116<pre class="programlisting">
117if (vm.count("response-file")) {
118     // Load the file and tokenize it
119     ifstream ifs(vm["response-file"].as&lt;string&gt;().c_str());
120     if (!ifs) {
121         cout &lt;&lt; "Could no open the response file\n";
122         return 1;
123     }
124     // Read the whole file into a string
125     stringstream ss;
126     ss &lt;&lt; ifs.rdbuf();
127     // Split the file content
128     char_separator&lt;char&gt; sep(" \n\r");
129     tokenizer&lt;char_separator&lt;char&gt; &gt; tok(ss.str(), sep);
130     vector&lt;string&gt; args;
131     copy(tok.begin(), tok.end(), back_inserter(args));
132     // Parse the file and store the options
133     store(command_line_parser(args).options(desc).run(), vm);     
134}
135
136</pre>
137<p>
138      The complete example can be found in the "example/response_file.cpp"
139      file.               
140    </p>
141</div>
142<div class="section" lang="en">
143<div class="titlepage"><div><div><h4 class="title">
144<a name="id2715975"></a>Winmain Command Line</h4></div></div></div>
145<p>On the Windows operating system, GUI applications receive the
146    command line as a single string, not split into elements. For that reason,
147    the command line parser cannot be used directly. At least on some
148    compilers, it is possible to obtain
149    the split command line, but it's not clear if all compilers support the
150    same mechanism on all versions of the operating system. The
151    <code class="computeroutput">split_winmain</code> function is a portable mechanism provided
152    by the library.</p>
153<p>Here's an example of use:
154</p>
155<pre class="programlisting">
156vector&lt;string&gt; args = split_winmain(lpCmdLine);
157store(command_line_parser(args).options(desc).run(), vm);
158</pre>
159<p>     
160      The function is an overload for <code class="computeroutput">wchar_t</code> strings, so can
161      also be used in Unicode applications.
162    </p>
163</div>
164<div class="section" lang="en">
165<div class="titlepage"><div><div><h4 class="title">
166<a name="id2716014"></a>Option Groups and Hidden Options</h4></div></div></div>
167<p>Having a single instance of the <code class="computeroutput"><a href="../options_description.html" title="Class options_description">options_description</a></code> class with all
168    the program's options can be problematic:
169      </p>
170<div class="itemizedlist"><ul type="disc">
171<li><p>Some options make sense only for specific source, for example,
172          configuration files.</p></li>
173<li><p>The user would prefer some structure in the generated help message.</p></li>
174<li><p>Some options shouldn't appear in the generated help message at all.</p></li>
175</ul></div>
176<p>To solve the above issues, the library allows a programmer to create several
177      instances of the <code class="computeroutput"><a href="../options_description.html" title="Class options_description">options_description</a></code> class, which can be merged in
178      different combinations. The following example will define three groups of
179      options: command line specific, and two options group for specific program
180      modules, only one of which is shown in the generated help message.
181    </p>
182<p>Each group is defined using standard syntax. However, you should
183      use reasonable names for each <code class="computeroutput"><a href="../options_description.html" title="Class options_description">options_description</a></code> instance:
184</p>
185<pre class="programlisting">
186options_description general("General options");
187general.add_options()
188    ("help", "produce a help message")
189    ("help-module", value&lt;string&gt;()-&gt;implicit(),
190        "produce a help for a given module")
191    ("version", "output the version number")
192    ;
193
194options_description gui("GUI options");
195gui.add_options()
196    ("display", value&lt;string&gt;(), "display to use")
197    ;
198
199options_description backend("Backend options");
200backend.add_options()
201    ("num-threads", value&lt;int&gt;(), "the initial number of threads")
202    ;
203</pre>
204<p>After declaring options groups, we merge them in two
205      combinations. The first will include all options and be used for parsing. The
206      second will be used for the "--help" option.
207</p>
208<pre class="programlisting">
209// Declare an options description instance which will include
210// all the options
211options_description all("Allowed options");
212all.add(general).add(gui).add(backend);
213
214// Declare an options description instance which will be shown
215// to the user
216options_description visible("Allowed options");
217visible.add(general).add(gui);
218</pre>
219<p>What is left is to parse and handle the options:
220</p>
221<pre class="programlisting">
222variables_map vm;
223store(parse_command_line(ac, av, all), vm);
224
225if (vm.count("help"))
226{
227    cout &lt;&lt; visible;
228    return 0;
229}
230if (vm.count("help-module")) {
231    const string&amp; s = vm["help-module"].as&lt;string&gt;();
232    if (s == "gui") {
233        cout &lt;&lt; gui;
234    } else if (s == "backend") {
235        cout &lt;&lt; backend;
236    } else {
237        cout &lt;&lt; "Unknown module '"
238             &lt;&lt; s &lt;&lt; "' in the --help-module option\n";
239        return 1;
240    }
241    return 0;
242}
243if (vm.count("num-threads")) {
244    cout &lt;&lt; "The 'num-threads' options was set to "
245         &lt;&lt; vm["num-threads"].as&lt;int&gt;() &lt;&lt; "\n";           
246}                           
247</pre>
248<p>
249      When parsing the command line, all options are allowed. The "--help"
250      message, however, does not include the "Backend options" group -- the
251      options in that group are hidden. The user can explicitly force the
252      display of that options group by passing "--help-module backend"
253      option. The complete example can be found in the
254      "example/option_groups.cpp" file.
255    </p>
256</div>
257<div class="section" lang="en">
258<div class="titlepage"><div><div><h4 class="title">
259<a name="id2716150"></a>Custom Validators</h4></div></div></div>
260<p>By default, the conversion of option's value from string into C++
261      type is done using iostreams, which sometimes is not convenient. The
262      library allows the user to customize the conversion for specific
263      classes. In order to do so, the user should provide suitable overload of
264      the <code class="computeroutput">validate</code> function.
265    </p>
266<p>
267      Let's first define a simple class:
268</p>
269<pre class="programlisting">
270struct magic_number {
271public:
272    magic_number(int n) : n(n) {}
273    int n;
274};
275</pre>
276<p> and then overload the <code class="computeroutput">validate</code> function:
277</p>
278<pre class="programlisting">
279void validate(boost::any&amp; v,
280              const std::vector&lt;std::string&gt;&amp; values,
281              magic_number* target_type, int)
282{
283    static regex r("\\d\\d\\d-(\\d\\d\\d)");
284
285    using namespace boost::program_options;
286
287    // Make sure no previous assignment to 'a' was made.
288    validators::check_first_occurence(v);
289    // Extract the first string from 'values'. If there is more than
290    // one string, it's an error, and exception will be thrown.
291    const string&amp; s = validators::get_single_string(values);
292
293    // Do regex match and convert the interesting part to
294    // int.
295    smatch match;
296    if (regex_match(s, match, r)) {
297        v = any(magic_number(lexical_cast&lt;int&gt;(match[1])));
298    } else {
299        throw validation_error("invalid value");
300    }       
301}
302       
303</pre>
304<p>The function takes four parameters. The first is the storage
305      for the value, and in this case is either empty or contains an instance of
306      the <code class="computeroutput">magic_number</code> class. The second is the list of strings
307      found in the next occurrence of the option. The remaining two parameters
308      are needed to workaround the lack of partial template specialization and
309      partial function template ordering on some compilers.
310    </p>
311<p>The function first checks that we don't try to assign to the same
312      option twice. Then it checks that only a single string was passed
313      in. Next the string is verified with the help of the Boost.Regex
314      library. If that test is passed, the parsed value is stored into the
315      <code class="computeroutput">v</code> variable.
316    </p>
317<p>The complete example can be found in the "example/regex.cpp" file.
318    </p>
319</div>
320<div class="section" lang="en">
321<div class="titlepage"><div><div><h4 class="title">
322<a name="id2716238"></a>Unicode Support</h4></div></div></div>
323<p>To use the library with Unicode, you'd need to:
324      </p>
325<div class="itemizedlist"><ul type="disc">
326<li><p>Use Unicode-aware parsers for Unicode input</p></li>
327<li><p>Require Unicode support for options which need it</p></li>
328</ul></div>
329<p>Most of the parsers have Unicode versions. For example, the
330      <code class="computeroutput"><a href="../parse_command_line.html" title="Function template parse_command_line">parse_command_line</a></code> function has an overload which takes
331      <code class="computeroutput">wchar_t</code> strings, instead of ordinary <code class="computeroutput">char</code>.
332    </p>
333<p>Even if some of the parsers are Unicode-aware, it does not mean you
334    need to change definition of all the options. In fact, for many options,
335    like integer ones, it makes no sense. To make use of Unicode you'll need
336    <span class="emphasis"><em>some</em></span> Unicode-aware options. They are different from
337    ordinary options in that they accept <code class="computeroutput">wstring</code> input, and
338    process it using wide character streams. Creating an Unicode-aware option
339    is easy: just use the the <code class="computeroutput">wvalue</code> function instead of the
340    regular <code class="computeroutput">value</code>.
341    </p>
342<p>When an ascii parser passes data to an ascii option, or a Unicode
343      parser passes data to a Unicode option, the data are not changed at
344      all. So, the ascii option will see a string in local 8-bit encoding, and
345      the Unicode option will see whatever string was passed as the Unicode
346      input.
347    </p>
348<p>What happens when Unicode data is passed to an ascii option, and
349      vice versa? The library automatically performs the conversion from
350      Unicode to local 8-bit encoding. For example, if command line is in
351      ascii, but you use <code class="computeroutput">wstring</code> options, then the ascii input
352      will be converted into Unicode.
353    </p>
354<p>To perform the conversion, the library uses the <code class="computeroutput">codecvt&lt;wchar_t,
355    char&gt;</code> locale facet from the global locale. If
356    you want to work with strings that use local 8-bit encoding (as opposed to
357    7-bit ascii subset), your application should start with:
358      </p>
359<pre class="programlisting">
360locale::global(locale(""));
361      </pre>
362<p>
363      which would set up the conversion facet according to the user's selected
364      locale.
365    </p>
366<p>It's wise to check the status of the C++ locale support on your
367      implementation, though. The quick test involves three steps:
368      </p>
369<div class="orderedlist"><ol type="1">
370<li><p>Go the the "test" directory and build the "test_convert" binary.</p></li>
371<li>
372<p>Set some non-ascii locale in the environmemt. On Linux, one can
373          run, for example: </p>
374<pre class="screen">
375$ export LC_CTYPE=ru_RU.KOI8-R
376</pre>
377</li>
378<li><p>Run the "test_convert" binary with any non-ascii string in the
379            selected encoding as its parameter. If you see a list of Unicode codepoints,
380            everything's OK. Otherwise, locale support on your system might be
381            broken.</p></li>
382</ol></div>
383</div>
384<div class="section" lang="en">
385<div class="titlepage"><div><div><h4 class="title">
386<a name="id2716386"></a>Allowing Unknown Options</h4></div></div></div>
387<p>Usually, the library throws an exception on unknown option names. This
388      behaviour can be changed. For example, only some part of your application uses
389      <a href="../program_options.html" title="Chapter 7. Boost.Program_options">Program_options</a>, and you wish to pass unrecognized options to another part of
390      the program, or even to another application.</p>
391<p>To allow unregistered options on the command line, you need to use
392      the <code class="computeroutput"><a href="../basic_command_line_parser.html" title="Class template basic_command_line_parser">basic_command_line_parser</a></code> class for parsing (not <code class="computeroutput"><a href="../parse_command_line.html" title="Function template parse_command_line">parse_command_line</a></code>)
393      and call the <code class="computeroutput"><a href="../basic_command_line_parser.html#id2491704-bb">allow_unregistered</a></code> 
394      method of that class:
395      </p>
396<pre class="programlisting">
397parsed_options parsed =
398    command_line_parser(argv, argc).options(desc).allow_unregistered().run();     
399      </pre>
400<p>
401     
402      For each token that looks like an option, but does not have a known name,
403      an instance of <code class="computeroutput"><a href="../basic_option.html" title="Class template basic_option">basic_option</a></code> will be added to the result.
404      The <code class="computeroutput">string_key</code> and <code class="computeroutput">value</code> fields of the instance will contain results
405      of syntactic parsing of the token, the <code class="computeroutput">unregistered</code> field will be set to <code class="computeroutput">true</code>,
406      and the <code class="computeroutput">original_tokens</code> field will contain the token as it appeared on the command line.
407      </p>
408<p>If you want to pass the unrecognized options further, the
409      <code class="computeroutput"><a href="../collect_unrecognized.html" title="Function template collect_unrecognized">collect_unrecognized</a></code> function can be used.
410      The function will collect original tokens for all unrecognized values, and optionally, all found positional options.
411      Say, if your code handles a few options, but does not handles positional options at all, you can use the function like this:
412      </p>
413<pre class="programlisting">
414vector&lt;string&gt; to_pass_further = collect_arguments(parsed.option, include_positional);
415      </pre>
416</div>
417</div>
418<table width="100%"><tr>
419<td align="left"></td>
420<td align="right"><small>Copyright © 2002-2004 Vladimir Prus</small></td>
421</tr></table>
422<hr>
423<div class="spirit-nav">
424<a accesskey="p" href="overview.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../program_options.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="design.html"><img src="../images/next.png" alt="Next"></a>
425</div>
426</body>
427</html>
Note: See TracBrowser for help on using the repository browser.