diff --git a/Source/Config/ArgvConfigSource.cs b/Source/Config/ArgvConfigSource.cs index 7855ffa..6c8567b 100644 --- a/Source/Config/ArgvConfigSource.cs +++ b/Source/Config/ArgvConfigSource.cs @@ -12,6 +12,7 @@ using System.IO; using System.Text; using System.Collections; +using System.Collections.Generic; using Nini.Util; namespace Nini.Config @@ -22,13 +23,14 @@ public class ArgvConfigSource : ConfigSourceBase #region Private variables ArgvParser parser = null; string[] arguments = null; + List parameterlessArgs = new List(); #endregion #region Constructors /// public ArgvConfigSource (string[] arguments) { - parser = new ArgvParser (arguments); + parser = new ArgvParser (arguments, parameterlessArgs); this.arguments = arguments; } #endregion @@ -57,7 +59,7 @@ public void AddSwitch (string configName, string longName) /// public void AddSwitch (string configName, string longName, - string shortName) + string shortName, bool parameterless = false) { IConfig config = GetConfig (configName); @@ -66,6 +68,17 @@ public void AddSwitch (string configName, string longName, throw new ArgumentException ("Short name may only be 1 or 2 characters"); } + if (parameterless) + { + parameterlessArgs.Add(longName); + if (shortName != null) + parameterlessArgs.Add(shortName); + + // Re-parse because there is a new parameterless argument. This will change + // the meaning of non-option args + parser = new ArgvParser (arguments, parameterlessArgs); + } + // Look for the long name first if (parser[longName] != null) { config.Set (longName, parser[longName]); @@ -82,6 +95,16 @@ public string[] GetArguments () return result; } + + public int GetPositionalArgumentCount() + { + return parser.Count(); + } + + public string GetPositionalArgument(int index) + { + return parser[index]; + } #endregion #region Private methods @@ -103,4 +126,4 @@ private IConfig GetConfig (string name) } #endregion } -} \ No newline at end of file +} diff --git a/Source/Util/ArgvParser.cs b/Source/Util/ArgvParser.cs index 885fa86..02befc7 100644 --- a/Source/Util/ArgvParser.cs +++ b/Source/Util/ArgvParser.cs @@ -12,6 +12,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Collections.Specialized; using System.Text.RegularExpressions; @@ -22,6 +23,8 @@ public class ArgvParser { #region Private variables StringDictionary parameters; + List positional; + List parameterlessArgs; #endregion #region Constructors @@ -43,11 +46,14 @@ public ArgvParser(string args) { parts[i-1] = matches[i].Value.Trim (); } + + Extract(parts); } /// - public ArgvParser (string[] args) + public ArgvParser (string[] args, List paramlessArgs) { + parameterlessArgs = paramlessArgs; Extract (args); } #endregion @@ -60,6 +66,21 @@ public string this [string param] return parameters[param]; } } + + public string this [int number] + { + get { + if (number < 0 || number >= positional.Count) + return String.Empty; + + return positional[number]; + } + } + + public int Count() + { + return positional.Count; + } #endregion #region Private methods @@ -67,6 +88,7 @@ public string this [string param] private void Extract(string[] args) { parameters = new StringDictionary(); + positional = new List(); Regex splitter = new Regex (@"^([/-]|--){1}(?\w+)([:=])?(?.+)?$", RegexOptions.Compiled); char[] trimChars = {'"','\''}; @@ -83,12 +105,21 @@ private void Extract(string[] args) // Found a value (for the last parameter found (space separator)) if (parameter != null) { parameters[parameter] = arg.Trim (trimChars); + parameter = null; + } else { + positional.Add(arg.Trim(trimChars)); } } else { // Matched a name, optionally with inline value parameter = part.Groups["name"].Value; parameters.Add (parameter, part.Groups["value"].Value.Trim (trimChars)); + if (parameterlessArgs != null && parameterlessArgs.Contains(parameter)) + { + // Make it true and don't look for an argument + parameters[parameter] = "True"; + parameter = null; + } } } }