Example #1
0
        /// <summary>
        /// Parses <paramref name="pattern"/>, calling appropriate overloads
        /// in <paramref name="parser"/>
        /// </summary>
        /// <param name="pattern">Pattern to parse</param>
        /// <param name="parser">Parser to call back</param>
        public static void Parse(
            WildcardPattern pattern, WildcardPatternParser parser)
        {
            parser.BeginWildcardPattern(pattern);

            bool          previousCharacterIsAnEscape = false;
            bool          previousCharacterStartedBracketExpression = false;
            bool          insideCharacterRange    = false;
            StringBuilder characterRangeContents  = null;
            StringBuilder characterRangeOperators = null;

            foreach (char c in pattern.Pattern)
            {
                if (insideCharacterRange)
                {
                    if (c == ']' && !previousCharacterStartedBracketExpression && !previousCharacterIsAnEscape)
                    {
                        // An unescaped closing square bracket closes the character set.  In other
                        // words, there are no nested square bracket expressions
                        // This is different than the POSIX spec
                        // (at http://www.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html),
                        // but we are keeping this behavior for back-compatibility.

                        insideCharacterRange = false;
                        parser.AppendBracketExpression(characterRangeContents.ToString(), characterRangeOperators.ToString(), pattern.Pattern);
                        characterRangeContents  = null;
                        characterRangeOperators = null;
                    }
                    else if (c != pattern.EscapeCharacter || previousCharacterIsAnEscape)
                    {
                        characterRangeContents.Append(c);
                        characterRangeOperators.Append((c == '-') && !previousCharacterIsAnEscape ? '-' : ' ');
                    }

                    previousCharacterStartedBracketExpression = false;
                }
                else
                {
                    if (c == '*' && !previousCharacterIsAnEscape)
                    {
                        parser.AppendAsterix();
                    }
                    else if (c == '?' && !previousCharacterIsAnEscape)
                    {
                        parser.AppendQuestionMark();
                    }
                    else if (c == '[' && !previousCharacterIsAnEscape)
                    {
                        insideCharacterRange    = true;
                        characterRangeContents  = new StringBuilder();
                        characterRangeOperators = new StringBuilder();
                        previousCharacterStartedBracketExpression = true;
                    }
                    else if (c != pattern.EscapeCharacter || previousCharacterIsAnEscape)
                    {
                        parser.AppendLiteralCharacter(c);
                    }
                }

                previousCharacterIsAnEscape = (c == pattern.EscapeCharacter) && (!previousCharacterIsAnEscape);
            }

            if (insideCharacterRange)
            {
                throw NewWildcardPatternException(pattern.Pattern);
            }

            if (previousCharacterIsAnEscape)
            {
                if (!pattern.Pattern.Equals($"{pattern.EscapeCharacter}", StringComparison.Ordinal)) // Win7 backcompatibility requires treating '`' pattern as '' pattern when this code was used with PowerShell.
                {
                    parser.AppendLiteralCharacter(pattern.Pattern[pattern.Pattern.Length - 1]);
                }
            }

            parser.EndWildcardPattern();
        }
Example #2
0
 /// <summary>
 /// Called from <see cref="Parse"/> method to indicate
 /// the beginning of the wildcard pattern.
 /// Default implementation simply returns.
 /// </summary>
 /// <param name="pattern">
 /// <see cref="WildcardPattern"/> object that includes both
 /// the text of the pattern (<see cref="WildcardPattern.Pattern"/>)
 /// and the pattern options (<see cref="WildcardPattern.Options"/>)
 /// </param>
 protected virtual void BeginWildcardPattern(WildcardPattern pattern)
 {
 }