NDesk.Options

GIT Repository

NDesk.Options : NDesk.Options Namespace

OptionSet Class

A class to parse program options.

public class OptionSet : System.Collections.ObjectModel.Collection<NDesk.Options.Option>


Thread Safety

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

Remarks

Use the NDesk.Options.OptionSet class to associate a list of option names with an action to execute (either a Action`1 or a Action`2) when the option name is encountered.

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 encountered, their registered action is invoked immediately. The Action`1 value will be non-null if the value is true, e.g. if -option or -option+ is specified, and the value will be null 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. When encountered, their corresponding Action`1 is invoked when the option's value is found, which may be either within the current option (for -option=value options) or when the next option is encountered (for -option value options). If there is no option value, then null is provided as the option value.
  3. Required value options, which correspond to a Option.OptionValueType value of OptionValueType.Requried. When encountered, their corresponding Action`1 is invoked when the option's value is found, which may be either within the current option (for -option=value options) or when the next option is encountered (for -option value options). If there is no option value, an NDesk.Options.OptionException is thrown from OptionSet.Parse(System.Collections.Generic.IEnumerable{System.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, System.Action{System.String}) and the other Add overloads.
  3. By creating a new subclass of NDesk.Options.Option and adding it via System.Collections.ObjectModel.Collection{NDesk.Options.Option}.Add(`0). 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 System.Collections.Generic.IEnumerable{System.String} is parsed, looking for options 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 are returned from Parse.

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:

Examples

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.",
			  (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=VALUE           the name of someone to greet.
  -r, --repeat=VALUE         the number of times to repeat the greeting.
  -v                         increase debug message verbosity
  -h, --help                 show this message and exit

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

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

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 OptionSet
using System;
using System.Collections.Generic;
using NDesk.Options;

class DemoOptionContext : OptionContext {
	public string OptionKey;
}

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 DemoOptionContext ();
	}

	protected override bool Parse (string option, OptionContext c)
	{
		DemoOptionContext d = (DemoOptionContext) c;
		// Prevent --a --b
		string f, n, v;
		bool haveParts = GetOptionParts (option, out f, out n, out v);
		Option nextOption = haveParts ? GetOptionForName (n.ToLower ()) : null;
		if (haveParts && c.Option != null) {
			if (nextOption == null)
				; // ignore
			else if (c.Option.OptionValueType == OptionValueType.Optional) {
				c.OptionValue = null;
				c.Option.Invoke (c);
			}
			else 
				throw new OptionException (
					string.Format ("Found option value `{0}' for option `{1}'.",
						option, c.OptionName), c.OptionName);
		}

		// option name already found, so `option' is the option value
		if (c.Option != null) {
			if (c.Option is KeyValueOption && d.OptionKey == null) {
				HandleKeyValue (option, d);
				return true;
			}
			return base.Parse (option, c);
		}

		if (!haveParts)
			// Not an option; let base handle as a non-option argument.
			return base.Parse (option, c);

		// use lower-case version of the option name.
		if (nextOption != null && nextOption is KeyValueOption) {
			d.Option     = nextOption;
			d.OptionName = f + n.ToLower ();
			HandleKeyValue (v, d);
			return true;
		}
		return base.Parse (f + n.ToLower () + (v != null ? "=" + v : ""), c);
	}

	static void HandleKeyValue (string option, DemoOptionContext d)
	{
		if (option == null)
			return;
		string[] parts = option.Split ('=');
		if (parts.Length == 1) {
			d.OptionKey = option;
			return;
		}
		d.OptionKey   = parts [0];
		d.OptionValue = parts [1];
		if (d.Option != null) {
			d.Option.Invoke (d);
		}
	}

	class KeyValueOption : Option {
		public KeyValueOption (string prototype, Action<string,string,OptionContext> action)
			: base (prototype, null)
		{
			this.action = action;
		}

		Action<string,string,OptionContext> action;

		protected override void OnParseComplete (OptionContext c)
		{
			DemoOptionContext d = (DemoOptionContext) c;
			action (d.OptionKey, d.OptionValue, d);
			d.OptionKey = null;
		}
	}

	public new DemoOptionSet Add (string prototype,
		Action<string,string,OptionContext> action)
	{
		base.Add (new KeyValueOption (prototype, action));
		return this;
	}
}

class Demo {
	public static void Main (string[] args)
	{
		bool show_help = false;
		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,c) => 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 value `--Repeat' for option `-name'.

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

Notice:

Members

See Also: Inherited members from System.Collections.ObjectModel.Collection<NDesk.Options.Option>.

Constructors

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

Methods

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

Protected Methods

override ClearItems ()
Removes all NDesk.Options.Options from this instance.
CreateOptionContext () : OptionContext
Creates an NDesk.Options.OptionContext instance.
GetOptionForName (string) : Option
Looks up the NDesk.Options.Option registered to handle the option name option.
GetOptionParts (string, out string, out string, out string) : bool
Splits option into its constituent parts.
override InsertItem (int, Option)
Inserts item at the specified index.
Parse (string, OptionContext) : bool
Parses option 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

public OptionSet ()

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

See Also

Remarks

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

OptionSet Constructor

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

Parameters

localizer
A System.Converter{System.String,System.String} instance that will be used to translate strings.

Remarks

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:

Examples

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)
	{
		Converter<string, string> localizer = f => f;
		bool with_gettext = false;
		var p = new OptionSet () {
			{ "with-gettext",
				v => { with_gettext = true; 
			         localizer = f => { return Catalog.GetString (f); }; } },
			{ "with-hello",   
				v => { localizer = f => { return "hello:" + f; }; } },
			{ "with-default", v => { /* do nothing */ } },
		};
		p.Parse (args);

		if (with_gettext)
			Catalog.Init ("localization", 
					Path.Combine (AppDomain.CurrentDomain.BaseDirectory,
						"locale"));

		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.

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add Method

public OptionSet Add (Option option)

Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}).

Parameters

option
The NDesk.Options.Option to register.

Returns

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

Exceptions

Type Condition
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.

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add Method

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype for details.
action
A System.Action{System.String,NDesk.Options.OptionContext} to invoke when an option is parsed.

Returns

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

Exceptions

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

options is null

-or-

action is null

Remarks

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add Method

public OptionSet Add (string options, System.Action<System.String> action)

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype for details.
action
A System.Action{System.String} to invoke when an option is parsed.

Returns

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

Exceptions

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

options is null

-or-

action is null

Remarks

Calls OptionSet.Add(string, string, System.Action{System.String}) with a description value of null.

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add Method

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype for details.
description
A string containing to used to initialize the Option.Description property.
action
An System.Action{System.String,NDesk.Options.OptionContext} to invoke when an option is parsed.

Returns

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

Exceptions

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

options is null

-or-

action is null

Remarks

Use this overload when your action needs access to additional NDesk.Options.OptionContext, such as for additional error context reporting.

The NDesk.Options.OptionContext provided to action is shared between all registered actions during the controlling OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) invocation. Consequently, care must be taken to not modify any of the NDesk.Options.OptionContext members.

Examples

The following example shows several actions which make use of the provided NDesk.Options.OptionContext parameter:

C# Example
using System;
using System.ComponentModel;
using System.Globalization;
using NDesk.Options;

class FooConverter : TypeConverter {
	public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
	{
		if (sourceType == typeof (string))
			return true;
		return base.CanConvertFrom (context, sourceType);
	}

	public override object ConvertFrom (ITypeDescriptorContext context,
			CultureInfo culture, object value)
	{
		string v = value as string;
		if (v != null) {
			switch (v) {
				case "A": return Foo.A;
				case "B": return Foo.B;
			}
		}

		return base.ConvertFrom (context, culture, value);
	}
}

[TypeConverter (typeof(FooConverter))]
class Foo {
	public static readonly Foo A = new Foo ("A");
	public static readonly Foo B = new Foo ("B");
	string s;
	Foo (string s) { this.s = s; }
	public override string ToString () {return s;}
}

class Test {
	public static void Main (string[] args)
	{
		Foo    f = null;
		int    n = -1;
		string s = null;
		OptionSet p = new OptionSet () {
			{ "f:", (Foo v, OptionContext c) => {
				Console.WriteLine ("# Parsed {0}; Value={1}; Index={2}",
					c.OptionName, c.OptionValue ?? "<null>", c.OptionIndex);
				f = v;
			} },
			{ "n=", (int v, OptionContext c) => {
				Console.WriteLine ("# Parsed {0}; Value={1}; Index={2}",
					c.OptionName, c.OptionValue, c.OptionIndex);
				n = v;
			} },
			{ "s:", (v, c) => {
				Console.WriteLine ("# Parsed {0}; Value={1}; Index={2}",
					c.OptionName, c.OptionValue, c.OptionIndex);
				s = v;
			} },
		};
		try {
			p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("context: ");
			Console.WriteLine (e.Message);
			return;
		}
		Console.WriteLine ("f={0}", f == null ? "<null>" : f.ToString ());
		Console.WriteLine ("n={0}", n);
		Console.WriteLine ("s={0}", s ?? "<null>");
	}
}

The following sh output shows the above programs behavior under the influence of a variety of program options.

sh Example
$ mono context.exe -f
# Parsed -f; Value=<null>; Index=0
f=<null>
n=-1
s=<null>

$ mono context.exe -n
context: Missing required value for option '-n'.

$ mono context.exe -s
# Parsed -s; Value=; Index=0
f=<null>
n=-1
s=<null>

$ mono context.exe -f invalid
context: Could not convert string `invalid' to type Foo for option `-f'.

$ mono context.exe -n invalid
context: Could not convert string `invalid' to type Int32 for option `-n'.

$ mono context.exe -s=
# Parsed -s; Value=; Index=0
f=<null>
n=-1
s=

$ mono context.exe -f A --n=42 /s forty-two
# Parsed -f; Value=A; Index=1
# Parsed --n; Value=42; Index=2
# Parsed /s; Value=forty-two; Index=4
f=A
n=42
s=forty-two

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add Method

public OptionSet Add (string options, string description, System.Action<System.String> action)

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype for details.
description
A string containing to used to initialize the Option.Description property.
action
A System.Action{System.String} to invoke when an option is parsed.

Returns

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

Exceptions

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

options is null

-or-

action is null

Remarks

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add<T> Generic Method

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Type Parameters

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

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype for details.
action
A System.Action{``0,NDesk.Options.OptionContext} to invoke when an option is parsed.

Returns

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

Exceptions

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

options is null

-or-

action is null

Remarks

Calls OptionSet.Add``1(string, string, Action{``0, OptionContext}) with a description value of null.

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add<T> Generic Method

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

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Type Parameters

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

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype 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 Condition
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.

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add<T> Generic Method

public OptionSet Add<T> (string options, string description, System.Action<T,NDesk.Options.OptionContext> action)

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Type Parameters

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

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype for details.
description
A string containing to used to initialize the Option.Description property.
action
A System.Action{``0,NDesk.Options.OptionContext} to invoke when an option is parsed.

Returns

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

Exceptions

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

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

Use this overload when your action needs access to additional NDesk.Options.OptionContext, such as for additional error context reporting.

The NDesk.Options.OptionContext provided to action is shared between all registered actions during the controlling OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) invocation. Consequently, care must be taken to not modify any of the NDesk.Options.OptionContext members.

Examples

The following example shows several actions which make use of the provided NDesk.Options.OptionContext parameter:

C# Example
using System;
using System.ComponentModel;
using System.Globalization;
using NDesk.Options;

class FooConverter : TypeConverter {
	public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
	{
		if (sourceType == typeof (string))
			return true;
		return base.CanConvertFrom (context, sourceType);
	}

	public override object ConvertFrom (ITypeDescriptorContext context,
			CultureInfo culture, object value)
	{
		string v = value as string;
		if (v != null) {
			switch (v) {
				case "A": return Foo.A;
				case "B": return Foo.B;
			}
		}

		return base.ConvertFrom (context, culture, value);
	}
}

[TypeConverter (typeof(FooConverter))]
class Foo {
	public static readonly Foo A = new Foo ("A");
	public static readonly Foo B = new Foo ("B");
	string s;
	Foo (string s) { this.s = s; }
	public override string ToString () {return s;}
}

class Test {
	public static void Main (string[] args)
	{
		Foo    f = null;
		int    n = -1;
		string s = null;
		OptionSet p = new OptionSet () {
			{ "f:", (Foo v, OptionContext c) => {
				Console.WriteLine ("# Parsed {0}; Value={1}; Index={2}",
					c.OptionName, c.OptionValue ?? "<null>", c.OptionIndex);
				f = v;
			} },
			{ "n=", (int v, OptionContext c) => {
				Console.WriteLine ("# Parsed {0}; Value={1}; Index={2}",
					c.OptionName, c.OptionValue, c.OptionIndex);
				n = v;
			} },
			{ "s:", (v, c) => {
				Console.WriteLine ("# Parsed {0}; Value={1}; Index={2}",
					c.OptionName, c.OptionValue, c.OptionIndex);
				s = v;
			} },
		};
		try {
			p.Parse (args);
		}
		catch (OptionException e) {
			Console.Write ("context: ");
			Console.WriteLine (e.Message);
			return;
		}
		Console.WriteLine ("f={0}", f == null ? "<null>" : f.ToString ());
		Console.WriteLine ("n={0}", n);
		Console.WriteLine ("s={0}", s ?? "<null>");
	}
}

The following sh output shows the above programs behavior under the influence of a variety of program options.

sh Example
$ mono context.exe -f
# Parsed -f; Value=<null>; Index=0
f=<null>
n=-1
s=<null>

$ mono context.exe -n
context: Missing required value for option '-n'.

$ mono context.exe -s
# Parsed -s; Value=; Index=0
f=<null>
n=-1
s=<null>

$ mono context.exe -f invalid
context: Could not convert string `invalid' to type Foo for option `-f'.

$ mono context.exe -n invalid
context: Could not convert string `invalid' to type Int32 for option `-n'.

$ mono context.exe -s=
# Parsed -s; Value=; Index=0
f=<null>
n=-1
s=

$ mono context.exe -f A --n=42 /s forty-two
# Parsed -f; Value=A; Index=1
# Parsed --n; Value=42; Index=2
# Parsed /s; Value=forty-two; Index=4
f=A
n=42
s=forty-two

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Add<T> Generic Method

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

Registers each alias within options so that any options matching the aliases in options will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) calls.

See Also

Type Parameters

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

Parameters

options
A string containing all option aliases to register and an (optional) type specifier; see Option.Prototype 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 Condition
ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option.
ArgumentNullException

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

ClearItems Method

protected override void ClearItems ()

Removes all NDesk.Options.Options from this instance.

Remarks

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

CreateOptionContext Method

protected virtual OptionContext CreateOptionContext ()

Creates an NDesk.Options.OptionContext instance.

See Also

Returns

A NDesk.Options.OptionContext instance to be used when parsing all options during the current OptionSet.Parse(System.Collections.Generic.IEnumerable{System.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(System.Collections.Generic.IEnumerable{System.String}) invocation.

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

GetOptionForName Method

protected Option GetOptionForName (string option)

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

See Also

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 Condition
ArgumentNullException option is null.

Remarks

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

GetOptionParts Method

protected bool GetOptionParts (string option, out string flag, out string name, out string value)

Splits option into its constituent parts.

Parameters

option
A string containing the option to parse into its constituent parts.
flag
If the method returns true, a string reference which contains the flag this option started with. Valid flags include: -, --, and /.
name
If the method returns true, a string reference which will contain the option name following a valid flag. No lookup is made to determine that flag has been registered via a prior OptionSet.Add() or related call.
value
If the method returns true, and option contains a =, value will contain the text after the =. Otherwise, value will be set to null.

Returns

A bool; if true, then flag and name will contain the option flag and name found within option, and value will contain any string found after a = (including the empty string). If false is returned, flag, name, and value are all set to null.

Remarks

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

InsertItem Method

protected override void InsertItem (int index, Option item)

Inserts item at the specified index.

Parameters

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

Remarks

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Parse Method

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

Parameters

options
A System.Collections.Generic.IEnumerable<System.String> containing all options to parse.

Returns

A System.Collections.Generic.List{System.String} containing all unhandled options.

Exceptions

Type Condition
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 , for options added with OptionSet.Add``1(string, string, Action{``0, OptionContext}) and related methods. The originating exception is provided via the Exception.InnerException property.

Remarks

An option is unhandled if:

  • 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 option as its value.

Furthermore, option parsing 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.

Examples

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.",
			  (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);
		}
	}
}

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

Parse Method

protected virtual bool Parse (string option, OptionContext c)

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

See Also

Parameters

option
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 option was handled. If false, then OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}) will return option as an unhandled option.

Remarks

This method is called for each string within the System.Collections.Generic.IEnumerable{System.String} provided to OptionSet.Parse(System.Collections.Generic.IEnumerable{System.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 OptionContext.OptionValue is set to option and Option.Invoke[] is invoked.

Next, OptionSet.GetOptionParts(System.String&System.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(System.Collections.Generic.IEnumerable{System.String}) invocation.

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

RemoveItem Method

protected override void RemoveItem (int index)

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

Parameters

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

Remarks

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

SetItem Method

protected override void SetItem (int index, Option item)

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

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0

WriteOptionDescriptions Method

public void WriteOptionDescriptions (System.IO.TextWriter o)

Writes NDesk.Options.Option documentation to 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.

Options requiring a value have =VALUE appended to their last name, while options with an optional value have [=VALUE] appended to their last name.

Examples

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.",
			  (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 is used to generate the esk.Options.Option description:

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=VALUE           the name of someone to greet.
  -r, --repeat=VALUE         the number of times to repeat the greeting.
  -v                         increase debug message verbosity
  -h, --help                 show this message and exit

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

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

Required Assembly Versions:

  • NDesk.Options 2.0.0.0
  • NDesk.Options 3.5.0.0