<commit_before>﻿using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;

namespace Discord.Commands
{
    internal static class CommandParser
    {
        private enum ParserPart
        {
            None,
            Parameter,
            QuotedParameter
        }

        //TODO: Check support for escaping
        public static async Task<ParseResult> ParseArgs(Command command, IMessage context, string input, int startPos)
        {
            CommandParameter curParam = null;
            StringBuilder argBuilder = new StringBuilder(input.Length);
            int endPos = input.Length;
            var curPart = ParserPart.None;
            int lastArgEndPos = int.MinValue;
            var argList = ImmutableArray.CreateBuilder<object>();
            bool isEscaping = false;
            char c;

            for (int curPos = startPos; curPos <= endPos; curPos++)
            {
                if (curPos < endPos)
                    c = input[curPos];
                else
                    c = '\0';

                //If this character is escaped, skip it
                if (isEscaping)
                {
                    if (curPos != endPos)
                    {
                        argBuilder.Append(c);
                        isEscaping = false;
                        continue;
                    }
                }
                //Are we escaping the next character?
                if (c == '\\')
                {
                    isEscaping = true;
                    continue;
                }

                //If we're processing an unparsed parameter, ignore all other logic
                if (curParam != null && curParam.IsUnparsed && curPos != endPos)
                {
                    argBuilder.Append(c);
                    continue;
                }

                //If we're not currently processing one, are we starting the next argument yet?
                if (curPart == ParserPart.None)
                {
                    if (char.IsWhiteSpace(c) || curPos == endPos)
                        continue; //Skip whitespace between arguments
                    else if (curPos == lastArgEndPos)
                        return ParseResult.FromError(CommandError.ParseFailed, "There must be at least one character of whitespace between arguments.");
                    else
                    {
                        curParam = command.Parameters.Count > argList.Count ? command.Parameters[argList.Count] : null;
                        if (curParam != null && curParam.IsUnparsed)
                        {
                            argBuilder.Append(c);
                            continue;
                        }
                        if (c == '\"')
                        {<commit_msg>Fixed escapes for unparsed parameters<commit_after>﻿using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;

namespace Discord.Commands
{
    internal static class CommandParser
    {
        private enum ParserPart
        {
            None,
            Parameter,
            QuotedParameter
        }
        
        public static async Task<ParseResult> ParseArgs(Command command, IMessage context, string input, int startPos)
        {
            CommandParameter curParam = null;
            StringBuilder argBuilder = new StringBuilder(input.Length);
            int endPos = input.Length;
            var curPart = ParserPart.None;
            int lastArgEndPos = int.MinValue;
            var argList = ImmutableArray.CreateBuilder<object>();
            bool isEscaping = false;
            char c;

            for (int curPos = startPos; curPos <= endPos; curPos++)
            {
                if (curPos < endPos)
                    c = input[curPos];
                else
                    c = '\0';

                //If this character is escaped, skip it
                if (isEscaping)
                {
                    if (curPos != endPos)
                    {
                        argBuilder.Append(c);
                        isEscaping = false;
                        continue;
                    }
                }
                //Are we escaping the next character?
                if (c == '\\' && (curParam == null || !curParam.IsUnparsed))
                {
                    isEscaping = true;
                    continue;
                }

                //If we're processing an unparsed parameter, ignore all other logic
                if (curParam != null && curParam.IsUnparsed && curPos != endPos)
                {
                    argBuilder.Append(c);
                    continue;
                }

                //If we're not currently processing one, are we starting the next argument yet?
                if (curPart == ParserPart.None)
                {
                    if (char.IsWhiteSpace(c) || curPos == endPos)
                        continue; //Skip whitespace between arguments
                    else if (curPos == lastArgEndPos)
                        return ParseResult.FromError(CommandError.ParseFailed, "There must be at least one character of whitespace between arguments.");
                    else
                    {
                        curParam = command.Parameters.Count > argList.Count ? command.Parameters[argList.Count] : null;
                        if (curParam != null && curParam.IsUnparsed)
                        {
                            argBuilder.Append(c);
                            continue;
                        }
                        if (c == '\"')
                        {
{'fraction_non_alphanumeric': 0.07488050982474774, 'fraction_numerical': 0.0003540449637103912, 'mean_word_length': 1.1074226035061545, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6333126', 'n_tokens_mistral': 1318, 'n_tokens_neox': 1224, 'n_words': 352}