A class to parse program options.
|
A common requirement for command-line programs is option parsing. The command line consists of a sequence of arguments. OptionSet.Parse(System.Collections.Generic.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(System.Collections.Generic.IEnumerable<string>), returns a System.Collections.Generic.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:
Simple names are matched when the argument consists solely of a flag followed by an option name.
Examples: -opt, --opt, and /opt are all simple names for the opt option.
Boolean names are matched when the argument consists of a flag, followed by an option name, followed by + or -. If a + follows the name, the option is enabled, otherwise the option is disabled.
Examples: -opt+ and -opt- enable and disble the opt option.
Assigned names are matched when the argument consists of a flag, followed by an option name, followed by a = or :, followed by an (optional) string.
Examples: -opt=A, --opt:B, and /opt=C all provide a value for the opt option.
Bundled names are matched only when simple, boolean, and assigned names are not matched, the flag is -, and the first character matches a registered option. Any number of (single-character) boolean options may be bundled in this fashion, and at most one OptionValueType.Optional or OptionValueType.Required option (which will use all remaining characters within the argument as a value).
Examples: -xvfinput-file could match the boolean NDesk.Options.Options x and v and the value-accepting option f, which will get the value input-file. (Other interpretations are also possible, depending upon which options are registered.)
There are three types of NDesk.Options.Options that can be parsed:
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, null is provided to their corresponding Action`1.
Thus, -opt:value would pass value to the action registered for opt, while -opt value would pass null to the action registered for opt and value would be an unparsed argument.
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(System.Collections.Generic.IEnumerable<string>).
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<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 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 -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.
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 }, }; List<string> extra; try { extra = 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 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 |
The following example shows a custom OptionSet subclass with the following additional functionality:
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) { nextOption = GetOptionForName (n.ToLower ()); 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:
See Also: Inherited members from System.Collections.ObjectModel.Collection<Option>.
OptionSet
()
Creates and initializes a new
NDesk.Options.OptionSet class instance.
|
Creates and initializes a new NDesk.Options.OptionSet class instance. |
MessageLocalizer [read-only] | Converter<string, string> . Permits access to the message localization facility. |
Add
(Option)
Registers option so that any options matching
Option.GetNames will be treated
specially by
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>).
|
|
Add
(string, OptionAction<string, string>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add
(string, Action<string>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add
(string, string, OptionAction<string, string>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add
(string, string, Action<string>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add<T>
(string, Action<T>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add<T>
(string, string, Action<T>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add<TKey,TValue>
(string, OptionAction<TKey, TValue>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Add<TKey,TValue>
(string, string, OptionAction<TKey, TValue>)
Registers each alias within prototype so that any
options matching the aliases in prototype will be
handled by action during any subsequent
OptionSet.Parse(System.Collections.Generic.IEnumerable<string>)
calls.
|
|
Parse
(System.Collections.Generic.IEnumerable<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.
|
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, out string)
Splits argument into its constituent parts.
|
|
override |
InsertItem
(int, Option)
Inserts item at the specified
index.
|
Parse
(string, OptionContext)
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.
|
Creates and initializes a new NDesk.Options.OptionSet class instance.
Creates and initializes a new NDesk.Options.OptionSet class instance.
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:
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:
Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(System.Collections.Generic.IEnumerable<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 prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
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.
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<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 prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
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.
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(System.Collections.Generic.IEnumerable<string>) calls.
Type | Condition |
---|---|
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 |
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.
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<string>) invocation.
Looks up the NDesk.Options.Option registered to handle the option name option.
Type | Condition |
---|---|
ArgumentNullException | option is null. |
Splits argument into its constituent parts.
Type | Condition |
---|---|
ArgumentNullException | argument is null. |
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.
Inserts item at the specified index.
Permits access to the message localization facility.
Parses each string within arguments, 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 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. |
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 argument and invokes Option.Invoke(OptionContext) if appropriate.
This method is called for each string within the System.Collections.Generic.IEnumerable<string> provided to OptionSet.Parse(System.Collections.Generic.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).
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.
Inheriting types can override this method if they want to customize the per-option parsing within the containing OptionSet.Parse(System.Collections.Generic.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.
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(System.IO.TextWriter) is used to generate the NDesk.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 -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. |