diff --git a/src/CommandLine/Core/Tokenizer.cs b/src/CommandLine/Core/Tokenizer.cs index 902b65e4..e0e09fd3 100644 --- a/src/CommandLine/Core/Tokenizer.cs +++ b/src/CommandLine/Core/Tokenizer.cs @@ -6,6 +6,7 @@ using CommandLine.Infrastructure; using CSharpx; using RailwaySharp.ErrorHandling; +using System.Text.RegularExpressions; namespace CommandLine.Core { @@ -188,9 +189,19 @@ private static IEnumerable TokenizeLongName( onError(new BadFormatTokenError(value)); yield break; } - var parts = text.Split('='); - yield return Token.Name(parts[0]); - yield return Token.Value(parts[1], true); + + var tokenMatch = Regex.Match(text, "^([^=]+)=([^ ].*)$"); + + if (tokenMatch.Success) + { + yield return Token.Name(tokenMatch.Groups[1].Value); + yield return Token.Value(tokenMatch.Groups[2].Value, true); + } + else + { + onError(new BadFormatTokenError(value)); + yield break; + } } } } diff --git a/tests/CommandLine.Tests/Unit/Core/TokenizerTests.cs b/tests/CommandLine.Tests/Unit/Core/TokenizerTests.cs index 37dbe51f..bceb1ea0 100644 --- a/tests/CommandLine.Tests/Unit/Core/TokenizerTests.cs +++ b/tests/CommandLine.Tests/Unit/Core/TokenizerTests.cs @@ -92,6 +92,41 @@ public void Normalize_should_remove_all_value_with_explicit_assignment_of_existi // Teardown } + + [Fact] + public void Should_properly_parse_option_with_equals_in_value() + { + /** + * This is how the arg. would look in `static void Main(string[] args)` + * if passed from the command-line and the option-value wrapped in quotes. + * Ex.) ./app --connectionString="Server=localhost;Data Source..." + */ + var args = new[] { "--connectionString=Server=localhost;Data Source=(LocalDB)\v12.0;Initial Catalog=temp;" }; + + var result = Tokenizer.Tokenize(args, name => NameLookupResult.OtherOptionFound, token => token); + + var tokens = result.SucceededWith(); + + Assert.NotNull(tokens); + Assert.Equal(2, tokens.Count()); + Assert.Equal("connectionString", tokens.First().Text); + Assert.Equal("Server=localhost;Data Source=(LocalDB)\v12.0;Initial Catalog=temp;", tokens.Last().Text); + } + + [Fact] + public void Should_return_error_if_option_format_with_equals_is_not_correct() + { + var args = new[] { "--option1 = fail", "--option2= fail" }; + + var result = Tokenizer.Tokenize(args, name => NameLookupResult.OtherOptionFound, token => token); + + var tokens = result.SuccessfulMessages(); + + Assert.NotNull(tokens); + Assert.Equal(2, tokens.Count()); + Assert.Equal(ErrorType.BadFormatTokenError, tokens.First().Tag); + Assert.Equal(ErrorType.BadFormatTokenError, tokens.Last().Tag); + } } }