A class to parse program options.
All public static members of this type are safe for multithreaded operations. The OptionSet.Parse(IEnumerable<string>) instance method is thread-safe if no concurrent modifying methods are invoked (OptionSet.Add(Option), System.Collections.ObjectModel.Collection<Option>.Remove(``0), etc.).
A common requirement for command-line programs is option parsing. The command line consists of a sequence of arguments. OptionSet.Parse(IEnumerable<string>) parses this argument sequence, invoking actions of registered NDesk.Options.Options when a sequence of arguments matching the NDesk.Options.Options requirements are encountered. NDesk.Options.Option's are registered with OptionSet.Add(Option) and its overloads.
OptionSet.Parse(IEnumerable<string>), returns a List<string> of all arguments which were not matched by a registered NDesk.Options.Option.
Three conditions must be met for a sequence of arguments to be considered as a match for an NDesk.Options.Option:
- The name must be matched. An NDesk.Options.Option has one or more names, as returned from Option.GetNames. Matched names must start with a flag (even though the flag is not part of the Option.Prototype): -, --, or /. There are several different name matching algorithms:
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.)
As a fallback, a default handler may be registered which will handle all arguments which are not handled by any of the above matching algorithms. The default handler is designated by the name <> (which may be an alias for another named NDesk.Options.Option).
Default handlers are useful for argument runs -- sequences of arguments that are not related to each other but are instead related to a prior option on the command line, and it isn't desirable to use named options for these. For example, mdoc-assemble --format=ecma DirA DirB --format=man FileC would process DirA and DirB with --format=ecma in effect, and then process FileC with --format=man in effect.
See Option(string, string, int) for additional details regarding default option handlers.
- The type must be matched. Option.OptionValueType specifies the option's type. See below for more information.
- The value count must be matched. Whether an option takes any values is dependent upon the option's type (previous bullet), but the number of values the option either accepts or requires is specified by the Option.MaxValueCount property.
There are three types of NDesk.Options.Options that can be parsed:
- Boolean options, which correspond to a Option.OptionValueType value of OptionValueType.None. When a matching argument is encountered, their registered action is invoked immediately. The Action`1 value will be non-default(T) if the value is true, e.g. if -option or -option+ is specified, and the value will be default(T) if the value is false, e.g. if -option- is specified.
Optional value options, which correspond to a Option.OptionValueType value of OptionValueType.Optional. Optional value options are not "greedy"; they will only get their value only from the current argument. If the value is not present, default(T) is provided to their corresponding Action`1.
Thus, -opt:value would pass value to the action registered for opt, while -opt value would pass default(T) to the action registered for opt and value would be an unparsed argument.
Required value options, which correspond to a Option.OptionValueType value of OptionValueType.Required. Required value options are "greedy" -- if the value is not found within the current argument, the following argument(s) will be used to supply the value(s). Once enough values have been parsed, their corresponding Action`1 is invoked.
Thus, both -opt:value and -opt value would pass value to the action registered for opt.
If no value can be found, an NDesk.Options.OptionException is thrown from OptionSet.Parse(IEnumerable<string>).
Operation
Use of OptionSet is split up into two parts:
- Initialization.
- 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:
- With C# collection initializers, as used above.
- Explicitly by calling OptionSet.Add(string, Action<string>) and the other Add overloads.
- By creating a new subclass of NDesk.Options.Option and adding it via OptionSet.Add(Option). This is not recommended, but is available if you require more direct option handling than the default NDesk.Options.Option implementation provides.
During the parsing phase, an IEnumerable<string> is enumerated, looking for arguments which match a registered option, and invoking the corresponding action when an option and associated (optional) value is encountered. During this phase, the NDesk.Options.OptionSet instance itself is thread safe, but full thread safety depends upon thread-safety of the registered actions. Any option-like strings for names that haven't been registered, e.g. --this-was-never-registered=false, and all arguments that are not used as option values are returned from OptionSet.Parse(IEnumerable<string>) or processed by the default handler <>, if registered.
C# Example List<string> extra = p.Parse (new string[]{"-option-a"});Note to Inheritors
Subclasses can override the following virtual methods to customize option parsing behavior:
The following example demonstrates some simple usage of NDesk.Options.OptionSet.
C# Example using System; using System.Collections.Generic; using NDesk.Options; class Test { static int verbosity; public static void Main (string[] args) { bool show_help = false; List<string> names = new List<string> (); int repeat = 1; var p = new OptionSet () { { "n|name=", "the {NAME} of someone to greet.", v => names.Add (v) }, { "r|repeat=", "the number of {TIMES} to repeat the greeting.\n" + "this must be an integer.", (int v) => repeat = v }, { "v", "increase debug message verbosity", v => { if (v != null) ++verbosity; } }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List<string> extra; try { extra = p.Parse (args); } catch (OptionException e) { Console.Write ("greet: "); Console.WriteLine (e.Message); Console.WriteLine ("Try `greet --help' for more information."); return; } if (show_help) { ShowHelp (p); return; } string message; if (extra.Count > 0) { message = string.Join (" ", extra.ToArray ()); Debug ("Using new message: {0}", message); } else { message = "Hello {0}!"; Debug ("Using default message: {0}", message); } foreach (string name in names) { for (int i = 0; i < repeat; ++i) Console.WriteLine (message, name); } } static void ShowHelp (OptionSet p) { Console.WriteLine ("Usage: greet [OPTIONS]+ message"); Console.WriteLine ("Greet a list of individuals with an optional message."); Console.WriteLine ("If no message is specified, a generic greeting is used."); Console.WriteLine (); Console.WriteLine ("Options:"); p.WriteOptionDescriptions (Console.Out); } static void Debug (string format, params object[] args) { if (verbosity > 0) { Console.Write ("# "); Console.WriteLine (format, args); } } }The output (under the influence of different command-line arguments) is:
sh Example $ mono greet.exe --help Usage: greet [OPTIONS]+ message Greet a list of individuals with an optional message. If no message is specified, a generic greeting is used. Options: -n, --name=NAME the NAME of someone to greet. -r, --repeat=TIMES the number of TIMES to repeat the greeting. this must be an integer. -v increase debug message verbosity -h, --help show this message and exit $ mono greet.exe -v- -n A -name=B --name=C /name D -nE Hello A! Hello B! Hello C! Hello D! Hello E! $ mono greet.exe -v -n E custom greeting for: {0} # Using new message: custom greeting for: {0} custom greeting for: E $ mono greet.exe -r 3 -n A Hello A! Hello A! Hello A! $ mono greet.exe -r not-an-int greet: Could not convert string `not-an-int' to type Int32 for option `-r'. Try `greet --help' for more information.Notice how the output produced by --help uses the descriptions provided during OptionSet initialization. Notice that the NDesk.Options.Option requiring a value (n|name=) can use multiple different forms of invocation, including: -n value, -n=value, -name value, -name=value, --name value, --name=value, /name value, and /name=value.
Notice also that the boolean v option can take three separate forms: -v and -v+, which both enable the option, and -v-, which disables the option. (The second greet invocation uses -v-, which is why no debug messages are shown.)
Finally, note that the action can specify a type to use. If no type is provided, the action parameter will be a string. If a type is provided, then System.ComponentModel.TypeConverter will be used to convert a string to the specified type.
The following example shows how options and values can be bundled together.
C# Example using System; using System.Linq; using System.Collections.Generic; using NDesk.Options; class Test { public static void Main (string[] args) { var show_help = false; var macros = new Dictionary<string, string>(); bool create = false, extract = false, list = false; string output = null, input = null; string color = null; var p = new OptionSet () { // gcc-like options { "D:", "Predefine a macro with an (optional) value.", (m, v) => { if (m == null) throw new OptionException ("Missing macro name for option -D.", "-D"); macros.Add (m, v); } }, { "d={-->}{=>}", "Alternate macro syntax.", (m, v) => macros.Add (m, v) }, { "o=", "Specify the output file", v => output = v }, // tar-like options { "f=", "The input file", v => input = v }, { "x", "Extract the file", v => extract = v != null }, { "c", "Create the file", v => create = v != null }, { "t", "List the file", v => list = v != null }, // ls-like optional values { "color:", "control whether and when color is used", v => color = v }, // other... { "h|help", "show this message and exit", v => show_help = v != null }, // default { "<>", v => Console.WriteLine ("def handler: color={0}; arg={1}", color, v)}, }; try { p.Parse (args); } catch (OptionException e) { Console.Write ("bundling: "); Console.WriteLine (e.Message); Console.WriteLine ("Try `greet --help' for more information."); return; } if (show_help) { ShowHelp (p); return; } Console.WriteLine ("Macros:"); foreach (var m in (from k in macros.Keys orderby k select k)) { Console.WriteLine ("\t{0}={1}", m, macros [m] ?? "<null>"); } Console.WriteLine ("Options:"); Console.WriteLine ("\t Input File: {0}", input); Console.WriteLine ("\tOuptut File: {0}", output); Console.WriteLine ("\t Create: {0}", create); Console.WriteLine ("\t Extract: {0}", extract); Console.WriteLine ("\t List: {0}", list); Console.WriteLine ("\t Color: {0}", color ?? "<null>"); } static void ShowHelp (OptionSet p) { Console.WriteLine ("Usage: bundling [OPTIONS]+"); Console.WriteLine ("Demo program to show the effects of bundling options and their values"); Console.WriteLine (); Console.WriteLine ("Options:"); p.WriteOptionDescriptions (Console.Out); } }The output (under the influence of different command-line arguments) is:
sh Example $ mono bundling.exe --help Usage: bundling [OPTIONS]+ Demo program to show the effects of bundling options and their values Options: -D[=VALUE1:VALUE2] Predefine a macro with an (optional) value. -d=VALUE1-->VALUE2 Alternate macro syntax. -o=VALUE Specify the output file -f=VALUE The input file -x Extract the file -c Create the file -t List the file --color[=VALUE] control whether and when color is used -h, --help show this message and exit $ mono bundling.exe -D bundling: Missing macro name for option -D. Try `greet --help' for more information. $ mono bundling.exe -DA -DB=C "-dD-->E" "-dF=>G" -d "H=>I" -cf input --color -ooutput Macros: A=<null> B=C D=E F=G H=I Options: Input File: input Ouptut File: output Create: True Extract: False List: False Color: <null> $ mono bundling.exe -cfv input def handler: color=; arg=input Macros: Options: Input File: v Ouptut File: Create: True Extract: False List: False Color: <null> $ mono bundling.exe -xctf input Macros: Options: Input File: input Ouptut File: Create: True Extract: True List: True Color: <null> $ mono bundling.exe --color=auto -o output -finput Macros: Options: Input File: input Ouptut File: output Create: False Extract: False List: False Color: auto $ mono bundling.exe --color=on A B --color=off C D def handler: color=on; arg=A def handler: color=on; arg=B def handler: color=off; arg=C def handler: color=off; arg=D Macros: Options: Input File: Ouptut File: Create: False Extract: False List: False Color: off
The following example shows a custom OptionSet subclass with the following additional functionality:
- Option name lookup is done in a case insensitive fashion, so --name and --NAME are identical.
- Option-like strings cannot be used as values to options, so --name --repeat is an error.
- A key/value parser is provided, to show the use of custom NDesk.Options.OptionContext and NDesk.Options.Option subclasses.
C# Example // Case-Insensitive and Concatenating OptionSet using System; using System.Collections.Generic; using NDesk.Options; class DemoOptionSet : OptionSet { protected override void InsertItem (int index, Option item) { if (item.Prototype.ToLower () != item.Prototype) throw new ArgumentException ("prototypes must be lower-case!"); base.InsertItem (index, item); } protected override OptionContext CreateOptionContext () { return new OptionContext (this); } protected override bool Parse (string option, OptionContext c) { string f, n, s, v; bool haveParts = GetOptionParts (option, out f, out n, out s, out v); Option nextOption = null; string newOption = option; if (haveParts) { string nl = n.ToLower (); nextOption = Contains (nl) ? this [nl] : null; newOption = f + n.ToLower () + (v != null ? s + v : ""); } if (c.Option != null) { // Prevent --a --b if (c.Option != null && haveParts) { if (nextOption == null) { // ignore } else throw new OptionException ( string.Format ("Found option `{0}' as value for option `{1}'.", option, c.OptionName), c.OptionName); } // have a option w/ required value; try to concat values. if (AppendValue (option, c)) { if (!option.EndsWith ("\\") && c.Option.MaxValueCount == c.OptionValues.Count) { c.Option.Invoke (c); } return true; } else base.Parse (newOption, c); } if (!haveParts || v == null) { // Not an option; let base handle as a non-option argument. return base.Parse (newOption, c); } if (nextOption.OptionValueType != OptionValueType.None && v.EndsWith ("\\")) { c.Option = nextOption; c.OptionValues.Add (v); c.OptionName = f + n; return true; } return base.Parse (newOption, c); } private bool AppendValue (string value, OptionContext c) { bool added = false; string[] seps = c.Option.GetValueSeparators (); foreach (var o in seps.Length != 0 ? value.Split (seps, StringSplitOptions.None) : new string[]{value}) { int idx = c.OptionValues.Count-1; if (idx == -1 || !c.OptionValues [idx].EndsWith ("\\")) { c.OptionValues.Add (o); added = true; } else { c.OptionValues [idx] += value; added = true; } } return added; } } class Demo { public static void Main (string[] args) { List<string> names = new List<string> (); Dictionary<string,string> map = new Dictionary<string,string> (); int repeat = 1; OptionSet p = new DemoOptionSet () { { "n|name=", v => names.Add (v) }, { "r|repeat:", (int v) => repeat = v }, { "m|map=", (k,v) => map.Add (k, v) }, }; List<string> extra; try { extra = p.Parse (args); } catch (OptionException e) { Console.Write ("subclass: "); Console.WriteLine (e.Message); return; } string message; if (extra.Count > 0) { message = string.Join (" ", extra.ToArray ()); } else { message = "Hello {0}!"; } foreach (string name in names) { for (int i = 0; i < repeat; ++i) Console.WriteLine (message, name); } List<string> keys = new List<string>(map.Keys); keys.Sort (); foreach (string key in keys) { Console.WriteLine ("Key: {0}={1}", key, map [key]); } } }The output (under the influence of different command-line arguments) is:
sh Example $ mono subclass.exe -n A -Name=B --NAME=C /nAMe D Hello A! Hello B! Hello C! Hello D! $ mono subclass.exe --Repeat -name A $ mono subclass.exe -Name --Repeat 3 subclass: Found option `--Repeat' as value for option `-name'. $ mono subclass.exe --Map a b -mAp c=d /maP=e=f Key: a=b Key: c=d Key: e=f $ mono subclass.exe --map 'a\' 'b\' c 'd\' 'e\' f Key: a\b\c=d\e\fNotice:
- That --name is treated in a case-insensitive fashion.
- That repeat has an optional value, so with --Repeat -name A the default int value is passed (0), so no message is printed.
- That name has a required value, so -Name --Repeat 3 generates an error.
- The DemoOptionSet.Add() method provides appropriate key/value option pairs to the callback method.
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
See Also: Inherited members from System.Collections.ObjectModel.KeyedCollection<string, Option>.
⊟ Public Constructors
OptionSet ()Creates and initializes a new NDesk.Options.OptionSet class instance. Creates and initializes a new NDesk.Options.OptionSet class instance. ⊟ Public Properties
[read-only] MessageLocalizer Converter<string, string> . Permits access to the message localization facility. ⊟ Public Methods
Add (Option) : OptionSet Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(IEnumerable<string>).Add (string, OptionAction<string, string>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add (string, Action<string>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add (string, string, OptionAction<string, string>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add (string, string, Action<string>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add<T> (string, Action<T>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add<T> (string, string, Action<T>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add<TKey,TValue> (string, OptionAction<TKey, TValue>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Add<TKey,TValue> (string, string, OptionAction<TKey, TValue>) : OptionSet Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.Parse (IEnumerable<string>) : List<string> Parses each string within arguments, invoking any registered actions if a registered option is encountered.WriteOptionDescriptions (System.IO.TextWriter) Writes NDesk.Options.Option documentation to o.⊟ Protected Methods
CreateOptionContext () : OptionContext Creates an NDesk.Options.OptionContext instance. overrideGetKeyForItem (Option) : string Returns item.GetNames()[0].GetOptionForName (string) : Option Looks up the NDesk.Options.Option registered to handle the option name option.GetOptionParts (string, out string, out string, out string, out string) : bool Splits argument into its constituent parts. overrideInsertItem (int, Option) Inserts item at the specified index.Parse (string, OptionContext) : bool Parses argument and invokes Option.Invoke(OptionContext) if appropriate. overrideRemoveItem (int) Removes the NDesk.Options.Option at the specified index. overrideSetItem (int, Option) Removes the current NDesk.Options.Option at index and sets item as the value for the index value.
⊟ OptionSet Constructor
Creates and initializes a new NDesk.Options.OptionSet class instance.
public OptionSet ()⊟ See Also
⊟ Remarks
This constructor causes the created NDesk.Options.OptionSet instance to perform no translation of string messages; consequently, no localization is performed.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ OptionSet Constructor
Creates and initializes a new NDesk.Options.OptionSet class instance.
public OptionSet (Converter<string, string> localizer)⊟ Parameters
- localizer
- A Converter<string, string> instance that will be used to translate strings.
⊟ Remarks
This constructor initializes the OptionSet.MessageLocalizer property of the new instance using localizer.
Use this constructor when you want to perform some form of localization or internationalization on text strings generated from the NDesk.Options.OptionSet class. Generated strings include:
- The Option.Description written by OptionSet.WriteOptionDescriptions(System.IO.TextWriter), but not the option names themselves.
- Message format strings used when an error is encountered.
⊟ Example
See the following example, which demonstrates how different localizers alter the program output.
C# Example // Localization with NDesk.Options.OptionSet. // // Compile as: // gmcs -r:Mono.Posix.dll -r:NDesk.Options.dll code-localization.cs using System; using System.IO; using Mono.Unix; using NDesk.Options; class LocalizationDemo { public static void Main (string[] args) { bool with_gettext = false; string useLocalizer = null; var p = new OptionSet () { { "with-gettext", v => { useLocalizer = "gettext"; } }, { "with-hello", v => { useLocalizer = "hello"; } }, { "with-default", v => { /* do nothing */ } }, }; p.Parse (args); Converter<string, string> localizer = f => f; switch (useLocalizer) { case "gettext": Catalog.Init ("localization", Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "locale")); localizer = f => { return Catalog.GetString (f); }; break; case "hello": localizer = f => { return "hello:" + f; };; break; } bool help = false; int verbose = 0; bool version = false; p = new OptionSet (localizer) { { "h|?|help", "show this message and exit.", v => help = v != null }, { "v|verbose", "increase message verbosity.", v => { ++verbose; } }, { "n=", "must be an int", (int n) => { /* ignore */ } }, { "V|version", "output version information and exit.", v => version = v != null }, }; try { p.Parse (args); } catch (OptionException e) { Console.Write ("localization: "); Console.WriteLine (e.Message); return; } if (help) p.WriteOptionDescriptions (Console.Out); if (version) Console.WriteLine ("NDesk.Options Localizer Demo 1.0"); if (verbose > 0) Console.WriteLine ("Message level: {0}", verbose); } }The output (under the influence of different command-line arguments) is:
sh Example $ mono localization.exe --help --version -h, -?, --help show this message and exit. -v, --verbose increase message verbosity. -n=VALUE must be an int -V, --version output version information and exit. NDesk.Options Localizer Demo 1.0 $ LANGUAGE=es mono localization.exe --with-gettext --help --version -h, -?, --help A mostrar este mensaje y salir. -v, --verbose Aumento mensaje verbosidad. -n=VALUE Debe ser un int -V, --version Salida de información de versión y sale. NDesk.Options Localizer Demo 1.0 $ mono localization.exe --with-hello --help --version -h, -?, --help hello:show this message and exit. -v, --verbose hello:increase message verbosity. -nhello:=VALUE hello:must be an int -V, --version hello:output version information and exit. NDesk.Options Localizer Demo 1.0 $ mono localization.exe -n not-an-int localization: Could not convert string `not-an-int' to type Int32 for option `-n'. $ mono localization.exe --with-hello -n not-an-int localization: hello:Could not convert string `not-an-int' to type Int32 for option `-n'.Notice:
- The --with-gettext parser uses Mono.Unix.Catalog.GetString to translate all messages
- The -with-hello parser prefixes all descriptions with hello:.
- Only the descriptions are translated, and not the command-line arguments themselves. Only error messages and option descriptions are translated, not the options themselves.
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add Method
Registers option so that any options matching Option.GetNames will be treated specially by OptionSet.Parse(IEnumerable<string>).
⊟ Parameters
- option
- The NDesk.Options.Option to register.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException option is null. ⊟ Remarks
Registers each option name returned by Option.GetNames, ensuring that any option with a matching name will be handled by the option instance.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- action
- A NDesk.Options.OptionAction<string, string> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
Calls OptionSet.Add(string, string, OptionAction<string, string>) with a description value of null.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- action
- A Action<string> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
Calls OptionSet.Add(string, string, Action<string>) with a description value of null.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- description
- A string to be used to initialize the Option.Description property.
- action
- A NDesk.Options.OptionAction<string, string> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
Use this method when prototype should accept two values, generally a key and a value.
Note: If prototype specifies a OptionValueType.Optional option, then it's possible that both the key and the value will be null in the callback function.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- description
- A string containing to used to initialize the Option.Description property.
- action
- A Action<string> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add<T> Generic Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Type Parameters
- T
- The type of the option to parse and provide to the action callback.
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- action
- A Action<``0> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ⊟ Remarks
Calls OptionSet.Add``1(string, string, Action<``0>) with a description value of null.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add<T> Generic Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Type Parameters
- T
- The type of the option to parse and provide to the action callback.
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- description
- A string containing to used to initialize the Option.Description property.
- action
- A Action<``0> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException option has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
Use this typed overload when you want strongly typed option values that correspond to a managed type. System.ComponentModel.TypeDescriptor.GetConverter(Type) is used to lookup the System.ComponentModel.TypeConverter to use when performing the string-to-type conversion.
Note:If prototype specifies an OptionValueType.Optional value and the value is not provided, then default(T) is provided as the value to action.
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add<TKey,TValue> Generic Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
⊟ See Also
⊟ Type Parameters
- TKey
- The type of the first argument to parse and provide to the action callback.
- TValue
- The type of the second argument to parse and provide to the action callback.
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- action
- A NDesk.Options.OptionAction<TKey, TValue> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
Calls OptionSet.Add``2(string, string, OptionAction<``0, ``1>) with a description value of null.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Add<TKey,TValue> Generic Method
Registers each alias within prototype so that any options matching the aliases in prototype will be handled by action during any subsequent OptionSet.Parse(IEnumerable<string>) calls.
public OptionSet Add<TKey, TValue> (string prototype, string description, OptionAction<TKey, TValue> action)⊟ See Also
⊟ Type Parameters
- TKey
- The type of the first argument to parse and provide to the action callback.
- TValue
- The type of the second argument to parse and provide to the action callback.
⊟ Parameters
- prototype
- A string containing all option aliases to register, an (optional) type specifier, and an (optional) value separator list; see Option(string, string, int) for details.
- description
- A string to be used to initialize the Option.Description property.
- action
- A NDesk.Options.OptionAction<TKey, TValue> to invoke when an option is parsed.
⊟ Returns
The current NDesk.Options.OptionSet instance. This is to permit method chaining.⊟ Exceptions
Type Reason ArgumentException prototype has an alias (as returned from Option.GetNames) that conflicts with a previously registered NDesk.Options.Option. ArgumentNullException prototype is null
-or-
action is null
⊟ Remarks
Use this method when prototype should accept two typed values, generally a key and a value.
Note:If prototype specifies an OptionValueType.Optional value and the value is not provided, then default(TKey) and default(TValue) may be provided as the values to action.
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ CreateOptionContext Method
Creates an NDesk.Options.OptionContext instance.
protected virtual OptionContext CreateOptionContext ()⊟ See Also
⊟ Returns
A NDesk.Options.OptionContext instance to be used when parsing all options during the current OptionSet.Parse(IEnumerable<string>) call.⊟ Remarks
Note to Inheritors
This method can be overridden if OptionSet.Parse(string, OptionContext) is overridden and requires access to an NDesk.Options.OptionContext subclass to store additional information during the current OptionSet.Parse(IEnumerable<string>) invocation.
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ GetKeyForItem Method
Returns item.GetNames()[0].
⊟ Parameters
- item
- An NDesk.Options.Option to return the key of.
⊟ Returns
A string containing the first alias returned by Option.GetNames.⊟ Remarks
This is to support the System.Collections.ObjectModel.KeyedCollection<string, NDesk.Options.Option> infrastructure. System.Collections.ObjectModel.KeyedCollection<string, NDesk.Options.Option> assumes only one key per item, so we arbitrarily choose the first item in the option alias list.
Note: All aliases returned by Option.GetNames are still registered with System.Collections.ObjectModel.KeyedCollection<string, NDesk.Options.Option> even though OptionSet.GetKeyForItem(Option) will never return them. Consequently, System.Collections.ObjectModel.KeyedCollection<string, Option>.Contains(`0) and System.Collections.ObjectModel.KeyedCollection<string, Option>.Item(`0) will both correctly use all aliases returned by Option.GetNames.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.1.0
⊟ GetOptionForName Method
Looks up the NDesk.Options.Option registered to handle the option name option.
[System.Obsolete("Use KeyedCollection.this[string]")]
protected Option GetOptionForName (string option)⊟ See Also
⊟ Parameters
- option
- A string containing the option name to lookup.
⊟ Returns
The NDesk.Options.Option instance registered to handle the option name option. If there is no registered handler for option, then null is returned.⊟ Exceptions
Type Reason ArgumentNullException option is null. ⊟ Remarks
Subclasses can use this function to perform option lookup when overriding OptionSet.Parse(string, OptionContext).⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ GetOptionParts Method
Splits argument into its constituent parts.
protected bool GetOptionParts (string argument, out string flag, out string name, out string sep, out string value)⊟ Parameters
- argument
- A string containing the option to parse into its constituent parts.
- flag
- A string reference which will be set to null if the method returns false, or set to the flag the option starts with if the method returns true. Valid flags include: -, --, and /.
- name
- A string reference which will be set to null if the method returns false, or set to the option name following a valid flag if the method returns true. No lookup is made to determine that flag has been registered via a prior call to OptionSet.Add(Option) or related overload.
- sep
- A string reference which will be set to null if either the method returns false or if = or : was not found within argument; if the method returns true and argument contains a = or :, then sep will contain either = or :, whichever was found within argument.
- value
- A string reference which will be set to null if either the method returns false or if sep is null; if the method returns true and sep is not null, then value will contain all text after sep.
⊟ Returns
true if argument could be split into its constituent parts, and flag and name are set (sep and value may not be set, depending on whether or not they are present within argument); true if argument is not the possible start of a valid option.⊟ Exceptions
Type Reason ArgumentNullException argument is null. ⊟ Remarks
Subclasses can call this method from their OptionSet.Parse(string, OptionContext) method to determine whether a given string is an option, and to split the option up for further processing.
For example, GetOptionParts("foo", ...) would return false, while GetOptionParts("--foo=bar", ...) would result in flag containing --, name containing foo, sep containing =, and value containing bar.
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ InsertItem Method
Inserts item at the specified index.
⊟ Parameters
- index
- A int specifying the index to insert item into.
- item
- The NDesk.Options.Option to insert.
⊟ Remarks
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ MessageLocalizer Property
Permits access to the message localization facility.
public Converter<string, string> MessageLocalizer { get; }⊟ See Also
⊟ Value
A Converter<string, string> that can be used to localize messages.⊟ Remarks
NDesk.Options.Option subclasses can use this property (via OptionContext.OptionSet) to perform message localization for their own exception messages.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Parse Method
Parses each string within arguments, invoking any registered actions if a registered option is encountered.
public List<string> Parse (IEnumerable<string> arguments)⊟ Parameters
- arguments
- A IEnumerable<string> containing all arguments to parse.
⊟ Returns
A List<string> containing all unhandled arguments.⊟ Exceptions
Type Reason NDesk.Options.OptionException A value was not found for an NDesk.Options.Option requiring a value.
-or-
An attempt was made to bundle together an option requiring a value.
-or-
An exception was generated when trying to convert the value to the type T, for options added with OptionSet.Add``1(string, string, Action<``0>) and related methods. The originating exception is provided via the Exception.InnerException property.
⊟ Remarks
An argument is unhandled if:
- There is no default handler registered (the <> handler). If there is a default handler registered, then the default handler is invoked for otherwise-unhandled arguments.
- The option starts with a flag such as -, --, /, and the option name following the flag is unregistered.
- Or, the option does not start with a flag, and there is no prior parsed option that accepts a value that would use the argument as its value.
Furthermore, argument parsing (including default handler invocation) stops whenever the -- option is encountered. This is in accordance with GNU conventions, and is frequently used to permit users to provide option-like filenames, e.g. ls -lF -- -l to view the file -l instead of needing to use ls -lF ./-l.
⊟ Example
The following example demonstrates some simple usage of NDesk.Options.OptionSet.
C# Example using System; using System.Collections.Generic; using NDesk.Options; class Test { static int verbosity; public static void Main (string[] args) { bool show_help = false; List<string> names = new List<string> (); int repeat = 1; var p = new OptionSet () { { "n|name=", "the {NAME} of someone to greet.", v => names.Add (v) }, { "r|repeat=", "the number of {TIMES} to repeat the greeting.\n" + "this must be an integer.", (int v) => repeat = v }, { "v", "increase debug message verbosity", v => { if (v != null) ++verbosity; } }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List<string> extra; try { extra = p.Parse (args); } catch (OptionException e) { Console.Write ("greet: "); Console.WriteLine (e.Message); Console.WriteLine ("Try `greet --help' for more information."); return; } if (show_help) { ShowHelp (p); return; } string message; if (extra.Count > 0) { message = string.Join (" ", extra.ToArray ()); Debug ("Using new message: {0}", message); } else { message = "Hello {0}!"; Debug ("Using default message: {0}", message); } foreach (string name in names) { for (int i = 0; i < repeat; ++i) Console.WriteLine (message, name); } } static void ShowHelp (OptionSet p) { Console.WriteLine ("Usage: greet [OPTIONS]+ message"); Console.WriteLine ("Greet a list of individuals with an optional message."); Console.WriteLine ("If no message is specified, a generic greeting is used."); Console.WriteLine (); Console.WriteLine ("Options:"); p.WriteOptionDescriptions (Console.Out); } static void Debug (string format, params object[] args) { if (verbosity > 0) { Console.Write ("# "); Console.WriteLine (format, args); } } }⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ Parse Method
Parses argument and invokes Option.Invoke(OptionContext) if appropriate.
⊟ See Also
⊟ Parameters
- argument
- A string containing the current option to parse.
- c
- A NDesk.Options.OptionContext containing the current parser context.
⊟ Returns
A bool specifying whether or not argument was handled. If false, then OptionSet.Parse(IEnumerable<string>) will return argument as an unhandled option.⊟ Remarks
This method is called for each string within the IEnumerable<string> provided to OptionSet.Parse(IEnumerable<string>), which thus gives this method a chance to parse a single option, or chain together multiple options to form a single option (as is necessary when an option and its value are separated, e.g. with -option value).
Operation
The default implementation will check OptionContext.Option, which is assumed to be a NDesk.Options.Option in need of a value. If OptionContext.Option is non-null, then argument is OptionValueCollection.Add(string)ed to OptionContext.OptionValues and Option.Invoke(OptionContext) is invoked.
Next, OptionSet.GetOptionParts(string, String@, String@, String@, String@) is invoked. If GetOptionParts returns false, then false is returned from Parse.
Finally, check to see if the name returned from GetOptionParts is registered; if it is, handle it appropriately. If it isn't, check to see if name is a bundled option or a boolean option. If name isn't any registered option, then false is returned. Otherwise, true is returned.
Note to Inheritors
Inheriting types can override this method if they want to customize the per-option parsing within the containing OptionSet.Parse(IEnumerable<string>) invocation.
Inheriting types should consider overriding OptionSet.CreateOptionContext if they want to store extra information for use and retrieval during each Parse invocation.
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ RemoveItem Method
Removes the NDesk.Options.Option at the specified index.
⊟ Parameters
- index
- A int containing the index of the NDesk.Options.Option to remove.
⊟ Remarks
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ SetItem Method
Removes the current NDesk.Options.Option at index and sets item as the value for the index value.
⊟ Parameters
- index
- A int containing the index of the NDesk.Options.Option to change.
- item
- The new NDesk.Options.Option to set at index.
⊟ Remarks
⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0
⊟ WriteOptionDescriptions Method
Writes NDesk.Options.Option documentation to o.
public void WriteOptionDescriptions (System.IO.TextWriter o)⊟ Parameters
- o
- The System.IO.TextWriter to write option descriptions to.
⊟ Remarks
For each NDesk.Options.Option previously added to the current instance, this method writes out a comma-separated list of all Option.GetNames followed by the Option.Description.
The Option.Description is automatically wrapped so that output will flow nicely across multiple lines. Wrapping is preferred at explicit embedded newline characters (\n) or spaces, but words will be split (by adding a -) if necessary.
Options requiring a value have =VALUE appended to their last name, while options with an optional value have [=VALUE] appended to their last name. The VALUE string can be changed by using a format specifier-like string within the Option.Description.
For NDesk.Options.Options accepting one value, the string {VALUE} or {0:VALUE} can be used to explicitly provide the value name. For Options accepting more than one value, the leading number is used to specify which value the string is for.
⊟ Example
The following example initializes a NDesk.Options.OptionSet instance to accept a variety of parameters and provides a description for each parameter:
C# Example using System; using System.Collections.Generic; using NDesk.Options; class Test { static int verbosity; public static void Main (string[] args) { bool show_help = false; List<string> names = new List<string> (); int repeat = 1; var p = new OptionSet () { { "n|name=", "the {NAME} of someone to greet.", v => names.Add (v) }, { "r|repeat=", "the number of {TIMES} to repeat the greeting.\n" + "this must be an integer.", (int v) => repeat = v }, { "v", "increase debug message verbosity", v => { if (v != null) ++verbosity; } }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List<string> extra; try { extra = p.Parse (args); } catch (OptionException e) { Console.Write ("greet: "); Console.WriteLine (e.Message); Console.WriteLine ("Try `greet --help' for more information."); return; } if (show_help) { ShowHelp (p); return; } string message; if (extra.Count > 0) { message = string.Join (" ", extra.ToArray ()); Debug ("Using new message: {0}", message); } else { message = "Hello {0}!"; Debug ("Using default message: {0}", message); } foreach (string name in names) { for (int i = 0; i < repeat; ++i) Console.WriteLine (message, name); } } static void ShowHelp (OptionSet p) { Console.WriteLine ("Usage: greet [OPTIONS]+ message"); Console.WriteLine ("Greet a list of individuals with an optional message."); Console.WriteLine ("If no message is specified, a generic greeting is used."); Console.WriteLine (); Console.WriteLine ("Options:"); p.WriteOptionDescriptions (Console.Out); } static void Debug (string format, params object[] args) { if (verbosity > 0) { Console.Write ("# "); Console.WriteLine (format, args); } } }Notice that when the above program is invoked with the --help parameter, OptionSet.WriteOptionDescriptions(System.IO.TextWriter) is used to generate the NDesk.Options.Option description, that the --repeat description spans multiple lines, and that format specifiers such as {NAME} are used to provide a description for the option value:
sh Example $ mono greet.exe --help Usage: greet [OPTIONS]+ message Greet a list of individuals with an optional message. If no message is specified, a generic greeting is used. Options: -n, --name=NAME the NAME of someone to greet. -r, --repeat=TIMES the number of TIMES to repeat the greeting. this must be an integer. -v increase debug message verbosity -h, --help show this message and exit $ mono greet.exe -v- -n A -name=B --name=C /name D -nE Hello A! Hello B! Hello C! Hello D! Hello E! $ mono greet.exe -v -n E custom greeting for: {0} # Using new message: custom greeting for: {0} custom greeting for: E $ mono greet.exe -r 3 -n A Hello A! Hello A! Hello A! $ mono greet.exe -r not-an-int greet: Could not convert string `not-an-int' to type Int32 for option `-r'. Try `greet --help' for more information.⊟ Requirements
Namespace: NDesk.Options
Assembly: NDesk.Options (in NDesk.Options.dll)
Assembly Versions: 0.2.0.0, 0.2.1.0