public IPattern Build(string pattern) { if (pattern == null) { throw new ArgumentNullException("pattern"); } pattern = pattern.TrimStart(_slashes); if (pattern.TrimEnd(_slashes).Length < pattern.Length) { // If the pattern end with a slash, it is considered as // a directory. pattern = pattern.TrimEnd(_slashes) + "/**"; } var allSegments = new List<IPathSegment>(); var isParentSegmentLegal = true; IList<IPathSegment> segmentsPatternStartsWith = null; IList<IList<IPathSegment>> segmentsPatternContains = null; IList<IPathSegment> segmentsPatternEndsWith = null; var endPattern = pattern.Length; for (int scanPattern = 0; scanPattern < endPattern;) { var beginSegment = scanPattern; var endSegment = NextIndex(pattern, _slashes, scanPattern, endPattern); IPathSegment segment = null; if (segment == null && endSegment - beginSegment == 3) { if (pattern[beginSegment] == '*' && pattern[beginSegment + 1] == '.' && pattern[beginSegment + 2] == '*') { // turn *.* into * beginSegment += 2; } } if (segment == null && endSegment - beginSegment == 2) { if (pattern[beginSegment] == '*' && pattern[beginSegment + 1] == '*') { // recognized ** segment = new RecursiveWildcardSegment(); } else if (pattern[beginSegment] == '.' && pattern[beginSegment + 1] == '.') { // recognized .. if (!isParentSegmentLegal) { throw new ArgumentException("\"..\" can be only added at the beginning of the pattern."); } segment = new ParentPathSegment(); } } if (segment == null && endSegment - beginSegment == 1) { if (pattern[beginSegment] == '.') { // recognized . segment = new CurrentPathSegment(); } } if (segment == null && endSegment - beginSegment > 2) { if (pattern[beginSegment] == '*' && pattern[beginSegment + 1] == '*' && pattern[beginSegment + 2] == '.') { // recognize **. // swallow the first *, add the recursive path segment and // the remaining part will be treat as wild card in next loop. segment = new RecursiveWildcardSegment(); endSegment = beginSegment; } } if (segment == null) { var beginsWith = string.Empty; var contains = new List<string>(); var endsWith = string.Empty; for (int scanSegment = beginSegment; scanSegment < endSegment;) { var beginLiteral = scanSegment; var endLiteral = NextIndex(pattern, _star, scanSegment, endSegment); if (beginLiteral == beginSegment) { if (endLiteral == endSegment) { // and the only bit segment = new LiteralPathSegment(Portion(pattern, beginLiteral, endLiteral), ComparisonType); } else { // this is the first bit beginsWith = Portion(pattern, beginLiteral, endLiteral); } } else if (endLiteral == endSegment) { // this is the last bit endsWith = Portion(pattern, beginLiteral, endLiteral); } else { if (beginLiteral != endLiteral) { // this is a middle bit contains.Add(Portion(pattern, beginLiteral, endLiteral)); } else { // note: NOOP here, adjacent *'s are collapsed when they // are mixed with literal text in a path segment } } scanSegment = endLiteral + 1; } if (segment == null) { segment = new WildcardPathSegment(beginsWith, contains, endsWith, ComparisonType); } } if (!(segment is ParentPathSegment)) { isParentSegmentLegal = false; } if (segment is CurrentPathSegment) { // ignore ".\" } else { if (segment is RecursiveWildcardSegment) { if (segmentsPatternStartsWith == null) { segmentsPatternStartsWith = new List<IPathSegment>(allSegments); segmentsPatternEndsWith = new List<IPathSegment>(); segmentsPatternContains = new List<IList<IPathSegment>>(); } else if (segmentsPatternEndsWith.Count != 0) { segmentsPatternContains.Add(segmentsPatternEndsWith); segmentsPatternEndsWith = new List<IPathSegment>(); } } else if (segmentsPatternEndsWith != null) { segmentsPatternEndsWith.Add(segment); } allSegments.Add(segment); } scanPattern = endSegment + 1; } if (segmentsPatternStartsWith == null) { return new LinearPattern(allSegments); } else { return new RaggedPattern(allSegments, segmentsPatternStartsWith, segmentsPatternEndsWith, segmentsPatternContains); } }
public void Match(string testSample, bool expectation) { var pathSegment = new ParentPathSegment(); Assert.Equal(expectation, pathSegment.Match(testSample)); }