Ejemplo n.º 1
0
    private CommandTree ParseCommandParameters(
        CommandTreeParserContext context,
        CommandInfo command,
        CommandTree?parent,
        CommandTreeTokenStream stream)
    {
        context.ResetArgumentPosition();

        var node = new CommandTree(parent, command);

        while (stream.Peek() != null)
        {
            var token = stream.Peek();
            if (token == null)
            {
                // Should not happen, but the compiler isn't
                // smart enough to realize this...
                throw new CommandRuntimeException("Could not get the next token.");
            }

            switch (token.TokenKind)
            {
            case CommandTreeToken.Kind.LongOption:
                // Long option
                ParseOption(context, stream, token, node, true);
                break;

            case CommandTreeToken.Kind.ShortOption:
                // Short option
                ParseOption(context, stream, token, node, false);
                break;

            case CommandTreeToken.Kind.String:
                // Command
                ParseString(context, stream, node);
                break;

            case CommandTreeToken.Kind.Remaining:
                // Remaining
                stream.Consume(CommandTreeToken.Kind.Remaining);
                context.State = State.Remaining;
                break;

            default:
                throw new InvalidOperationException($"Encountered unknown token ({token.TokenKind}).");
            }
        }

        // Add unmapped parameters.
        foreach (var parameter in node.Command.Parameters)
        {
            if (node.Mapped.All(m => m.Parameter != parameter))
            {
                node.Unmapped.Add(parameter);
            }
        }

        return(node);
    }
Ejemplo n.º 2
0
    private string?ParseOptionValue(
        CommandTreeParserContext context,
        CommandTreeTokenStream stream,
        CommandTreeToken token,
        CommandTree current,
        CommandParameter?parameter)
    {
        var value = default(string);

        // Parse the value of the token (if any).
        var valueToken = stream.Peek();

        if (valueToken?.TokenKind == CommandTreeToken.Kind.String)
        {
            var parseValue = true;
            if (token.TokenKind == CommandTreeToken.Kind.ShortOption && token.IsGrouped)
            {
                parseValue = false;
            }

            if (context.State == State.Normal && parseValue)
            {
                // Is this a command?
                if (current.Command.FindCommand(valueToken.Value, CaseSensitivity) == null)
                {
                    if (parameter != null)
                    {
                        if (parameter.ParameterKind == ParameterKind.Flag)
                        {
                            if (!CliConstants.AcceptedBooleanValues.Contains(valueToken.Value, StringComparer.OrdinalIgnoreCase))
                            {
                                // Flags cannot be assigned a value.
                                throw CommandParseException.CannotAssignValueToFlag(context.Arguments, token);
                            }
                        }

                        value = stream.Consume(CommandTreeToken.Kind.String)?.Value;
                    }
                    else
                    {
                        // Unknown parameter value.
                        value = stream.Consume(CommandTreeToken.Kind.String)?.Value;

                        // In relaxed parsing mode?
                        if (context.ParsingMode == ParsingMode.Relaxed)
                        {
                            context.AddRemainingArgument(token.Value, value);
                        }
                    }
                }
            }
            else
            {
                context.AddRemainingArgument(token.Value, parseValue ? valueToken.Value : null);
            }
        }
        else
        {
            if (context.State == State.Remaining || context.ParsingMode == ParsingMode.Relaxed)
            {
                context.AddRemainingArgument(token.Value, null);
            }
        }

        // No value?
        if (context.State == State.Normal)
        {
            if (value == null && parameter != null)
            {
                if (parameter.ParameterKind == ParameterKind.Flag)
                {
                    value = "true";
                }
                else
                {
                    if (parameter is CommandOption option)
                    {
                        if (parameter.IsFlagValue())
                        {
                            return(null);
                        }

                        throw CommandParseException.OptionHasNoValue(context.Arguments, token, option);
                    }
                    else
                    {
                        // This should not happen at all. If it does, it's because we've added a new
                        // option type which isn't a CommandOption for some reason.
                        throw new InvalidOperationException($"Found invalid parameter type '{parameter.GetType().FullName}'.");
                    }
                }
            }
        }

        return(value);
    }