A class to parse program options.
|
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:
Use of OptionSet is split up into two parts:
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:
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"}); |
Subclasses can override the following virtual methods to customize option parsing behavior:
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:
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:
See Also: Inherited members from System.Collections.ObjectModel.Collection<NDesk.Options.Option>.
OptionSet
()
Creates and initializes a new
NDesk.Options.OptionSet class instance.
|
Creates and initializes a new NDesk.Options.OptionSet class instance. |
Add
(Option)
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>)
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>)
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>)
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>)
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>)
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>)
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>)
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>)
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>)
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.
|
override |
ClearItems
()
Removes all NDesk.Options.Options from this
instance.
|
CreateOptionContext
()
Creates an NDesk.Options.OptionContext instance.
|
|
GetOptionForName
(string)
Looks up the NDesk.Options.Option registered to
handle the option name option.
|
|
GetOptionParts
(string, out string, out string, out string)
Splits option into its constituent parts.
|
|
override |
InsertItem
(int, Option)
Inserts item at the specified
index.
|
Parse
(string, OptionContext)
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.
|
Creates and initializes a new NDesk.Options.OptionSet class instance.
Creates and initializes a new NDesk.Options.OptionSet class instance.
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:
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:
Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String}).
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. |
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.
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 |
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.
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 |
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.
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 |
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.
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 |
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.
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 |
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.
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 |
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.
Type | Condition |
---|---|
ArgumentException | option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. |
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.
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 |
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.
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 |
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.
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 |
Removes all NDesk.Options.Options from this instance.
Creates an NDesk.Options.OptionContext instance.
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.
Looks up the NDesk.Options.Option registered to handle the option name option.
Type | Condition |
---|---|
ArgumentNullException | option is null. |
Splits option into its constituent parts.
Inserts item at the specified index.
Parses each string within options, invoking any registered actions if a registered option is encountered.
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. |
An option is unhandled if:
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.
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); } } } |
Parses option and invokes Option.Invoke(OptionContext) if appropriate.
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.
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.
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.
Removes the NDesk.Options.Option at the specified index.
Removes the current NDesk.Options.Option at index and sets item as the value for the index value.
Writes NDesk.Options.Option documentation to o.
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.
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. |