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