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(); } }
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."); } }
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); }
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(); } } }
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); }
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); } }
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); } } }