Example #1
0
 public Parser(CommandLineConfiguration configuration)
 {
     Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
 }
        internal static TokenizeResult Tokenize(
            this IEnumerable <string> args,
            CommandLineConfiguration configuration)
        {
            var tokenList = new List <Token>();
            var errorList = new List <TokenizeError>();

            ISymbol currentSymbol        = null;
            var     foundEndOfArguments  = false;
            var     foundEndOfDirectives = false;
            var     argList = args.ToList();

            var argumentDelimiters = configuration.ArgumentDelimiters.ToArray();

            var knownTokens = new HashSet <Token>(configuration.Symbols.SelectMany(ValidTokens));

            for (var i = 0; i < argList.Count; i++)
            {
                var arg = argList[i];

                if (foundEndOfArguments)
                {
                    tokenList.Add(Operand(arg));
                    continue;
                }

                if (arg == "--")
                {
                    tokenList.Add(EndOfArguments());
                    foundEndOfArguments = true;
                    continue;
                }

                if (!foundEndOfDirectives)
                {
                    if (arg.StartsWith("[") &&
                        arg.EndsWith("]") &&
                        arg[1] != ']' &&
                        arg[1] != ':')
                    {
                        tokenList.Add(Directive(arg));
                        continue;
                    }

                    if (!configuration.RootCommand.HasRawAlias(arg))
                    {
                        foundEndOfDirectives = true;
                    }
                }

                if (configuration.ResponseFileHandling != ResponseFileHandling.Disabled &&
                    arg.GetResponseFileReference() is string filePath)
                {
                    ReadResponseFile(filePath, i);
                    continue;
                }

                var argHasPrefix = HasPrefix(arg);

                if (argHasPrefix &&
                    arg.SplitByDelimiters(argumentDelimiters) is string[] subtokens &&
                    subtokens.Length > 1)
                {
                    if (knownTokens.Any(t => t.Value == subtokens.First()))
                    {
                        tokenList.Add(Option(subtokens[0]));

                        if (subtokens.Length > 1)
                        {
                            // trim outer quotes in case of, e.g., -x="why"
                            var secondPartWithOuterQuotesRemoved = subtokens[1].Trim('"');
                            tokenList.Add(Argument(secondPartWithOuterQuotesRemoved));
                        }
                    }
                    else
                    {
                        tokenList.Add(Argument(arg));
                    }
                }
        internal static LexResult Lex(
            this IEnumerable <string> args,
            CommandLineConfiguration configuration)
        {
            var tokenList = new List <Token>();
            var errorList = new List <ParseError>();

            ISymbol currentSymbol        = null;
            var     foundEndOfArguments  = false;
            var     foundEndOfDirectives = false;
            var     argList = args.ToList();

            var argumentDelimiters = configuration.ArgumentDelimiters.ToArray();

            var knownTokens = new HashSet <Token>(configuration.Symbols.SelectMany(ValidTokens));

            for (var i = 0; i < argList.Count; i++)
            {
                var arg = argList[i];

                if (foundEndOfArguments)
                {
                    tokenList.Add(Operand(arg));
                    continue;
                }

                if (arg == "--")
                {
                    tokenList.Add(EndOfArguments());
                    foundEndOfArguments = true;
                    continue;
                }

                if (!foundEndOfDirectives)
                {
                    if (arg.StartsWith("[") && arg.EndsWith("]") && arg[1] != ']' && arg[1] != ':')
                    {
                        tokenList.Add(Directive(arg));
                        continue;
                    }

                    if (!configuration.RootCommand.HasRawAlias(arg))
                    {
                        foundEndOfDirectives = true;
                    }
                }

                if (configuration.ResponseFileHandling != ResponseFileHandling.Disabled &&
                    arg.StartsWith("@"))
                {
                    var filePath = arg.Substring(1);
                    if (!string.IsNullOrWhiteSpace(filePath))
                    {
                        try
                        {
                            var next = i + 1;
                            foreach (var newArg in ParseResponseFile(
                                         filePath,
                                         configuration.ResponseFileHandling))
                            {
                                argList.Insert(next, newArg);
                                next += 1;
                            }
                        }
                        catch (FileNotFoundException)
                        {
                            errorList.Add(new ParseError(configuration.ValidationMessages.ResponseFileNotFound(filePath),
                                                         null,
                                                         false));
                        }
                        catch (IOException e)
                        {
                            errorList.Add(new ParseError(
                                              configuration.ValidationMessages.ErrorReadingResponseFile(filePath, e),
                                              null,
                                              false));
                        }

                        continue;
                    }
                }

                var argHasPrefix = HasPrefix(arg);

                if (argHasPrefix &&
                    SplitTokenByArgumentDelimiter(arg, argumentDelimiters) is string[] subtokens &&
                    subtokens.Length > 1)
                {
                    if (knownTokens.Any(t => t.Value == subtokens.First()))
                    {
                        tokenList.Add(Option(subtokens[0]));

                        if (subtokens.Length > 1)
                        {
                            // trim outer quotes in case of, e.g., -x="why"
                            var secondPartWithOuterQuotesRemoved = subtokens[1].Trim('"');
                            tokenList.Add(Argument(secondPartWithOuterQuotesRemoved));
                        }
                    }
                    else
                    {
                        tokenList.Add(Argument(arg));
                    }
                }
        internal static TokenizeResult Tokenize(
            this IReadOnlyList <string> args,
            CommandLineConfiguration configuration)
        {
            var tokenList = new List <Token>();
            var errorList = new List <TokenizeError>();

            ICommand currentCommand       = null;
            var      foundEndOfArguments  = false;
            var      foundEndOfDirectives = !configuration.EnableDirectives;
            var      argList = NormalizeRootCommand(configuration, args);

            var argumentDelimiters = configuration.ArgumentDelimiters.ToArray();

            var knownTokens        = new HashSet <Token>(configuration.Symbols.SelectMany(ValidTokens));
            var knownTokensStrings = new HashSet <string>(knownTokens.Select(t => t.Value));

            for (var i = 0; i < argList.Count; i++)
            {
                var arg = argList[i];

                if (foundEndOfArguments)
                {
                    tokenList.Add(Operand(arg));
                    continue;
                }

                if (arg == "--")
                {
                    tokenList.Add(EndOfArguments());
                    foundEndOfArguments = true;
                    continue;
                }

                if (!foundEndOfDirectives)
                {
                    if (arg.StartsWith("[") &&
                        arg.EndsWith("]") &&
                        arg[1] != ']' &&
                        arg[1] != ':')
                    {
                        tokenList.Add(Directive(arg));
                        continue;
                    }

                    if (!configuration.RootCommand.HasRawAlias(arg))
                    {
                        foundEndOfDirectives = true;
                    }
                }

                if (configuration.ResponseFileHandling != ResponseFileHandling.Disabled &&
                    arg.GetResponseFileReference() is { } filePath)
                {
                    ReadResponseFile(filePath, i);
                    continue;
                }

                if (configuration.EnablePosixBundling &&
                    CanBeUnbundled(arg, out var replacement))
                {
                    argList.InsertRange(i + 1, replacement);
                    argList.RemoveAt(i);
                    arg = argList[i];
                }

                if (arg.SplitByDelimiters(argumentDelimiters) is { } subtokens&&
                    subtokens.Length > 1)
                {
                    if (knownTokensStrings.Contains(subtokens[0]))
                    {
                        tokenList.Add(Option(subtokens[0]));

                        if (subtokens.Length > 1)
                        {
                            // trim outer quotes in case of, e.g., -x="why"
                            var secondPartWithOuterQuotesRemoved = subtokens[1].Trim('"');
                            tokenList.Add(Argument(secondPartWithOuterQuotesRemoved));
                        }
                    }
                    else
                    {
                        tokenList.Add(Argument(arg));
                    }
                }