From c88a92f5e6753e6640934f6f9d9b093f98a26fe2 Mon Sep 17 00:00:00 2001 From: RogueException Date: Sun, 29 Nov 2015 11:16:10 -0400 Subject: [PATCH] Ignore repeated whitespaces in commands, and support linebreaks and tabs --- src/Discord.Net.Commands/CommandParser.cs | 31 ++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index c45473f33..d282a651d 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -4,7 +4,7 @@ namespace Discord.Commands { internal static class CommandParser { - private enum CommandParserPart + private enum ParserPart { None, Parameter, @@ -32,7 +32,7 @@ namespace Discord.Commands else if (currentChar == '\\') isEscaped = true; - if ((!isEscaped && currentChar == ' ') || endPosition >= inputLength) + if ((!isEscaped && IsWhiteSpace(currentChar)) || endPosition >= inputLength) { int length = (currentChar == ' ' ? endPosition - 1 : endPosition) - startPosition; string temp = input.Substring(startPosition, length); @@ -55,11 +55,12 @@ namespace Discord.Commands commands = map.GetCommands(); //Work our way backwards to find a command that matches our input return commands != null; } + private static bool IsWhiteSpace(char c) => c == ' ' || c == '\n' || c == '\r' || c == '\t'; //TODO: Check support for escaping public static CommandErrorType? ParseArgs(string input, int startPos, Command command, out string[] args) { - CommandParserPart currentPart = CommandParserPart.None; + ParserPart currentPart = ParserPart.None; int startPosition = startPos; int endPosition = startPos; int inputLength = input.Length; @@ -94,20 +95,26 @@ namespace Discord.Commands else if (currentChar == '\\') isEscaped = true; + if (endPosition == startPosition + 1 && IsWhiteSpace(currentChar)) //Has no text yet, and is another whitespace + { + startPosition = endPosition; + continue; + } + switch (currentPart) { - case CommandParserPart.None: + case ParserPart.None: if ((!isEscaped && currentChar == '\"')) { - currentPart = CommandParserPart.DoubleQuotedParameter; + currentPart = ParserPart.DoubleQuotedParameter; startPosition = endPosition; } else if ((!isEscaped && currentChar == '\'')) { - currentPart = CommandParserPart.QuotedParameter; + currentPart = ParserPart.QuotedParameter; startPosition = endPosition; } - else if ((!isEscaped && currentChar == ' ') || endPosition >= inputLength) + else if ((!isEscaped && IsWhiteSpace(currentChar)) || endPosition >= inputLength) { int length = (currentChar == ' ' ? endPosition - 1 : endPosition) - startPosition; string temp = input.Substring(startPosition, length); @@ -115,28 +122,28 @@ namespace Discord.Commands startPosition = endPosition; else { - currentPart = CommandParserPart.None; + currentPart = ParserPart.None; argList.Add(temp); startPosition = endPosition; } } break; - case CommandParserPart.QuotedParameter: + case ParserPart.QuotedParameter: if ((!isEscaped && currentChar == '\'')) { string temp = input.Substring(startPosition, endPosition - startPosition - 1); - currentPart = CommandParserPart.None; + currentPart = ParserPart.None; argList.Add(temp); startPosition = endPosition; } else if (endPosition >= inputLength) return CommandErrorType.InvalidInput; break; - case CommandParserPart.DoubleQuotedParameter: + case ParserPart.DoubleQuotedParameter: if ((!isEscaped && currentChar == '\"')) { string temp = input.Substring(startPosition, endPosition - startPosition - 1); - currentPart = CommandParserPart.None; + currentPart = ParserPart.None; argList.Add(temp); startPosition = endPosition; }