コード例 #1
0
        public static IEnumerable <CommandToken> Parse(string commandLine)
        {
            CommandToken lastToken = null;

            for (int index = 0, count = commandLine.Length; index < count;)
            {
                switch (commandLine[index])
                {
                case ' ':
                {
                    lastToken = CommandSpaceToken.Parse(commandLine, ref index);
                    yield return(lastToken);

                    break;
                }

                case '"':
                case '\'':
                {
                    // "'"
                    if (lastToken is CommandQuoteToken quote && quote.Value[0] != commandLine[index])
                    {
                        goto default;
                    }

                    lastToken = CommandQuoteToken.Parse(commandLine, ref index);
                    yield return(lastToken);

                    break;
                }

                default:
                {
                    lastToken = CommandStringToken.Parse(commandLine, ref index,
                                                         lastToken is CommandQuoteToken quote ? quote : null);

                    yield return(lastToken);

                    break;
                }
                }
            }
        }
コード例 #2
0
        public bool OnCommand(string commandLine)
        {
            if (string.IsNullOrEmpty(commandLine))
            {
                return(true);
            }

            string possibleHelp      = null;
            var    commandArgs       = CommandToken.Parse(commandLine).ToArray();
            var    availableCommands = new List <(ConsoleCommandMethod Command, object[] Arguments)>();

            foreach (var entries in _verbs.Values)
            {
                foreach (var command in entries)
                {
                    if (command.IsThisCommand(commandArgs, out var consumedArgs))
                    {
                        var arguments = new List <object>();
                        var args      = commandArgs.Skip(consumedArgs).ToList();

                        CommandSpaceToken.Trim(args);

                        try
                        {
                            var parameters = command.Method.GetParameters();

                            foreach (var arg in parameters)
                            {
                                // Parse argument

                                if (TryProcessValue(arg.ParameterType, args, arg == parameters.Last(), out var value))
                                {
                                    arguments.Add(value);
                                }
                                else
                                {
                                    if (arg.HasDefaultValue)
                                    {
                                        arguments.Add(arg.DefaultValue);
                                    }
                                    else
                                    {
                                        throw new ArgumentException(arg.Name);
                                    }
                                }
                            }

                            availableCommands.Add((command, arguments.ToArray()));
                        }
                        catch
                        {
                            // Skip parse errors
                            possibleHelp = command.Key;
                        }
                    }
                }
            }

            switch (availableCommands.Count)
            {
            case 0:
            {
                if (!string.IsNullOrEmpty(possibleHelp))
                {
                    OnHelpCommand(possibleHelp);
                    return(true);
                }

                return(false);
            }

            case 1:
            {
                var(command, arguments) = availableCommands[0];
                if (command.HelpCategory.Equals("NexusAPI"))
                {
                    try
                    {
                        string[] args = arguments.Where(x => x != null)
                                        .Select(x => x.ToString())
                                        .ToArray();
                        _cli.ExecuteAPI(command.Method.Name, args);
                    }
                    catch (Exception)
                    {
                        Spook.Logger.Message("invalid api command");
                    }

                    return(true);
                }
                else
                {
                    try
                    {
                        command.Method.Invoke(command.Instance, arguments);
                    }
                    catch (Exception e)
                    {
                        e = e.ExpandInnerExceptions();
                        Spook.Logger.Message(e.Message);
                    }
                }

                return(true);
            }

            default:
            {
                // Show Ambiguous call

                throw new ArgumentException("Ambiguous calls for: " + string.Join(',', availableCommands.Select(u => u.Command.Key).Distinct()));
            }
            }
        }