protected override bool CompareAndAdvanceImp(
            string input,
            int pos,
            int depth,
            RunState runState,
            out int index)
        {
            int depthPlusOne = depth + 1;

            // If the start doesn't match the open then this is not a match
            if (m_Open.CompareAndAdvance(input, pos, depthPlusOne, runState, out pos))
            {
                // How far down the rabbit hole are we?
                int nestedDepth = 1;
                for (; ;)
                {
                    int currentPos = pos;
                    if (m_Open.CompareAndAdvance(input, currentPos, depthPlusOne, runState, out pos))
                    {
                        ++nestedDepth;
                    }
                    else if (m_Close.CompareAndAdvance(input, currentPos, depthPlusOne, runState, out pos))
                    {
                        --nestedDepth;
                        if (nestedDepth == 0)
                        {
                            // Found the end
                            index = pos;
                            return(true);
                        }
                    }
                    else
                    {
                        // Advance by 1
                        pos = currentPos + 1;
                    }
                }
            }

            index = -1;
            return(false);
        }
Exemple #2
0
 protected override void PerformImp(
     string input,
     int pos,
     int depth,
     RunState runState,
     out int index)
 {
     if (!m_Comparison.CompareAndAdvance(input, pos, depth + 1, runState, out index))
     {
         // Reset the position back to the beginning if the comparison is false
         index = pos;
     }
 }
Exemple #3
0
        protected override bool CompareAndAdvanceImp(
            string input,
            int pos,
            int depth,
            RunState runState,
            out int index)
        {
            bool rv = Comparison.CompareAndAdvance(input, pos, depth + 1, runState, out index);

            if (rv)
            {
                // Do the capture
                Length   = index - pos;
                Captured = input.Substring(pos, Length);
                BeginPos = pos;
                EndPos   = index;
            }

            return(rv);
        }
        protected override bool CompareAndAdvanceImp(
            string input,
            int pos,
            int depth,
            RunState runState,
            out int index)
        {
            index = -1;
            // Basically just loop until the comparison returns true
            bool end          = false;
            int  depthPlusOne = depth + 1;

            for (index = pos; ;)
            {
                // Continue??
                if (m_ContinueComp != null)
                {
                    if (!m_ContinueComp.Compare(input, index, depthPlusOne, runState))
                    {
                        // No.
                        return(false);
                    }
                }

                int previousPos = index;
                end = m_Comparison.CompareAndAdvance(input, index, depthPlusOne, runState, out index);
                if (end)
                {
                    return(true);
                }

                // If the comparison fails and we are at the end of the string (last char + 1) then cease to continue
                if (previousPos == input.Length)
                {
                    return(false);
                }

                // Advance by 1 and try again
                index = previousPos + ((m_Forwards)?1: -1);
            }
        }
        protected override void PerformImp(
            string input,
            int pos,
            int depth,
            RunState runState,
            out int index)
        {
            index = -1;
            // Basically just loop until the comparison returns false
            bool end          = false;
            int  depthPlusOne = depth + 1;

            for (index = pos; index < input.Length && !end;)
            {
                int previousPos = index;
                end = !m_Comparison.CompareAndAdvance(input, index, depthPlusOne, runState, out index);
                if (end)
                {
                    index = previousPos;
                }
            }
        }
Exemple #6
0
        //TODO does it make sense to have a list of 0 items?
        protected override bool CompareAndAdvanceImp(
            string input,
            int pos,
            int depth,
            RunState runState,
            out int index)
        {
            index = -1;
            // 'i' keeps track of how many iterations (list items) we've had
            int  i;
            bool reachedEndOfList = false;
            int  depthPlusOne     = depth + 1;

            for (i = 0;;)
            {
#if DEBUG
                int dbgPosAtStart = pos;
#endif
                // Skip the line wrap if there is one before the list item
                m_Options.SkipLineWrap(input, pos, depthPlusOne, runState, out pos);
                if (pos >= input.Length)
                {
                    // Reached the end of the input string
                    break;
                }

                // Trim left
                if (ItemTrim != null)
                {
                    ItemTrim.Perform(input, pos, depthPlusOne, runState, out pos);
                    if (pos >= input.Length)
                    {
                        // Reached the end of the input string
                        break;
                    }
                }

                // Do the comparison
                if (!m_Comparison.CompareAndAdvance(input, pos, depthPlusOne, runState, out pos))
                {
                    // This list item does not match so overall it is a fail
                    index = -1;
                    return(false);
                }

                // We've had another successful item match
                ++i;

                // Skip the line wrap if there is one after the list item
                m_Options.SkipLineWrap(input, pos, depthPlusOne, runState, out pos);
                if (pos >= input.Length)
                {
                    // Reached the end of the input string
                    break;
                }

                // Trim right
                int beforeRightTrim = pos;
                if (ItemTrim != null)
                {
                    ItemTrim.Perform(input, pos, depthPlusOne, runState, out pos);
                    if (pos >= input.Length)
                    {
                        // Reached the end of the input string
                        break;
                    }
                }

                // Did we reach the seperator/delimiter?
                int afterSeperator;
                if (m_Seperator.CompareAndAdvance(
                        input,
                        pos,
                        depthPlusOne,
                        runState,
                        out afterSeperator))
                {
                    // Update the index to be after the seperator
                    pos = afterSeperator;
                    // Get another list item
                }
                else
                {
                    // Must have reached the end of the list
                    // Keep the index as the first character of the end - key nuance design decision
                    reachedEndOfList = true;

                    // If we've reached the end of the list, retreat to before the item trim
                    pos = beforeRightTrim;
                    break;
                }
            }

            // Do we have the minimum number of items?
            bool rv;
            if (MinAmount.HasValue && i < MinAmount.Value)
            {
                rv = false;
            }
            // Do we have too many items?
            else if (MaxAmount.HasValue && i > MaxAmount.Value)
            {
                rv = false;
            }
            else
            {
                rv = reachedEndOfList;
            }

            index = pos;
            return(rv);
        }
Exemple #7
0
        // Returns whether this state is enabled
        public bool Update(
            string input,
            int pos,
            RunState runState,
            out int index)
        {
            bool orgEnabled = IsEnabled;

            index = pos;
            if (IsEnabled)
            {
                // Look for the disable state
                int afterDisable;
                IsEnabled = !m_Disable.CompareAndAdvance(input, pos, 0, runState, out afterDisable);
                if (!IsEnabled)
                {
                    // Skip to after the compare
                    index = afterDisable;
                }
            }
            else
            {
                // Look for the enable state
                int afterEnable;
                IsEnabled = m_Enable.CompareAndAdvance(input, pos, 0, runState, out afterEnable);
                if (IsEnabled)
                {
                    // Skip to after the compare
                    index = afterEnable;
                }
            }

#if DEBUG
            // Has become enabled
            if (!orgEnabled && IsEnabled)
            {
                if (pos <= 9279)
                {
                    //Console.WriteLine(string.Format("enabled: {0}", pos));
                }
            }
            if (pos == 1374)
            {
                Misc.Break();
            }
#endif

#if DEBUG
            if (Name == @"style=""" || Name == @"table or th")
            {
                if (orgEnabled != IsEnabled)
                {
                    /*
                     * string stringPortion = input.Substring(pos, Math.Min(20, input.Length));
                     * Console.WriteLine(string.Format("Changed from {0} to {1}. pos: {3} string:\r\n{2}",
                     * orgEnabled,
                     * IsEnabled,
                     * stringPortion,
                     * pos));
                     */
                }
            }
#endif

            return(IsEnabled);
        }
Exemple #8
0
        protected override bool CompareAndAdvanceImp(
            string str,
            int firstIndex,
            int depth,
            RunState runState,
            out int index)
        {
            index = -1;
            // Statement index
            int  stmtIndex;
            bool failedMatch = false;
            int  pos;
            int  depthPlusOne = depth + 1;

            for (stmtIndex = 0, pos = firstIndex; !failedMatch && stmtIndex < m_Statements.Count;
                 ++stmtIndex)
            {
                // Key nuance design decision. It's OK to perform operations/comparisons even if we have reached the end of
                //  the string. This is necessary for things like setting variables, comparing against the end of the
                //  string e.t.c. No doubt there will be bugs presuming this isn't the case but I've only realised
                //  retrospectively that this is a requirement.
                IStatement stmt = m_Statements[stmtIndex];
                if (stmt is IOperation)
                {
                    IOperation op = (IOperation)stmt;
                    op.Perform(str, pos, depthPlusOne, runState, out pos);
                }
                else
                {
                    if (stmt is IComparisonWithAdvance)
                    {
                        IComparisonWithAdvance comp = (IComparisonWithAdvance)stmt;
                        int previousPos             = pos;
                        if (!comp.CompareAndAdvance(str, pos, depthPlusOne, runState, out pos))
                        {
                            // This part of the pattern match failed. Start again (using the outer loop/index) but at
                            //  the next character
                            failedMatch = true;
                        }
                    }
                    else if (stmt is IComparison)
                    {
                        //sidtodo not sure about this - I'm not sure the design of the statement classes is right
                        IComparison comp = (IComparison)stmt;
                        if (!comp.Compare(str, pos, depthPlusOne, runState))
                        {
                            failedMatch = true;
                        }
                    }
                }
            }

            // Got this far without a match?
            if (!failedMatch)
            {
                // Did we execute all statements?
                if (stmtIndex == m_Statements.Count)
                {
                    // Exclusions?
                    if (Exclusion != null)
                    {
                        string subStr = str.Substring(firstIndex, pos - firstIndex);
                        failedMatch = Exclusion.Compare(subStr, 0, depthPlusOne, runState);
                    }
                    if (!failedMatch)
                    {
                        // Successful match
                        index = pos;
                    }
                }
                else
                {
                    // We did not complete all of the comparisons
                    // Go to the next character
                    // Potentially a speedup here? If we reach the end of the input string but cannot complete all
                    //  comparisons then copy the remaining string rather than trying to do any more comparisons?
                    failedMatch = true;
                }
            }

            return(!failedMatch);
        }
Exemple #9
0
        private string Process(
            string input,
            string replaceWith,
            IComparisonWithAdvance mainComparison,
            Dictionary <string, Capture> capturing,
            List <State> stateList,
            bool replace,
            out int numMatches,
            Func <RunState, string, int, string> ReplaceFunc = null,
            Action <RunState> InitRunState = null)
        {
            // The replaced string
            StringBuilder replaced = new StringBuilder();

            var runState = new RunState();

            if (InitRunState != null)
            {
                InitRunState(runState);
            }
            numMatches = 0;

            // Iterate the input string character by character
            for (int outerIndex = 0; outerIndex < input.Length;)
            {
                runState.Clear();
                runState.BeginPos = outerIndex;
#if DEBUG
                int dbgInitialOuterIndex = outerIndex;
                if (dbgInitialOuterIndex == 1374)
                {
                    Misc.Break();
                }
                string dbgInputPortion = input.Substring(dbgInitialOuterIndex,
                                                         Math.Min(20, input.Length - dbgInitialOuterIndex));
#endif
                //// All states enabled?
                int  afterState = outerIndex;
                bool stateEnabled;
                if (stateList != null)
                {
                    for (; ;)
                    {
                        // If the state becomes enabled, check that directly afterwards we don't encounter a close state
                        // Imagine we have a state which opens on '<%' and closes on '%>' and the input string is '<%%> ...'
                        // We enable then instantly disable again. We only stop trying to update the state when updating the
                        //  state doesn't advance the position
                        int curIndex = afterState;
                        stateEnabled = UpdateState(stateList, input, afterState, runState, out afterState);
                        if (curIndex == afterState)
                        {
                            // Updating the state did not advance the position - continue with the replace
                            break;
                        }
                    }
                }
                else
                {
                    stateEnabled = true;
                }

                // Copy the state string (if any)
                if (afterState != outerIndex)
                {
                    string stateString = input.Substring(outerIndex, afterState - outerIndex);
                    replaced.Append(stateString);
                }

                // Update the main index
                outerIndex = afterState;

                if (outerIndex < input.Length)
                {
                    bool matched = stateEnabled;
                    if (stateEnabled)
                    {
                        // Run the statements beginning from 'afterState'
                        int innerIndex = outerIndex;
                        int afterMatch;
                        matched = mainComparison.CompareAndAdvance(input, innerIndex, 0, runState, out afterMatch);
                        if (matched)
                        {
                            // The begin of the matching string
                            runState.BeginPos = outerIndex;

                            ++numMatches;

                            // This is a match! :)
                            // Do the replace
                            string iterReplaced = ReplaceMatch(replaceWith, ReplaceFunc, capturing, runState, input, afterMatch);
                            replaced.Append(iterReplaced);
                            LogMatchReplace(
                                input,
                                innerIndex,
                                afterMatch,
                                iterReplaced,
                                capturing);

                            // Update the outer index and continue iterating from there
                            outerIndex = afterMatch;
                        }
                    }

                    if (!matched)
                    {
                        if (replace)
                        {
                            // Match failed: copy this character to the output string and move on to the next one (if this is replace mode)
                            replaced.Append(input[outerIndex]);
                        }
                        ++outerIndex;
                    }
                }
            }
            return(replaced.ToString());
        }