Skip to content

Commit 509d4f5

Browse files
committed
C#: Fix ExprMatch for case sensitive matching
We were accidentally stopping the recursion when matching in the case sensitive scenario. Took the opportunity to also rename the private method to follow the Core method naming more closely so it's easier to compare the implementations in the future. Also, the private method now uses `ReadOnlySpan<char>` to avoid allocating strings on each recursion.
1 parent b2f425f commit 509d4f5

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,39 +1208,39 @@ public static string Left(this string instance, int pos)
12081208
/// Do a simple expression match, where '*' matches zero or more
12091209
/// arbitrary characters and '?' matches any single character except '.'.
12101210
/// </summary>
1211-
/// <param name="instance">The string to check.</param>
1212-
/// <param name="expr">Expression to check.</param>
1211+
/// <param name="str">The string to check.</param>
1212+
/// <param name="pattern">Expression to check.</param>
12131213
/// <param name="caseSensitive">
12141214
/// If <see langword="true"/>, the check will be case sensitive.
12151215
/// </param>
12161216
/// <returns>If the expression has any matches.</returns>
1217-
private static bool ExprMatch(this string instance, string expr, bool caseSensitive)
1217+
private static bool WildcardMatch(ReadOnlySpan<char> str, ReadOnlySpan<char> pattern, bool caseSensitive)
12181218
{
12191219
// case '\0':
1220-
if (expr.Length == 0)
1221-
return instance.Length == 0;
1220+
if (pattern.IsEmpty)
1221+
return str.IsEmpty;
12221222

1223-
switch (expr[0])
1223+
switch (pattern[0])
12241224
{
12251225
case '*':
1226-
return ExprMatch(instance, expr.Substring(1), caseSensitive) || (instance.Length > 0 &&
1227-
ExprMatch(instance.Substring(1), expr, caseSensitive));
1226+
return WildcardMatch(str, pattern.Slice(1), caseSensitive)
1227+
|| (!str.IsEmpty && WildcardMatch(str.Slice(1), pattern, caseSensitive));
12281228
case '?':
1229-
return instance.Length > 0 && instance[0] != '.' &&
1230-
ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
1229+
return !str.IsEmpty && str[0] != '.' &&
1230+
WildcardMatch(str.Slice(1), pattern.Slice(1), caseSensitive);
12311231
default:
1232-
if (instance.Length == 0)
1232+
if (str.IsEmpty)
12331233
return false;
1234-
if (caseSensitive)
1235-
return instance[0] == expr[0];
1236-
return (char.ToUpperInvariant(instance[0]) == char.ToUpperInvariant(expr[0])) &&
1237-
ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
1234+
bool charMatches = caseSensitive ?
1235+
str[0] == pattern[0] :
1236+
char.ToUpperInvariant(str[0]) == char.ToUpperInvariant(pattern[0]);
1237+
return charMatches &&
1238+
WildcardMatch(str.Slice(1), pattern.Slice(1), caseSensitive);
12381239
}
12391240
}
12401241

12411242
/// <summary>
1242-
/// Do a simple case sensitive expression match, using ? and * wildcards
1243-
/// (see <see cref="ExprMatch(string, string, bool)"/>).
1243+
/// Do a simple case sensitive expression match, using ? and * wildcards.
12441244
/// </summary>
12451245
/// <seealso cref="MatchN(string, string)"/>
12461246
/// <param name="instance">The string to check.</param>
@@ -1254,12 +1254,11 @@ public static bool Match(this string instance, string expr, bool caseSensitive =
12541254
if (instance.Length == 0 || expr.Length == 0)
12551255
return false;
12561256

1257-
return instance.ExprMatch(expr, caseSensitive);
1257+
return WildcardMatch(instance, expr, caseSensitive);
12581258
}
12591259

12601260
/// <summary>
1261-
/// Do a simple case insensitive expression match, using ? and * wildcards
1262-
/// (see <see cref="ExprMatch(string, string, bool)"/>).
1261+
/// Do a simple case insensitive expression match, using ? and * wildcards.
12631262
/// </summary>
12641263
/// <seealso cref="Match(string, string, bool)"/>
12651264
/// <param name="instance">The string to check.</param>
@@ -1270,7 +1269,7 @@ public static bool MatchN(this string instance, string expr)
12701269
if (instance.Length == 0 || expr.Length == 0)
12711270
return false;
12721271

1273-
return instance.ExprMatch(expr, caseSensitive: false);
1272+
return WildcardMatch(instance, expr, caseSensitive: false);
12741273
}
12751274

12761275
/// <summary>

0 commit comments

Comments
 (0)