# HG changeset patch # User Bram Moolenaar # Date 1390504174 -3600 # Node ID d59544f3022ba0a35af174d1085a321de6d3b9b4 # Parent cae8fca838abd430bda4ca78b17fa7421a2b2c33 updated for version 7.4.158 Problem: Pattern containing \zs is not handled correctly by substitute(). Solution: Change how an empty match is skipped. (Yukihiro Nakadaira) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -24365,7 +24365,7 @@ do_string_sub(str, pat, sub, flags) garray_T ga; char_u *ret; char_u *save_cpo; - int zero_width; + char_u *zero_width = NULL; /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ save_cpo = p_cpo; @@ -24382,6 +24382,19 @@ do_string_sub(str, pat, sub, flags) tail = str; while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) { + /* Skip empty match except for first match. */ + if (regmatch.startp[0] == regmatch.endp[0]) + { + if (zero_width == regmatch.startp[0]) + { + /* avoid getting stuck on a match with an empty string */ + *((char_u *)ga.ga_data + ga.ga_len) = *tail++; + ++ga.ga_len; + continue; + } + zero_width = regmatch.startp[0]; + } + /* * Get some space for a temporary buffer to do the substitution * into. It will contain: @@ -24404,17 +24417,9 @@ do_string_sub(str, pat, sub, flags) (void)vim_regsub(®match, sub, (char_u *)ga.ga_data + ga.ga_len + i, TRUE, TRUE, FALSE); ga.ga_len += i + sublen - 1; - zero_width = (tail == regmatch.endp[0] - || regmatch.startp[0] == regmatch.endp[0]); tail = regmatch.endp[0]; if (*tail == NUL) break; - if (zero_width) - { - /* avoid getting stuck on a match with an empty string */ - *((char_u *)ga.ga_data + ga.ga_len) = *tail++; - ++ga.ga_len; - } if (!do_all) break; } diff --git a/src/testdir/test80.in b/src/testdir/test80.in --- a/src/testdir/test80.in +++ b/src/testdir/test80.in @@ -176,6 +176,23 @@ ENDTEST TEST_10: STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_10:\" +:let y = substitute('123', '\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\zs.', 'a', 'g') | $put =y +:let y = substitute('123', '.\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\ze', 'a', 'g') | $put =y +:let y = substitute('123', '\ze.', 'a', 'g') | $put =y +:let y = substitute('123', '.\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\zs\|[23]', 'a', 'g') | $put =y +/^TEST_11 +ENDTEST + +TEST_11: + +STARTTEST :/^Results/,$wq! test.out ENDTEST diff --git a/src/testdir/test80.ok b/src/testdir/test80.ok --- a/src/testdir/test80.ok +++ b/src/testdir/test80.ok @@ -115,3 +115,14 @@ N,,NZ TEST_9: XXx + + +TEST_10: +a1a2a3a +aaa +1a2a3a +a1a2a3a +a1a2a3 +aaa +aa2a3a +1aaa diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -739,6 +739,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 158, +/**/ 157, /**/ 156,