Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Fix bracket escaping in Mono/NDesk Options
Browse files Browse the repository at this point in the history
  • Loading branch information
caesay committed Jan 17, 2022
1 parent 7038ff3 commit 05ec119
Showing 1 changed file with 48 additions and 22 deletions.
70 changes: 48 additions & 22 deletions src/Squirrel/Lib/Mono.Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,8 +1030,8 @@ private static bool Unprocessed (ICollection<string> extra, Option def, OptionCo
return false;
}

private readonly Regex ValueOption = new Regex (
@"^(?<flag>--|-|/)(?<name>[^:=]+)((?<sep>[:=])(?<value>.*))?$");
private readonly static Regex ValueOption = new Regex (
@"^(?<flag>--|-|/)(?<name>[^:=]+)((?<sep>[:=])(?<value>.*))?$", RegexOptions.Compiled);

protected bool GetOptionParts (string argument, out string flag, out string name, out string sep, out string value)
{
Expand Down Expand Up @@ -1295,28 +1295,54 @@ static void Write (TextWriter o, ref int n, string s)
o.Write (s);
}

// this regex will match {argName}, {0:argName} etc - but not {{argName}} (we treat double brackets like they are escaped)
private static readonly Regex _argNameRegex = new Regex(@"(^|[^{]){(?<name>[^{}]*)}($|[^}])", RegexOptions.Compiled);
private static string GetArgumentName (int index, int maxIndex, string description)
{
if (description == null)
return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
string[] nameStart;
if (maxIndex == 1)
nameStart = new string[]{"{0:", "{"};
else
nameStart = new string[]{"{" + index + ":"};
for (int i = 0; i < nameStart.Length; ++i) {
int start, j = 0;
do {
start = description.IndexOf (nameStart [i], j);
} while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false);
if (start == -1)
continue;
int end = description.IndexOf ("}", start);
if (end == -1)
continue;
return description.Substring (start + nameStart [i].Length, end - start - nameStart [i].Length);
}
return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
if (description != null) {
if (maxIndex == 1) {
// if there can only be one argument, we're looking for {argName} or {0:argName}
var match = _argNameRegex.Match(description);
if (match.Success) {
var argName = match.Groups["name"].Value;
return argName.StartsWith("0:") ? argName.Substring(2) : argName;
}
} else {
// if there are more than one arguments, we are looking for {index:argName} only
var matches = _argNameRegex.Matches(description);
foreach (Match m in matches) {
var argName = m.Groups["name"].Value;
if (argName.StartsWith(index + ":")) {
return argName.Substring(index.ToString().Length + 1);
}
}
}
}

// CS: this is the original NDesk implementation which did not support escaped brackets
// strangely enough GetDescription(string) below does support this very thing.

//if (description == null)
// return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
//string[] nameStart;
//if (maxIndex == 1)
// nameStart = new string[]{"{0:", "{"};
//else
// nameStart = new string[]{"{" + index + ":"};
//for (int i = 0; i < nameStart.Length; ++i) {
// int start, j = 0;
// do {
// start = description.IndexOf (nameStart [i], j);
// } while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false);
// if (start == -1)
// continue;
// int end = description.IndexOf ("}", start);
// if (end == -1)
// continue;
// return description.Substring (start + nameStart [i].Length, end - start - nameStart [i].Length);
//}

return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
}

private static string GetDescription (string description)
Expand Down

0 comments on commit 05ec119

Please sign in to comment.