diff options
Diffstat (limited to 'docs/CommandLine.html')
-rw-r--r-- | docs/CommandLine.html | 1907 |
1 files changed, 1907 insertions, 0 deletions
diff --git a/docs/CommandLine.html b/docs/CommandLine.html new file mode 100644 index 0000000000..3140b98ddf --- /dev/null +++ b/docs/CommandLine.html @@ -0,0 +1,1907 @@ +<!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="llvm.css" type="text/css"> +</head> +<body> + +<div class="doc_title"> + CommandLine 2.0 Library Manual +</div> + +<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> + </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::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="#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> + +<!-- *********************************************************************** --> +<div class="doc_section"> + <a name="introduction">Introduction</a> +</div> +<!-- *********************************************************************** --> + +<div class="doc_text"> + +<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> + +<!-- *********************************************************************** --> +<div class="doc_section"> + <a name="quickstart">Quick Start Guide</a> +</div> +<!-- *********************************************************************** --> + +<div class="doc_text"> + +<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 "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 argument 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> + ... + ofstream Output(OutputFilename.c_str()); + if (Out.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> + +</div> + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="bool">Boolean Arguments</a> +</div> + +<div class="doc_text"> + +<p>In addition to input and output filenames, we would like the compiler example +to support three boolean flags: "<tt>-f</tt>" to force overwriting of the output +file, "<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>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::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 - Overwrite output files</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>opt --help-hidden</tt>" prints this:</p> + +<div class="doc_code"><pre> +USAGE: compiler [options] <input file> + +OPTIONS: + -f - Overwrite output files + -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> + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="alias">Argument Aliases</a> +</div> + +<div class="doc_text"> + +<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> + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="onealternative">Selecting an alternative from a set of + possibilities</a> +</div> + +<div class="doc_text"> + +<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>Lets 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>opt -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 - Overwrite output files + -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> + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="namedalternatives">Named Alternatives</a> +</div> + +<div class="doc_text"> + +<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 - Overwrite output files + -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> + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="list">Parsing a list of options</a> +</div> + +<div class="doc_text"> + +<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> + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="bits">Collecting options as a set of flags</a> +</div> + +<div class="doc_text"> + +<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 represention 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 morally equivalent to a <a +href="#list"> <tt>cl::list</tt></a> option.</p> + +</div> + + +<!-- ======================================================================= --> +<div class="doc_subsection"> + <a name="description">Adding freeform text to help output</a> +</div> + +<div class="doc_text"> + +<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> +call in main. This additional argument is then printed as the overview +information for your program, allowing you to include any additional information +that you want. For example:</p> + +<div class="doc_code"><pre> +int main(int argc, char **argv) { + <a href="#cl::ParseCommandLineOptions">cl::ParseCommandLineOptions</a>(argc, argv, " CommandLine compiler example\n\n" + " This program |