X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FCommandLine.html;h=83db04d6ed4f6a23ba4ad408f329e66957822cc3;hb=d985a1ca699ee51ca68ee20b11ea06038b17d467;hp=3533f14f48897e58ffa2a0395ff17cc1fb015c49;hpb=be801bf248a76b6a721a2f055bc9bd75f5cf4961;p=oota-llvm.git diff --git a/docs/CommandLine.html b/docs/CommandLine.html index 3533f14f488..83db04d6ed4 100644 --- a/docs/CommandLine.html +++ b/docs/CommandLine.html @@ -2,6 +2,7 @@ "http://www.w3.org/TR/html4/strict.dtd"> + CommandLine 2.0 Library Manual @@ -30,6 +31,8 @@
  • Positional Arguments
  • @@ -59,6 +62,7 @@
  • The cl::opt class
  • The cl::list class
  • The cl::alias class
  • +
  • The cl::extrahelp class
  • Builtin parsers @@ -84,8 +88,8 @@
  • -
    -

    Written by Chris Lattner

    +
    +

    Written by Chris Lattner

    @@ -188,19 +192,19 @@ can do.

    To start out, you need to include the CommandLine header file into your program:

    -
    +
       #include "Support/CommandLine.h"
    -
    +

    Additionally, you need to add this as the first line of your main program:

    -
    +
     int main(int argc, char **argv) {
       cl::ParseCommandLineOptions(argc, argv);
       ...
     }
    -
    +

    ... which actually parses the arguments and fills in the variable declarations.

    @@ -215,10 +219,10 @@ 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:

    -

    - -cl::opt<string> OutputFilename("o", cl::desc("Specify output filename"), cl::value_desc("filename")); -

    + +
    +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 @@ -231,25 +235,25 @@ that the data type that we are parsing is a string.

    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:

    -
    +
       ...
       ofstream Output(OutputFilename.c_str());
       if (Out.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 @@ -266,9 +270,9 @@ href="#positional">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:

    -
    +
     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::Required flag, and we could eliminate the cl::init modifier, like this:

    -
    +
     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:

    -
    +
     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 @@ -300,13 +304,13 @@ 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.

    @@ -325,11 +329,11 @@ file, "--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:

    -
    +
     cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
     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 @@ -347,12 +351,12 @@ 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 @@ -363,7 +367,7 @@ 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:
    @@ -371,11 +375,11 @@ OPTIONS:
       -o     - Override output filename
       -quiet - Don't print informational messages
       -help  - display available options (--help-hidden for more)
    -
    +

    and "opt --help-hidden" prints this:

    -
    +
     USAGE: compiler [options] <input file>
     
     OPTIONS:
    @@ -384,7 +388,7 @@ OPTIONS:
       -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 @@ -404,22 +408,22 @@ and lists of options.

    So far, the example works well, except for the fact that we need to check the quiet condition like this now:

    -
    +
     ...
       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:

    -
    +
     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 @@ -432,11 +436,11 @@ output).

    Now the application code can simply use:

    -
    +
     ...
       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 @@ -458,10 +462,10 @@ 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, are +Guide). This parser maps literal strings to whatever type is required, and requires you to tell it what this mapping should be.

    -

    Lets say that we would like to add four optimizations levels to our +

    Lets 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:

    @@ -482,7 +486,7 @@ see if some level >= "-O1" is enabled. CommandLine library fill it in with the appropriate level directly, which is used like this:

    -
    +
     enum OptLevel {
       g, O1, O2, O3
     };
    @@ -493,23 +497,24 @@ enum OptLevel {
         clEnumVal(O1, "Enable trivial optimizations"),
         clEnumVal(O2, "Enable default optimizations"),
         clEnumVal(O3, "Enable expensive optimizations"),
    -   0));
    +   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 "0" argument!). The CommandLine library enforces +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:
    @@ -522,14 +527,14 @@ OPTIONS:
       -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:

    -
    +
     enum OptLevel {
       Debug, O1, O2, O3
     };
    @@ -540,12 +545,12 @@ enum OptLevel {
         clEnumVal(O1        , "Enable trivial optimizations"),
         clEnumVal(O2        , "Enable default optimizations"),
         clEnumVal(O3        , "Enable expensive optimizations"),
    -   0));
    +   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 @@ -570,7 +575,7 @@ following options, of which only one can be specified at a time: our optimization level flags, but we also specify an option name. For this case, the code looks like this:

    -
    +
     enum DebugLev {
       nodebuginfo, quick, detailed
     };
    @@ -581,15 +586,15 @@ enum DebugLev {
         clEnumValN(nodebuginfo, "none", "disable debug information"),
          clEnumVal(quick,               "enable quick debug information"),
          clEnumVal(detailed,            "enable detailed debug information"),
    -    0));
    -
    + 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:
    @@ -606,10 +611,10 @@ OPTIONS:
       -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 optimiation level declaration is that the debug level declaration includes +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.

    @@ -632,34 +637,34 @@ 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:

    -
    +
     enum Opts {
       // 'inline' is a C++ keyword, so name it 'inlining'
       dce, constprop, inlining, strip
     };
    -
    +

    Then define your "cl::list" variable:

    -
    +
     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"),
    -  0));
    -
    + clEnumValEnd)); +

    This defines a variable that is conceptually of the type "std::vector<enum Opts>". Thus, you can access it with standard vector methods:

    -
    +
       for (unsigned i = 0; i != OptimizationList.size(); ++i)
         switch (OptimizationList[i])
            ...
    -
    +

    ... to iterate through the list of options specified.

    @@ -671,11 +676,11 @@ 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:

    -
    +
     ...
     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 @@ -704,17 +709,17 @@ 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:

    -
    +
     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:

    +

    would yield the help output:

    -
    +
     OVERVIEW: CommandLine compiler example
     
       This program blah blah blah...
    @@ -725,7 +730,7 @@ OPTIONS:
       ...
       -help             - display available options (--help-hidden for more)
       -o <filename>     - Specify output filename
    -
    +
    @@ -759,27 +764,27 @@ 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:

    -
    +
     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 they positional arguments +.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.

    @@ -799,7 +804,7 @@ 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'
     
    @@ -808,7 +813,7 @@ Note that the system grep has the same problem:

    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 @@ -816,11 +821,70 @@ 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:

    + +
    +  static cl::list<std::string> Files(cl::Positional, cl::OneOrMore);
    +  static cl::listlt;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.

    @@ -844,23 +908,23 @@ 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:

    -
    +
     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 +

    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 @@ -899,6 +963,7 @@ all of these clients (requiring lots of .cpp files to #include

    To do this, set up your .h file with your option, like this for example:

    +
     // DebugFlag.h - Get access to the '-debug' command line option
     //
    @@ -914,15 +979,15 @@ extern bool DebugFlag;
     // debug build, then the code specified as the option to the macro will be
     // executed.  Otherwise it will not be.  Example:
     //
    -// DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
    +// DEBUG(std::cerr << "Bitset contains: " << Bitset << "\n");
     //
    -#ifdef NDEBUG
    +#ifdef NDEBUG
     #define DEBUG(X)
     #else
    -#define DEBUG(X) \
    -  do { if (DebugFlag) { X; } } while (0)
    -#endif
    +#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 @@ -931,18 +996,19 @@ an additial argument to our command line argument processor, and we specify where to fill in with the cl::location attribute:

    +
    -bool DebugFlag;      // the actual value
    +bool DebugFlag;                  // the actual value
     static cl::opt<bool, true>       // The parser
    -Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
    -      cl::location(DebugFlag));
    +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.

    +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.

    @@ -993,12 +1059,13 @@ the section on Internal vs External Storage for more information.
  • The cl::aliasopt attribute -specifies which option a cl::alias option is an alias -for.
  • +specifies which option a cl::alias option is +an alias for.
  • The cl::values attribute specifies the string-to-value mapping to be used by the generic parser. It takes a -null terminated list of (option, value, description) triplets that +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 the generic parser is used most frequently with enum values, two macros are often useful: @@ -1213,35 +1280,40 @@ Arguments section for more information.
  • specifies that this option is used to capture "interpreter style" arguments. See this section for more information.
  • The cl::Prefix modifier specifies -that this option prefixes its value. With 'Prefix' options, there is no equal -sign that separates the value from the option name specified. This is useful -for processing odd arguments like '-lmalloc -L/usr/lib' in a linker -tool. Here, the 'l' and 'L' options are normal string (list) -options, that have the cl::Prefix modifier added to -allow the CommandLine library to recognize them. Note that cl::Prefix options must not have the cl::ValueDisallowed modifier specified.
  • +that this option prefixes its value. With 'Prefix' options, the equal sign does +not separate the value from the option name specified. Instead, the value is +everything after the prefix, including any equal sign if present. This is useful +for processing odd arguments like -lmalloc and -L/usr/lib in a +linker tool or -DNAME=value in a compiler tool. Here, the +'l', 'D' and 'L' options are normal string (or list) +options, that have the cl::Prefix +modifier added to allow the CommandLine library to recognize them. Note that +cl::Prefix options must not have the +cl::ValueDisallowed modifier +specified.
  • The cl::Grouping modifier is used to implement unix style tools (like ls) that have lots of single letter arguments, but only require a single dash. For example, the 'ls -labF' command actually enables four different options, all of which are single -letters. Note that cl::Grouping options cannot have -values.
  • +letters. Note that cl::Grouping +options cannot have values. -

    The CommandLine library does not restrict how you use the cl::Prefix or cl::Grouping -modifiers, but it is possible to specify ambiguous argument settings. Thus, it -is possible to have multiple letter options that are prefix or grouping options, -and they will still work as designed.

    +

    The CommandLine library does not restrict how you use the cl::Prefix or cl::Grouping modifiers, but it is possible to +specify ambiguous argument settings. Thus, it is possible to have multiple +letter options that are prefix or grouping options, and they will still work as +designed.

    To do this, the CommandLine library uses a greedy algorithm to parse the input option into (potentially multiple) prefix and grouping options. The strategy basically looks like this:

    -

    parse(string OrigInput) { +

    parse(string OrigInput) { +
    1. string input = OrigInput;
    2. if (isOption(input)) return getOption(input).parse();    // Normal option @@ -1255,11 +1327,11 @@ strategy basically looks like this:

        input = OrigInput;
        while (!isOption(input) && !input.empty()) input.pop_back();
      }
      -
    3. if (!OrigInput.empty()) error(); - - +
    4. if (!OrigInput.empty()) error();
    -}

    + +

    }

    +
    @@ -1384,13 +1456,13 @@ options, and is the one used most of the time. It is a templated class which can take up to three arguments (all except for the first have default values though):

    -
    +
     namespace cl {
       template <class DataType, bool ExternalStorage = false,
                 class ParserClass = parser<DataType> >
       class opt;
     }
    -
    +

    The first template argument specifies what underlying data type the command line argument is, and is used to select a default parser implementation. The @@ -1418,13 +1490,13 @@ href="#customparser">custom parser.

    line options. It too is a templated class which can take up to three arguments:

    -
    +
     namespace cl {
       template <class DataType, class Storage = bool,
                 class ParserClass = parser<DataType> >
       class list;
     }
    -
    +

    This class works the exact same as the cl::opt class, except that the second argument is @@ -1444,11 +1516,11 @@ be used.

    The cl::alias class is a nontemplated class that is used to form aliases for other arguments.

    -
    +
     namespace cl {
       class alias;
     }
    -
    +

    The cl::aliasopt attribute should be used to specify which option this is an alias for. Alias arguments default to @@ -1457,6 +1529,34 @@ the conversion from string to data.

    + +
    + The cl::extrahelp class +
    + +
    + +

    The cl::extrahelp class is a nontemplated class that allows extra +help text to be printed out for the --help option.

    + +
    +namespace cl {
    +  struct extrahelp;
    +}
    +
    + +

    To use the extrahelp, simply construct one with a const char* +parameter to the constructor. The text passed to the constructor will be printed +at the bottom of the help message, verbatim. Note that multiple +cl::extrahelp can be used, but this practice is discouraged. If +your tool needs to print additional help information, put all that help into a +single cl::extrahelp instance.

    +

    For example:

    +
    +  cl::extrahelp("\nADDITIONAL HELP:\n\n  This is the extra help\n");
    +
    +
    +
    Builtin parsers @@ -1581,13 +1681,13 @@ this the default for all unsigned options.

    To start out, we declare our new FileSizeParser class:

    -
    +
     struct FileSizeParser : public cl::basic_parser<unsigned> {
       // parse - Return true on error.
       bool parse(cl::Option &O, const char *ArgName, const std::string &ArgValue,
                  unsigned &Val);
     };
    -
    +

    Our new class inherits from the cl::basic_parser template class to fill in the default, boiler plate, code for us. We give it the data type that @@ -1603,7 +1703,7 @@ is not well formed, the parser should output an error message and return true. Otherwise it should return false and set 'Val' to the parsed value. In our example, we implement parse as:

    -
    +
     bool FileSizeParser::parse(cl::Option &O, const char *ArgName,
                                const std::string &Arg, unsigned &Val) {
       const char *ArgStart = Arg.c_str();
    @@ -1629,7 +1729,7 @@ our example, we implement parse as:

    } } } -
    +

    This function implements a very simple parser for the kinds of strings we are interested in. Although it has some holes (it allows "123KKK" for @@ -1638,25 +1738,25 @@ itself to print out the error message (the error method always returns true) in order to get a nice error message (shown below). Now that we have our parser class, we can use it like this:

    -
    +
     static cl::opt<unsigned, false, FileSizeParser>
     MFS("max-file-size", cl::desc("Maximum file size to accept"),
         cl::value_desc("size"));
    -
    +

    Which adds this to the output of our program:

    -
    +
     OPTIONS:
       -help                 - display available options (--help-hidden for more)
       ...
       -max-file-size=<size> - Maximum file size to accept
    -
    +

    And we can test that our parse works correctly now (the test program just prints out the max-file-size argument value):

    -
    +
     $ ./test
     MFS: 0
     $ ./test -max-file-size=123MB
    @@ -1665,7 +1765,7 @@ $ ./test -max-file-size=3G
     MFS: 3221225472
     $ ./test -max-file-size=dog
     -max-file-size option: 'dog' value invalid for file size argument!
    -
    +

    It looks like it works. The error message that we get is nice and helpful, and we seem to accept reasonable file sizes. This wraps up the "custom parser" @@ -1679,8 +1779,16 @@ tutorial.

    +

    Several of the LLVM libraries define static cl::opt instances that + will automatically be included in any program that links with that library. + This is a feature. However, sometimes it is necessary to know the value of the + command line option outside of the library. In these cases the library does or + should provide an external storage location that is accessible to users of the + library. Examples of this include the llvm::DebugFlag exported by the + lib/Support/Debug.cpp file and the llvm::TimePassesIsEnabled + flag exported by the lib/VMCore/Pass.cpp file.

    -

    TODO: fill in this section

    +

    TODO: complete this section

    @@ -1698,12 +1806,16 @@ tutorial.


    - +