From f8e2f911a3813c45b8753a0412ab624be770f298 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Jan 2018 16:21:25 +0100 Subject: [PATCH 1/5] Make the plain string constructor work It would split but never called Extract() --- Source/Util/ArgvParser.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Util/ArgvParser.cs b/Source/Util/ArgvParser.cs index 885fa86..d9b4433 100644 --- a/Source/Util/ArgvParser.cs +++ b/Source/Util/ArgvParser.cs @@ -43,6 +43,8 @@ public ArgvParser(string args) { parts[i-1] = matches[i].Value.Trim (); } + + Extract(parts); } /// From 3e3affd1acec81edc0cbb9bd3120f10f506a36f9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Jan 2018 16:22:06 +0100 Subject: [PATCH 2/5] Prevent a parameter from consuming all non-option args --- Source/Util/ArgvParser.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Util/ArgvParser.cs b/Source/Util/ArgvParser.cs index d9b4433..225d4f7 100644 --- a/Source/Util/ArgvParser.cs +++ b/Source/Util/ArgvParser.cs @@ -85,6 +85,7 @@ 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 { // Matched a name, optionally with inline value From d2d739072807c431be29ad3d22d3a2c2fa0c05e7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Jan 2018 16:37:09 +0100 Subject: [PATCH 3/5] Add support for positional parameters (non-option arguments) Bringing this in line with the capabilities of getopt_long --- Source/Config/ArgvConfigSource.cs | 12 +++++++++++- Source/Nini.sln | 4 ++-- Source/Util/ArgvParser.cs | 20 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Source/Config/ArgvConfigSource.cs b/Source/Config/ArgvConfigSource.cs index 7855ffa..2b16a2e 100644 --- a/Source/Config/ArgvConfigSource.cs +++ b/Source/Config/ArgvConfigSource.cs @@ -82,6 +82,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 +113,4 @@ private IConfig GetConfig (string name) } #endregion } -} \ No newline at end of file +} diff --git a/Source/Nini.sln b/Source/Nini.sln index 7357198..eb76031 100644 --- a/Source/Nini.sln +++ b/Source/Nini.sln @@ -2,8 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nini", "Nini.csproj", "{9B920C90-08EF-4123-A6B7-5F25CF0F94EC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NiniTest", "Test\NiniTest.csproj", "{BF80879B-3F0D-44A8-87FF-00143FDD3D16}" -EndProject +#Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NiniTest", "Test\NiniTest.csproj", "{BF80879B-3F0D-44A8-87FF-00143FDD3D16}" +#EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Source/Util/ArgvParser.cs b/Source/Util/ArgvParser.cs index 225d4f7..f72642c 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,7 @@ public class ArgvParser { #region Private variables StringDictionary parameters; + List positional; #endregion #region Constructors @@ -62,6 +64,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 @@ -69,6 +86,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 = {'"','\''}; @@ -86,6 +104,8 @@ private void Extract(string[] args) if (parameter != null) { parameters[parameter] = arg.Trim (trimChars); parameter = null; + } else { + positional.Add(arg.Trim(trimChars)); } } else { // Matched a name, optionally with inline value From 3090c0fc67dc28c9908c34e276fd1c5f9e4285cb Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Jan 2018 16:40:24 +0100 Subject: [PATCH 4/5] Reinstate the accidentally commented-out tests --- Source/Nini.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Nini.sln b/Source/Nini.sln index eb76031..7357198 100644 --- a/Source/Nini.sln +++ b/Source/Nini.sln @@ -2,8 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nini", "Nini.csproj", "{9B920C90-08EF-4123-A6B7-5F25CF0F94EC}" EndProject -#Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NiniTest", "Test\NiniTest.csproj", "{BF80879B-3F0D-44A8-87FF-00143FDD3D16}" -#EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NiniTest", "Test\NiniTest.csproj", "{BF80879B-3F0D-44A8-87FF-00143FDD3D16}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From 559c1962e83c59effabd2426541d908b28e23500 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Jan 2018 18:32:27 +0100 Subject: [PATCH 5/5] Allow specification of parameterless options. --- Source/Config/ArgvConfigSource.cs | 17 +++++++++++++++-- Source/Util/ArgvParser.cs | 10 +++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Source/Config/ArgvConfigSource.cs b/Source/Config/ArgvConfigSource.cs index 2b16a2e..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]); diff --git a/Source/Util/ArgvParser.cs b/Source/Util/ArgvParser.cs index f72642c..02befc7 100644 --- a/Source/Util/ArgvParser.cs +++ b/Source/Util/ArgvParser.cs @@ -24,6 +24,7 @@ public class ArgvParser #region Private variables StringDictionary parameters; List positional; + List parameterlessArgs; #endregion #region Constructors @@ -50,8 +51,9 @@ public ArgvParser(string args) } /// - public ArgvParser (string[] args) + public ArgvParser (string[] args, List paramlessArgs) { + parameterlessArgs = paramlessArgs; Extract (args); } #endregion @@ -112,6 +114,12 @@ private void Extract(string[] args) 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; + } } } }