]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.0951: trying every character position for a match is inefficient v9.0.0951
authorBram Moolenaar <Bram@vim.org>
Sat, 26 Nov 2022 11:47:10 +0000 (11:47 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 26 Nov 2022 11:47:10 +0000 (11:47 +0000)
Problem:    Trying every character position for a match is inefficient.
Solution:   Use the start position of the match ignoring "\zs".

src/regexp.c
src/regexp.h
src/regexp_bt.c
src/regexp_nfa.c
src/version.c

index 74ed13f3fba3954824943ed2e45b2491036a9074..af8b375b60d3062c06f57671eec67a0405da6247 100644 (file)
@@ -1123,10 +1123,12 @@ static unsigned reg_tofreelen;
 typedef struct {
     regmatch_T         *reg_match;
     regmmatch_T                *reg_mmatch;
+
     char_u             **reg_startp;
     char_u             **reg_endp;
     lpos_T             *reg_startpos;
     lpos_T             *reg_endpos;
+
     win_T              *reg_win;
     buf_T              *reg_buf;
     linenr_T           reg_firstlnum;
index 89c41c9579bfcc36343c35c90afa2f8fc23a3cfb..d6c8f48c7b93390fe9db076d95fcce649ecaa83c 100644 (file)
@@ -133,6 +133,8 @@ typedef struct
     regprog_T          *regprog;
     char_u             *startp[NSUBEXP];
     char_u             *endp[NSUBEXP];
+
+    colnr_T            rm_matchcol;   // match start without "\zs"
     int                        rm_ic;
 } regmatch_T;
 
@@ -149,6 +151,8 @@ typedef struct
     regprog_T          *regprog;
     lpos_T             startpos[NSUBEXP];
     lpos_T             endpos[NSUBEXP];
+
+    colnr_T            rmm_matchcol;   // match start without "\zs"
     int                        rmm_ic;
     colnr_T            rmm_maxcol;     // when not zero: maximum column
 } regmmatch_T;
index 520656798fae8d4ae73c2ca2b3903223eafb0dc0..42b6ac20137cf92d27078a6b7f57be6c784e3e40 100644 (file)
@@ -4842,11 +4842,12 @@ regtry(
     static long
 bt_regexec_both(
     char_u     *line,
-    colnr_T    col,            // column to start looking for match
+    colnr_T    startcol,       // column to start looking for match
     int                *timed_out)     // flag set on timeout or NULL
 {
     bt_regprog_T    *prog;
     char_u         *s;
+    colnr_T        col = startcol;
     long           retval = 0L;
 
     // Create "regstack" and "backpos" if they are not allocated yet.
@@ -5042,11 +5043,19 @@ theend:
            if (end->lnum < start->lnum
                        || (end->lnum == start->lnum && end->col < start->col))
                rex.reg_mmatch->endpos[0] = rex.reg_mmatch->startpos[0];
+
+           // startpos[0] may be set by "\zs", also return the column where
+           // the whole pattern matched.
+           rex.reg_mmatch->rmm_matchcol = col;
        }
        else
        {
            if (rex.reg_match->endp[0] < rex.reg_match->startp[0])
                rex.reg_match->endp[0] = rex.reg_match->startp[0];
+
+           // startpos[0] may be set by "\zs", also return the column where
+           // the whole pattern matched.
+           rex.reg_match->rm_matchcol = col;
        }
     }
 
index 0228cfc42b901f54b48ff7766c0e4afefb80b042..17025108a767abe9b32e1e8347eec971d042a8b0 100644 (file)
@@ -7378,7 +7378,14 @@ nfa_regexec_both(
        // If match_text is set it contains the full text that must match.
        // Nothing else to try. Doesn't handle combining chars well.
        if (prog->match_text != NULL && !rex.reg_icombine)
-           return find_match_text(col, prog->regstart, prog->match_text);
+       {
+           retval = find_match_text(col, prog->regstart, prog->match_text);
+           if (REG_MULTI)
+               rex.reg_mmatch->rmm_matchcol = col;
+           else
+               rex.reg_match->rm_matchcol = col;
+           return retval;
+       }
     }
 
     // If the start column is past the maximum column: no need to try.
@@ -7414,11 +7421,19 @@ theend:
            if (end->lnum < start->lnum
                        || (end->lnum == start->lnum && end->col < start->col))
                rex.reg_mmatch->endpos[0] = rex.reg_mmatch->startpos[0];
+
+           // startpos[0] may be set by "\zs", also return the column where
+           // the whole pattern matched.
+           rex.reg_mmatch->rmm_matchcol = col;
        }
        else
        {
            if (rex.reg_match->endp[0] < rex.reg_match->startp[0])
                rex.reg_match->endp[0] = rex.reg_match->startp[0];
+
+           // startpos[0] may be set by "\zs", also return the column where
+           // the whole pattern matched.
+           rex.reg_match->rm_matchcol = col;
        }
     }
 
index 9566edd996867968b14cea411db17b6ca30f77f8..829e71dea731686967f6489deb5976341db1d0c5 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    951,
 /**/
     950,
 /**/