diff options
author | Derek Schuff <dschuff@chromium.org> | 2012-08-21 17:32:13 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2012-08-21 17:32:13 -0700 |
commit | 66f271497ed92ebb05c66f54616e512606a2e314 (patch) | |
tree | 96d54cd64804ab7c9f2f52f680c3301aa789ce1d /docs/CommandLine.html | |
parent | b62e9abf7dd9e39c95327914ce9dfe216386824a (diff) | |
parent | bc363931085587bac42a40653962a3e5acd1ffce (diff) |
Merge up to r162331, git commit bc363931085587bac42a40653962a3e5acd1ffce
Diffstat (limited to 'docs/CommandLine.html')
-rw-r--r-- | docs/CommandLine.html | 1976 |
1 files changed, 0 insertions, 1976 deletions
diff --git a/docs/CommandLine.html b/docs/CommandLine.html deleted file mode 100644 index 6f3298ab39..0000000000 --- a/docs/CommandLine.html +++ /dev/null @@ -1,1976 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title>CommandLine 2.0 Library Manual</title> - <link rel="stylesheet" href="_static/llvm.css" type="text/css"> -</head> -<body> - -<h1> - CommandLine 2.0 Library Manual -</h1> - -<ol> - <li><a href="#introduction">Introduction</a></li> - - <li><a href="#quickstart">Quick Start Guide</a> - <ol> - <li><a href="#bool">Boolean Arguments</a></li> - <li><a href="#alias">Argument Aliases</a></li> - <li><a href="#onealternative">Selecting an alternative from a - set of possibilities</a></li> - <li><a href="#namedalternatives">Named alternatives</a></li> - <li><a href="#list">Parsing a list of options</a></li> - <li><a href="#bits">Collecting options as a set of flags</a></li> - <li><a href="#description">Adding freeform text to help output</a></li> - </ol></li> - - <li><a href="#referenceguide">Reference Guide</a> - <ol> - <li><a href="#positional">Positional Arguments</a> - <ul> - <li><a href="#--">Specifying positional options with hyphens</a></li> - <li><a href="#getPosition">Determining absolute position with - getPosition</a></li> - <li><a href="#cl::ConsumeAfter">The <tt>cl::ConsumeAfter</tt> - modifier</a></li> - </ul></li> - - <li><a href="#storage">Internal vs External Storage</a></li> - - <li><a href="#attributes">Option Attributes</a></li> - - <li><a href="#modifiers">Option Modifiers</a> - <ul> - <li><a href="#hiding">Hiding an option from <tt>-help</tt> - output</a></li> - <li><a href="#numoccurrences">Controlling the number of occurrences - required and allowed</a></li> - <li><a href="#valrequired">Controlling whether or not a value must be - specified</a></li> - <li><a href="#formatting">Controlling other formatting options</a></li> - <li><a href="#misc">Miscellaneous option modifiers</a></li> - <li><a href="#response">Response files</a></li> - </ul></li> - - <li><a href="#toplevel">Top-Level Classes and Functions</a> - <ul> - <li><a href="#cl::ParseCommandLineOptions">The - <tt>cl::ParseCommandLineOptions</tt> function</a></li> - <li><a href="#cl::ParseEnvironmentOptions">The - <tt>cl::ParseEnvironmentOptions</tt> function</a></li> - <li><a href="#cl::SetVersionPrinter">The <tt>cl::SetVersionPrinter</tt> - function</a></li> - <li><a href="#cl::opt">The <tt>cl::opt</tt> class</a></li> - <li><a href="#cl::list">The <tt>cl::list</tt> class</a></li> - <li><a href="#cl::bits">The <tt>cl::bits</tt> class</a></li> - <li><a href="#cl::alias">The <tt>cl::alias</tt> class</a></li> - <li><a href="#cl::extrahelp">The <tt>cl::extrahelp</tt> class</a></li> - </ul></li> - - <li><a href="#builtinparsers">Builtin parsers</a> - <ul> - <li><a href="#genericparser">The Generic <tt>parser<t></tt> - parser</a></li> - <li><a href="#boolparser">The <tt>parser<bool></tt> - specialization</a></li> - <li><a href="#boolOrDefaultparser">The <tt>parser<boolOrDefault></tt> - specialization</a></li> - <li><a href="#stringparser">The <tt>parser<string></tt> - specialization</a></li> - <li><a href="#intparser">The <tt>parser<int></tt> - specialization</a></li> - <li><a href="#doubleparser">The <tt>parser<double></tt> and - <tt>parser<float></tt> specializations</a></li> - </ul></li> - </ol></li> - <li><a href="#extensionguide">Extension Guide</a> - <ol> - <li><a href="#customparser">Writing a custom parser</a></li> - <li><a href="#explotingexternal">Exploiting external storage</a></li> - <li><a href="#dynamicopts">Dynamically adding command line - options</a></li> - </ol></li> -</ol> - -<div class="doc_author"> - <p>Written by <a href="mailto:sabre@nondot.org">Chris Lattner</a></p> -</div> - -<!-- *********************************************************************** --> -<h2> - <a name="introduction">Introduction</a> -</h2> -<!-- *********************************************************************** --> - -<div> - -<p>This document describes the CommandLine argument processing library. It will -show you how to use it, and what it can do. The CommandLine library uses a -declarative approach to specifying the command line options that your program -takes. By default, these options declarations implicitly hold the value parsed -for the option declared (of course this <a href="#storage">can be -changed</a>).</p> - -<p>Although there are a <b>lot</b> of command line argument parsing libraries -out there in many different languages, none of them fit well with what I needed. -By looking at the features and problems of other libraries, I designed the -CommandLine library to have the following features:</p> - -<ol> -<li>Speed: The CommandLine library is very quick and uses little resources. The -parsing time of the library is directly proportional to the number of arguments -parsed, not the the number of options recognized. Additionally, command line -argument values are captured transparently into user defined global variables, -which can be accessed like any other variable (and with the same -performance).</li> - -<li>Type Safe: As a user of CommandLine, you don't have to worry about -remembering the type of arguments that you want (is it an int? a string? a -bool? an enum?) and keep casting it around. Not only does this help prevent -error prone constructs, it also leads to dramatically cleaner source code.</li> - -<li>No subclasses required: To use CommandLine, you instantiate variables that -correspond to the arguments that you would like to capture, you don't subclass a -parser. This means that you don't have to write <b>any</b> boilerplate -code.</li> - -<li>Globally accessible: Libraries can specify command line arguments that are -automatically enabled in any tool that links to the library. This is possible -because the application doesn't have to keep a list of arguments to pass to -the parser. This also makes supporting <a href="#dynamicopts">dynamically -loaded options</a> trivial.</li> - -<li>Cleaner: CommandLine supports enum and other types directly, meaning that -there is less error and more security built into the library. You don't have to -worry about whether your integral command line argument accidentally got -assigned a value that is not valid for your enum type.</li> - -<li>Powerful: The CommandLine library supports many different types of -arguments, from simple <a href="#boolparser">boolean flags</a> to <a -href="#cl::opt">scalars arguments</a> (<a href="#stringparser">strings</a>, <a -href="#intparser">integers</a>, <a href="#genericparser">enums</a>, <a -href="#doubleparser">doubles</a>), to <a href="#cl::list">lists of -arguments</a>. This is possible because CommandLine is...</li> - -<li>Extensible: It is very simple to add a new argument type to CommandLine. -Simply specify the parser that you want to use with the command line option when -you declare it. <a href="#customparser">Custom parsers</a> are no problem.</li> - -<li>Labor Saving: The CommandLine library cuts down on the amount of grunt work -that you, the user, have to do. For example, it automatically provides a -<tt>-help</tt> option that shows the available command line options for your -tool. Additionally, it does most of the basic correctness checking for -you.</li> - -<li>Capable: The CommandLine library can handle lots of different forms of -options often found in real programs. For example, <a -href="#positional">positional</a> arguments, <tt>ls</tt> style <a -href="#cl::Grouping">grouping</a> options (to allow processing '<tt>ls --lad</tt>' naturally), <tt>ld</tt> style <a href="#cl::Prefix">prefix</a> -options (to parse '<tt>-lmalloc -L/usr/lib</tt>'), and <a -href="#cl::ConsumeAfter">interpreter style options</a>.</li> - -</ol> - -<p>This document will hopefully let you jump in and start using CommandLine in -your utility quickly and painlessly. Additionally it should be a simple -reference manual to figure out how stuff works. If it is failing in some area -(or you want an extension to the library), nag the author, <a -href="mailto:sabre@nondot.org">Chris Lattner</a>.</p> - -</div> - -<!-- *********************************************************************** --> -<h2> - <a name="quickstart">Quick Start Guide</a> -</h2> -<!-- *********************************************************************** --> - -<div> - -<p>This section of the manual runs through a simple CommandLine'ification of a -basic compiler tool. This is intended to show you how to jump into using the -CommandLine library in your own program, and show you some of the cool things it -can do.</p> - -<p>To start out, you need to include the CommandLine header file into your -program:</p> - -<div class="doc_code"><pre> - #include "llvm/Support/CommandLine.h" -</pre></div> - -<p>Additionally, you need to add this as the first line of your main -program:</p> - -<div class="doc_code"><pre> -int main(int argc, char **argv) { - <a href="#cl::ParseCommandLineOptions">cl::ParseCommandLineOptions</a>(argc, argv); - ... -} -</pre></div> - -<p>... which actually parses the arguments and fills in the variable -declarations.</p> - -<p>Now that you are ready to support command line arguments, we need to tell the -system which ones we want, and what type of arguments they are. The CommandLine -library uses a declarative syntax to model command line arguments with the -global variable declarations that capture the parsed values. This means that -for every command line option that you would like to support, there should be a -global variable declaration to capture the result. For example, in a compiler, -we would like to support the Unix-standard '<tt>-o <filename></tt>' option -to specify where to put the output. With the CommandLine library, this is -represented like this:</p> - -<a name="value_desc_example"></a> -<div class="doc_code"><pre> -<a href="#cl::opt">cl::opt</a><string> OutputFilename("<i>o</i>", <a href="#cl::desc">cl::desc</a>("<i>Specify output filename</i>"), <a href="#cl::value_desc">cl::value_desc</a>("<i>filename</i>")); -</pre></div> - -<p>This declares a global variable "<tt>OutputFilename</tt>" that is used to -capture the result of the "<tt>o</tt>" argument (first parameter). We specify -that this is a simple scalar option by using the "<tt><a -href="#cl::opt">cl::opt</a></tt>" template (as opposed to the <a -href="#list">"<tt>cl::list</tt> template</a>), and tell the CommandLine library -that the data type that we are parsing is a string.</p> - -<p>The second and third parameters (which are optional) are used to specify what -to output for the "<tt>-help</tt>" option. In this case, we get a line that -looks like this:</p> - -<div class="doc_code"><pre> -USAGE: compiler [options] - -OPTIONS: - -help - display available options (-help-hidden for more) - <b>-o <filename> - Specify output filename</b> -</pre></div> - -<p>Because we specified that the command line option should parse using the -<tt>string</tt> data type, the variable declared is automatically usable as a -real string in all contexts that a normal C++ string object may be used. For -example:</p> - -<div class="doc_code"><pre> - ... - std::ofstream Output(OutputFilename.c_str()); - if (Output.good()) ... - ... -</pre></div> - -<p>There are many different options that you can use to customize the command -line option handling library, but the above example shows the general interface -to these options. The options can be specified in any order, and are specified -with helper functions like <a href="#cl::desc"><tt>cl::desc(...)</tt></a>, so -there are no positional dependencies to remember. The available options are -discussed in detail in the <a href="#referenceguide">Reference Guide</a>.</p> - -<p>Continuing the example, we would like to have our compiler take an input -filename as well as an output filename, but we do not want the input filename to -be specified with a hyphen (ie, not <tt>-filename.c</tt>). To support this -style of argument, the CommandLine library allows for <a -href="#positional">positional</a> arguments to be specified for the program. -These positional arguments are filled with command line parameters that are not -in option form. We use this feature like this:</p> - -<div class="doc_code"><pre> -<a href="#cl::opt">cl::opt</a><string> InputFilename(<a href="#cl::Positional">cl::Positional</a>, <a href="#cl::desc">cl::desc</a>("<i><input file></i>"), <a href="#cl::init">cl::init</a>("<i>-</i>")); -</pre></div> - -<p>This declaration indicates that the first positional argument should be -treated as the input filename. Here we use the <tt><a -href="#cl::init">cl::init</a></tt> option to specify an initial value for the -command line option, which is used if the option is not specified (if you do not -specify a <tt><a href="#cl::init">cl::init</a></tt> modifier for an option, then -the default constructor for the data type is used to initialize the value). -Command line options default to being optional, so if we would like to require -that the user always specify an input filename, we would add the <tt><a -href="#cl::Required">cl::Required</a></tt> flag, and we could eliminate the -<tt><a href="#cl::init">cl::init</a></tt> modifier, like this:</p> - -<div class="doc_code"><pre> -<a href="#cl::opt">cl::opt</a><string> InputFilename(<a href="#cl::Positional">cl::Positional</a>, <a href="#cl::desc">cl::desc</a>("<i><input file></i>"), <b><a href="#cl::Required">cl::Required</a></b>); -</pre></div> - -<p>Again, the CommandLine library does not require the options to be specified -in any particular order, so the above declaration is equivalent to:</p> - -<div class="doc_code"><pre> -<a href="#cl::opt">cl::opt</a><string> InputFilename(<a href="#cl::Positional">cl::Positional</a>, <a href="#cl::Required">cl::Required</a>, <a href="#cl::desc">cl::desc</a>("<i><input file></i>")); -</pre></div> - -<p>By simply adding the <tt><a href="#cl::Required">cl::Required</a></tt> flag, -the CommandLine library will automatically issue an error if the argument is not -specified, which shifts all of the command line option verification code out of -your application into the library. This is just one example of how using flags -can alter the default behaviour of the library, on a per-option basis. By -adding one of the declarations above, the <tt>-help</tt> option synopsis is now -extended to:</p> - -<div class="doc_code"><pre> -USAGE: compiler [options] <b><input file></b> - -OPTIONS: - -help - display available options (-help-hidden for more) - -o <filename> - Specify output filename -</pre></div> - -<p>... indicating that an input filename is expected.</p> - -<!-- ======================================================================= --> -<h3> - <a name="bool">Boolean Arguments</a> -</h3> - -<div> - -<p>In addition to input and output filenames, we would like the compiler example -to support three boolean flags: "<tt>-f</tt>" to force writing binary output to -a terminal, "<tt>--quiet</tt>" to enable quiet mode, and "<tt>-q</tt>" for -backwards compatibility with some of our users. We can support these by -declaring options of boolean type like this:</p> - -<div class="doc_code"><pre> -<a href="#cl::opt">cl::opt</a><bool> Force ("<i>f</i>", <a href="#cl::desc">cl::desc</a>("<i>Enable binary output on terminals</i>")); -<a href="#cl::opt">cl::opt</a><bool> Quiet ("<i>quiet</i>", <a href="#cl::desc">cl::desc</a>("<i>Don't print informational messages</i>")); -<a href="#cl::opt">cl::opt</a><bool> Quiet2("<i>q</i>", <a href="#cl::desc">cl::desc</a>("<i>Don't print informational messages</i>"), <a href="#cl::Hidden">cl::Hidden</a>); -</pre></div> - -<p>This does what you would expect: it declares three boolean variables -("<tt>Force</tt>", "<tt>Quiet</tt>", and "<tt>Quiet2</tt>") to recognize these -options. Note that the "<tt>-q</tt>" option is specified with the "<a -href="#cl::Hidden"><tt>cl::Hidden</tt></a>" flag. This modifier prevents it -from being shown by the standard "<tt>-help</tt>" output (note that it is still -shown in the "<tt>-help-hidden</tt>" output).</p> - -<p>The CommandLine library uses a <a href="#builtinparsers">different parser</a> -for different data types. For example, in the string case, the argument passed -to the option is copied literally into the content of the string variable... we -obviously cannot do that in the boolean case, however, so we must use a smarter -parser. In the case of the boolean parser, it allows no options (in which case -it assigns the value of true to the variable), or it allows the values -"<tt>true</tt>" or "<tt>false</tt>" to be specified, allowing any of the -following inputs:</p> - -<div class="doc_code"><pre> - compiler -f # No value, 'Force' == true - compiler -f=true # Value specified, 'Force' == true - compiler -f=TRUE # Value specified, 'Force' == true - compiler -f=FALSE # Value specified, 'Force' == false -</pre></div> - -<p>... you get the idea. The <a href="#boolparser">bool parser</a> just turns -the string values into boolean values, and rejects things like '<tt>compiler --f=foo</tt>'. Similarly, the <a href="#doubleparser">float</a>, <a -href="#doubleparser">double</a>, and <a href="#intparser">int</a> parsers work -like you would expect, using the '<tt>strtol</tt>' and '<tt>strtod</tt>' C -library calls to parse the string value into the specified data type.</p> - -<p>With the declarations above, "<tt>compiler -help</tt>" emits this:</p> - -<div class="doc_code"><pre> -USAGE: compiler [options] <input file> - -OPTIONS: - <b>-f - Enable binary output on terminals</b> - -o - Override output filename - <b>-quiet - Don't print informational messages</b> - -help - display available options (-help-hidden for more) -</pre></div> - -<p>and "<tt>compiler -help-hidden</tt>" prints this:</p> - -<div class="doc_code"><pre> -USAGE: compiler [options] <input file> - -OPTIONS: - -f - Enable binary output on terminals - -o - Override output filename - <b>-q - Don't print informational messages</b> - -quiet - Don't print informational messages - -help - display available options (-help-hidden for more) -</pre></div> - -<p>This brief example has shown you how to use the '<tt><a -href="#cl::opt">cl::opt</a></tt>' class to parse simple scalar command line -arguments. In addition to simple scalar arguments, the CommandLine library also -provides primitives to support CommandLine option <a href="#alias">aliases</a>, -and <a href="#list">lists</a> of options.</p> - -</div> - -<!-- ======================================================================= --> -<h3> - <a name="alias">Argument Aliases</a> -</h3> - -<div> - -<p>So far, the example works well, except for the fact that we need to check the -quiet condition like this now:</p> - -<div class="doc_code"><pre> -... - if (!Quiet && !Quiet2) printInformationalMessage(...); -... -</pre></div> - -<p>... which is a real pain! Instead of defining two values for the same -condition, we can use the "<tt><a href="#cl::alias">cl::alias</a></tt>" class to make the "<tt>-q</tt>" -option an <b>alias</b> for the "<tt>-quiet</tt>" option, instead of providing -a value itself:</p> - -<div class="doc_code"><pre> -<a href="#cl::opt">cl::opt</a><bool> Force ("<i>f</i>", <a href="#cl::desc">cl::desc</a>("<i>Overwrite output files</i>")); -<a href="#cl::opt">cl::opt</a><bool> Quiet ("<i>quiet</i>", <a href="#cl::desc">cl::desc</a>("<i>Don't print informational messages</i>")); -<a href="#cl::alias">cl::alias</a> QuietA("<i>q</i>", <a href="#cl::desc">cl::desc</a>("<i>Alias for -quiet</i>"), <a href="#cl::aliasopt">cl::aliasopt</a>(Quiet)); -</pre></div> - -<p>The third line (which is the only one we modified from above) defines a -"<tt>-q</tt>" alias that updates the "<tt>Quiet</tt>" variable (as specified by -the <tt><a href="#cl::aliasopt">cl::aliasopt</a></tt> modifier) whenever it is -specified. Because aliases do not hold state, the only thing the program has to -query is the <tt>Quiet</tt> variable now. Another nice feature of aliases is -that they automatically hide themselves from the <tt>-help</tt> output -(although, again, they are still visible in the <tt>-help-hidden -output</tt>).</p> - -<p>Now the application code can simply use:</p> - -<div class="doc_code"><pre> -... - if (!Quiet) printInformationalMessage(...); -... -</pre></div> - -<p>... which is much nicer! The "<tt><a href="#cl::alias">cl::alias</a></tt>" -can be used to specify an alternative name for any variable type, and has many -uses.</p> - -</div> - -<!-- ======================================================================= --> -<h3> - <a name="onealternative">Selecting an alternative from a set of - possibilities</a> -</h3> - -<div> - -<p>So far we have seen how the CommandLine library handles builtin types like -<tt>std::string</tt>, <tt>bool</tt> and <tt>int</tt>, but how does it handle -things it doesn't know about, like enums or '<tt>int*</tt>'s?</p> - -<p>The answer is that it uses a table-driven generic parser (unless you specify -your own parser, as described in the <a href="#extensionguide">Extension -Guide</a>). This parser maps literal strings to whatever type is required, and -requires you to tell it what this mapping should be.</p> - -<p>Let's say that we would like to add four optimization levels to our -optimizer, using the standard flags "<tt>-g</tt>", "<tt>-O0</tt>", -"<tt>-O1</tt>", and "<tt>-O2</tt>". We could easily implement this with boolean -options like above, but there are several problems with this strategy:</p> - -<ol> -<li>A user could specify more than one of the options at a time, for example, -"<tt>compiler -O3 -O2</tt>". The CommandLine library would not be able to -catch this erroneous input for us.</li> - -<li>We would have to test 4 different variables to see which ones are set.</li> - -<li>This doesn't map to the numeric levels that we want... so we cannot easily -see if some level >= "<tt>-O1</tt>" is enabled.</li> - -</ol> - -<p>To cope with these problems, we can use an enum value, and have the -CommandLine library fill it in with the appropriate level directly, which is -used like this:</p> - -<div class="doc_code"><pre> -enum OptLevel { - g, O1, O2, O3 -}; - -<a href="#cl::opt">cl::opt</a><OptLevel> OptimizationLevel(<a href="#cl::desc">cl::desc</a>("<i>Choose optimization level:</i>"), - <a href="#cl::values">cl::values</a>( - clEnumVal(g , "<i>No optimizations, enable debugging</i>"), - clEnumVal(O1, "<i>Enable trivial optimizations</i>"), - clEnumVal(O2, "<i>Enable default optimizations</i>"), - clEnumVal(O3, "<i>Enable expensive optimizations</i>"), - clEnumValEnd)); - -... - if (OptimizationLevel >= O2) doPartialRedundancyElimination(...); -... -</pre></div> - -<p>This declaration defines a variable "<tt>OptimizationLevel</tt>" of the -"<tt>OptLevel</tt>" enum type. This variable can be assigned any of the values -that are listed in the declaration (Note that the declaration list must be -terminated with the "<tt>clEnumValEnd</tt>" argument!). The CommandLine -library enforces -that the user can only specify one of the options, and it ensure that only valid -enum values can be specified. The "<tt>clEnumVal</tt>" macros ensure that the -command line arguments matched the enum values. With this option added, our -help output now is:</p> - -<div class="doc_code"><pre> -USAGE: compiler [options] <input file> - -OPTIONS: - <b>Choose optimization level: - -g - No optimizations, enable debugging - -O1 - Enable trivial optimizations - -O2 - Enable default optimizations - -O3 - Enable expensive optimizations</b> - -f - Enable binary output on terminals - -help - display available options (-help-hidden for more) - -o <filename> - Specify output filename - -quiet - Don't print informational messages -</pre></div> - -<p>In this case, it is sort of awkward that flag names correspond directly to -enum names, because we probably don't want a enum definition named "<tt>g</tt>" -in our program. Because of this, we can alternatively write this example like -this:</p> - -<div class="doc_code"><pre> -enum OptLevel { - Debug, O1, O2, O3 -}; - -<a href="#cl::opt">cl::opt</a><OptLevel> OptimizationLevel(<a href="#cl::desc">cl::desc</a>("<i>Choose optimization level:</i>"), - <a href="#cl::values">cl::values</a>( - clEnumValN(Debug, "g", "<i>No optimizations, enable debugging</i>"), - clEnumVal(O1 , "<i>Enable trivial optimizations</i>"), - clEnumVal(O2 , "<i>Enable default optimizations</i>"), - clEnumVal(O3 , "<i>Enable expensive optimizations</i>"), - clEnumValEnd)); - -... - if (OptimizationLevel == Debug) outputDebugInfo(...); -... -</pre></div> - -<p>By using the "<tt>clEnumValN</tt>" macro instead of "<tt>clEnumVal</tt>", we -can directly specify the name that the flag should get. In general a direct -mapping is nice, but sometimes you can't or don't want to preserve the mapping, -which is when you would use it.</p> - -</div> - -<!-- ======================================================================= --> -<h3> - <a name="namedalternatives">Named Alternatives</a> -</h3> - -<div> - -<p>Another useful argument form is a named alternative style. We shall use this -style in our compiler to specify different debug levels that can be used. -Instead of each debug level being its own switch, we want to support the -following options, of which only one can be specified at a time: -"<tt>--debug-level=none</tt>", "<tt>--debug-level=quick</tt>", -"<tt>--debug-level=detailed</tt>". To do this, we use the exact same format as -our optimization level flags, but we also specify an option name. For this -case, the code looks like this:</p> - -<div class="doc_code"><pre> -enum DebugLev { - nodebuginfo, quick, detailed -}; - -// Enable Debug Options to be specified on the command line -<a href="#cl::opt">cl::opt</a><DebugLev> DebugLevel("<i>debug_level</i>", <a href="#cl::desc">cl::desc</a>("<i>Set the debugging level:</i>"), - <a href="#cl::values">cl::values</a>( - clEnumValN(nodebuginfo, "none", "<i>disable debug information</i>"), - clEnumVal(quick, "<i>enable quick debug information</i>"), - clEnumVal(detailed, "<i>enable detailed debug information</i>"), - clEnumValEnd)); -</pre></div> - -<p>This definition defines an enumerated command line variable of type "<tt>enum -DebugLev</tt>", which works exactly the same way as before. The difference here -is just the interface exposed to the user of your program and the help output by -the "<tt>-help</tt>" option:</p> - -<div class="doc_code"><pre> -USAGE: compiler [options] <input file> - -OPTIONS: - Choose optimization level: - -g - No optimizations, enable debugging - -O1 - Enable trivial optimizations - -O2 - Enable default optimizations - -O3 - Enable expensive optimizations - <b>-debug_level - Set the debugging level: - =none - disable debug information - =quick - enable quick debug information - =detailed - enable detailed debug information</b> - -f - Enable binary output on terminals - -help - display available options (-help-hidden for more) - -o <filename> - Specify output filename - -quiet - Don't print informational messages -</pre></div> - -<p>Again, the only structural difference between the debug level declaration and -the optimization level declaration is that the debug level declaration includes -an option name (<tt>"debug_level"</tt>), which automatically changes how the -library processes the argument. The CommandLine library supports both forms so -that you can choose the form most appropriate for your application.</p> - -</div> - -<!-- ======================================================================= --> -<h3> - <a name="list">Parsing a list of options</a> -</h3> - -<div> - -<p>Now that we have the standard run-of-the-mill argument types out of the way, -lets get a little wild and crazy. Lets say that we want our optimizer to accept -a <b>list</b> of optimizations to perform, allowing duplicates. For example, we -might want to run: "<tt>compiler -dce -constprop -inline -dce -strip</tt>". In -this case, the order of the arguments and the number of appearances is very -important. This is what the "<tt><a href="#cl::list">cl::list</a></tt>" -template is for. First, start by defining an enum of the optimizations that you -would like to perform:</p> - -<div class="doc_code"><pre> -enum Opts { - // 'inline' is a C++ keyword, so name it 'inlining' - dce, constprop, inlining, strip -}; -</pre></div> - -<p>Then define your "<tt><a href="#cl::list">cl::list</a></tt>" variable:</p> - -<div class="doc_code"><pre> -<a href="#cl::list">cl::list</a><Opts> OptimizationList(<a href="#cl::desc">cl::desc</a>("<i>Available Optimizations:</i>"), - <a href="#cl::values">cl::values</a>( - clEnumVal(dce , "<i>Dead Code Elimination</i>"), - clEnumVal(constprop , "<i>Constant Propagation</i>"), - clEnumValN(inlining, "<i>inline</i>", "<i>Procedure Integration</i>"), - clEnumVal(strip , "<i>Strip Symbols</i>"), - clEnumValEnd)); -</pre></div> - -<p>This defines a variable that is conceptually of the type -"<tt>std::vector<enum Opts></tt>". Thus, you can access it with standard -vector methods:</p> - -<div class="doc_code"><pre> - for (unsigned i = 0; i != OptimizationList.size(); ++i) - switch (OptimizationList[i]) - ... -</pre></div> - -<p>... to iterate through the list of options specified.</p> - -<p>Note that the "<tt><a href="#cl::list">cl::list</a></tt>" template is -completely general and may be used with any data types or other arguments that -you can use with the "<tt><a href="#cl::opt">cl::opt</a></tt>" template. One -especially useful way to use a list is to capture all of the positional -arguments together if there may be more than one specified. In the case of a -linker, for example, the linker takes several '<tt>.o</tt>' files, and needs to -capture them into a list. This is naturally specified as:</p> - -<div class="doc_code"><pre> -... -<a href="#cl::list">cl::list</a><std::string> InputFilenames(<a href="#cl::Positional">cl::Positional</a>, <a href="#cl::desc">cl::desc</a>("<Input files>"), <a href="#cl::OneOrMore">cl::OneOrMore</a>); -... -</pre></div> - -<p>This variable works just like a "<tt>vector<string></tt>" object. As -such, accessing the list is simple, just like above. In this example, we used -the <tt><a href="#cl::OneOrMore">cl::OneOrMore</a></tt> modifier to inform the -CommandLine library that it is an error if the user does not specify any -<tt>.o</tt> files on our command line. Again, this just reduces the amount of -checking we have to do.</p> - -</div> - -<!-- ======================================================================= --> -<h3> - <a name="bits">Collecting options as a set of flags</a> -</h3> - -<div> - -<p>Instead of collecting sets of options in a list, it is also possible to -gather information for enum values in a <b>bit vector</b>. The representation used by -the <a href="#bits"><tt>cl::bits</tt></a> class is an <tt>unsigned</tt> -integer. An enum value is represented by a 0/1 in the enum's ordinal value bit -position. 1 indicating that the enum was specified, 0 otherwise. As each -specified value is parsed, the resulting enum's bit is set in the option's bit -vector:</p> - -<div class="doc_code"><pre> - <i>bits</i> |= 1 << (unsigned)<i>enum</i>; -</pre></div> - -<p>Options that are specified multiple times are redundant. Any instances after -the first are discarded.</p> - -<p>Reworking the above list example, we could replace <a href="#list"> -<tt>cl::list</tt></a> with <a href="#bits"><tt>cl::bits</tt></a>:</p> - -<div class="doc_code"><pre> -<a href="#cl::bits">cl::bits</a><Opts> OptimizationBits(<a href="#cl::desc">cl::desc</a>("<i>Available Optimizations:</i>"), - <a href="#cl::values">cl::values</a>( - clEnumVal(dce , "<i>Dead Code Elimination</i>"), - clEnumVal(constprop , "<i>Constant Propagation</i>"), - clEnumValN(inlining, "<i>inline</i>", "<i>Procedure Integration</i>"), - clEnumVal(strip , "<i>Strip Symbols</i>"), - clEnumValEnd)); -</pre></div> - -<p>To test to see if <tt>constprop</tt> was specified, we can use the -<tt>cl:bits::isSet</tt> function:</p> - -<div class="doc_code"><pre> - if (OptimizationBits.isSet(constprop)) { - ... - } -</pre></div> - -<p>It's also possible to get the raw bit vector using the -<tt>cl::bits::getBits</tt> function:</p> - -<div class="doc_code"><pre> - unsigned bits = OptimizationBits.getBits(); -</pre></div> - -<p>Finally, if external storage is used, then the location specified must be of -<b>type</b> <tt>unsigned</tt>. In all other ways a <a -href="#bits"><tt>cl::bits</tt></a> option is equivalent to a <a -href="#list"> <tt>cl::list</tt></a> option.</p> - -</div> - - -<!-- ======================================================================= --> -<h3> - <a name="description">Adding freeform text to help output</a> -</h3> - -<div> - -<p>As our program grows and becomes more mature, we may decide to put summary -information about what it does into the help output. The help output is styled -to look similar to a Unix <tt>man</tt> page, providing concise information about -a program. Unix <tt>man</tt> pages, however often have a description about what -the program does. To add this to your CommandLine program, simply pass a third -argument to the <a -href="#cl::ParseCommandLineOptions"><tt>cl::ParseCommandLineOptions</tt></a |