private void ReadLiteral(GlobPatternReader reader, char[] terminators)
            {
                var text = reader.ReadUntilAny(terminators);

                if (text.Length == 0)
                {
                    return;
                }
                builder.Append(Regex.Escape(text));
            }
Exemplo n.º 2
0
        private bool TryReadEscapeCode(GlobPatternReader reader, out string escaped)
        {
            escaped = "";
            var firstCharacter = reader.ReadOne();

            if (firstCharacter == null)
            {
                return(false);
            }

            escaped = firstCharacter.ToString();

            return(true);
        }
            public string Compile(string globPattern)
            {
                builder.Clear();
                builder.Append("^");
                var reader = new GlobPatternReader(globPattern);

                do
                {
                    ReadLiteral(reader, BeginWildcardChars);
                    if (reader.IsEndOfPattern)
                    {
                        break;
                    }
                    TryReadWildcard(reader);
                }while (!reader.IsEndOfPattern);
                builder.Append("$");
                return(builder.ToString());
            }
Exemplo n.º 4
0
        public IEnumerable <Token> Tokenise(ParseContext context)
        {
            var reader = new GlobPatternReader(context.Pattern);

            do
            {
                var start = reader.Position;
                var text  = ReadLiteral(reader, beginSpecialChars);
                if (text.Length > 0)
                {
                    yield return(Token.Literal(text, start, reader.Position));
                }
                if (reader.IsEndOfPattern)
                {
                    break;
                }
                yield return(TryReadSpecial(context, reader));
            }while (!reader.IsEndOfPattern);
        }
            private void TryReadWildcard(GlobPatternReader reader)
            {
                var start = reader.Position;

                if (reader.TryRead("/**/"))
                {
                    builder.Append("/(.+/)?");
                    return;
                }
                if (reader.TryRead("/**"))
                {
                    builder.Append("(/.+)?");
                    return;
                }
                if (reader.TryRead('/'))
                {
                    builder.Append("/");
                    return;
                }
                if (reader.TryRead("**/"))
                {
                    builder.Append("(.+/)?");
                    return;
                }
                if (reader.TryRead('*'))
                {
                    builder.Append("[^/]*");
                    return;
                }
                if (reader.TryRead('?'))
                {
                    builder.Append("[^/]");
                    return;
                }
                if (reader.TryRead('['))
                {
                    var range = reader.ReadUntilAny(WildcardChars);
                    if (!reader.TryRead(']'))
                    {
                        throw reader.IsEndOfPattern
                            ? new GlobFormatException($"Range at position {start} is not closed: {reader.GetSnippet(start, range.Length + 1)}", reader.Pattern, start)
                            : new GlobFormatException($"Range at position {start} contains an invalid character: {reader.GetSnippet(5)}", reader.Pattern, start);
                    }
                    if (range.Length == 0)
                    {
                        throw new GlobFormatException($"Range at position {start} is empty: {reader.GetSnippet(start, 10)}", reader.Pattern, start);
                    }
                    var m = RxRange.Match(range);
                    if (range[0] == '!')
                    {
                        if (range.Length == 1)
                        {
                            throw new GlobFormatException($"Range at position {start} is empty: {reader.GetSnippet(start, 10)}", reader.Pattern, start);
                        }
                    }
                    if (!m.Success)
                    {
                        throw new GlobFormatException($"Range at position {start} is not valid: {reader.GetSnippet(start, range.Length + 2)}", reader.Pattern, start);
                    }

                    builder.Append('[');
                    if (range[0] == '!')
                    {
                        builder.Append('^');
                    }
                    builder.Append(Regex.Escape(m.Groups[1].Value));
                    builder.Append(']');
                    return;
                }
                throw new GlobFormatException($"Unable to parse wildcard expression at position {start}: {reader.GetSnippet(start, 10)}", reader.Pattern, start);
            }
Exemplo n.º 6
0
        private Token TryReadSpecial(ParseContext context, GlobPatternReader reader)
        {
            var start = reader.Position;

            if (reader.TryRead(SegmentSeparator))
            {
                return(Token.Separator(start));
            }
            if (reader.TryRead(EscapePrefix))
            {
                if (!TryReadEscapeCode(reader, out var escaped))
                {
                    throw context.CreateError($"Invalid escape code: {reader.GetSnippet(start, reader.Position)}", start);
                }
                return(Token.Literal(escaped, start, reader.Position));
            }
            if (reader.TryRead('*'))
            {
                if (reader.TryRead('*'))
                {
                    return(Token.MatchAnyRecursive(start, reader.Position));
                }
                return(Token.MatchAny(start, reader.Position));
            }
            if (reader.TryRead('?'))
            {
                return(Token.MatchSingle(start, reader.Position));
            }
            if (reader.TryRead('['))
            {
                var range = reader.ReadUntilAny(wildcardChars);
                if (!reader.TryRead(']'))
                {
                    throw reader.IsEndOfPattern
                        ? context.CreateError($"Range at position {start} is not closed: {reader.GetSnippet(start, range.Length + 1)}", start)
                        : context.CreateError($"Range at position {start} contains an invalid character: {reader.GetSnippet(5)}", start);
                }
                if (range.Length == 0)
                {
                    throw context.CreateError($"Range at position {start} is empty: {reader.GetSnippet(start, 10)}", start);
                }
                var m = rxRange.Match(range);
                if (range[0] == '!')
                {
                    if (range.Length == 1)
                    {
                        throw context.CreateError($"Range at position {start} is empty: {reader.GetSnippet(start, 10)}", start);
                    }
                }
                if (!m.Success)
                {
                    throw context.CreateError($"Range at position {start} is not valid: {reader.GetSnippet(start, range.Length + 2)}", start);
                }

                var rangeCharacters = m.Groups[1].Value;
                if (range[0] == '!')
                {
                    return(Token.MatchRangeInverted(rangeCharacters, start, reader.Position));
                }
                return(Token.MatchRange(rangeCharacters, start, reader.Position));
            }
            if (reader.TryRead('{'))
            {
                var variableName = reader.ReadUntilAny(wildcardChars);
                if (!reader.TryRead('}'))
                {
                    throw reader.IsEndOfPattern
                        ? context.CreateError($"Variable reference at position {start} is not closed: {reader.GetSnippet(start, variableName.Length + 1)}", start)
                        : context.CreateError($"Variable reference at position {start} contains an invalid character: {reader.GetSnippet(5)}", start);
                }
                return(Token.MatchVariable(variableName, start, reader.Position));
            }
            throw context.CreateError($"Unable to parse wildcard expression at position {start}: {reader.GetSnippet(start, 10)}", start);
        }
Exemplo n.º 7
0
 private string ReadLiteral(GlobPatternReader reader, char[] terminators)
 {
     return(reader.ReadUntilAny(terminators));
 }