| # 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 {ref}`can be changed <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: | |
| 1. 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). | |
| 1. 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. | |
| 1. 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. | |
| 1. 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 {ref}`dynamically loaded options <dynamically loaded options>` | |
| trivial. | |
| 1. 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. | |
| 1. Powerful: The CommandLine library supports many different types of arguments, | |
| from simple {ref}`boolean flags <boolean flags>` to {ref}`scalars arguments <scalars arguments>` ({ref}`strings <strings>`, | |
| {ref}`integers <integers>`, {ref}`enums <enums>`, {ref}`doubles <doubles>`), to {ref}`lists of arguments <lists of arguments>`. This is | |
| possible because CommandLine is... | |
| 1. 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. {ref}`Custom parsers <Custom parsers>` are no problem. | |
| 1. 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. | |
| 1. Capable: The CommandLine library can handle lots of different forms of | |
| options often found in real programs. For example, {ref}`positional <positional>` arguments, | |
| `ld` style {ref}`prefix <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. | |
| ## 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: | |
| ```cpp | |
| #include "llvm/Support/CommandLine.h" | |
| ``` | |
| Additionally, you need to add this as the first line of your main program: | |
| ```cpp | |
| 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)= | |
| ```cpp | |
| 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: | |
| -h - Alias for -help | |
| -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: | |
| ```cpp | |
| ... | |
| 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 {ref}`cl::desc(...) <cl::desc(...)>`, so there are no positional | |
| dependencies to remember. The available options are discussed in detail in the | |
| {ref}`Reference Guide <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 {ref}`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: | |
| ```cpp | |
| 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 {ref}`cl::init <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 {ref}`cl::init <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 {ref}`cl::Required <cl::Required>` flag, and we | |
| could eliminate the {ref}`cl::init <cl::init>` modifier, like this: | |
| ```cpp | |
| 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: | |
| ```cpp | |
| cl::opt<string> InputFilename(cl::Positional, cl::Required, cl::desc("<input file>")); | |
| ``` | |
| By simply adding the {ref}`cl::Required <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: | |
| -h - Alias for -help | |
| -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: | |
| ```cpp | |
| 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 "{ref}`cl::Hidden <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 {ref}`different parser <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=1 # Value specified, 'Force' == true | |
| compiler -f=false # Value specified, 'Force' == false | |
| ``` | |
| ... you get the idea. The {ref}`bool parser <bool parser>` just turns the string values into | |
| boolean values, and rejects things like '`compiler -f=foo`'. Similarly, the | |
| {ref}`float <float>`, {ref}`double <double>`, and {ref}`int <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 '{ref}`cl::opt <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 | |
| {ref}`aliases <aliases>`, and {ref}`lists <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: | |
| ```cpp | |
| ... | |
| if (!Quiet && !Quiet2) printInformationalMessage(...); | |
| ... | |
| ``` | |
| ... which is a real pain! Instead of defining two values for the same | |
| condition, we can use the "{ref}`cl::alias <cl::alias>`" class to make the "`-q`" option an | |
| **alias** for the "`-quiet`" option, instead of providing a value itself: | |
| ```cpp | |
| 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 {ref}`cl::aliasopt <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: | |
| ```cpp | |
| ... | |
| if (!Quiet) printInformationalMessage(...); | |
| ... | |
| ``` | |
| ... which is much nicer! The "{ref}`cl::alias <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 {ref}`Extension Guide <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: | |
| 1. 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. | |
| 1. We would have to test 4 different variables to see which ones are set. | |
| 1. 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: | |
| ```cpp | |
| 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"))); | |
| ... | |
| 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. 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 an enum definition named "`g`" in our | |
| program. Because of this, we can alternatively write this example like this: | |
| ```cpp | |
| 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"))); | |
| ... | |
| 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: | |
| ```cpp | |
| 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"))); | |
| ``` | |
| 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 -instsimplify -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: | |
| ```cpp | |
| enum Opts { | |
| // 'inline' is a C++ keyword, so name it 'inlining' | |
| dce, instsimplify, inlining, strip | |
| }; | |
| ``` | |
| Then define your "`cl::list`" variable: | |
| ```cpp | |
| cl::list<Opts> OptimizationList(cl::desc("Available Optimizations:"), | |
| cl::values( | |
| clEnumVal(dce , "Dead Code Elimination"), | |
| clEnumVal(instsimplify , "Instruction Simplification"), | |
| clEnumValN(inlining, "inline", "Procedure Integration"), | |
| clEnumVal(strip , "Strip Symbols"))); | |
| ``` | |
| This defines a variable that is conceptually of the type | |
| "`std::vector<enum Opts>`". Thus, you can access it with standard vector | |
| methods: | |
| ```cpp | |
| 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: | |
| ```cpp | |
| ... | |
| 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 | |
| {ref}`cl::OneOrMore <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. | |
| (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 {ref}`cl::ParseCommandLineOptions <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: | |
| ```cpp | |
| 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 | |
| ``` | |
| (grouping options into categories)= | |
| ### Grouping options into categories | |
| If our program has a large number of options it may become difficult for users | |
| of our tool to navigate the output of `-help`. To alleviate this problem we | |
| can put our options into categories. This can be done by declaring option | |
| categories ({ref}`cl::OptionCategory <cl::OptionCategory>` objects) and then placing our options into | |
| these categories using the {ref}`cl::cat <cl::cat>` option attribute. For example: | |
| ```cpp | |
| cl::OptionCategory StageSelectionCat("Stage Selection Options", | |
| "These control which stages are run."); | |
| cl::opt<bool> Preprocessor("E",cl::desc("Run preprocessor stage."), | |
| cl::cat(StageSelectionCat)); | |
| cl::opt<bool> NoLink("c",cl::desc("Run all stages except linking."), | |
| cl::cat(StageSelectionCat)); | |
| ``` | |
| The output of `-help` will become categorized if an option category is | |
| declared. The output looks something like: | |
| ``` | |
| OVERVIEW: This is a small program to demo the LLVM CommandLine API | |
| USAGE: Sample [options] | |
| OPTIONS: | |
| General options: | |
| -help - Display available options (-help-hidden for more) | |
| -help-list - Display list of available options (-help-list-hidden for more) | |
| Stage Selection Options: | |
| These control which stages are run. | |
| -E - Run preprocessor stage. | |
| -c - Run all stages except linking. | |
| ``` | |
| In addition to the behaviour of `-help` changing when an option category is | |
| declared, the command line option `-help-list` becomes visible which will | |
| print the command line options as uncategorized list. | |
| Note that Options that are not explicitly categorized will be placed in the | |
| `cl::getGeneralCategory()` category. | |
| (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: | |
| ```cpp | |
| 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: | |
| ```cpp | |
| static cl::list<std::string> Files(cl::Positional, cl::OneOrMore); | |
| static cl::list<std::string> Libraries("l"); | |
| 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` {ref}`formatting option <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: | |
| ```cpp | |
| 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 {ref}`positional argument <positional argument>` specified, there must | |
| not be any {ref}`cl::list <cl::list>` positional arguments, and the `cl::ConsumeAfter` option | |
| should be a {ref}`cl::list <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: | |
| ```cpp | |
| // 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 LLVM_DEBUG(X) | |
| #else | |
| #define LLVM_DEBUG(X) do { if (DebugFlag) { X; } } while (0) | |
| #endif | |
| ``` | |
| This allows clients to blissfully use the `LLVM_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 {ref}`cl::location <cl::location>` attribute: | |
| ```cpp | |
| 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 | |
| {ref}`cl::opt <cl::opt>` template, indicating that the template should not maintain a copy of | |
| the value itself. In addition to this, we specify the {ref}`cl::location <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 | |
| {ref}`positional options <positional options>`) specifies what the option name is. This option is | |
| specified in simple double quotes: | |
| ```cpp | |
| 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. This attribute supports | |
| multi-line descriptions with lines separated by '\n'. | |
| (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 {ref}`here <here>` for an | |
| example. | |
| (cl::init)= | |
| * The **cl::init** attribute specifies an initial value for a {ref}`scalar <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 {ref}`Internal vs External Storage <Internal vs External Storage>` | |
| for more information. | |
| (cl::aliasopt)= | |
| * The **cl::aliasopt** attribute specifies which option a {ref}`cl::alias <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 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: | |
| 1. The **clEnumVal** macro is used as a nice simple way to specify a triplet | |
| for an enum. This macro automatically makes the option name be the same as | |
| the enum name. The first option to the macro is the enum, the second is | |
| the description for the command line option. | |
| 1. The **clEnumValN** macro is used to specify macro options where the option | |
| name doesn't equal the enum name. For this macro, the first argument is | |
| the enum value, the second is the flag name, and the second is the | |
| description. | |
| You will get a compile time error if you try to use cl::values with a parser | |
| that does not support it. | |
| (cl::cat)= | |
| * The **cl::cat** attribute specifies the option category that the option | |
| belongs to. The category should be a {ref}`cl::OptionCategory <cl::OptionCategory>` object. | |
| (cl::callback)= | |
| * The **cl::callback** attribute specifies a callback function that is | |
| called when an option is seen, and can be used to set other options, | |
| as in option B implies option A. If the option is a {ref}`cl::list <cl::list>`, | |
| and {ref}`cl::CommaSeparated <cl::CommaSeparated>` is also specified, the callback will fire | |
| once for each value. This could be used to validate combinations or | |
| selectively set other options. | |
| ```cpp | |
| cl::opt<bool> OptA("a", cl::desc("option a")); | |
| cl::opt<bool> OptB( | |
| "b", cl::desc("option b -- This option turns on option a"), | |
| cl::callback([&](const bool &) { OptA = true; })); | |
| cl::list<std::string, cl::list<std::string>> List( | |
| "list", | |
| cl::desc("option list -- This option turns on options a when " | |
| "'foo' is included in list"), | |
| cl::CommaSeparated, | |
| cl::callback([&](const std::string &Str) { | |
| if (Str == "foo") | |
| OptA = true; | |
| })); | |
| ``` | |
| ### Option Modifiers | |
| Option modifiers are the flags and expressions that you pass into the | |
| constructors for {ref}`cl::opt <cl::opt>` and {ref}`cl::list <cl::list>`. These modifiers give you the | |
| ability to tweak how options are parsed and how `-help` output is generated to | |
| fit your application well. | |
| These options fall into five main categories: | |
| 1. Hiding an option from `-help` output | |
| 1. Controlling the number of occurrences required and allowed | |
| 1. Controlling whether or not a value must be specified | |
| 1. Controlling other formatting options | |
| 1. Miscellaneous option modifiers | |
| It is not possible to specify two options from the same category (you'll get a | |
| runtime error) to a single option, except for options in the miscellaneous | |
| category. The CommandLine library specifies defaults for all of these settings | |
| that are the most useful in practice and the most common, which mean that you | |
| usually shouldn't have to worry about these. | |
| #### Hiding an option from `-help` output | |
| The `cl::NotHidden`, `cl::Hidden`, and `cl::ReallyHidden` modifiers are | |
| used to control whether or not an option appears in the `-help` and | |
| `-help-hidden` output for the compiled program: | |
| (cl::NotHidden)= | |
| * The **cl::NotHidden** modifier (which is the default for {ref}`cl::opt <cl::opt>` and | |
| {ref}`cl::list <cl::list>` options) indicates the option is to appear in both help | |
| listings. | |
| (cl::Hidden)= | |
| * The **cl::Hidden** modifier (which is the default for {ref}`cl::alias <cl::alias>` options) | |
| indicates that the option should not appear in the `-help` output, but | |
| should appear in the `-help-hidden` output. | |
| (cl::ReallyHidden)= | |
| * The **cl::ReallyHidden** modifier indicates that the option should not appear | |
| in any help output. | |
| #### Controlling the number of occurrences required and allowed | |
| This group of options is used to control how many time an option is allowed (or | |
| required) to be specified on the command line of your program. Specifying a | |
| value for this setting allows the CommandLine library to do error checking for | |
| you. | |
| The allowed values for this option group are: | |
| (cl::Optional)= | |
| * The **cl::Optional** modifier (which is the default for the {ref}`cl::opt <cl::opt>` and | |
| {ref}`cl::alias <cl::alias>` classes) indicates that your program will allow either zero or | |
| one occurrence of the option to be specified. | |
| (cl::ZeroOrMore)= | |
| * The **cl::ZeroOrMore** modifier (which is the default for the {ref}`cl::list <cl::list>` | |
| class) indicates that your program will allow the option to be specified zero | |
| or more times. | |
| (cl::Required)= | |
| * The **cl::Required** modifier indicates that the specified option must be | |
| specified exactly one time. | |
| (cl::OneOrMore)= | |
| * The **cl::OneOrMore** modifier indicates that the option must be specified at | |
| least one time. | |
| * The **cl::ConsumeAfter** modifier is described in the {ref}`Positional arguments section <Positional arguments section>`. | |
| If an option is not specified, then the value of the option is equal to the | |
| value specified by the {ref}`cl::init <cl::init>` attribute. If the `cl::init` attribute is | |
| not specified, the option value is initialized with the default constructor for | |
| the data type. | |
| If an option is specified multiple times for an option of the {ref}`cl::opt <cl::opt>` class, | |
| only the last value will be retained. | |
| #### Controlling whether or not a value must be specified | |
| This group of options is used to control whether or not the option allows a | |
| value to be present. In the case of the CommandLine library, a value is either | |
| specified with an equal sign (e.g. '`-index-depth=17`') or as a trailing | |
| string (e.g. '`-o a.out`'). | |
| The allowed values for this option group are: | |
| (cl::ValueOptional)= | |
| * The **cl::ValueOptional** modifier (which is the default for `bool` typed | |
| options) specifies that it is acceptable to have a value, or not. A boolean | |
| argument can be enabled just by appearing on the command line, or it can have | |
| an explicit '`-foo=true`'. If an option is specified with this mode, it is | |
| illegal for the value to be provided without the equal sign. Therefore | |
| '`-foo true`' is illegal. To get this behavior, you must use | |
| the {ref}`cl::ValueRequired <cl::ValueRequired>` modifier. | |
| (cl::ValueRequired)= | |
| * The **cl::ValueRequired** modifier (which is the default for all other types | |
| except for {ref}`unnamed alternatives using the generic parser <unnamed alternatives using the generic parser>`) specifies that a | |
| value must be provided. This mode informs the command line library that if an | |
| option is not provides with an equal sign, that the next argument provided | |
| must be the value. This allows things like '`-o a.out`' to work. | |
| (cl::ValueDisallowed)= | |
| * The **cl::ValueDisallowed** modifier (which is the default for {ref}`unnamed alternatives using the generic parser <unnamed alternatives using the generic parser>`) | |
| indicates that it is a runtime error | |
| for the user to specify a value. This can be provided to disallow users from | |
| providing options to boolean options (like '`-foo=true`'). | |
| In general, the default values for this option group work just like you would | |
| want them to. As mentioned above, you can specify the {ref}`cl::ValueDisallowed <cl::ValueDisallowed>` | |
| modifier to a boolean argument to restrict your command line parser. These | |
| options are mostly useful when {ref}`extending the library <extending the library>`. | |
| (formatting option)= | |
| #### Controlling other formatting options | |
| The formatting option group is used to specify that the command line option has | |
| special abilities and is otherwise different from other command line arguments. | |
| As usual, you can only specify one of these arguments at most. | |
| (cl::NormalFormatting)= | |
| * The **cl::NormalFormatting** modifier (which is the default all options) | |
| specifies that this option is "normal". | |
| (cl::Positional)= | |
| * The **cl::Positional** modifier specifies that this is a positional argument | |
| that does not have a command line option associated with it. See the | |
| {ref}`Positional Arguments <Positional Arguments>` section for more information. | |
| * The **cl::ConsumeAfter** modifier specifies that this option is used to | |
| capture "interpreter style" arguments. See {ref}`this section for more information <this section for more information>`. | |
| (prefix)= | |
| (cl::Prefix)= | |
| * The **cl::Prefix** modifier specifies 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. | |
| #### Miscellaneous option modifiers | |
| The miscellaneous option modifiers are the only flags where you can specify more | |
| than one flag from the set: they are not mutually exclusive. These flags | |
| specify boolean properties that modify the option. | |
| (cl::CommaSeparated)= | |
| * The **cl::CommaSeparated** modifier indicates that any commas specified for an | |
| option's value should be used to split the value up into multiple values for | |
| the option. For example, these two options are equivalent when | |
| `cl::CommaSeparated` is specified: "`-foo=a -foo=b -foo=c`" and | |
| "`-foo=a,b,c`". This option only makes sense to be used in a case where the | |
| option is allowed to accept one or more values (i.e. it is a {ref}`cl::list <cl::list>` | |
| option). | |
| (cl::PositionalEatsArgs)= | |
| * The **cl::PositionalEatsArgs** modifier (which only applies to positional | |
| arguments, and only makes sense for lists) indicates that positional argument | |
| should consume any strings after it (including strings that start with a "-") | |
| up until another recognized positional argument. For example, if you have two | |
| "eating" positional arguments, "`pos1`" and "`pos2`", the string "`-pos1 | |
| -foo -bar baz -pos2 -bork`" would cause the "`-foo -bar -baz`" strings to | |
| be applied to the "`-pos1`" option and the "`-bork`" string to be applied | |
| to the "`-pos2`" option. | |
| (response files)= | |
| #### Response files | |
| Some systems, such as certain variants of Microsoft Windows and some older | |
| Unices have a relatively low limit on command-line length. It is therefore | |
| customary to use the so-called 'response files' to circumvent this | |
| restriction. These files are mentioned on the command-line (using the "@file") | |
| syntax. The program reads these files and inserts the contents into argv, | |
| thereby working around the command-line length limits. | |
| ### Top-Level Classes and Functions | |
| Despite all of the built-in flexibility, the CommandLine option library really | |
| only consists of one function {ref}`cl::ParseCommandLineOptions <cl::ParseCommandLineOptions>` and three main | |
| classes: {ref}`cl::opt <cl::opt>`, {ref}`cl::list <cl::list>`, and {ref}`cl::alias <cl::alias>`. This section describes | |
| these three classes in detail. | |
| (cl::getRegisteredOptions)= | |
| #### The `cl::getRegisteredOptions` function | |
| The `cl::getRegisteredOptions` function is designed to give a programmer | |
| access to declared non-positional command line options so that how they appear | |
| in `-help` can be modified prior to calling {ref}`cl::ParseCommandLineOptions <cl::ParseCommandLineOptions>`. | |
| Note this method should not be called during any static initialisation because | |
| it cannot be guaranteed that all options will have been initialised. Hence it | |
| should be called from `main`. | |
| This function can be used to gain access to options declared in libraries that | |
| the tool writer may not have direct access to. | |
| The function retrieves a {ref}`StringMap <dss_stringmap>` that maps the option | |
| string (e.g. `-help`) to an `Option*`. | |
| Here is an example of how the function could be used: | |
| ```cpp | |
| using namespace llvm; | |
| int main(int argc, char **argv) { | |
| cl::OptionCategory AnotherCategory("Some options"); | |
| StringMap<cl::Option*> &Map = cl::getRegisteredOptions(); | |
| //Unhide useful option and put it in a different category | |
| assert(Map.count("print-all-options") > 0); | |
| Map["print-all-options"]->setHiddenFlag(cl::NotHidden); | |
| Map["print-all-options"]->setCategory(AnotherCategory); | |
| //Hide an option we don't want to see | |
| assert(Map.count("enable-no-infs-fp-math") > 0); | |
| Map["enable-no-infs-fp-math"]->setHiddenFlag(cl::Hidden); | |
| //Change --version to --show-version | |
| assert(Map.count("version") > 0); | |
| Map["version"]->setArgStr("show-version"); | |
| //Change --help description | |
| assert(Map.count("help") > 0); | |
| Map["help"]->setDescription("Shows help"); | |
| cl::ParseCommandLineOptions(argc, argv, "This is a small program to demo the LLVM CommandLine API"); | |
| ... | |
| } | |
| ``` | |
| (cl::ParseCommandLineOptions)= | |
| #### The `cl::ParseCommandLineOptions` function | |
| The `cl::ParseCommandLineOptions` function is designed to be called directly | |
| from `main`, and is used to fill in the values of all of the command line | |
| option variables once `argc` and `argv` are available. | |
| The `cl::ParseCommandLineOptions` function requires two parameters (`argc` | |
| and `argv`), but may also take an optional third parameter which holds | |
| {ref}`additional extra text <additional extra text>` to emit when the `-help` option is invoked. | |
| #### The `cl::SetVersionPrinter` function | |
| The `cl::SetVersionPrinter` function is designed to be called directly from | |
| `main` and *before* `cl::ParseCommandLineOptions`. Its use is optional. It | |
| simply arranges for a function to be called in response to the `--version` | |
| option instead of having the `CommandLine` library print out the usual version | |
| string for LLVM. This is useful for programs that are not part of LLVM but wish | |
| to use the `CommandLine` facilities. Such programs should just define a small | |
| function that takes no arguments and returns `void` and that prints out | |
| whatever version information is appropriate for the program. Pass the address of | |
| that function to `cl::SetVersionPrinter` to arrange for it to be called when | |
| the `--version` option is given by the user. | |
| (cl::opt)= | |
| (scalar)= | |
| #### The `cl::opt` class | |
| The `cl::opt` class is the class used to represent scalar command line | |
| 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): | |
| ```cpp | |
| 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 second | |
| template argument is used to specify whether the option should contain the | |
| storage for the option (the default) or whether external storage should be used | |
| to contain the value parsed for the option (see {ref}`Internal vs External Storage <Internal vs External Storage>` | |
| for more information). | |
| The third template argument specifies which parser to use. The default value | |
| selects an instantiation of the `parser` class based on the underlying data | |
| type of the option. In general, this default works well for most applications, | |
| so this option is only used when using a {ref}`custom parser <custom parser>`. | |
| (lists of arguments)= | |
| (cl::list)= | |
| #### The `cl::list` class | |
| The `cl::list` class is the class used to represent a list of command line | |
| options. It too is a templated class which can take up to three arguments: | |
| ```cpp | |
| namespace cl { | |
| template <class DataType, class Storage = bool, | |
| class ParserClass = parser<DataType> > | |
| class list; | |
| } | |
| ``` | |
| This class works the exact same as the {ref}`cl::opt <cl::opt>` class, except that the second | |
| argument is the **type** of the external storage, not a boolean value. For this | |
| class, the marker type '`bool`' is used to indicate that internal storage | |
| should be used. | |
| (cl::alias)= | |
| #### The `cl::alias` class | |
| The `cl::alias` class is a nontemplated class that is used to form aliases for | |
| other arguments. | |
| ```cpp | |
| namespace cl { | |
| class alias; | |
| } | |
| ``` | |
| The {ref}`cl::aliasopt <cl::aliasopt>` attribute should be used to specify which option this is an | |
| alias for. Alias arguments default to being {ref}`cl::Hidden <cl::Hidden>`, and use the aliased | |
| options parser to do the conversion from string to data. | |
| (cl::extrahelp)= | |
| #### 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. | |
| ```cpp | |
| 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: | |
| ```cpp | |
| cl::extrahelp("\nADDITIONAL HELP:\n\n This is the extra help\n"); | |
| ``` | |
| (cl::OptionCategory)= | |
| #### The `cl::OptionCategory` class | |
| The `cl::OptionCategory` class is a simple class for declaring | |
| option categories. | |
| ```cpp | |
| namespace cl { | |
| class OptionCategory; | |
| } | |
| ``` | |
| An option category must have a name and optionally a description which are | |
| passed to the constructor as `const char*`. | |
| Note that declaring an option category and associating it with an option before | |
| parsing options (e.g. statically) will change the output of `-help` from | |
| uncategorized to categorized. If an option category is declared but not | |
| associated with an option then it will be hidden from the output of `-help`. | |
| (different parser)= | |
| (discussed previously)= | |
| ### Builtin parsers | |
| Parsers control how the string value taken from the command line is translated | |
| into a typed value, suitable for use in a C++ program. By default, the | |
| CommandLine library uses an instance of `parser<type>` if the command line | |
| option specifies that it uses values of type '`type`'. Because of this, | |
| custom option processing is specified with specializations of the '`parser`' | |
| class. | |
| The CommandLine library provides the following builtin parser specializations, | |
| which are sufficient for most applications. It can, however, also be extended to | |
| work with new data types and new ways of interpreting the same data. See the | |
| {ref}`Writing a Custom Parser <Writing a Custom Parser>` for more details on this type of library extension. | |
| (enums)= | |
| (cl::parser)= | |
| * The generic `parser<t>` parser can be used to map strings values to any data | |
| type, through the use of the {ref}`cl::values <cl::values>` property, which specifies the | |
| mapping information. The most common use of this parser is for parsing enum | |
| values, which allows you to use the CommandLine library for all of the error | |
| checking to make sure that only valid enum values are specified (as opposed to | |
| accepting arbitrary strings). Despite this, however, the generic parser class | |
| can be used for any data type. | |
| (boolean flags)= | |
| (bool parser)= | |
| * The **parser<bool> specialization** is used to convert boolean strings to a | |
| boolean value. Currently accepted strings are "`true`", "`1`", | |
| "`false`", and "`0`". | |
| * The **parser<boolOrDefault> specialization** is used for cases where the value | |
| is boolean, but we also need to know whether the option was specified at all. | |
| boolOrDefault is an enum with 3 values, BOU_UNSET, BOU_TRUE and BOU_FALSE. | |
| This parser accepts the same strings as **`parser<bool>`**. | |
| (strings)= | |
| * The **parser<string> specialization** simply stores the parsed string into the | |
| string value specified. No conversion or modification of the data is | |
| performed. | |
| (integers)= | |
| (int)= | |
| * The **parser<int> specialization** uses the C `strtol` function to parse the | |
| string input. As such, it will accept a decimal number (with an optional '+' | |
| or '-' prefix) which must start with a non-zero digit. It accepts octal | |
| numbers, which are identified with a '`0`' prefix digit, and hexadecimal | |
| numbers with a prefix of '`0x`' or '`0X`'. | |
| (doubles)= | |
| (float)= | |
| (double)= | |
| * The **parser<double>** and **parser<float> specializations** use the standard | |
| C `strtod` function to convert floating point strings into floating point | |
| values. As such, a broad range of string formats is supported, including | |
| exponential notation (ex: `1.7e15`) and properly supports locales. | |
| (Extension Guide)= | |
| (extending the library)= | |
| ## Extension Guide | |
| Although the CommandLine library has a lot of functionality built into it | |
| already (as discussed previously), one of its true strengths lie in its | |
| extensibility. This section discusses how the CommandLine library works under | |
| the covers and illustrates how to do some simple, common, extensions. | |
| (Custom parsers)= | |
| (custom parser)= | |
| (Writing a Custom Parser)= | |
| ### Writing a custom parser | |
| One of the simplest and most common extensions is the use of a custom parser. | |
| As {ref}`discussed previously <discussed previously>`, parsers are the portion of the CommandLine library | |
| that turns string input from the user into a particular parsed data type, | |
| validating the input in the process. | |
| There are two ways to use a new parser: | |
| 1. Specialize the {ref}`cl::parser <cl::parser>` template for your custom data type. | |
| This approach has the advantage that users of your custom data type will | |
| automatically use your custom parser whenever they define an option with a | |
| value type of your data type. The disadvantage of this approach is that it | |
| doesn't work if your fundamental data type is something that is already | |
| supported. | |
| 1. Write an independent class, using it explicitly from options that need it. | |
| This approach works well in situations where you would line to parse an | |
| option using special syntax for a not-very-special data-type. The drawback | |
| of this approach is that users of your parser have to be aware that they are | |
| using your parser instead of the builtin ones. | |
| To guide the discussion, we will discuss a custom parser that accepts file | |
| sizes, specified with an optional unit after the numeric size. For example, we | |
| would like to parse "102kb", "41M", "1G" into the appropriate integer value. In | |
| this case, the underlying data type we want to parse into is '`unsigned`'. We | |
| choose approach #2 above because we don't want to make this the default for all | |
| `unsigned` options. | |
| To start out, we declare our new `FileSizeParser` class: | |
| ```cpp | |
| struct FileSizeParser : public cl::parser<unsigned> { | |
| // parse - Return true on error. | |
| bool parse(cl::Option &O, StringRef ArgName, const std::string &ArgValue, | |
| unsigned &Val); | |
| }; | |
| ``` | |
| Our new class inherits from the `cl::parser` template class to fill in | |
| the default, boiler plate code for us. We give it the data type that we parse | |
| into, the last argument to the `parse` method, so that clients of our custom | |
| parser know what object type to pass in to the parse method. (Here we declare | |
| that we parse into '`unsigned`' variables.) | |
| For most purposes, the only method that must be implemented in a custom parser | |
| is the `parse` method. The `parse` method is called whenever the option is | |
| invoked, passing in the option itself, the option name, the string to parse, and | |
| a reference to a return value. If the string to parse 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: | |
| ```cpp | |
| bool FileSizeParser::parse(cl::Option &O, StringRef ArgName, | |
| const std::string &Arg, unsigned &Val) { | |
| const char *ArgStart = Arg.c_str(); | |
| char *End; | |
| // Parse integer part, leaving 'End' pointing to the first non-integer char | |
| Val = (unsigned)strtol(ArgStart, &End, 0); | |
| while (1) { | |
| switch (*End++) { | |
| case 0: return false; // No error | |
| case 'i': // Ignore the 'i' in KiB if people use that | |
| case 'b': case 'B': // Ignore B suffix | |
| break; | |
| case 'g': case 'G': Val *= 1024*1024*1024; break; | |
| case 'm': case 'M': Val *= 1024*1024; break; | |
| case 'k': case 'K': Val *= 1024; break; | |
| default: | |
| // Print an error message if unrecognized character! | |
| return O.error("'" + Arg + "' value invalid for file size argument!"); | |
| } | |
| } | |
| } | |
| ``` | |
| 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 example), | |
| it is good enough for this example. Note that we use the option 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: | |
| ```cpp | |
| 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 | |
| MFS: 128974848 | |
| $ ./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" | |
| tutorial. | |
| ### Exploiting external storage | |
| 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/IR/PassManager.cpp` file. | |
| :::{todo} | |
| TODO: complete this section | |
| ::: | |
| (dynamically loaded options)= | |
| ### Dynamically adding command line options | |
| :::{todo} | |
| TODO: fill in this section | |
| ::: | |
| ## Declaring a Library's Options in TableGen | |
| A library can declare its options in a `.td` file instead of as `cl::opt` globals. | |
| `llvm-tblgen -gen-opt-parser-defs` generates a struct with a member per option, the table that parses them, and the hooks through which `cl::ParseCommandLineOptions` parses them and `-help-hidden` lists them. | |
| ```text | |
| include "llvm/Option/LibraryOptions.td" | |
| def FooOptions : OptionsStruct; | |
| defm : BoolField<"enable-foo", "true", "Enable foo">; | |
| defm threshold : ValueField<"foo-threshold", "unsigned", "8", "The threshold">; | |
| defm : ValueField<"foo-path", "StringRef", "\"-\"", "The input path">; | |
| ``` | |
| The struct is in namespace `llvm` unless the def names another, as in `OptionsStruct<"mlir">`. | |
| A member is named after its option, `enable_foo` for `-enable-foo`; a named `defm` such as `defm threshold` names it `threshold`. | |
| `OptionsStruct<prefix = "foo-">` drops that prefix from member names, so `-foo-path` sets `path`. | |
| The `BoolField` is set by `-enable-foo` or `-enable-foo=true|false|1|0`. | |
| A `ValueField`, of an integer type, `float`, `double`, or `StringRef`, is set by `-foo-threshold=8` or `-foo-threshold 8`. | |
| A `ListField<"foo-ids", "unsigned", ...>` is an `ArrayRef<unsigned>`, replacing a `cl::list` with `cl::CommaSeparated`: each `-foo-ids=1,2` or `-foo-ids 1,2` appends its values. | |
| A reader applies a `cl::list_init` default to an empty list, since a given option never leaves it empty. | |
| An `OptionalBoolField` is a `BoolOrDefault` that stays `Default` unless the option is given, replacing `cl::boolOrDefault`; read it with `valueOr(X, Default)`. | |
| An `EnumField` maps each of its comma-separated values to an enumerator, replacing `cl::values`: `defm : EnumField<"foo-mode", "FooMode", "FooMode::Fast", "fast,safe", ["FooMode::Fast", "FooMode::Safe"], "The mode">;` accepts `-foo-mode=fast` and `-foo-mode=safe`. | |
| An `EnumListField` is a `ListField` whose values map to enumerators as in an `EnumField`. | |
| A `FlagOrEnumField` takes one more argument, the enumerator the bare option selects, replacing `cl::ValueOptional`: with `"FooMode::Fast"`, `-foo-mode` sets `FooMode::Fast`, and `-foo-mode safe` does not consume `safe`. | |
| A `DefaultOnOffField` is a `BoolOrDefault` set by `=Default`, `=Enable`, or `=Disable`. | |
| Both accept `--` for `-`. | |
| Only `-help-hidden` lists the options, like `cl::Hidden`. | |
| A default is the member's C++ initializer, so `"\"-\""` initializes `foo_path` to `"-"`. | |
| An `OptionalValueField` or `OptionalEnumField` takes no default; its `std::optional` member stays `std::nullopt` unless the option is given, replacing `getNumOccurrences()`. | |
| The header declares the struct after including what the member defaults need, and one source file defines it and registers it with `cl::`. | |
| The library then lists `FooOptionsTableGen` under `DEPENDS` and `Option` under `LINK_COMPONENTS`. | |
| A library that otherwise needs only `llvm-min-tblgen` sets `LLVM_TABLEGEN_PROJECT` to `LLVM_HEADERS` before its `tablegen()` call, so that its sources need not wait for `llvm-tblgen`. | |
| Code reads `FooOptions::Global.enable_foo`, the instance the command line sets. | |
| Keep the header in `lib/`, as private as the `static cl::opt` it replaces; another library that needs a value calls a function or takes a parameter. |