Exemple #1
0
        public void TakeArgumentStateLogInitTest()
        {
            var sut       = new RemoveArgumentStateLog();
            var initHisto = sut.ToString(true);

            const string expected = @"
                                             Start:    0
                                 LeadingWhitespace:    0
                  ScanningBackslashesOutsideQuotes:    0
                QuoteAfterBackslashesOutsideQuotes:    0
                  EmittingBackslashesOutsideQuotes:    0
                  CheckForArgumentEndOutsideQuotes:    0
 EmittingBackslashesOutsideQuotesGoingInsideQuotes:    0
                   ScanningBackslashesInsideQuotes:    0
                 QuoteAfterBackslashesInsideQuotes:    0
                   EmittingBackslashesInsideQuotes:    0
     CheckForTwoQuotesAfterBackslashesInsideQuotes:    0
 EmittingBackslashesInsideQuotesGoingOutsideQuotes:    0
 CheckForArgumentEndInsideQuotesGoingOutsideQuotes:    0
EmittingBackslashesInsideQuotesStayingInsideQuotes:    0
                  EmitFinalBackslashesInsideQuotes:    0
                                         CopyToEnd:    0
                                               End:    0
";

            Assert.Equal(expected, initHisto);
        }
Exemple #2
0
        public void TakeArgumentTests(string input, string expectedArgument, string expectedRemainingLine)
        {
            var argumentStream = input.ToCharArray().AsEnumerable();
            var argumentValue  = new StringBuilder();
            var log            = new RemoveArgumentStateLog();
            var remainingLine  = input.RemoveArgument(argumentValue, log).Collect();

            output_.WriteLine(log.ToString(true));
            argumentValue.ToString().Should().Be(expectedArgument, "arg failed, input was \"{0}\"", input.ToLiteralFormat());
            remainingLine.Should().Be(expectedRemainingLine, "remaining failed, input was \"{0}\"", input.ToLiteralFormat());
        }
Exemple #3
0
        public void TakeArgumentStateLogWithLoggingTest()
        {
            var sut = new RemoveArgumentStateLog();
            var sb  = new StringBuilder();

            sb.Append('x');
            sut.Add("Start-a-0-x", CppArgumentLexing.ArgStates.Start, 'a', 0, sb);
            sb.Append('y');
            sut.Add("LeadingWhitespace-b-1-xy", CppArgumentLexing.ArgStates.LeadingWhitespace, 'b', 1, sb);
            sb.Append('z');
            sut.Add("EmitFinalBackslashesInsideQuotes-c-2-xyz", CppArgumentLexing.ArgStates.EmitFinalBackslashesInsideQuotes, 'c', 2, sb);
            sb.Append('w');
            sut.Add("LeadingWhitespace-d-3-xyzw", CppArgumentLexing.ArgStates.LeadingWhitespace, 'd', 3, sb);
            var log = sut.ToString();

            output_.WriteLine(log);
            const string expectedLog = @"(Start-a-0-x, Start, 'a', 0, ""x"")
(LeadingWhitespace-b-1-xy, LeadingWhitespace, 'b', 1, ""xy"")
(EmitFinalBackslashesInsideQuotes-c-2-xyz, EmitFinalBackslashesInsideQuotes, 'c', 2, ""xyz"")
(LeadingWhitespace-d-3-xyzw, LeadingWhitespace, 'd', 3, ""xyzw"")
";

            Assert.Equal(expectedLog, log);

            var          histo         = sut.ToString(true);
            const string expectedHisto = expectedLog + @"
                                             Start:    1
                                 LeadingWhitespace:    2
                  ScanningBackslashesOutsideQuotes:    0
                QuoteAfterBackslashesOutsideQuotes:    0
                  EmittingBackslashesOutsideQuotes:    0
                  CheckForArgumentEndOutsideQuotes:    0
 EmittingBackslashesOutsideQuotesGoingInsideQuotes:    0
                   ScanningBackslashesInsideQuotes:    0
                 QuoteAfterBackslashesInsideQuotes:    0
                   EmittingBackslashesInsideQuotes:    0
     CheckForTwoQuotesAfterBackslashesInsideQuotes:    0
 EmittingBackslashesInsideQuotesGoingOutsideQuotes:    0
 CheckForArgumentEndInsideQuotesGoingOutsideQuotes:    0
EmittingBackslashesInsideQuotesStayingInsideQuotes:    0
                  EmitFinalBackslashesInsideQuotes:    1
                                         CopyToEnd:    0
                                               End:    0
";

            Assert.Equal(expectedHisto, histo);
        }
Exemple #4
0
            /// <summary>
            /// Grab a parameter (_not_ the first) off of incoming stream, then pass
            /// all the rest of the characters unchanged.  Quoting rules are
            /// complicated, see http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULES
            /// and https://msdn.microsoft.com/en-us/library/17w5ykft(v=vs.120).aspx
            /// for details.
            /// </summary>
            /// <remarks>
            /// Engineered from the D.Deley article above into a state machine.
            /// </remarks>
            public static IEnumerable<char> RemoveArgument(
                this IEnumerable<char> source,
                StringBuilder argument,
                /*out*/ RemoveArgumentStateLog log = null)
            {
                ArgStates state = ArgStates.Start;
                int nBackslashes = 0;

                foreach (char c in source)
                {
                    if (null != log) log.Add("fetchChar", state, c, nBackslashes, argument);
                    goto stateAction;

                reinspectChar:
                    if (null != log) log.Add("reinspectChar", state, c, nBackslashes, argument);
                    goto stateAction;

                stateAction:
                    switch (state)
                    {
                        case ArgStates.Start:
                            state = ArgStates.LeadingWhitespace;
                            goto reinspectChar;

                        case ArgStates.LeadingWhitespace:
                            if (' ' == c || '\t' == c)
                            {
                                continue;
                            }
                            else
                            {
                                state = ArgStates.ScanningBackslashesOutsideQuotes;
                                nBackslashes = 0;
                                goto reinspectChar;
                            }

                        case ArgStates.ScanningBackslashesOutsideQuotes:
                            if ('\\' == c)
                            {
                                nBackslashes++;
                                continue;
                            }
                            else if ('\"' == c)
                            {
                                state = ArgStates.QuoteAfterBackslashesOutsideQuotes;
                                goto reinspectChar;
                            }
                            else
                            {
                                state = ArgStates.EmittingBackslashesOutsideQuotes;
                                goto reinspectChar;
                            }

                        case ArgStates.QuoteAfterBackslashesOutsideQuotes:
                            {
                                bool oddBackslashes = 1 == nBackslashes % 2;
                                nBackslashes /= 2;
                                if (oddBackslashes)
                                {
                                    state = ArgStates.EmittingBackslashesOutsideQuotes;
                                    goto reinspectChar;
                                }
                                else
                                {
                                    state = ArgStates.EmittingBackslashesOutsideQuotesGoingInsideQuotes;
                                    continue;
                                }
                            }

                        case ArgStates.EmittingBackslashesOutsideQuotes:
                            argument.Append('\\', nBackslashes);
                            nBackslashes = 0;
                            state = ArgStates.CheckForArgumentEndOutsideQuotes;
                            goto reinspectChar;

                        case ArgStates.CheckForArgumentEndOutsideQuotes:
                            if (' ' == c || '\t' == c)
                            {
                                state = ArgStates.CopyToEnd;
                                goto reinspectChar;
                            }
                            else
                            {
                                argument.Append(c);
                                nBackslashes = 0;
                                state = ArgStates.ScanningBackslashesOutsideQuotes;
                                continue;
                            }

                        case ArgStates.EmittingBackslashesOutsideQuotesGoingInsideQuotes:
                            argument.Append('\\', nBackslashes);
                            nBackslashes = 0;
                            state = ArgStates.ScanningBackslashesInsideQuotes;
                            goto reinspectChar;

                        case ArgStates.ScanningBackslashesInsideQuotes:
                            if ('\\' == c)
                            {
                                nBackslashes++;
                                continue;
                            }
                            else if ('\"' == c)
                            {
                                state = ArgStates.QuoteAfterBackslashesInsideQuotes;
                                goto reinspectChar;
                            }
                            else
                            {
                                state = ArgStates.EmittingBackslashesInsideQuotes;
                                goto reinspectChar;
                            }

                        case ArgStates.QuoteAfterBackslashesInsideQuotes:
                            {
                                bool oddBackslashes = 1 == nBackslashes % 2;
                                nBackslashes /= 2;
                                if (oddBackslashes)
                                {
                                    state = ArgStates.EmittingBackslashesInsideQuotes;
                                    goto reinspectChar;
                                }
                                else
                                {
                                    state = ArgStates.CheckForTwoQuotesAfterBackslashesInsideQuotes;
                                    continue;
                                }
                            }

                        case ArgStates.EmittingBackslashesInsideQuotes:
                            argument.Append('\\', nBackslashes).Append(c);
                            nBackslashes = 0;
                            state = ArgStates.ScanningBackslashesInsideQuotes;
                            continue;

                        case ArgStates.CheckForTwoQuotesAfterBackslashesInsideQuotes:
                            if ('\"' == c)
                            {
                                state = ArgStates.EmittingBackslashesInsideQuotesStayingInsideQuotes;
                                goto reinspectChar;
                            }
                            else
                            {
                                state = ArgStates.EmittingBackslashesInsideQuotesGoingOutsideQuotes;
                                goto reinspectChar;
                            }

                        case ArgStates.EmittingBackslashesInsideQuotesGoingOutsideQuotes:
                            argument.Append('\\', nBackslashes);
                            nBackslashes = 0;
                            state = ArgStates.CheckForArgumentEndInsideQuotesGoingOutsideQuotes;
                            goto reinspectChar;

                        case ArgStates.EmittingBackslashesInsideQuotesStayingInsideQuotes:
                            argument.Append('\\', nBackslashes).Append('\"');
                            nBackslashes = 0;
                            state = ArgStates.ScanningBackslashesInsideQuotes;
                            continue;

                        case ArgStates.CheckForArgumentEndInsideQuotesGoingOutsideQuotes:
                            if (' ' == c || '\t' == c)
                            {
                                state = ArgStates.CopyToEnd;
                                goto reinspectChar;
                            }
                            else
                            {
                                argument.Append(c);
                                nBackslashes = 0;
                                state = ArgStates.ScanningBackslashesOutsideQuotes;
                                continue;
                            }

                        case ArgStates.CopyToEnd:
                            yield return c;
                            state = ArgStates.CopyToEnd;
                            continue;
                    }
                }

                // Flush final backslashes if any (there's only one state where this is necessary)
                if (ArgStates.CheckForTwoQuotesAfterBackslashesInsideQuotes == state)
                {
                    if (null != log) log.Add("flushing final backslashes", state, '¶', nBackslashes, argument);
                    argument.Append('\\', nBackslashes);
                }

                if (null != log) log.Add("final result", ArgStates.End, '¶', 0, argument);
            }