NDesk.Options : NDesk.Options Namespace

NDesk.Options

GIT Repository

OptionSet Class

A class to parse program options.

public class OptionSet : System.Collections.ObjectModel.KeyedCollection<string, Option>

Thread Safety

All public static members of this type are safe for multithreaded operations. The OptionSet.Parse(IEnumerable<string>) instance method is thread-safe if no concurrent modifying methods are invoked (OptionSet.Add(Option), System.Collections.ObjectModel.Collection<Option>.Remove(``0), etc.).

Remarks

A common requirement for command-line programs is option parsing. The command line consists of a sequence of arguments. OptionSet.Parse(IEnumerable<string>) parses this argument sequence, invoking actions of registered NDesk.Options.Options when a sequence of arguments matching the NDesk.Options.Options requirements are encountered. NDesk.Options.Option's are registered with OptionSet.Add(Option) and its overloads.

OptionSet.Parse(IEnumerable<string>), returns a List<string> of all arguments which were not matched by a registered NDesk.Options.Option.

Three conditions must be met for a sequence of arguments to be considered as a match for an NDesk.Options.Option:

There are three types of NDesk.Options.Options that can be parsed:

  1. Boolean options, which correspond to a Option.OptionValueType value of OptionValueType.None. When a matching argument is encountered, their registered action is invoked immediately. The Action`1 value will be non-default(T) if the value is true, e.g. if -option or -option+ is specified, and the value will be default(T) if the value is false, e.g. if -option- is specified.
  2. Optional value options, which correspond to a Option.OptionValueType value of OptionValueType.Optional. Optional value options are not "greedy"; they will only get their value only from the current argument. If the value is not present, default(T) is provided to their corresponding Action`1.

    Thus, -opt:value would pass value to the action registered for opt, while -opt value would pass default(T) to the action registered for opt and value would be an unparsed argument.

  3. Required value options, which correspond to a Option.OptionValueType value of OptionValueType.Required. Required value options are "greedy" -- if the value is not found within the current argument, the following argument(s) will be used to supply the value(s). Once enough values have been parsed, their corresponding Action`1 is invoked.

    Thus, both -opt:value and -opt value would pass value to the action registered for opt.

    If no value can be found, an NDesk.Options.OptionException is thrown from OptionSet.Parse(IEnumerable<string>).

Operation

Use of OptionSet is split up into two parts:

  1. Initialization.
  2. Parsing.

During the initialization phase, new NDesk.Options.Option instances are created and associated with an action to perform when the Option requirements are met (e.g. when a required value has been encountered). This phase is not thread safe. All options added during this phase are considered to have been registered.

C# Example
OptionSet p = new OptionSet () {
  { "option-a", v => { /* action to perform */ } },
};

There are three ways to add NDesk.Options.Options to the NDesk.Options.OptionSet:

  1. With C# collection initializers, as used above.
  2. Explicitly by calling OptionSet.Add(string, Action<string>) and the other Add overloads.
  3. By creating a new subclass of NDesk.Options.Option and adding it via OptionSet.Add(Option). This is not recommended, but is available if you require more direct option handling than the default NDesk.Options.Option implementation provides.

During the parsing phase, an IEnumerable<string> is enumerated, looking for arguments which match a registered option, and invoking the corresponding action when an option and associated (optional) value is encountered. During this phase, the NDesk.Options.OptionSet instance itself is thread safe, but full thread safety depends upon thread-safety of the registered actions. Any option-like strings for names that haven't been registered, e.g. --this-was-never-registered=false, and all arguments that are not used as option values are returned from OptionSet.Parse(IEnumerable<string>) or processed by the default handler <>, if registered.

C# Example
List<string> extra = p.Parse (new string[]{"-option-a"});
Note to Inheritors

Subclasses can override the following virtual methods to customize option parsing behavior:

Example

The following example demonstrates some simple usage of NDesk.Options.OptionSet.

C# Example
using System;
using System.Collections.Generic;
using NDesk.Options;

class Test {
	static int verbosity;

	public static void Main (string[] args)
	{
		bool show_help = false;
		List<string> names = new List<string> ();
		int repeat = 1;

		var p = new OptionSet () {
			{ "n|name=", "the {NAME} of someone to greet.",
			  v => names.Add (v) },
			{ "r|repeat=", 
				"the number of {TIMES} to repeat the greeting.\n" + 
					"this must be an integer.",
			  (int v) => repeat = v },
			{ "v", "increase debug message verbosity",
			  v => { if (v != null) ++verbosity; } },
			{ "h|help",  "show this message and exit", 
			  v => show_help = v != null },
		};

		List<string> extra;
		try {
			extra = p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("greet: ");
			Console.WriteLine (e.Message);
			Console.WriteLine ("Try `greet --help' for more information.");
			return;
		}

		if (show_help) {
			ShowHelp (p);
			return;
		}

		string message;
		if (extra.Count > 0) {
			message = string.Join (" ", extra.ToArray ());
			Debug ("Using new message: {0}", message);
		}
		else {
			message = "Hello {0}!";
			Debug ("Using default message: {0}", message);
		}

		foreach (string name in names) {
			for (int i = 0; i < repeat; ++i)
				Console.WriteLine (message, name);
		}
	}

	static void ShowHelp (OptionSet p)
	{
		Console.WriteLine ("Usage: greet [OPTIONS]+ message");
		Console.WriteLine ("Greet a list of individuals with an optional message.");
		Console.WriteLine ("If no message is specified, a generic greeting is used.");
		Console.WriteLine ();
		Console.WriteLine ("Options:");
		p.WriteOptionDescriptions (Console.Out);
	}

	static void Debug (string format, params object[] args)
	{
		if (verbosity > 0) {
			Console.Write ("# ");
			Console.WriteLine (format, args);
		}
	}
}

The output (under the influence of different command-line arguments) is:

sh Example
$ mono greet.exe --help
Usage: greet [OPTIONS]+ message
Greet a list of individuals with an optional message.
If no message is specified, a generic greeting is used.

Options:
  -n, --name=NAME            the NAME of someone to greet.
  -r, --repeat=TIMES         the number of TIMES to repeat the greeting.
                               this must be an integer.
  -v                         increase debug message verbosity
  -h, --help                 show this message and exit

$ mono greet.exe -v- -n A -name=B --name=C /name D -nE
Hello A!
Hello B!
Hello C!
Hello D!
Hello E!

$ mono greet.exe -v -n E custom greeting for: {0}
# Using new message: custom greeting for: {0}
custom greeting for: E

$ mono greet.exe -r 3 -n A
Hello A!
Hello A!
Hello A!

$ mono greet.exe -r not-an-int
greet: Could not convert string `not-an-int' to type Int32 for option `-r'.
Try `greet --help' for more information.

Notice how the output produced by --help uses the descriptions provided during OptionSet initialization. Notice that the NDesk.Options.Option requiring a value (n|name=) can use multiple different forms of invocation, including: -n value, -n=value, -name value, -name=value, --name value, --name=value, /name value, and /name=value.

Notice also that the boolean v option can take three separate forms: -v and -v+, which both enable the option, and -v-, which disables the option. (The second greet invocation uses -v-, which is why no debug messages are shown.)

Finally, note that the action can specify a type to use. If no type is provided, the action parameter will be a string. If a type is provided, then System.ComponentModel.TypeConverter will be used to convert a string to the specified type.

Example

The following example shows how options and values can be bundled together.

C# Example
using System;
using System.Linq;
using System.Collections.Generic;
using NDesk.Options;

class Test {
	public static void Main (string[] args)
	{
		var show_help = false;
		var macros = new Dictionary<string, string>();
		bool create = false, extract = false, list = false;
		string output = null, input = null;
		string color  = null;

		var p = new OptionSet () {
			// gcc-like options
			{ "D:", "Predefine a macro with an (optional) value.",
				(m, v) => {
					if (m == null)
						throw new OptionException ("Missing macro name for option -D.", 
								"-D");
					macros.Add (m, v);
				} },
			{ "d={-->}{=>}", "Alternate macro syntax.", 
				(m, v) => macros.Add (m, v) },
			{ "o=", "Specify the output file", v => output = v },

			// tar-like options
			{ "f=", "The input file",   v => input = v },
			{ "x",  "Extract the file", v => extract = v != null },
			{ "c",  "Create the file",  v => create = v != null },
			{ "t",  "List the file",    v => list = v != null },

			// ls-like optional values
			{ "color:", "control whether and when color is used", 
				v => color = v },

			// other...
			{ "h|help",  "show this message and exit", 
			  v => show_help = v != null },
			// default
			{ "<>",
				v => Console.WriteLine ("def handler: color={0}; arg={1}", color, v)},
		};

		try {
			p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("bundling: ");
			Console.WriteLine (e.Message);
			Console.WriteLine ("Try `greet --help' for more information.");
			return;
		}

		if (show_help) {
			ShowHelp (p);
			return;
		}

		Console.WriteLine ("Macros:");
		foreach (var m in (from k in macros.Keys orderby k select k)) {
			Console.WriteLine ("\t{0}={1}", m, macros [m] ?? "<null>");
		}
		Console.WriteLine ("Options:");
		Console.WriteLine ("\t Input File: {0}", input);
		Console.WriteLine ("\tOuptut File: {0}", output);
		Console.WriteLine ("\t     Create: {0}", create);
		Console.WriteLine ("\t    Extract: {0}", extract);
		Console.WriteLine ("\t       List: {0}", list);
		Console.WriteLine ("\t      Color: {0}", color ?? "<null>");
	}

	static void ShowHelp (OptionSet p)
	{
		Console.WriteLine ("Usage: bundling [OPTIONS]+");
		Console.WriteLine ("Demo program to show the effects of bundling options and their values");
		Console.WriteLine ();
		Console.WriteLine ("Options:");
		p.WriteOptionDescriptions (Console.Out);
	}
}

The output (under the influence of different command-line arguments) is:

sh Example
$ mono bundling.exe --help
Usage: bundling [OPTIONS]+
Demo program to show the effects of bundling options and their values

Options:
  -D[=VALUE1:VALUE2]         Predefine a macro with an (optional) value.
  -d=VALUE1-->VALUE2         Alternate macro syntax.
  -o=VALUE                   Specify the output file
  -f=VALUE                   The input file
  -x                         Extract the file
  -c                         Create the file
  -t                         List the file
      --color[=VALUE]        control whether and when color is used
  -h, --help                 show this message and exit

$ mono bundling.exe -D
bundling: Missing macro name for option -D.
Try `greet --help' for more information.

$ mono bundling.exe -DA -DB=C "-dD-->E" "-dF=>G" -d "H=>I" -cf input --color -ooutput
Macros:
	A=<null>
	B=C
	D=E
	F=G
	H=I
Options:
	 Input File: input
	Ouptut File: output
	     Create: True
	    Extract: False
	       List: False
	      Color: <null>

$ mono bundling.exe -cfv input
def handler: color=; arg=input
Macros:
Options:
	 Input File: v
	Ouptut File: 
	     Create: True
	    Extract: False
	       List: False
	      Color: <null>

$ mono bundling.exe -xctf input
Macros:
Options:
	 Input File: input
	Ouptut File: 
	     Create: True
	    Extract: True
	       List: True
	      Color: <null>

$ mono bundling.exe --color=auto -o output -finput
Macros:
Options:
	 Input File: input
	Ouptut File: output
	     Create: False
	    Extract: False
	       List: False
	      Color: auto

$ mono bundling.exe --color=on A B --color=off C D
def handler: color=on; arg=A
def handler: color=on; arg=B
def handler: color=off; arg=C
def handler: color=off; arg=D
Macros:
Options:
	 Input File: 
	Ouptut File: 
	     Create: False
	    Extract: False
	       List: False
	      Color: off

Example

The following example shows a custom OptionSet subclass with the following additional functionality:

  1. Option name lookup is done in a case insensitive fashion, so --name and --NAME are identical.
  2. Option-like strings cannot be used as values to options, so --name --repeat is an error.
  3. A key/value parser is provided, to show the use of custom NDesk.Options.OptionContext and NDesk.Options.Option subclasses.
C# Example
// Case-Insensitive and Concatenating OptionSet
using System;
using System.Collections.Generic;
using NDesk.Options;

class DemoOptionSet : OptionSet {
	protected override void InsertItem (int index, Option item)
	{
		if (item.Prototype.ToLower () != item.Prototype)
			throw new ArgumentException ("prototypes must be lower-case!");
		base.InsertItem (index, item);
	}

	protected override OptionContext CreateOptionContext ()
	{
		return new OptionContext (this);
	}

	protected override bool Parse (string option, OptionContext c)
	{
		string f, n, s, v;
		bool haveParts = GetOptionParts (option, out f, out n, out s, out v);
		Option nextOption = null;
		string newOption  = option;

		if (haveParts) {
			string nl = n.ToLower ();
			nextOption = Contains (nl) ? this [nl] : null;
			newOption = f + n.ToLower () + (v != null ? s + v : "");
		}

		if (c.Option != null) {
			// Prevent --a --b
			if (c.Option != null && haveParts) {
				if (nextOption == null) {
					// ignore
				}
				else 
					throw new OptionException (
						string.Format ("Found option `{0}' as value for option `{1}'.",
							option, c.OptionName), c.OptionName);
			}

			// have a option w/ required value; try to concat values.
			if (AppendValue (option, c)) {
				if (!option.EndsWith ("\\") && 
						c.Option.MaxValueCount == c.OptionValues.Count) {
					c.Option.Invoke (c);
				}
				return true;
			}
			else
				base.Parse (newOption, c);
		}

		if (!haveParts || v == null) {
			// Not an option; let base handle as a non-option argument.
			return base.Parse (newOption, c);
		}

		if (nextOption.OptionValueType != OptionValueType.None && 
				v.EndsWith ("\\")) {
			c.Option = nextOption;
			c.OptionValues.Add (v);
			c.OptionName = f + n;
			return true;
		}

		return base.Parse (newOption, c);
	}

	private bool AppendValue (string value, OptionContext c)
	{
		bool added = false;
		string[] seps = c.Option.GetValueSeparators ();
		foreach (var o in seps.Length != 0
				? value.Split (seps, StringSplitOptions.None)
				: new string[]{value}) {
			int idx = c.OptionValues.Count-1;
			if (idx == -1 || !c.OptionValues [idx].EndsWith ("\\")) {
				c.OptionValues.Add (o);
				added = true;
			}
			else {
				c.OptionValues [idx] += value;
				added = true;
			}
		}
		return added;
	}
}

class Demo {
	public static void Main (string[] args)
	{
		List<string> names = new List<string> ();
		Dictionary<string,string> map = new Dictionary<string,string> ();
		int repeat = 1;

		OptionSet p = new DemoOptionSet () {
			{ "n|name=",    v => names.Add (v) },
			{ "r|repeat:",  (int v) => repeat = v },
			{ "m|map=",     (k,v) => map.Add (k, v) },
		};

		List<string> extra;
		try {
			extra = p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("subclass: ");
			Console.WriteLine (e.Message);
			return;
		}

		string message;
		if (extra.Count > 0) {
			message = string.Join (" ", extra.ToArray ());
		}
		else {
			message = "Hello {0}!";
		}

		foreach (string name in names) {
			for (int i = 0; i < repeat; ++i)
				Console.WriteLine (message, name);
		}
		List<string> keys = new List<string>(map.Keys);
		keys.Sort ();
		foreach (string key in keys) {
			Console.WriteLine ("Key: {0}={1}", key, map [key]);
		}
	}
}

The output (under the influence of different command-line arguments) is:

sh Example
$ mono subclass.exe -n A -Name=B --NAME=C /nAMe D
Hello A!
Hello B!
Hello C!
Hello D!

$ mono subclass.exe --Repeat -name A

$ mono subclass.exe -Name --Repeat 3
subclass: Found option `--Repeat' as value for option `-name'.

$ mono subclass.exe --Map a b -mAp c=d /maP=e=f
Key: a=b
Key: c=d
Key: e=f

$ mono subclass.exe --map 'a\' 'b\' c 'd\' 'e\' f
Key: a\b\c=d\e\f

Notice:

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Members

See Also: Inherited members from System.Collections.ObjectModel.KeyedCollection<string, Option>.

Public Constructors

Creates and initializes a new NDesk.Options.OptionSet class instance.
Creates and initializes a new NDesk.Options.OptionSet class instance.

Public Properties

[read-only]
MessageLocalizer Converter<string, string> . Permits access to the message localization facility.

Public Methods

Add (Option) : OptionSet
Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(IEnumerable<string>).
Add (string, OptionAction<string, string>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add (string, Action<string>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add (string, string, OptionAction<string, string>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add (string, string, Action<string>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add<T> (string, Action<T>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add<T> (string, string, Action<T>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add<TKey,TValue> (string, OptionAction<TKey, TValue>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Add<TKey,TValue> (string, string, OptionAction<TKey, TValue>) : OptionSet
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
Parse (IEnumerable<string>) : List<string>
Parses each string within arguments, invoking any registered actions if a registered option is encountered.
WriteOptionDescriptions (System.IO.TextWriter)
Writes NDesk.Options.Option documentation to o.

Protected Methods

CreateOptionContext () : OptionContext
Creates an NDesk.Options.OptionContext instance.
override
GetKeyForItem (Option) : string
Returns item.GetNames()[0].
GetOptionForName (string) : Option
Looks up the NDesk.Options.Option registered to handle the option name option.
GetOptionParts (string, out string, out string, out string, out string) : bool
Splits argument into its constituent parts.
override
InsertItem (int, Option)
Inserts item at the specified index.
Parse (string, OptionContext) : bool
Parses argument and invokes Option.Invoke(OptionContext) if appropriate.
override
RemoveItem (int)
Removes the NDesk.Options.Option at the specified index.
override
SetItem (int, Option)
Removes the current NDesk.Options.Option at index and sets item as the value for the index value.

Member Details

OptionSet Constructor

Creates and initializes a new NDesk.Options.OptionSet class instance.

public OptionSet ()

See Also

OptionSet(Converter<string, string>)

Remarks

This constructor causes the created NDesk.Options.OptionSet instance to perform no translation of string messages; consequently, no localization is performed.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

OptionSet Constructor

Creates and initializes a new NDesk.Options.OptionSet class instance.

public OptionSet (Converter<string, string> localizer)

Parameters

localizer
A Converter<string, string> instance that will be used to translate strings.

Remarks

This constructor initializes the OptionSet.MessageLocalizer property of the new instance using localizer.

Use this constructor when you want to perform some form of localization or internationalization on text strings generated from the NDesk.Options.OptionSet class. Generated strings include:

Example

See the following example, which demonstrates how different localizers alter the program output.

C# Example
// Localization with NDesk.Options.OptionSet.
//
// Compile as:
//   gmcs -r:Mono.Posix.dll -r:NDesk.Options.dll code-localization.cs
using System;
using System.IO;
using Mono.Unix;
using NDesk.Options;

class LocalizationDemo {
	public static void Main (string[] args)
	{
		bool with_gettext = false;
		string useLocalizer = null;
		var p = new OptionSet () {
			{ "with-gettext", v => { useLocalizer = "gettext"; } },
			{ "with-hello",   v => { useLocalizer = "hello"; } },
			{ "with-default", v => { /* do nothing */ } },
		};
		p.Parse (args);

		Converter<string, string> localizer = f => f;
		switch (useLocalizer) {
			case "gettext":
				Catalog.Init ("localization", 
						Path.Combine (AppDomain.CurrentDomain.BaseDirectory,
							"locale"));
				localizer = f => { return Catalog.GetString (f); };
				break;
			case "hello":
				localizer = f => { return "hello:" + f; };;
				break;
		}

		bool help = false;
		int verbose = 0;
		bool version = false;
		p = new OptionSet (localizer) {
			{ "h|?|help", "show this message and exit.", 
				v => help = v != null },
			{ "v|verbose", "increase message verbosity.",
				v => { ++verbose; } },
			{ "n=", "must be an int",
				(int n) => { /* ignore */ } },
			{ "V|version", "output version information and exit.",
				v => version = v != null },
		};
		try {
			p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("localization: ");
			Console.WriteLine (e.Message);
			return;
		}
		if (help)
			p.WriteOptionDescriptions (Console.Out);
		if (version)
			Console.WriteLine ("NDesk.Options Localizer Demo 1.0");
		if (verbose > 0)
			Console.WriteLine ("Message level: {0}", verbose);
	}
}

The output (under the influence of different command-line arguments) is:

sh Example
$ mono localization.exe --help --version
  -h, -?, --help             show this message and exit.
  -v, --verbose              increase message verbosity.
  -n=VALUE                   must be an int
  -V, --version              output version information and exit.
NDesk.Options Localizer Demo 1.0

$ LANGUAGE=es mono localization.exe --with-gettext --help --version
  -h, -?, --help             A mostrar este mensaje y salir.
  -v, --verbose              Aumento mensaje verbosidad.
  -n=VALUE                   Debe ser un int
  -V, --version              Salida de información de versión y sale.
NDesk.Options Localizer Demo 1.0

$ mono localization.exe --with-hello --help --version
  -h, -?, --help             hello:show this message and exit.
  -v, --verbose              hello:increase message verbosity.
  -nhello:=VALUE             hello:must be an int
  -V, --version              hello:output version information and exit.
NDesk.Options Localizer Demo 1.0

$ mono localization.exe -n not-an-int
localization: Could not convert string `not-an-int' to type Int32 for option `-n'.

$ mono localization.exe --with-hello -n not-an-int
localization: hello:Could not convert string `not-an-int' to type Int32 for option `-n'.

Notice:

  • The --with-gettext parser uses Mono.Unix.Catalog.GetString to translate all messages
  • The -with-hello parser prefixes all descriptions with hello:.
  • Only the descriptions are translated, and not the command-line arguments themselves. Only error messages and option descriptions are translated, not the options themselves.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add Method

Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(IEnumerable<string>).

public OptionSet Add (Option option)

Parameters

option
The NDesk.Options.Option to register.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException option is null.

Remarks

Registers each option name returned by Option.GetNames, ensuring that any option with a matching name will be handled by the option instance.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add (string prototype, OptionAction<string, string> action)

See Also

OptionSet.Add(string, string, OptionAction<string, string>)
OptionSet.Add(Option)

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
action
A NDesk.Options.OptionAction<string, string> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Calls OptionSet.Add(string, string, OptionAction<string, string>) with a description value of null.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add (string prototype, Action<string> action)

See Also

OptionSet.Add(string, string, Action<string>)
OptionSet.Add(Option)

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
action
A Action<string> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Calls OptionSet.Add(string, string, Action<string>) with a description value of null.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add (string prototype, string description, OptionAction<string, string> action)

See Also

OptionSet.Add(Option)

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
description
A string to be used to initialize the Option.Description property.
action
A NDesk.Options.OptionAction<string, string> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Use this method when prototype should accept two values, generally a key and a value.

Note: If prototype specifies a OptionValueType.Optional option, then it's possible that both the key and the value will be null in the callback function.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add (string prototype, string description, Action<string> action)

See Also

OptionSet.Add(Option)

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
description
A string containing to used to initialize the Option.Description property.
action
A Action<string> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add<T> Generic Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add<T> (string prototype, Action<T> action)

See Also

OptionSet.Add(Option)
OptionSet.Add``1(string, string, Action<``0>)

Type Parameters

T
The type of the option to parse and provide to the action callback.

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
action
A Action<``0> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.

Remarks

Calls OptionSet.Add``1(string, string, Action<``0>) with a description value of null.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add<T> Generic Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add<T> (string prototype, string description, Action<T> action)

See Also

OptionSet.Add(Option)

Type Parameters

T
The type of the option to parse and provide to the action callback.

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
description
A string containing to used to initialize the Option.Description property.
action
A Action<``0> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Use this typed overload when you want strongly typed option values that correspond to a managed type. System.ComponentModel.TypeDescriptor.GetConverter(Type) is used to lookup the System.ComponentModel.TypeConverter to use when performing the string-to-type conversion.

Note:

If prototype specifies an OptionValueType.Optional value and the value is not provided, then default(T) is provided as the value to action.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add<TKey,TValue> Generic Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add<TKey, TValue> (string prototype, OptionAction<TKey, TValue> action)

See Also

OptionSet.Add(Option)
OptionSet.Add``2(string, string, OptionAction<``0, ``1>)

Type Parameters

TKey
The type of the first argument to parse and provide to the action callback.
TValue
The type of the second argument to parse and provide to the action callback.

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
action
A NDesk.Options.OptionAction<TKey, TValue> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Calls OptionSet.Add``2(string, string, OptionAction<``0, ``1>) with a description value of null.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Add<TKey,TValue> Generic Method

Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.

public OptionSet Add<TKey, TValue> (string prototype, string description, OptionAction<TKey, TValue> action)

See Also

OptionSet.Add(Option)

Type Parameters

TKey
The type of the first argument to parse and provide to the action callback.
TValue
The type of the second argument to parse and provide to the action callback.

Parameters

prototype
A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
description
A string to be used to initialize the Option.Description property.
action
A NDesk.Options.OptionAction<TKey, TValue> to invoke when an option is parsed.

Returns

The current NDesk.Options.OptionSet instance. This is to permit method chaining.

Exceptions

Type Reason
ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

prototype is null

-or-

action is null

Remarks

Use this method when prototype should accept two typed values, generally a key and a value.

Note:

If prototype specifies an OptionValueType.Optional value and the value is not provided, then default(TKey) and default(TValue) may be provided as the values to action.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

CreateOptionContext Method

Creates an NDesk.Options.OptionContext instance.

protected virtual OptionContext CreateOptionContext ()

See Also

OptionSet.Parse(IEnumerable<string>)
OptionSet.Parse(string, OptionContext)

Returns

A NDesk.Options.OptionContext instance to be used when parsing all options during the current OptionSet.Parse(IEnumerable<string>) call.

Remarks

Note to Inheritors

This method can be overridden if OptionSet.Parse(string, OptionContext) is overridden and requires access to an NDesk.Options.OptionContext subclass to store additional information during the current OptionSet.Parse(IEnumerable<string>) invocation.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

GetKeyForItem Method

Returns item.GetNames()[0].

protected override string GetKeyForItem (Option item)

Parameters

item
An NDesk.Options.Option to return the key of.

Returns

A string containing the first alias returned by Option.GetNames.

Remarks

This is to support the System.Collections.ObjectModel.KeyedCollection<string, NDesk.Options.Option> infrastructure. System.Collections.ObjectModel.KeyedCollection<string, NDesk.Options.Option> assumes only one key per item, so we arbitrarily choose the first item in the option alias list.

Note: All aliases returned by Option.GetNames are still registered with System.Collections.ObjectModel.KeyedCollection<string, NDesk.Options.Option> even though OptionSet.GetKeyForItem(Option) will never return them. Consequently, System.Collections.ObjectModel.KeyedCollection<string, Option>.Contains(`0) and System.Collections.ObjectModel.KeyedCollection<string, Option>.Item(`0) will both correctly use all aliases returned by Option.GetNames.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.1.0

GetOptionForName Method

Looks up the NDesk.Options.Option registered to handle the option name option.

[System.Obsolete("Use KeyedCollection.this[string]")]
protected Option GetOptionForName (string option)

See Also

OptionSet.Parse(string, OptionContext)

Parameters

option
A string containing the option name to lookup.

Returns

The NDesk.Options.Option instance registered to handle the option name option. If there is no registered handler for option, then null is returned.

Exceptions

Type Reason
ArgumentNullException option is null.

Remarks

Subclasses can use this function to perform option lookup when overriding OptionSet.Parse(string, OptionContext).

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

GetOptionParts Method

Splits argument into its constituent parts.

protected bool GetOptionParts (string argument, out string flag, out string name, out string sep, out string value)

Parameters

argument
A string containing the option to parse into its constituent parts.
flag
A string reference which will be set to null if the method returns false, or set to the flag the option starts with if the method returns true. Valid flags include: -, --, and /.
name
A string reference which will be set to null if the method returns false, or set to the option name following a valid flag if the method returns true. No lookup is made to determine that flag has been registered via a prior call to OptionSet.Add(Option) or related overload.
sep
A string reference which will be set to null if either the method returns false or if = or : was not found within argument; if the method returns true and argument contains a = or :, then sep will contain either = or :, whichever was found within argument.
value
A string reference which will be set to null if either the method returns false or if sep is null; if the method returns true and sep is not null, then value will contain all text after sep.

Returns

true if argument could be split into its constituent parts, and flag and name are set (sep and value may not be set, depending on whether or not they are present within argument); true if argument is not the possible start of a valid option.

Exceptions

Type Reason
ArgumentNullException argument is null.

Remarks

Subclasses can call this method from their OptionSet.Parse(string, OptionContext) method to determine whether a given string is an option, and to split the option up for further processing.

For example, GetOptionParts("foo", ...) would return false, while GetOptionParts("--foo=bar", ...) would result in flag containing --, name containing foo, sep containing =, and value containing bar.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

InsertItem Method

Inserts item at the specified index.

protected override void InsertItem (int index, Option item)

Parameters

index
A int specifying the index to insert item into.
item
The NDesk.Options.Option to insert.

Remarks

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

MessageLocalizer Property

Permits access to the message localization facility.

public Converter<string, string> MessageLocalizer { get; }

See Also

OptionSet(Converter<string, string>)

Value

A Converter<string, string> that can be used to localize messages.

Remarks

NDesk.Options.Option subclasses can use this property (via OptionContext.OptionSet) to perform message localization for their own exception messages.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Parse Method

Parses each string within arguments, invoking any registered actions if a registered option is encountered.

public List<string> Parse (IEnumerable<string> arguments)

Parameters

arguments
A IEnumerable<string> containing all arguments to parse.

Returns

A List<string> containing all unhandled arguments.

Exceptions

Type Reason
NDesk.Options.OptionException

A value was not found for an NDesk.Options.Option requiring a value.

-or-

An attempt was made to bundle together an option requiring a value.

-or-

An exception was generated when trying to convert the value to the type T, for options added with OptionSet.Add``1(string, string, Action<``0>) and related methods. The originating exception is provided via the Exception.InnerException property.

Remarks

An argument is unhandled if:

  • There is no default handler registered (the <> handler). If there is a default handler registered, then the default handler is invoked for otherwise-unhandled arguments.
  • The option starts with a flag such as -, --, /, and the option name following the flag is unregistered.
  • Or, the option does not start with a flag, and there is no prior parsed option that accepts a value that would use the argument as its value.

Furthermore, argument parsing (including default handler invocation) stops whenever the -- option is encountered. This is in accordance with GNU conventions, and is frequently used to permit users to provide option-like filenames, e.g. ls -lF -- -l to view the file -l instead of needing to use ls -lF ./-l.

Example

The following example demonstrates some simple usage of NDesk.Options.OptionSet.

C# Example
using System;
using System.Collections.Generic;
using NDesk.Options;

class Test {
	static int verbosity;

	public static void Main (string[] args)
	{
		bool show_help = false;
		List<string> names = new List<string> ();
		int repeat = 1;

		var p = new OptionSet () {
			{ "n|name=", "the {NAME} of someone to greet.",
			  v => names.Add (v) },
			{ "r|repeat=", 
				"the number of {TIMES} to repeat the greeting.\n" + 
					"this must be an integer.",
			  (int v) => repeat = v },
			{ "v", "increase debug message verbosity",
			  v => { if (v != null) ++verbosity; } },
			{ "h|help",  "show this message and exit", 
			  v => show_help = v != null },
		};

		List<string> extra;
		try {
			extra = p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("greet: ");
			Console.WriteLine (e.Message);
			Console.WriteLine ("Try `greet --help' for more information.");
			return;
		}

		if (show_help) {
			ShowHelp (p);
			return;
		}

		string message;
		if (extra.Count > 0) {
			message = string.Join (" ", extra.ToArray ());
			Debug ("Using new message: {0}", message);
		}
		else {
			message = "Hello {0}!";
			Debug ("Using default message: {0}", message);
		}

		foreach (string name in names) {
			for (int i = 0; i < repeat; ++i)
				Console.WriteLine (message, name);
		}
	}

	static void ShowHelp (OptionSet p)
	{
		Console.WriteLine ("Usage: greet [OPTIONS]+ message");
		Console.WriteLine ("Greet a list of individuals with an optional message.");
		Console.WriteLine ("If no message is specified, a generic greeting is used.");
		Console.WriteLine ();
		Console.WriteLine ("Options:");
		p.WriteOptionDescriptions (Console.Out);
	}

	static void Debug (string format, params object[] args)
	{
		if (verbosity > 0) {
			Console.Write ("# ");
			Console.WriteLine (format, args);
		}
	}
}

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

Parse Method

Parses argument and invokes Option.Invoke(OptionContext) if appropriate.

protected virtual bool Parse (string argument, OptionContext c)

See Also

OptionSet.CreateOptionContext
OptionSet.Parse(IEnumerable<string>)

Parameters

argument
A string containing the current option to parse.
c
A NDesk.Options.OptionContext containing the current parser context.

Returns

A bool specifying whether or not argument was handled. If false, then OptionSet.Parse(IEnumerable<string>) will return argument as an unhandled option.

Remarks

This method is called for each string within the IEnumerable<string> provided to OptionSet.Parse(IEnumerable<string>), which thus gives this method a chance to parse a single option, or chain together multiple options to form a single option (as is necessary when an option and its value are separated, e.g. with -option value).

Operation

The default implementation will check OptionContext.Option, which is assumed to be a NDesk.Options.Option in need of a value. If OptionContext.Option is non-null, then argument is OptionValueCollection.Add(string)ed to OptionContext.OptionValues and Option.Invoke(OptionContext) is invoked.

Next, OptionSet.GetOptionParts(string, String@, String@, String@, String@) is invoked. If GetOptionParts returns false, then false is returned from Parse.

Finally, check to see if the name returned from GetOptionParts is registered; if it is, handle it appropriately. If it isn't, check to see if name is a bundled option or a boolean option. If name isn't any registered option, then false is returned. Otherwise, true is returned.

Note to Inheritors

Inheriting types can override this method if they want to customize the per-option parsing within the containing OptionSet.Parse(IEnumerable<string>) invocation.

Inheriting types should consider overriding OptionSet.CreateOptionContext if they want to store extra information for use and retrieval during each Parse invocation.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

RemoveItem Method

Removes the NDesk.Options.Option at the specified index.

protected override void RemoveItem (int index)

Parameters

index
A int containing the index of the NDesk.Options.Option to remove.

Remarks

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

SetItem Method

Removes the current NDesk.Options.Option at index and sets item as the value for the index value.

protected override void SetItem (int index, Option item)

Parameters

index
A int containing the index of the NDesk.Options.Option to change.
item
The new NDesk.Options.Option to set at index.

Remarks

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0

WriteOptionDescriptions Method

Writes NDesk.Options.Option documentation to o.

public void WriteOptionDescriptions (System.IO.TextWriter o)

Parameters

o
The System.IO.TextWriter to write option descriptions to.

Remarks

For each NDesk.Options.Option previously added to the current instance, this method writes out a comma-separated list of all Option.GetNames followed by the Option.Description.

The Option.Description is automatically wrapped so that output will flow nicely across multiple lines. Wrapping is preferred at explicit embedded newline characters (\n) or spaces, but words will be split (by adding a -) if necessary.

Options requiring a value have =VALUE appended to their last name, while options with an optional value have [=VALUE] appended to their last name. The VALUE string can be changed by using a format specifier-like string within the Option.Description.

For NDesk.Options.Options accepting one value, the string {VALUE} or {0:VALUE} can be used to explicitly provide the value name. For Options accepting more than one value, the leading number is used to specify which value the string is for.

Example

The following example initializes a NDesk.Options.OptionSet instance to accept a variety of parameters and provides a description for each parameter:

C# Example
using System;
using System.Collections.Generic;
using NDesk.Options;

class Test {
	static int verbosity;

	public static void Main (string[] args)
	{
		bool show_help = false;
		List<string> names = new List<string> ();
		int repeat = 1;

		var p = new OptionSet () {
			{ "n|name=", "the {NAME} of someone to greet.",
			  v => names.Add (v) },
			{ "r|repeat=", 
				"the number of {TIMES} to repeat the greeting.\n" + 
					"this must be an integer.",
			  (int v) => repeat = v },
			{ "v", "increase debug message verbosity",
			  v => { if (v != null) ++verbosity; } },
			{ "h|help",  "show this message and exit", 
			  v => show_help = v != null },
		};

		List<string> extra;
		try {
			extra = p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("greet: ");
			Console.WriteLine (e.Message);
			Console.WriteLine ("Try `greet --help' for more information.");
			return;
		}

		if (show_help) {
			ShowHelp (p);
			return;
		}

		string message;
		if (extra.Count > 0) {
			message = string.Join (" ", extra.ToArray ());
			Debug ("Using new message: {0}", message);
		}
		else {
			message = "Hello {0}!";
			Debug ("Using default message: {0}", message);
		}

		foreach (string name in names) {
			for (int i = 0; i < repeat; ++i)
				Console.WriteLine (message, name);
		}
	}

	static void ShowHelp (OptionSet p)
	{
		Console.WriteLine ("Usage: greet [OPTIONS]+ message");
		Console.WriteLine ("Greet a list of individuals with an optional message.");
		Console.WriteLine ("If no message is specified, a generic greeting is used.");
		Console.WriteLine ();
		Console.WriteLine ("Options:");
		p.WriteOptionDescriptions (Console.Out);
	}

	static void Debug (string format, params object[] args)
	{
		if (verbosity > 0) {
			Console.Write ("# ");
			Console.WriteLine (format, args);
		}
	}
}

Notice that when the above program is invoked with the --help parameter, OptionSet.WriteOptionDescriptions(System.IO.TextWriter) is used to generate the NDesk.Options.Option description, that the --repeat description spans multiple lines, and that format specifiers such as {NAME} are used to provide a description for the option value:

sh Example
$ mono greet.exe --help
Usage: greet [OPTIONS]+ message
Greet a list of individuals with an optional message.
If no message is specified, a generic greeting is used.

Options:
  -n, --name=NAME            the NAME of someone to greet.
  -r, --repeat=TIMES         the number of TIMES to repeat the greeting.
                               this must be an integer.
  -v                         increase debug message verbosity
  -h, --help                 show this message and exit

$ mono greet.exe -v- -n A -name=B --name=C /name D -nE
Hello A!
Hello B!
Hello C!
Hello D!
Hello E!

$ mono greet.exe -v -n E custom greeting for: {0}
# Using new message: custom greeting for: {0}
custom greeting for: E

$ mono greet.exe -r 3 -n A
Hello A!
Hello A!
Hello A!

$ mono greet.exe -r not-an-int
greet: Could not convert string `not-an-int' to type Int32 for option `-r'.
Try `greet --help' for more information.

Requirements

Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0