示例#1
0
        private static GitCmdToken ParseLiteral(GitCmdTokens tokens)
        {
            var sb       = new StringBuilder();
            var position = tokens.Current.Position;

            var token = tokens.Current;

            while (true)
            {
                if (token.Type == GitCmdTokenType.Quote)
                {
                    ParseQuotedString(tokens, sb);
                }

                else if (token.Type == GitCmdTokenType.Literal)
                {
                    sb.Append(token.Value);
                }

                else if (token.Type == GitCmdTokenType.Backslash)
                {
                    sb.Append(token.Value);
                }

                else
                {
                    tokens.Requeue();
                    return(new GitCmdToken(GitCmdTokenType.Literal, sb.ToString(), position));
                }

                token = tokens.Dequeue();
            }
        }
示例#2
0
        private GitCmdArgs(
            string args,
            int minArgs,
            int maxArgs,
            IEnumerable <GitCmdSwitchInfo> switchInfos = null)
        {
            if (switchInfos != null)
            {
                m_switchInfo = switchInfos
                               .ToDictionary(o => o.Name, StringComparer.InvariantCultureIgnoreCase);
            }
            m_switches  = new HashSet <object>();
            m_arguments = new List <string>();

            var tokens = GitCmdTokens.Tokenize(args);

            Parse(tokens);

            if (Length < minArgs)
            {
                throw new GitCmdException($"Expected at least '{minArgs}' arguments.");
            }

            if (Length > maxArgs)
            {
                throw new GitCmdException($"Expected at most '{maxArgs}' arguments.");
            }
        }
示例#3
0
        private void ParseLongSwitch(GitCmdTokens tokens)
        {
            var token = tokens.Dequeue(
                GitCmdTokenType.Literal,
                GitCmdTokenType.WhiteSpace,
                GitCmdTokenType.EndOfStram
                );

            if (token.Value.Length == 1)
            {
                throw new GitCmdException(
                          $"Token '{token}' following single dash must be multi-character literal.");
            }

            AddSwitch(token);
        }
示例#4
0
        private void Parse(GitCmdTokens tokens)
        {
            m_exe = tokens.Dequeue(GitCmdTokenType.Literal).Value;

            var token = tokens.Dequeue();

            if (token.Type == GitCmdTokenType.EndOfStram)
            {
                return;
            }

            if (token.Type != GitCmdTokenType.Literal)
            {
                tokens.ParseError();
            }
            m_name = token.Value;

            while (tokens.Any())
            {
                token = tokens.Dequeue();

                if (token.Type == GitCmdTokenType.Dash)
                {
                    ParseShortSwitch(tokens);
                }

                else if (token.Type == GitCmdTokenType.DoubleDash)
                {
                    ParseLongSwitch(tokens);
                }

                else if (token.Type == GitCmdTokenType.Literal)
                {
                    m_arguments.Add(token.Value);
                }

                else if (token.Type == GitCmdTokenType.EndOfStram)
                {
                    break;
                }

                else
                {
                    tokens.ParseError();
                }
            }
        }
示例#5
0
        private void ParseShortSwitch(GitCmdTokens tokens)
        {
            var token = tokens.Dequeue();

            if (token.Type != GitCmdTokenType.Literal)
            {
                tokens.ParseError();
            }

            if (token.Value.Length != 1)
            {
                throw new GitCmdException(
                          $"Token '{token}' following single dash must be a single character literal.");
            }

            AddSwitch(token);
        }
示例#6
0
        private static void ParseQuotedString(GitCmdTokens tokens, StringBuilder sb)
        {
            while (true)
            {
                var token = tokens.Dequeue();

                if (token.Type == GitCmdTokenType.Quote)
                {
                    return;
                }

                if (token.Type == GitCmdTokenType.Backslash && tokens.Peek().Type == GitCmdTokenType.Quote)
                {
                    token = tokens.Dequeue();
                }

                sb.Append(token.Value);
            }
        }
示例#7
0
        private static IEnumerable <GitCmdToken> GenerateTokens(string commandLine)
        {
            var match = Regex.Match(commandLine, TokenPattern);

            if (!match.Success)
            {
                throw new GitCmdException(
                          $"Failed to parse command line '{commandLine}' into tokens using pattern: {TokenPattern}");
            }

            var tokens = new GitCmdTokens(
                from pair in TokenPatterns
                let token = pair.Key
                            from Capture capture in match.Groups[$"{token}"].Captures
                            orderby capture.Index
                            select new GitCmdToken(token, capture.Value, capture.Index)
                );

            // unescape quoted string into literal
            while (tokens.Any())
            {
                var token = tokens.Dequeue();
                var type  = token.Type;

                if (type == GitCmdTokenType.WhiteSpace)
                {
                    continue;
                }

                if (type == GitCmdTokenType.Quote ||
                    type == GitCmdTokenType.Backslash ||
                    type == GitCmdTokenType.Literal)
                {
                    yield return(ParseLiteral(tokens));
                }

                else
                {
                    yield return(token);
                }
            }
        }