/// <summary> /// Parse command line /// </summary> /// <param name="commandLine">Command line</param> /// <returns></returns> 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) { // "'" if (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; } } } }
private bool OnCommand(string commandLine) { if (string.IsNullOrEmpty(commandLine)) { return(true); } string possibleHelp = null; var tokens = CommandToken.Parse(commandLine).ToArray(); 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]; command.Method.Invoke(command.Instance, arguments); return(true); } default: { // Show Ambiguous call throw new ArgumentException("Ambiguous calls for: " + string.Join(',', availableCommands.Select(u => u.Command.Key).Distinct())); } } }