Exemplo n.º 1
0
        private void ParseCommand(CommandContext commandContext)
        {
            bool ignoreRemainingArguments = false;
            var  remainingOperands        = new List <Token>();

            Command currentCommand         = commandContext.RootCommand;
            Option  currentOption          = null;
            Token   currentOptionToken     = null;
            IEnumerator <Operand> operands = new OperandEnumerator(currentCommand.Operands);

            IEnumerable <Token> tokens = commandContext.Tokens.Arguments;

            // using TakeWhile ensures we're evaluating ParseSeparatedArguments
            // with the final command. We know this because separated arguments
            // can only contain operands.
            bool UsingEndOfOptions()
            {
                var separatorStrategy = currentCommand.GetArgumentSeparatorStrategy(_appSettings);

                return(separatorStrategy == ArgumentSeparatorStrategy.EndOfOptions);
            }

            IEnumerable <Token> EndOfOptionsTokens()
            {
                if (!UsingEndOfOptions())
                {
                    yield break;
                }
                foreach (var token in commandContext.Tokens.Separated)
                {
                    yield return(token);
                }
            }

            //tokens = tokens.Concat(EndOfOptionsTokens());

            tokens = tokens.Concat(commandContext.Tokens.Separated.TakeWhile(t => UsingEndOfOptions()));

            foreach (var token in tokens)
            {
                switch (token.TokenType)
                {
                case TokenType.Option:
                    ParseOption(token, currentCommand, out currentOption);
                    if (currentOption != null)
                    {
                        currentOptionToken = token;
                    }
                    break;

                case TokenType.Value:
                    if (ignoreRemainingArguments && currentOption == null)
                    {
                        remainingOperands.Add(token);
                    }
                    else
                    {
                        var operandResult = ParseArgumentValue(
                            token, ref currentCommand, ref currentOption, ref currentOptionToken, operands);

                        switch (operandResult)
                        {
                        case ParseOperandResult.Succeeded:
                            break;

                        case ParseOperandResult.UnexpectedArgument:
                            ignoreRemainingArguments = true;
                            remainingOperands.Add(token);
                            break;

                        case ParseOperandResult.NewSubCommand:
                            operands = new OperandEnumerator(currentCommand.Operands);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(operandResult.ToString());
                        }
                    }
                    break;

                case TokenType.Separator:
                    throw new ArgumentOutOfRangeException($"The argument list should have already had the separator removed: {token.RawValue}");

                case TokenType.Directive:
                    throw new ArgumentOutOfRangeException($"Directives should have already been processed and removed: {token.RawValue}");

                default:
                    throw new ArgumentOutOfRangeException($"Unknown {nameof(TokenType)}: {token.TokenType}");
                }
            }

            if (currentOption != null) // an option was left without a value
            {
                throw new CommandParsingException(currentCommand, $"Missing value for option '{currentOption.Name}'");
            }

            commandContext.ParseResult = new ParseResult(
                currentCommand,
                remainingOperands,
                commandContext.Tokens.Separated);
        }
Exemplo n.º 2
0
        private void ParseCommand(CommandContext commandContext)
        {
            bool ignoreRemainingArguments = false;
            var  remainingOperands        = new List <Token>();

            Command currentCommand         = commandContext.RootCommand;
            Option  currentOption          = null;
            IEnumerator <Operand> operands = new OperandEnumerator(currentCommand.Operands);

            foreach (var token in commandContext.Tokens.Arguments)
            {
                switch (token.TokenType)
                {
                case TokenType.Option:
                    ParseOption(token, currentCommand, out currentOption);
                    break;

                case TokenType.Value:
                    if (ignoreRemainingArguments && currentOption == null)
                    {
                        remainingOperands.Add(token);
                    }
                    else
                    {
                        var operandResult = ParseArgumentValue(
                            token, ref currentCommand, ref currentOption, operands);

                        switch (operandResult)
                        {
                        case ParseOperandResult.Succeeded:
                            break;

                        case ParseOperandResult.UnexpectedArgument:
                            ignoreRemainingArguments = true;
                            break;

                        case ParseOperandResult.NewSubCommand:
                            operands = new OperandEnumerator(currentCommand.Operands);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(operandResult.ToString());
                        }
                    }
                    break;

                case TokenType.Separator:
                    throw new ArgumentOutOfRangeException($"The argument list should have already had the separator removed: {token.RawValue}");

                case TokenType.Directive:
                    throw new ArgumentOutOfRangeException($"Directives should have already been processed and removed: {token.RawValue}");

                default:
                    throw new ArgumentOutOfRangeException($"Unknown {nameof(TokenType)}: {token.TokenType}");
                }
            }

            if (currentOption != null) // an option was left without a value
            {
                throw new CommandParsingException(currentCommand, $"Missing value for option '{currentOption.Name}'");
            }

            commandContext.ParseResult = new ParseResult(
                currentCommand,
                remainingOperands,
                commandContext.Tokens.Separated);
        }
Exemplo n.º 3
0
        private ParseOperandResult ParseArgumentValue(Token token, ref Command command, OperandEnumerator operands)
        {
            if (!operands.Any && command.FindArgumentNode(token.Value) is Command subcommand)
            {
                command = subcommand;
                return(ParseOperandResult.NewSubCommand);
            }

            if (operands.MoveNext())
            {
                var current = operands.Current;
                ThrowIfValueNotAllowed(command, current, token);
                GetArgumentParsedValues(current).Add(new ValueFromToken(token.Value, token, null));
            }
            else
            {
                if (command.GetIgnoreUnexpectedOperands(_appSettings))
                {
                    return(ParseOperandResult.UnexpectedArgument);
                }

                // use the term "argument" for messages displayed to users
                throw new UnrecognizedArgumentCommandParsingException(command, token, $"Unrecognized command or argument '{token.RawValue}'");
            }

            return(ParseOperandResult.Succeeded);
        }