optparse

Table of Contents


Introduction

Parsing command-line options with optparse begins with defining the options the program can accept. This starts with creating an instance of the OptionParser class, whose constructor is defined like this:

OptionParser(char[] desc="")

The desc parameter should be a short description of your program. It is used by the built-in help features, described later. OptionParser has a number of methods, the most important of which is addOption. The addOption method has a large number of overloads, representing the large number of kinds of options that optparse supports. Before going over these overloads, it is necessary to go over some of optparse's concepts.

First, this documentation makes the distinction between an option and an argument. An option is a literal string supplied by client code, such as "-f" or "--file". An argument is supplied by the end-user on the command-line. Some options accept arguments. If the user supplies "myapp --file=somefile.txt" to your program, then "--file" is an option, and "somefile.txt" is an argument to it. Arguments not associated with any particular option are called leftover arguments.

Options of the form "-f" are called short options. They start with a dash and are followed by any single non-dash character. Options of the form "--file" are called long options. They start with two dashes and may be of any length, and contain any characters, so long as they don't start with a third dash.

Every option has an action associated with it. The actions supported by optparse are:

The meaning of these actions will be discussed later. (Users of Python's optparse will probably find them familiar.) Certain actions accept arguments, and others do not. If an option's action accepts an argument, then that option also has a type. Types are represented by the ArgType enumerated type. Currently, the only types supported by optparse are ArgType.String and ArgType.Integer, which represent the D types char[] and int, respectively.

Options also have a name, which is used in a number of contexts. The name defaults to the first long option specified, without the dashes. If no long options are specified, it uses the first short option. An option's name is mainly used when retrieving its results, after parsing the arguments. Occasionally, it is useful to give multiple options the same name. Examples of this are given later.

For completeness' sake, here are all of the overloads of addOption:

As I describe each action, I will also list the relevant addOption overloads to that action. Not all of these apply to all of the actions.

A very simple use of optparse looks like this:

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption("-o", "--option");
    auto options = parser.parse(args);
}

Once the command-line has been parsed, the results are stored in an instance of the Options class. How you retrieve the results depends on the action.


Actions

Actions in optparse are represented by the Action enumerated type. Each of the following is a member of this enum.

Action.Store

This is the default action. An option with the Store action accepts an argument, and stores it. If the option is specified multiple times, then the last one is the one captured.

Methods

Results

Retrieving the results of Store differs based on the option's type. Store's default type is String.

To retrieve a string argument, simply index the Options object with the option's name:

char[] filename = options["file"];

To retrieve an integer argument, pass the option's name to the value method of Options:

int num = options.value("number");

If the option was not provided on the command line, and no default was supplied with def, opIndex will return the empty string, and value will return 0.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption("-f", "--file");
    parser.addOption(["-n", "--number"], ArgType.Integer);
    auto options = parser.parse(args);
    writefln("file: %s", options["file"]);
    writefln("number: %s", options.value("number"));
}

This produces the following on the command-line:

$ myapp --file foo.txt -n28
file: foo.txt
number: 28
$ myapp
file: 
number: 0

Action.Append

Append behaves much like Store. Instead of simply storing its arguments, however, it appends them to a list.

Methods

Results

Also as with Store, Append's default type is String. If the type of the option is string, pass its name to the list method of Options:

char[][] imports = options.list("import");

If the type is Integer, use the valueList method:

int[] values = options.valueList("value");

If the option is not provided on the command line, and no default was provided with def, these will both return an empty array.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(["-I", "--import"], Action.Append);
    parser.addOption(["-V", "--value"], Action.Append, ArgType.Integer);
    auto options = parser.parse(args);
    writefln("imports: %s", options.list("import"));
    writefln("values: %s", options.valueList("value"));
}

This produces the following on the command-line:

$ myapp -Isome/path -Ianother/path -V20 --value=30
imports: [some/path,another/path]
values: [20,30]
$ myapp
imports: []
values: []

Action.StoreConst

When an option with the StoreConst action is found, it stores some constant value provided by the client code. This is one way to implement a simple flag.

It is worth pointing out that you can have two different StoreConst options with the same name, but different constant values. This is one way of implementing a pair of "--enable" and "--disable" flags. (Even better would be using the SetTrue and SetFalse actions.)

Methods

Results

Accessing the results of a StoreConst option is exactly like accessing those of a Store action with a String type. (Using opIndex.) If the option was specified, the constant value will be returned. If it wasn't, and no default was provided with def, it will return an empty string.

At this time, only strings are supported as constant values.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(["--enable"], "flag", Action.StoreConst, "on");
    parser.addOption(["--disable"], "flag", Action.StoreConst, "off");
    auto options = parser.parse(args);
    writefln("flag: %s", options["flag"]);
}

This produces the following on the command-line:

$ myapp --enable
flag: on
$ myapp --disable
flag: off
$ myapp
flag: 

Action.AppendConst

Similar to StoreConst, this will append the supplied constant to a list whenever the option is found on the command-line.

Methods

Results

Accessing the results of AppendConst works just like accessing those of an Append action with the String type, using the list method.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(["--blue"], "color", Action.AppendConst, "blue");
    parser.addOption(["--green"], "color", Action.AppendConst, "green");
    auto options = parser.parse(args);
    writefln("colors: %s", options.list("color"));
}

This produces the following on the command-line:

$ myapp --blue --green --blue
colors: [blue,green,blue]
$ myapp
colors: []

Action.SetTrue and Action.SetFalse

Flag options may be implemented with these actions. The SetTrue action will set a flag to true, and SetFalse will set it to false.

Methods

Results

The flag is retrieved using the flag method of the Options class.

bool flag = options.flag("flag");

If the flag was not specified, and no default was provided with def, it defaults to false.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(["--enable"], "flag", Action.SetTrue);
    parser.addOption(["--disable"], "flag", Action.SetFalse);
    auto options = parser.parse(args);
    writefln("flag: %s", options.flag("flag"));
}

This produces the following on the command-line:

$ myapp --enable
flag: true
$ myapp --enable --disable
flag: false
$ myapp
flag: false

Action.Count

The Count action simply counts the number of times the option occurs on the command-line.

Methods

Results

The count may be retrieved from the count method of Options.

int c = options.count("verbosity");

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(["-v", "--verbose"], "verbosity", Action.Count);
    auto options = parser.parse(args);
    writefln("verbosity: %s", options.count("verbosity"));
}

This produces the following on the command-line:

$ myapp -vvv
verbosity: 3
$ myapp -v --verbose
verbosity: 2
$ myapp
verbosity: 0

Action.Callback

Sometimes, the above actions aren't enough. To extend optparse, users may provide a callback as an option's action. A callback option may accept an argument. Whether it accepts an argument is determined by the type of the callback.

Important note: A callback is called as soon as it is encountered in the argument list. This means that optparse may still exit with an error if it finds malformed or invalid options on the command line, after the callback is run. For this reason, users should not place actual program logic inside of callbacks, and should only use them to store option data for later use.

Methods

Results

The results of a callback option are not stored anywhere by optparse. It is assumed the user will keep any information about the callback themselves.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(["--callback"], {
        writefln("Callback encountered!");
    });
    auto options = parser.parse(args);
    writefln("Done.");
}

This produces the following on the command-line:

$ myapp --callback
Callback encountered!
Done.
$ myapp
Done.

Action.CallbackFancy

If client code wants to handle the parsing process at a lower level, optparse provides these advanced callbacks.

The first four arguments to these callbacks have the following types and meanings:

Options
The current results of parsing the command-line, up to when the callback was encountered.
inout char[][]
The args array. This is mostly identical to the array originally passed to parse, with the following differences:
  1. The first element, with the executable name, has been removed.
  2. Options of the form "--option=argument" preceeding (or including) this option have been parsed apart into two elements, as in [--option,argument]. Elements of the array after the current option have not been touched, yet.
It is useful to note that this argument is declared inout, meaning callbacks are free to modify the array.
inout int
The index in the args array of this option; or, if this option accepts an argument, of the option's argument. Note that this is declared inout. When the callback returns, parsing will resume with the element of args following this int. If this argument is advanced beyond the end of the args array, parsing will quietly terminate.
char[]
The name of this option.

The fifth argument to the callback, if it exists, controls the type of the argument to the option.

Methods

Results

As with regular callbacks, optparse does not store the results of advanced callbacks.

Example

void main(char[][] args) {
    auto parser = new OptionParser();
    parser.addOption(
        ["--adv-callback"],
        (Options o, inout char[][] a, inout int i, char[] name) {
            // Skip the next argument, whatever it is.
            ++i;
        }
    );
    parser.addOption(["-c"], Action.Count);
    auto options = parser.parse(args);
    writefln("count: %s", options.count("c"));
}

This produces the following on the command-line:

$ myapp -c --adv-callback -cc
count: 1

Action.Help

The Help action prints out a listing of the options in the parser.

The listing begins with a header like the following:

Usage: myapp [options] args...
A short description of myapp.

Options:

This header is customizable in two ways:

Additionally, the name of the application is derived directly from the first element of the args array.

Options are printed in the following form. Given these options:

parser.addOption("-f", "--file").help("The file to operate on.")
parser.addOption(["--enable"], Action.SetTrue).help("Enables the option.")

Help produces the following:

  -f, --file=FILE The file to operate on.
  --enable        Enables the option.

The help method of the Option class provides the description used in the listing. Notice also the "=FILE" in the first option above. This indicates that the option accepts an argument. If you wanted to have this say "=FILENAME" instead, you would instead define the --file option as:

parser.addOption("-f", "--file").help("The file to operate on.").argName("filename");

The argName method of Option class defines this string, which otherwise defaults to the option's name. Note that it always converts the argument's name to all-caps.

Methods

Results

Help terminates the program when found.

Example

Bringing it all together, we get this:

void main(char[][] args) {
    auto parser = new OptionParser("Testing the Help action.");
    parser.argdesc = "[options]";
    parser.addOption("-f", "--file").help("Defines the file to use.").argName("filename");
    parser.addOption(["-n", "--number"], ArgType.Integer).help("Specifies the number.");
    parser.addOption(["--blue"], "color", Action.AppendConst, "blue").help("Adds the color blue.");
    parser.addOption(["--green"], "color", Action.AppendConst, "green").help("Adds the color green.");
    parser.addOption(["--help"], Action.Help).help("Displays this help message.");
    auto options = parser.parse(args);
    writefln("Done.");
}

This produces the following on the command-line:

$ myapp --help
Usage: myapp [options]
Testing the Help action.

Options:
  -f, --file=FILENAME Defines the file to use.
  -n, --number=NUMBER Specifies the number.
  --blue              Adds the color blue.
  --green             Adds the color green.
  --help              Displays this help message.
$ myapp
Done.

API Reference

Miscellaneous

class OptionError : Exception;

This exception is thrown by OptionParser when client code attempts to set up a malformed option.

enum Action { Store, StoreConst, Append, AppendConst, Count, SetTrue, SetFalse, Callback, CallbackFancy, Help }

enum ArgType { None, String, Integer }

The following delegate types define all the possible callback types used by optparse:

alias void delegate(Options, inout char[][], inout int, char[], char[]) OptionCallbackFancyArg;
alias void delegate(Options, inout char[][], inout int, char[], int) OptionCallbackFancyInt;
alias void delegate(Options, inout char[][], inout int, char[]) OptionCallbackFancy;

alias void delegate(char[]) OptionCallbackArg;
alias void delegate(int) OptionCallbackInt;
alias void delegate() OptionCallback;

OptionParser

Refer to the rest of this document for the meanings of parse and addOption.

class OptionParser {
    Option[] options;
    char[] argdesc;
    this(char[] desc="");
    void setErrorCallback(void delegate(char[]) dg);
    void error(char[] err);
    void helpText();
    Options parse(char[][] args);
    void leftoverCallback(OptionCallbackArg dg);
    Option addOption(Option option);
    Option addOption(char[][] options ...);
    Option addOption(char[][] options, char[] name);
    Option addOption(char[][] options, Action action);
    Option addOption(char[][] options, ArgType type);
    Option addOption(char[][] options, Action action, ArgType type);
    Option addOption(char[][] options, char[] name, Action action);
    Option addOption(char[][] options, char[] name, Action action, ArgType type);
    Option addOption(char[][] options, Action action, char[] const_value);
    Option addOption(char[][] options, char[] name, char[] const_value);
    Option addOption(char[][] options, char[] name, Action action, char[] const_value);
    Option addOption(char[][] options, OptionCallback dg);
    Option addOption(char[][] options, OptionCallbackArg dg);
    Option addOption(char[][] options, OptionCallbackInt dg);
    Option addOption(char[][] options, OptionCallbackFancy dg);
    Option addOption(char[][] options, OptionCallbackFancyArg dg);
    Option addOption(char[][] options, OptionCallbackFancyInt dg);
    Option addOption(char[][] options, char[] name, OptionCallbackFancy dg);
    Option addOption(char[][] options, char[] name, OptionCallbackFancyArg dg);
    Option addOption(char[][] options, char[] name, OptionCallbackFancyInt dg);
}
void leftoverCallback(OptionCallbackArg dg);
Normally, leftover arguments are simply added to an array in the Options object. By calling this, client code may get these arguments sent to this callback, instead.
void error(char[] err);
When parse is unable to parse the arguments passed to it, this function is called. By default, it calls helpText, prints out the error message, and then terminates the program with a failure state.
void setErrorCallback(void delegate(char[]) dg);
When client code supplies a delegate to this function, the behavior of error changes. Instead of calling helpText and printing out its error message, it calls the passed delegate with it, and then terminates the program with a failure state.
void helpText();
This function is used by the Help action. It prints out a nice listing of all the options known by the OptionParser.
char[] argdesc;
When helpText is called, it prints a message before the list of options in the following form:
Usage: myapp [options] args...
The "[options] args..." part of this message is contained in argdesc, and may be overidden by client code. (The "myapp" part of the message is automatically derived from the first element of the args array.)
Option[] options;
This array holds all of the instances of Option known by the parser.

Option

Each option defined by the client code is represented by an instance of this class. Client code does not typically interact with or instantiate this class directly, although the help and argName methods are needed when using the Help action.

class Option {
    Option help(char[] helpstr);
    Option argName(char[] argname);
    bool hasArg();
    char[] toString();
}
Option help(char[] helpstr);
The string passed to this method will be printed next to the option when the Help action is called. The easiest way to use this method is directly off of a call to addOption, as in:
parser.addOption("--someopt").help("Does something.");
Option argName(char[] argname);
When an option accepts an argument, the Help action will indicate this by putting something informative after the option. By default, it uses the all-caps form of the option's name. You can supply a different string to this method, which will be converted to all-caps.
Option def(char[] val);
Option def(int val);
Option def(bool val);
Supplies the default value for an option. This only applies to the following actions: Store, Append, StoreConst, AppendConst, SetTrue, and SetFalse. In the case of the two "append" actions, supplying a default will result in a single-element array with the default in it, in the event that the option is never specified on the command-line. If multiple options have the same name, only the first default supplied is used. An exception will be raised if (for example) an integer default value is provided to an option which expects a string argument.
bool hasArg();
Returns whether this option accepts an argument.
char[] toString();
Returns a string with all of the forms of the option, short and long, seperated by commas, and possibly ending with an indication of whether the option accepts an argument. (See also: argName.)

Options

When a command-line gets parsed by optparse, parse returns an instance of this class. All of the parsing results are stored here.

class Options {
    char[] opIndex(char[] name);
    int value(char[] name);
    char[][] list(char[] name);
    int[] valueList(char[] name);
    int count(char[] name);
    bool flag(char[] name);
    char[][] args;
}
char[] opIndex(char[] name);
The results of the Store and StoreConst actions may be retrieved from here. (Store only when the type is String.)
int value(char[] name);
The results of the Store action may be retrieved here when the type is Integer.
char[][] list(char[] name);
The results of the Append and AppendConst actions may be retrieved from here. (Append only when the type is String.)
int[] valueList(char[] name);
The results of the Append action may be retrieved from here when its type is Integer.
int count(char[] name);
The results of the Count action may be retrieved from here.
bool flag(char[] name);
The results of the SetTrue and SetFalse actions may be retrieved from here.
char[][] args;
By default, leftover args are simply added to this array when they are encountered. (See also the leftoverCallback method of OptionParser, however.)