Tidy() private method

private Tidy ( int textpos ) : void
textpos int
return void
Example #1
0
        // TODO https://github.com/dotnet/runtime/issues/62573: Obsolete this.
        /// <summary>
        /// This method's body is only kept since it is a protected member that could be called by someone outside
        /// the assembly.
        /// </summary>
        protected internal Match?Scan(Regex regex, string text, int textbeg, int textend, int textstart, int prevlen, bool quick, TimeSpan timeout)
        {
            InitializeTimeout(timeout);

            RegexRunnerMode mode = quick ? RegexRunnerMode.ExistenceRequired : RegexRunnerMode.FullMatchRequired;

            // We set runtext before calling InitializeForScan so that runmatch object is initialized with the text
            runtext = text;

            InitializeForScan(regex, text, textstart, mode);

            // InitializeForScan will default runtextstart and runtextend to 0 and length of string
            // since it is configured to work over a sliced portion of text so we adjust those values.
            runtextstart = textstart;
            runtextend   = textend;

            // Configure the additional value to "bump" the position along each time we loop around
            // to call FindFirstChar again, as well as the stopping position for the loop.  We generally
            // bump by 1 and stop at textend, but if we're examining right-to-left, we instead bump
            // by -1 and stop at textbeg.
            int bump = 1, stoppos = textend;

            if (regex.RightToLeft)
            {
                bump    = -1;
                stoppos = textbeg;
            }

            // If previous match was empty or failed, advance by one before matching.
            if (prevlen == 0)
            {
                if (textstart == stoppos)
                {
                    return(Match.Empty);
                }

                runtextpos += bump;
            }

            Match match = InternalScan(regex, textbeg, textend);

            runtext = null; //drop reference

            if (match.FoundMatch)
            {
                if (quick)
                {
                    return(null);
                }

                runmatch = null;
                match.Tidy(runtextpos, 0, mode);
            }
            else
            {
                runmatch !.Text = null;
            }

            return(match);
        }
Example #2
0
 private Match TidyMatch(bool quick)
 {
     if (!quick)
     {
         Match runmatch = this.runmatch;
         this.runmatch = null;
         runmatch.Tidy(this.runtextpos);
         return(runmatch);
     }
     return(null);
 }
Example #3
0
        /*
         * Put match in its canonical form before returning it.
         */
        private Match TidyMatch(bool quick)
        {
            if (!quick)
            {
                Match match = _runmatch;

                _runmatch = null;

                match.Tidy(_runtextpos);
                return(match);
            }
            else
            {
                // in quick mode, a successful match returns null, and
                // the allocated match object is left in the cache

                return(null);
            }
        }
Example #4
0
        protected internal Match?Scan(Regex regex, string text, int textbeg, int textend, int textstart, int prevlen, bool quick, TimeSpan timeout)
        {
            // Store arguments into fields for derived runner to examine
            runregex   = regex;
            runtext    = text;
            runtextbeg = textbeg;
            runtextend = textend;
            runtextpos = runtextstart = textstart;

            // Handle timeout argument
            _timeout = -1; // (int)Regex.InfiniteMatchTimeout.TotalMilliseconds
            bool ignoreTimeout = _ignoreTimeout = Regex.InfiniteMatchTimeout == timeout;

            if (!ignoreTimeout)
            {
                // We are using Environment.TickCount and not Stopwatch for performance reasons.
                // Environment.TickCount is an int that cycles. We intentionally let timeoutOccursAt
                // overflow it will still stay ahead of Environment.TickCount for comparisons made
                // in DoCheckTimeout().
                Regex.ValidateMatchTimeout(timeout);                           // validate timeout as this could be called from user code due to being protected
                _timeout             = (int)(timeout.TotalMilliseconds + 0.5); // Round;
                _timeoutOccursAt     = Environment.TickCount + _timeout;
                _timeoutChecksToSkip = TimeoutCheckFrequency;
            }

            // Configure the additional value to "bump" the position along each time we loop around
            // to call FindFirstChar again, as well as the stopping position for the loop.  We generally
            // bump by 1 and stop at runtextend, but if we're examining right-to-left, we instead bump
            // by -1 and stop at runtextbeg.
            int bump = 1, stoppos = runtextend;

            if (runregex.RightToLeft)
            {
                bump    = -1;
                stoppos = runtextbeg;
            }

            // If previous match was empty or failed, advance by one before matching.
            if (prevlen == 0)
            {
                if (runtextpos == stoppos)
                {
                    return(Match.Empty);
                }

                runtextpos += bump;
            }

            // Main loop: FindFirstChar/Go + bump until the ending position.
            bool initialized = false;

            while (true)
            {
#if DEBUG
                if (runregex.IsDebug)
                {
                    Debug.WriteLine("");
                    Debug.WriteLine($"Search range: from {runtextbeg} to {runtextend}");
                    Debug.WriteLine($"Firstchar search starting at {runtextpos} stopping at {stoppos}");
                }
#endif

                // Find the next potential location for a match in the input.
                if (FindFirstChar())
                {
                    if (!ignoreTimeout)
                    {
                        DoCheckTimeout();
                    }

                    // Ensure that the runner is initialized.  This includes initializing all of the state in the runner
                    // that Go might use, such as the backtracking stack, as well as a Match object for it to populate.
                    if (!initialized)
                    {
                        InitializeForGo();
                        initialized = true;
                    }

#if DEBUG
                    if (runregex.IsDebug)
                    {
                        Debug.WriteLine($"Executing engine starting at {runtextpos}");
                        Debug.WriteLine("");
                    }
#endif

                    // See if there's a match at this position.
                    Go();

                    // If we got a match, we're done.
                    Match match = runmatch !;
                    if (match._matchcount[0] > 0)
                    {
                        if (quick)
                        {
                            return(null);
                        }

                        // Return the match in its canonical form.
                        runmatch = null;
                        match.Tidy(runtextpos);
                        return(match);
                    }

                    // Reset state for another iteration.
                    runtrackpos = runtrack !.Length;
                    runstackpos = runstack !.Length;
                    runcrawlpos = runcrawl !.Length;
                }

                // We failed to match at this position.  If we're at the stopping point, we're done.
                if (runtextpos == stoppos)
                {
                    return(Match.Empty);
                }

                // Bump by one (in whichever direction is appropriate) and loop to go again.
                runtextpos += bump;
            }
        }
Example #5
0
        /// <summary>Enumerates all of the matches with the specified regex, invoking the callback for each.</summary>
        /// <remarks>
        /// This optionally repeatedly hands out the same Match instance, updated with new information.
        /// <paramref name="reuseMatchObject"/> should be set to false if the Match object is handed out to user code.
        /// </remarks>
        internal void Scan <TState>(Regex regex, string text, int textstart, ref TState state, MatchCallback <TState> callback, bool reuseMatchObject, TimeSpan timeout)
        {
            // Handle timeout argument
            _timeout = -1; // (int)Regex.InfiniteMatchTimeout.TotalMilliseconds
            bool ignoreTimeout = _ignoreTimeout = Regex.InfiniteMatchTimeout == timeout;

            if (!ignoreTimeout)
            {
                // We are using Environment.TickCount and not Stopwatch for performance reasons.
                // Environment.TickCount is an int that cycles. We intentionally let timeoutOccursAt
                // overflow it will still stay ahead of Environment.TickCount for comparisons made
                // in DoCheckTimeout().
                _timeout             = (int)(timeout.TotalMilliseconds + 0.5); // Round;
                _timeoutOccursAt     = Environment.TickCount + _timeout;
                _timeoutChecksToSkip = TimeoutCheckFrequency;
            }

            // Configure the additional value to "bump" the position along each time we loop around
            // to call FindFirstChar again, as well as the stopping position for the loop.  We generally
            // bump by 1 and stop at text.Length, but if we're examining right-to-left, we instead bump
            // by -1 and stop at 0.
            int bump = 1, stoppos = text.Length;

            if (regex.RightToLeft)
            {
                bump    = -1;
                stoppos = 0;
            }

            // Store remaining arguments into fields now that we're going to start the scan.
            // These are referenced by the derived runner.
            runregex     = regex;
            runtextstart = runtextpos = textstart;
            runtext      = text;
            runtextend   = text.Length;
            runtextbeg   = 0;

            // Main loop: FindFirstChar/Go + bump until the ending position.
            bool initialized = false;

            while (true)
            {
#if DEBUG
                if (regex.IsDebug)
                {
                    Debug.WriteLine("");
                    Debug.WriteLine($"Search range: from {runtextbeg} to {runtextend}");
                    Debug.WriteLine($"Firstchar search starting at {runtextpos} stopping at {stoppos}");
                }
#endif

                // Find the next potential location for a match in the input.
                if (FindFirstChar())
                {
                    if (!ignoreTimeout)
                    {
                        DoCheckTimeout();
                    }

                    // Ensure that the runner is initialized.  This includes initializing all of the state in the runner
                    // that Go might use, such as the backtracking stack, as well as a Match object for it to populate.
                    if (!initialized)
                    {
                        InitializeForGo();
                        initialized = true;
                    }

#if DEBUG
                    if (regex.IsDebug)
                    {
                        Debug.WriteLine($"Executing engine starting at {runtextpos}");
                        Debug.WriteLine("");
                    }
#endif

                    // See if there's a match at this position.
                    Go();

                    // See if we have a match.
                    Match match = runmatch !;
                    if (match._matchcount[0] > 0)
                    {
                        // Hand it out to the callback in canonical form.
                        if (!reuseMatchObject)
                        {
                            // We're not reusing match objects, so null out our field reference to the instance.
                            // It'll be recreated the next time one is needed.
                            runmatch = null;
                        }
                        match.Tidy(runtextpos);
                        initialized = false;
                        if (!callback(ref state, match))
                        {
                            // If the callback returns false, we're done.
                            // Drop reference to text to avoid keeping it alive in a cache.
                            runtext = null !;
                            if (reuseMatchObject)
                            {
                                // We're reusing the single match instance, so clear out its text as well.
                                // We don't do this if we're not reusing instances, as in that case we're
                                // dropping the whole reference to the match, and we no longer own the instance
                                // having handed it out to the callback.
                                match.Text = null !;
                            }
                            return;
                        }

                        // Now that we've matched successfully, update the starting position to reflect
                        // the current position, just as Match.NextMatch() would pass in _textpos as textstart.
                        runtextstart = runtextpos;

                        // Reset state for another iteration.
                        runtrackpos = runtrack !.Length;
                        runstackpos = runstack !.Length;
                        runcrawlpos = runcrawl !.Length;
                        if (match.Length == 0)
                        {
                            if (runtextpos == stoppos)
                            {
                                // Drop reference to text to avoid keeping it alive in a cache.
                                runtext = null !;
                                if (reuseMatchObject)
                                {
                                    // See above comment.
                                    match.Text = null !;
                                }
                                return;
                            }

                            runtextpos += bump;
                        }

                        // Loop around to perform next match from where we left off.
                        continue;
                    }

                    // Ran Go but it didn't find a match. Reset state for another iteration.
                    runtrackpos = runtrack !.Length;
                    runstackpos = runstack !.Length;
                    runcrawlpos = runcrawl !.Length;
                }

                // We failed to match at this position.  If we're at the stopping point, we're done.
                if (runtextpos == stoppos)
                {
                    runtext = null; // drop reference to text to avoid keeping it alive in a cache
                    if (runmatch != null)
                    {
                        runmatch.Text = null !;
                    }
                    return;
                }

                // Bump by one (in whichever direction is appropriate) and loop to go again.
                runtextpos += bump;
            }
        }
Example #6
0
 private Match TidyMatch(bool quick)
 {
     if (!quick)
     {
         Match runmatch = this.runmatch;
         this.runmatch = null;
         runmatch.Tidy(this.runtextpos);
         return runmatch;
     }
     return null;
 }