aboutsummaryrefslogtreecommitdiff
path: root/docs/CommandLine.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/CommandLine.rst')
-rw-r--r--docs/CommandLine.rst1615
1 files changed, 1615 insertions, 0 deletions
diff --git a/docs/CommandLine.rst b/docs/CommandLine.rst
new file mode 100644
index 0000000000..302f5a4cf5
--- /dev/null
+++ b/docs/CommandLine.rst
@@ -0,0 +1,1615 @@
+.. _commandline:
+
+==============================
+CommandLine 2.0 Library Manual
+==============================
+
+Introduction
+============
+
+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 `can be changed`_).
+
+Although there are a **lot** 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:
+
+#. 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 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).
+
+#. 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.
+
+#. 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 **any**
+ boilerplate code.
+
+#. 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 `dynamically loaded options`_
+ trivial.
+
+#. 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.
+
+#. Powerful: The CommandLine library supports many different types of arguments,
+ from simple `boolean flags`_ to `scalars arguments`_ (`strings`_,
+ `integers`_, `enums`_, `doubles`_), to `lists of arguments`_. This is
+ possible because CommandLine is...
+
+#. 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. `Custom parsers`_ are no problem.
+
+#. 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
+ ``-help`` option that shows the available command line options for your tool.
+ Additionally, it does most of the basic correctness checking for you.
+
+#. Capable: The CommandLine library can handle lots of different forms of
+ options often found in real programs. For example, `positional`_ arguments,
+ ``ls`` style `grouping`_ options (to allow processing '``ls -lad``'
+ naturally), ``ld`` style `prefix`_ options (to parse '``-lmalloc
+ -L/usr/lib``'), and interpreter style options.
+
+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, `Chris
+Lattner <mailto:sabre@nondot.org>`_.
+
+Quick Start Guide
+=================
+
+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.
+
+To start out, you need to include the CommandLine header file into your program:
+
+.. code-block:: c++
+
+ #include "llvm/Support/CommandLine.h"
+
+Additionally, you need to add this as the first line of your main program:
+
+.. code-block:: c++
+
+ int main(int argc, char **argv) {
+ cl::ParseCommandLineOptions(argc, argv);
+ ...
+ }
+
+... which actually parses the arguments and fills in the variable declarations.
+
+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 '``-o <filename>``' option to specify
+where to put the output. With the CommandLine library, this is represented like
+this:
+
+.. _scalars arguments:
+.. _here:
+
+.. code-block:: c++
+
+ cl::opt<string> OutputFilename("o", cl::desc("Specify output filename"), cl::value_desc("filename"));
+
+This declares a global variable "``OutputFilename``" that is used to capture the
+result of the "``o``" argument (first parameter). We specify that this is a
+simple scalar option by using the "``cl::opt``" template (as opposed to the
+"``cl::list``" template), and tell the CommandLine library that the data
+type that we are parsing is a string.
+
+The second and third parameters (which are optional) are used to specify what to
+output for the "``-help``" option. In this case, we get a line that looks like
+this:
+
+::
+
+ USAGE: compiler [options]
+
+ OPTIONS:
+ -help - display available options (-help-hidden for more)
+ -o <filename> - Specify output filename
+
+Because we specified that the command line option should parse using the
+``string`` 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:
+
+.. code-block:: c++
+
+ ...
+ std::ofstream Output(OutputFilename.c_str());
+ if (Output.good()) ...
+ ...
+
+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 `cl::desc(...)`_, so there are no positional
+dependencies to remember. The available options are discussed in detail in the
+`Reference Guide`_.
+
+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 ``-filename.c``). To support this style of
+argument, the CommandLine library allows for `positional`_ 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:
+
+.. code-block:: c++
+
+
+ cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
+
+This declaration indicates that the first positional argument should be treated
+as the input filename. Here we use the `cl::init`_ 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 `cl::init`_ 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 `cl::Required`_ flag, and we
+could eliminate the `cl::init`_ modifier, like this:
+
+.. code-block:: c++
+
+ cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::Required);
+
+Again, the CommandLine library does not require the options to be specified in
+any particular order, so the above declaration is equivalent to:
+
+.. code-block:: c++
+
+ cl::opt<string> InputFilename(cl::Positional, cl::Required, cl::desc("<input file>"));
+
+By simply adding the `cl::Required`_ 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 ``-help`` option synopsis is now extended to:
+
+::
+
+ USAGE: compiler [options] <input file>
+
+ OPTIONS:
+ -help - display available options (-help-hidden for more)
+ -o <filename> - Specify output filename
+
+... indicating that an input filename is expected.
+
+Boolean Arguments
+-----------------
+
+In addition to input and output filenames, we would like the compiler example to
+support three boolean flags: "``-f``" to force writing binary output to a
+terminal, "``--quiet``" to enable quiet mode, and "``-q``" for backwards
+compatibility with some of our users. We can support these by declaring options
+of boolean type like this:
+
+.. code-block:: c++
+
+ cl::opt<bool> Force ("f", cl::desc("Enable binary output on terminals"));
+ cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
+ cl::opt<bool> Quiet2("q", cl::desc("Don't print informational messages"), cl::Hidden);
+
+This does what you would expect: it declares three boolean variables
+("``Force``", "``Quiet``", and "``Quiet2``") to recognize these options. Note
+that the "``-q``" option is specified with the "`cl::Hidden`_" flag. This
+modifier prevents it from being shown by the standard "``-help``" output (note
+that it is still shown in the "``-help-hidden``" output).
+
+The CommandLine library uses a `different parser`_ 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 "``true``" or "``false``" to be
+specified, allowing any of the following inputs:
+
+::
+
+ 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
+
+... you get the idea. The `bool parser`_ just turns the string values into
+boolean values, and rejects things like '``compiler -f=foo``'. Similarly, the
+`float`_, `double`_, and `int`_ parsers work like you would expect, using the
+'``strtol``' and '``strtod``' C library calls to parse the string value into the
+specified data type.
+
+With the declarations above, "``compiler -help``" emits this:
+
+::
+
+ USAGE: compiler [options] <input file>
+
+ OPTIONS:
+ -f - Enable binary output on terminals
+ -o - Override output filename
+ -quiet - Don't print informational messages
+ -help - display available options (-help-hidden for more)
+
+and "``compiler -help-hidden``" prints this:
+
+::
+
+ USAGE: compiler [options] <input file>
+
+ OPTIONS:
+ -f - Enable binary output on terminals
+ -o - Override output filename
+ -q - Don't print informational messages
+ -quiet - Don't print informational messages
+ -help - display available options (-help-hidden for more)
+
+This brief example has shown you how to use the '`cl::opt`_' class to parse
+simple scalar command line arguments. In addition to simple scalar arguments,
+the CommandLine library also provides primitives to support CommandLine option
+`aliases`_, and `lists`_ of options.
+
+.. _aliases:
+
+Argument Aliases
+----------------
+
+So far, the example works well, except for the fact that we need to check the
+quiet condition like this now:
+
+.. code-block:: c++
+
+ ...
+ if (!Quiet && !Quiet2) printInformationalMessage(...);
+ ...
+
+... which is a real pain! Instead of defining two values for the same
+condition, we can use the "`cl::alias`_" class to make the "``-q``" option an
+**alias** for the "``-quiet``" option, instead of providing a value itself:
+
+.. code-block:: c++
+
+ cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
+ cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
+ cl::alias QuietA("q", cl::desc("Alias for -quiet"), cl::aliasopt(Quiet));
+
+The third line (which is the only one we modified from above) defines a "``-q``"
+alias that updates the "``Quiet``" variable (as specified by the `cl::aliasopt`_
+modifier) whenever it is specified. Because aliases do not hold state, the only
+thing the program has to query is the ``Quiet`` variable now. Another nice
+feature of aliases is that they automatically hide themselves from the ``-help``
+output (although, again, they are still visible in the ``-help-hidden output``).
+
+Now the application code can simply use:
+
+.. code-block:: c++
+
+ ...
+ if (!Quiet) printInformationalMessage(...);
+ ...
+
+... which is much nicer! The "`cl::alias`_" can be used to specify an
+alternative name for any variable type, and has many uses.
+
+.. _unnamed alternatives using the generic parser:
+
+Selecting an alternative from a set of possibilities
+----------------------------------------------------
+
+So far we have seen how the CommandLine library handles builtin types like
+``std::string``, ``bool`` and ``int``, but how does it handle things it doesn't
+know about, like enums or '``int*``'s?
+
+The answer is that it uses a table-driven generic parser (unless you specify
+your own parser, as described in the `Extension Guide`_). This parser maps
+literal strings to whatever type is required, and requires you to tell it what
+this mapping should be.
+
+Let's say that we would like to add four optimization levels to our optimizer,
+using the standard flags "``-g``", "``-O0``", "``-O1``", and "``-O2``". We
+could easily implement this with boolean options like above, but there are
+several problems with this strategy:
+
+#. A user could specify more than one of the options at a time, for example,
+ "``compiler -O3 -O2``". The CommandLine library would not be able to catch
+ this erroneous input for us.
+
+#. We would have to test 4 different variables to see which ones are set.
+
+#. This doesn't map to the numeric levels that we want... so we cannot easily
+ see if some level >= "``-O1``" is enabled.
+
+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:
+
+.. code-block:: c++
+
+ enum OptLevel {
+ g, O1, O2, O3
+ };
+
+ cl::opt<OptLevel> OptimizationLevel(cl::desc("Choose optimization level:"),
+ cl::values(
+ clEnumVal(g , "No optimizations, enable debugging"),
+ clEnumVal(O1, "Enable trivial optimizations"),
+ clEnumVal(O2, "Enable default optimizations"),
+ clEnumVal(O3, "Enable expensive optimizations"),
+ clEnumValEnd));
+
+ ...
+ if (OptimizationLevel >= O2) doPartialRedundancyElimination(...);
+ ...
+
+This declaration defines a variable "``OptimizationLevel``" of the
+"``OptLevel``" 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 "``clEnumValEnd``" 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 "``clEnumVal``" macros ensure that the command
+line arguments matched the enum values. With this option added, our help output
+now is:
+
+::
+
+ 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
+ -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
+
+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 "``g``" in our
+program. Because of this, we can alternatively write this example like this:
+
+.. code-block:: c++
+
+ enum OptLevel {
+ Debug, O1, O2, O3
+ };
+
+ cl::opt<OptLevel> OptimizationLevel(cl::desc("Choose optimization level:"),
+ cl::values(
+ clEnumValN(Debug, "g", "No optimizations, enable debugging"),
+ clEnumVal(O1 , "Enable trivial optimizations"),
+ clEnumVal(O2 , "Enable default optimizations"),
+ clEnumVal(O3 , "Enable expensive optimizations"),
+ clEnumValEnd));
+
+ ...
+ if (OptimizationLevel == Debug) outputDebugInfo(...);
+ ...
+
+By using the "``clEnumValN``" macro instead of "``clEnumVal``", 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.
+
+Named Alternatives
+------------------
+
+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:
+"``--debug-level=none``", "``--debug-level=quick``",
+"``--debug-level=detailed``". 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:
+
+.. code-block:: c++
+
+ enum DebugLev {
+ nodebuginfo, quick, detailed
+ };
+
+ // Enable Debug Options to be specified on the command line
+ cl::opt<DebugLev> DebugLevel("debug_level", cl::desc("Set the debugging level:"),
+ cl::values(
+ clEnumValN(nodebuginfo, "none", "disable debug information"),
+ clEnumVal(quick, "enable quick debug information"),
+ clEnumVal(detailed, "enable detailed debug information"),
+ clEnumValEnd));
+
+This definition defines an enumerated command line variable of type "``enum
+DebugLev``", 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 "``-help``" option:
+
+::
+
+ 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
+ -debug_level - Set the debugging level:
+ =none - disable debug information
+ =quick - enable quick debug information
+ =detailed - enable detailed debug information
+ -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
+
+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 (``"debug_level"``), 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.
+
+.. _lists:
+
+Parsing a list of options
+-------------------------
+
+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 **list** of optimizations to perform, allowing duplicates. For example, we
+might want to run: "``compiler -dce -constprop -inline -dce -strip``". In this
+case, the order of the arguments and the number of appearances is very
+important. This is what the "``cl::list``" template is for. First, start by
+defining an enum of the optimizations that you would like to perform:
+
+.. code-block:: c++
+
+ enum Opts {
+ // 'inline' is a C++ keyword, so name it 'inlining'
+ dce, constprop, inlining, strip
+ };
+
+Then define your "``cl::list``" variable:
+
+.. code-block:: c++
+
+ cl::list<Opts> OptimizationList(cl::desc("Available Optimizations:"),
+ cl::values(
+ clEnumVal(dce , "Dead Code Elimination"),
+ clEnumVal(constprop , "Constant Propagation"),
+ clEnumValN(inlining, "inline", "Procedure Integration"),
+ clEnumVal(strip , "Strip Symbols"),
+ clEnumValEnd));
+
+This defines a variable that is conceptually of the type
+"``std::vector<enum Opts>``". Thus, you can access it with standard vector
+methods:
+
+.. code-block:: c++
+
+ for (unsigned i = 0; i != OptimizationList.size(); ++i)
+ switch (OptimizationList[i])
+ ...
+
+... to iterate through the list of options specified.
+
+Note that the "``cl::list``" template is completely general and may be used with
+any data types or other arguments that you can use with the "``cl::opt``"
+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 '``.o``' files, and
+needs to capture them into a list. This is naturally specified as:
+
+.. code-block:: c++
+
+ ...
+ cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<Input files>"), cl::OneOrMore);
+ ...
+
+This variable works just like a "``vector<string>``" object. As such, accessing
+the list is simple, just like above. In this example, we used the
+`cl::OneOrMore`_ modifier to inform the CommandLine library that it is an error
+if the user does not specify any ``.o`` files on our command line. Again, this
+just reduces the amount of checking we have to do.
+
+Collecting options as a set of flags
+------------------------------------
+
+Instead of collecting sets of options in a list, it is also possible to gather
+information for enum values in a **bit vector**. The representation used by the
+`cl::bits`_ class is an ``unsigned`` 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:
+
+.. code-block:: c++
+
+ bits |= 1 << (unsigned)enum;
+
+Options that are specified multiple times are redundant. Any instances after
+the first are discarded.
+
+Reworking the above list example, we could replace `cl::list`_ with `cl::bits`_:
+
+.. code-block:: c++
+
+ cl::bits<Opts> OptimizationBits(cl::desc("Available Optimizations:"),
+ cl::values(
+ clEnumVal(dce , "Dead Code Elimination"),
+ clEnumVal(constprop , "Constant Propagation"),
+ clEnumValN(inlining, "inline", "Procedure Integration"),
+ clEnumVal(strip , "Strip Symbols"),
+ clEnumValEnd));
+
+To test to see if ``constprop`` was specified, we can use the ``cl:bits::isSet``
+function:
+
+.. code-block:: c++
+
+ if (OptimizationBits.isSet(constprop)) {
+ ...
+ }
+
+It's also possible to get the raw bit vector using the ``cl::bits::getBits``
+function:
+
+.. code-block:: c++
+
+ unsigned bits = OptimizationBits.getBits();
+
+Finally, if external storage is used, then the location specified must be of
+**type** ``unsigned``. In all other ways a `cl::bits`_ option is equivalent to a
+`cl::list`_ option.
+
+.. _additional extra text:
+
+Adding freeform text to help output
+-----------------------------------
+
+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 ``man`` page, providing concise information about a
+program. Unix ``man`` 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 `cl::ParseCommandLineOptions`_ 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:
+
+.. code-block:: c++
+
+ int main(int argc, char **argv) {
+ cl::ParseCommandLineOptions(argc, argv, " CommandLine compiler example\n\n"
+ " This program blah blah blah...\n");
+ ...
+ }
+
+would yield the help output:
+
+::
+
+ **OVERVIEW: CommandLine compiler example
+
+ This program blah blah blah...**
+
+ USAGE: compiler [options] <input file>
+
+ OPTIONS:
+ ...
+ -help - display available options (-help-hidden for more)
+ -o <filename> - Specify output filename
+
+.. _Reference Guide:
+
+Reference Guide
+===============
+
+Now that you know the basics of how to use the CommandLine library, this section
+will give you the detailed information you need to tune how command line options
+work, as well as information on more "advanced" command line option processing
+capabilities.
+
+.. _positional:
+.. _positional argument:
+.. _Positional Arguments:
+.. _Positional arguments section:
+.. _positional options:
+
+Positional Arguments
+--------------------
+
+Positional arguments are those arguments that are not named, and are not
+specified with a hyphen. Positional arguments should be used when an option is
+specified by its position alone. For example, the standard Unix ``grep`` tool
+takes a regular expression argument, and an optional filename to search through
+(which defaults to standard input if a filename is not specified). Using the
+CommandLine library, this would be specified as:
+
+.. code-block:: c++
+
+ cl::opt<string> Regex (cl::Positional, cl::desc("<regular expression>"), cl::Required);
+ cl::opt<string> Filename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
+
+Given these two option declarations, the ``-help`` output for our grep
+replacement would look like this:
+
+::
+
+ USAGE: spiffygrep [options] <regular expression> <input file>
+
+ OPTIONS:
+ -help - display available options (-help-hidden for more)
+
+... and the resultant program could be used just like the standard ``grep``
+tool.
+
+Positional arguments are sorted by their order of construction. This means that
+command line options will be ordered according to how they are listed in a .cpp
+file, but will not have an ordering defined if the positional arguments are
+defined in multiple .cpp files. The fix for this problem is simply to define
+all of your positional arguments in one .cpp file.
+
+Specifying positional options with hyphens
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes you may want to specify a value to your positional argument that
+starts with a hyphen (for example, searching for '``-foo``' in a file). At
+first, you will have trouble doing this, because it will try to find an argument
+named '``-foo``', and will fail (and single quotes will not save you). Note
+that the system ``grep`` has the same problem:
+
+::
+
+ $ spiffygrep '-foo' test.txt
+ Unknown command line argument '-foo'. Try: spiffygrep -help'
+
+ $ grep '-foo' test.txt
+ grep: illegal option -- f
+ grep: illegal option -- o
+ grep: illegal option -- o
+ Usage: grep -hblcnsviw pattern file . . .
+
+The solution for this problem is the same for both your tool and the system
+version: use the '``--``' marker. When the user specifies '``--``' on the
+command line, it is telling the program that all options after the '``--``'
+should be treated as positional arguments, not options. Thus, we can use it
+like this:
+
+::
+
+ $ spiffygrep -- -foo test.txt
+ ...output...
+
+Determining absolute position with getPosition()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes an option can affect or modify the meaning of another option. For
+example, consider ``gcc``'s ``-x LANG`` option. This tells ``gcc`` to ignore the
+suffix of subsequent positional arguments and force the file to be interpreted
+as if it contained source code in language ``LANG``. In order to handle this
+properly, you need to know the absolute position of each argument, especially
+those in lists, so their interaction(s) can be applied correctly. This is also
+useful for options like ``-llibname`` which is actually a positional argument
+that starts with a dash.
+
+So, generally, the problem is that you have two ``cl::list`` variables that
+interact in some way. To ensure the correct interaction, you can use the
+``cl::list::getPosition(optnum)`` method. This method returns the absolute
+position (as found on the command line) of the ``optnum`` item in the
+``cl::list``.
+
+The idiom for usage is like this:
+
+.. code-block:: c++
+
+ static cl::list<std::string> Files(cl::Positional, cl::OneOrMore);
+ static cl::list<std::string> Libraries("l", cl::ZeroOrMore);
+
+ int main(int argc, char**argv) {
+ // ...
+ std::vector<std::string>::iterator fileIt = Files.begin();
+ std::vector<std::string>::iterator libIt = Libraries.begin();
+ unsigned libPos = 0, filePos = 0;
+ while ( 1 ) {
+ if ( libIt != Libraries.end() )
+ libPos = Libraries.getPosition( libIt - Libraries.begin() );
+ else
+ libPos = 0;
+ if ( fileIt != Files.end() )
+ filePos = Files.getPosition( fileIt - Files.begin() );
+ else
+ filePos = 0;
+
+ if ( filePos != 0 && (libPos == 0 || filePos < libPos) ) {
+ // Source File Is next
+ ++fileIt;
+ }
+ else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) {
+ // Library is next
+ ++libIt;
+ }
+ else
+ break; // we're done with the list
+ }
+ }
+
+Note that, for compatibility reasons, the ``cl::opt`` also supports an
+``unsigned getPosition()`` option that will provide the absolute position of
+that option. You can apply the same approach as above with a ``cl::opt`` and a
+``cl::list`` option as you can with two lists.
+
+.. _interpreter style options:
+.. _cl::ConsumeAfter:
+.. _this section for more information:
+
+The ``cl::ConsumeAfter`` modifier
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``cl::ConsumeAfter`` `formatting option`_ is used to construct programs that
+use "interpreter style" option processing. With this style of option
+processing, all arguments specified after the last positional argument are
+treated as special interpreter arguments that are not interpreted by the command
+line argument.
+
+As a concrete example, lets say we are developing a replacement for the standard
+Unix Bourne shell (``/bin/sh``). To run ``/bin/sh``, first you specify options
+to the shell itself (like ``-x`` which turns on trace output), then you specify
+the name of the script to run, then you specify arguments to the script. These
+arguments to the script are parsed by the Bourne shell command line option
+processor, but are not interpreted as options to the shell itself. Using the
+CommandLine library, we would specify this as:
+
+.. code-block:: c++
+
+ cl::opt<string> Script(cl::Positional, cl::desc("<input script>"), cl::init("-"));
+ cl::list<string> Argv(cl::ConsumeAfter, cl::desc("<program arguments>..."));
+ cl::opt<bool> Trace("x", cl::desc("Enable trace output"));
+
+which automatically provides the help output:
+
+::
+
+ USAGE: spiffysh [options] <input script> <program arguments>...
+
+ OPTIONS:
+ -help - display available options (-help-hidden for more)
+ -x - Enable trace output
+
+At runtime, if we run our new shell replacement as ```spiffysh -x test.sh -a -x
+-y bar``', the ``Trace`` variable will be set to true, the ``Script`` variable
+will be set to "``test.sh``", and the ``Argv`` list will contain ``["-a", "-x",
+"-y", "bar"]``, because they were specified after the last positional argument
+(which is the script name).
+
+There are several limitations to when ``cl::ConsumeAfter`` options can be
+specified. For example, only one ``cl::ConsumeAfter`` can be specified per
+program, there must be at least one `positional argument`_ specified, there must
+not be any `cl::list`_ positional arguments, and the ``cl::ConsumeAfter`` option
+should be a `cl::list`_ option.
+
+.. _can be changed:
+.. _Internal vs External Storage:
+
+Internal vs External Storage
+----------------------------
+
+By default, all command line options automatically hold the value that they
+parse from the command line. This is very convenient in the common case,
+especially when combined with the ability to define command line options in the
+files that use them. This is called the internal storage model.
+
+Sometimes, however, it is nice to separate the command line option processing
+code from the storage of the value parsed. For example, lets say that we have a
+'``-debug``' option that we would like to use to enable debug information across
+the entire body of our program. In this case, the boolean value controlling the
+debug code should be globally accessible (in a header file, for example) yet the
+command line option processing code should not be exposed to all of these
+clients (requiring lots of .cpp files to ``#include CommandLine.h``).
+
+To do this, set up your .h file with your option, like this for example:
+
+.. code-block:: c++
+
+ // DebugFlag.h - Get access to the '-debug' command line option
+ //
+
+ // DebugFlag - This boolean is set to true if the '-debug' command line option
+ // is specified. This should probably not be referenced directly, instead, use
+ // the DEBUG macro below.
+ //
+ extern bool DebugFlag;
+
+ // DEBUG macro - This macro should be used by code to emit debug information.
+ // In the '-debug' option is specified on the command line, and if this is a
+ // debug build, then the code specified as the option to the macro will be
+ // executed. Otherwise it will not be.
+ #ifdef NDEBUG
+ #define DEBUG(X)
+ #else
+ #define DEBUG(X) do { if (DebugFlag) { X; } } while (0)
+ #endif
+
+This allows clients to blissfully use the ``DEBUG()`` macro, or the
+``DebugFlag`` explicitly if they want to. Now we just need to be able to set
+the ``DebugFlag`` boolean when the option is set. To do this, we pass an
+additional argument to our command line argument processor, and we specify where
+to fill in with the `cl::location`_ attribute:
+
+.. code-block:: c++
+
+ bool DebugFlag; // the actual value
+ static cl::opt<bool, true> // The parser
+ Debug("debug", cl::desc("Enable debug output"), cl::Hidden, cl::location(DebugFlag));
+
+In the above example, we specify "``true``" as the second argument to the
+`cl::opt`_ template, indicating that the template should not maintain a copy of
+the value itself. In addition to this, we specify the `cl::location`_
+attribute, so that ``DebugFlag`` is automatically set.
+
+Option Attributes
+-----------------
+
+This section describes the basic attributes that you can specify on options.
+
+* The option name attribute (which is required for all options, except
+ `positional options`_) specifies what the option name is. This option is
+ specified in simple double quotes:
+
+ .. code-block:: c++
+
+ cl::opt<**bool**> Quiet("quiet");
+
+.. _cl::desc(...):
+
+* The **cl::desc** attribute specifies a description for the option to be
+ shown in the ``-help`` output for the program.
+
+.. _cl::value_desc:
+
+* The **cl::value_desc** attribute specifies a string that can be used to
+ fine tune the ``-help`` output for a command line option. Look `here`_ for an
+ example.
+
+.. _cl::init:
+
+* The **cl::init** attribute specifies an initial value for a `scalar`_
+ option. If this attribute is not specified then the command line option value
+ defaults to the value created by the default constructor for the
+ type.
+
+ .. warning::
+
+ If you specify both **cl::init** and **cl::location** for an option, you
+ must specify **cl::location** first, so that when the command-line parser
+ sees **cl::init**, it knows where to put the initial value. (You will get an
+ error at runtime if you don't put them in the right order.)
+
+.. _cl::location:
+
+* The **cl::location** attribute where to store the value for a parsed command
+ line option if using external storage. See the section on `Internal vs
+ External Storage`_ for more information.
+
+.. _cl::aliasopt:
+
+* The **cl::aliasopt** attribute specifies which option a `cl::alias`_ option is
+ an alias for.
+
+.. _cl::values:
+
+* The **cl::values** attribute specifies the string-to-value mapping to be used
+ by the generic parser. It takes a **clEnumValEnd terminated** list of
+ (option, value, description) triplets that specify the option name, the value
+ mapped to, and the description shown in the ``-help`` for the tool. Because