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