Skip to content

Commit f82437c

Browse files
committed
Fixed bug with parsing of multiple quoted arguments. Added a test for values with inner quotes, fixed the value trimming code to only trim the outermost pair.
1 parent ce14242 commit f82437c

File tree

2 files changed

+51
-27
lines changed

2 files changed

+51
-27
lines changed

Utility.CommandLine.Arguments.Tests/Arguments.cs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,27 +86,27 @@ public class Arguments
8686
private static string LowerCase { get; set; }
8787

8888
/// <summary>
89-
/// Gets or sets a test property.
89+
/// Gets or sets a property with no attribute.
9090
/// </summary>
91-
[CommandLine.Argument('t', "test-prop")]
92-
private static string TestProp { get; set; }
91+
private static string NonArgumentProperty { get; set; }
9392

9493
/// <summary>
95-
/// Gets or sets a test property.
94+
/// Gets or sets a property with an attribute other than Argument
9695
/// </summary>
97-
[CommandLine.Argument('C', "CASE-SENSITIVE")]
98-
private static string UpperCase { get; set; }
96+
[Obsolete]
97+
private static string PlainProperty { get; set; }
9998

10099
/// <summary>
101-
/// Gets or sets a property with no attribute.
100+
/// Gets or sets a test property.
102101
/// </summary>
103-
private static string NonArgumentProperty { get; set; }
102+
[CommandLine.Argument('t', "test-prop")]
103+
private static string TestProp { get; set; }
104104

105105
/// <summary>
106-
/// Gets or sets a property with an attribute other than Argument
106+
/// Gets or sets a test property.
107107
/// </summary>
108-
[Obsolete]
109-
private static string PlainProperty { get; set; }
108+
[CommandLine.Argument('C', "CASE-SENSITIVE")]
109+
private static string UpperCase { get; set; }
110110

111111
#endregion Private Properties
112112

@@ -145,6 +145,19 @@ public void ParseCaseSensitive()
145145
Assert.False(test.ContainsKey("C"));
146146
}
147147

148+
/// <summary>
149+
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an exclicit command line string
150+
/// containing values with inner quoted strings.
151+
/// </summary>
152+
[Fact]
153+
public void ParseInnerQuotedStrings()
154+
{
155+
Dictionary<string, string> test = CommandLine.Arguments.Parse("--test1 \"test \'1\'\" --test2 \'test \"2\"\'");
156+
157+
Assert.Equal("test \'1\'", test["test1"]);
158+
Assert.Equal("test \"2\"", test["test2"]);
159+
}
160+
148161
/// <summary>
149162
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an explicit command line string
150163
/// containing a mixture of short and long arguments.
@@ -162,6 +175,21 @@ public void ParseLongAndShortMix()
162175
Assert.Equal("4", test["4"]);
163176
}
164177

178+
/// <summary>
179+
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an explicit command line string
180+
/// containing multiple pairs of arguments containing quoted values.
181+
/// </summary>
182+
[Fact]
183+
public void ParseMultipleQuotes()
184+
{
185+
Dictionary<string, string> test = CommandLine.Arguments.Parse("--test1 \"1\" --test2 \"2\" --test3 \'3\' --test4 \'4\'");
186+
187+
Assert.Equal("1", test["test1"]);
188+
Assert.Equal("2", test["test2"]);
189+
Assert.Equal("3", test["test3"]);
190+
Assert.Equal("4", test["test4"]);
191+
}
192+
165193
/// <summary>
166194
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an explicit command line string
167195
/// containing only short parameters.
@@ -199,20 +227,6 @@ public void ParseStringOfLongs()
199227
Assert.Equal("5 5", test["five"]);
200228
}
201229

202-
/// <summary>
203-
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an explicit command line string containing multiple pairs of arguments containing quoted values.
204-
/// </summary>
205-
[Fact]
206-
public void ParseMultipleQuotes()
207-
{
208-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--test1 \"1\" --test2 \"2\" --test3 \'3\' --test4 \'4\'");
209-
210-
Assert.Equal("1", test["test1"]);
211-
Assert.Equal("2", test["test2"]);
212-
Assert.Equal("3", test["test3"]);
213-
Assert.Equal("4", test["test4"]);
214-
}
215-
216230
/// <summary>
217231
/// Tests the <see cref="Utility.CommandLine.Arguments.Populate(string)"/> method with the default values.
218232
/// </summary>

Utility.CommandLine.Arguments/Arguments.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public static class Arguments
6666
/// <summary>
6767
/// The regular expression with which to parse the command line string.
6868
/// </summary>
69-
private const string ArgumentRegEx = "(?:[-]{1,2}|\\/)([\\w-]+)[=|:| ]?(\\w\\S*|\\\".*\\\"|\\\'.*\\\')?";
69+
private const string ArgumentRegEx = "(?:[-]{1,2}|\\/)([\\w-]+)[=|:| ]?(\\w\\S*|\\\"[^\".]*\\\"|\\\'[^'.]*\\\')?";
7070

7171
/// <summary>
7272
/// The regular expression with which to parse argument-value groups.
@@ -232,7 +232,17 @@ private static Dictionary<string, string> GetArgumentDictionary(string commandLi
232232
{
233233
string fullMatch = match.Groups[0].Value;
234234
string argument = match.Groups[1].Value;
235-
string value = match.Groups[2].Value.Trim('"', '\'');
235+
string value = match.Groups[2].Value;
236+
237+
// trim outer quotes, if present
238+
if (value.StartsWith("\"") && value.EndsWith("\""))
239+
{
240+
value = value.Trim('"');
241+
}
242+
else if (value.StartsWith("'") && value.EndsWith("'"))
243+
{
244+
value = value.Trim('\'');
245+
}
236246

237247
// check to see if the argument uses a single dash. if so, split the argument name into a char array and add each
238248
// to the dictionary. if a value is specified, it belongs to the final character.

0 commit comments

Comments
 (0)