-
Notifications
You must be signed in to change notification settings - Fork 25
/
Wildcard.cs
115 lines (106 loc) · 2.41 KB
/
Wildcard.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace GitDepsPacker
{
enum EMatch
{
MatchEquals,
MatchRegex,
MatchSubtree
}
struct WildcardItem
{
public EMatch Match;
public string Mask;
public WildcardItem(EMatch Match, string Mask)
{
this.Match = Match;
this.Mask = Mask;
}
}
class Wildcard
{
private static char[] Separators = { '/', '\\' };
private WildcardItem[] Parts;
private bool ExcludeMask;
public Wildcard(string Mask)
{
ExcludeMask = Mask.StartsWith("!");
Parts = ParseWildcard(Mask.Substring(ExcludeMask ? 1 : 0));
}
private static WildcardItem[] ParseWildcard(string Mask)
{
string[] Parts = Mask.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
WildcardItem[] Result = new WildcardItem[Parts.Length];
for (int i = 0; i < Parts.Length; ++i)
{
string Part = Parts[i];
if (Part == "**")
{
Result[i] = new WildcardItem(EMatch.MatchSubtree, null);
}
else
{
string Escaped = Regex.Escape(Part);
string Pattern = Escaped.Replace("\\*", ".*").Replace("\\?", ".");
if (Pattern != Escaped)
{
Result[i] = new WildcardItem(EMatch.MatchRegex, Pattern);
}
else
{
Result[i] = new WildcardItem(EMatch.MatchEquals, Part);
}
}
}
return Result;
}
public bool Exclude
{
get
{
return ExcludeMask;
}
}
public bool IsMatched(string path, bool FilePath)
{
return CheckMatched(path.Split(Separators, StringSplitOptions.RemoveEmptyEntries), 0, 0, FilePath);
}
private bool CheckMatched(string[] Items, int ItemsPos, int PartsPos, bool FilePath)
{
if (PartsPos >= Parts.Length)
{
return true;
}
if (ItemsPos >= Items.Length)
{
return !(FilePath || ExcludeMask);
}
switch (Parts[PartsPos].Match)
{
case EMatch.MatchEquals:
if (!Parts[PartsPos].Mask.Equals(Items[ItemsPos], StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
break;
case EMatch.MatchRegex:
if (!Regex.IsMatch(Items[ItemsPos], Parts[PartsPos].Mask, RegexOptions.IgnoreCase))
{
return false;
}
break;
case EMatch.MatchSubtree:
if (CheckMatched(Items, ItemsPos + 1, PartsPos, FilePath))
{
return true;
}
break;
}
return CheckMatched(Items, ItemsPos + 1, PartsPos + 1, FilePath);
}
}
}