diff --git a/7.1.292 b/7.1.292 new file mode 100644 index 0000000..2ebecfc --- /dev/null +++ b/7.1.292 @@ -0,0 +1,251 @@ +To: vim-dev@vim.org +Subject: Patch 7.1.292 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=ISO-8859-1 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.1.292 +Problem: When using a pattern with "\@<=" the submatches can be wrong. + (Brett Stahlman) +Solution: Save the submatches when attempting a look-behind match. +Files: src/regexp.c + + +*** ../vim-7.1.291/src/regexp.c Sat Jan 19 15:55:51 2008 +--- src/regexp.c Tue Apr 1 18:15:47 2008 +*************** +*** 3039,3044 **** +--- 3039,3053 ---- + } se_u; + } save_se_T; + ++ /* used for BEHIND and NOBEHIND matching */ ++ typedef struct regbehind_S ++ { ++ regsave_T save_after; ++ regsave_T save_behind; ++ save_se_T save_start[NSUBEXP]; ++ save_se_T save_end[NSUBEXP]; ++ } regbehind_T; ++ + static char_u *reg_getline __ARGS((linenr_T lnum)); + static long vim_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm)); + static long regtry __ARGS((regprog_T *prog, colnr_T col)); +*************** +*** 3046,3051 **** +--- 3055,3062 ---- + #ifdef FEAT_SYN_HL + static void cleanup_zsubexpr __ARGS((void)); + #endif ++ static void save_subexpr __ARGS((regbehind_T *bp)); ++ static void restore_subexpr __ARGS((regbehind_T *bp)); + static void reg_nextline __ARGS((void)); + static void reg_save __ARGS((regsave_T *save, garray_T *gap)); + static void reg_restore __ARGS((regsave_T *save, garray_T *gap)); +*************** +*** 3166,3184 **** + save_se_T sesave; + regsave_T regsave; + } rs_un; /* room for saving reginput */ +! short rs_no; /* submatch nr */ + } regitem_T; + + static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan)); + static void regstack_pop __ARGS((char_u **scan)); + +- /* used for BEHIND and NOBEHIND matching */ +- typedef struct regbehind_S +- { +- regsave_T save_after; +- regsave_T save_behind; +- } regbehind_T; +- + /* used for STAR, PLUS and BRACE_SIMPLE matching */ + typedef struct regstar_S + { +--- 3177,3188 ---- + save_se_T sesave; + regsave_T regsave; + } rs_un; /* room for saving reginput */ +! short rs_no; /* submatch nr or BEHIND/NOBEHIND */ + } regitem_T; + + static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan)); + static void regstack_pop __ARGS((char_u **scan)); + + /* used for STAR, PLUS and BRACE_SIMPLE matching */ + typedef struct regstar_S + { +*************** +*** 4888,4893 **** +--- 4892,4901 ---- + status = RA_FAIL; + else + { ++ /* Need to save the subexpr to be able to restore them ++ * when there is a match but we don't use it. */ ++ save_subexpr(((regbehind_T *)rp) - 1); ++ + rp->rs_no = op; + reg_save(&rp->rs_un.regsave, &backpos); + /* First try if what follows matches. If it does then we +*************** +*** 5118,5132 **** + reg_restore(&(((regbehind_T *)rp) - 1)->save_after, + &backpos); + else +! /* But we didn't want a match. */ + status = RA_NOMATCH; + regstack_pop(&scan); + regstack.ga_len -= sizeof(regbehind_T); + } + else + { +! /* No match: Go back one character. May go to previous +! * line once. */ + no = OK; + if (REG_MULTI) + { +--- 5126,5145 ---- + reg_restore(&(((regbehind_T *)rp) - 1)->save_after, + &backpos); + else +! { +! /* But we didn't want a match. Need to restore the +! * subexpr, because what follows matched, so they have +! * been set. */ + status = RA_NOMATCH; ++ restore_subexpr(((regbehind_T *)rp) - 1); ++ } + regstack_pop(&scan); + regstack.ga_len -= sizeof(regbehind_T); + } + else + { +! /* No match or a match that doesn't end where we want it: Go +! * back one character. May go to previous line once. */ + no = OK; + if (REG_MULTI) + { +*************** +*** 5160,5165 **** +--- 5173,5185 ---- + /* Advanced, prepare for finding match again. */ + reg_restore(&rp->rs_un.regsave, &backpos); + scan = OPERAND(rp->rs_scan); ++ if (status == RA_MATCH) ++ { ++ /* We did match, so subexpr may have been changed, ++ * need to restore them for the next try. */ ++ status = RA_NOMATCH; ++ restore_subexpr(((regbehind_T *)rp) - 1); ++ } + } + else + { +*************** +*** 5172,5178 **** + status = RA_MATCH; + } + else +! status = RA_NOMATCH; + regstack_pop(&scan); + regstack.ga_len -= sizeof(regbehind_T); + } +--- 5192,5207 ---- + status = RA_MATCH; + } + else +! { +! /* We do want a proper match. Need to restore the +! * subexpr if we had a match, because they may have +! * been set. */ +! if (status == RA_MATCH) +! { +! status = RA_NOMATCH; +! restore_subexpr(((regbehind_T *)rp) - 1); +! } +! } + regstack_pop(&scan); + regstack.ga_len -= sizeof(regbehind_T); + } +*************** +*** 5820,5825 **** +--- 5849,5903 ---- + #endif + + /* ++ * Save the current subexpr to "bp", so that they can be restored ++ * later by restore_subexpr(). ++ */ ++ static void ++ save_subexpr(bp) ++ regbehind_T *bp; ++ { ++ int i; ++ ++ for (i = 0; i < NSUBEXP; ++i) ++ { ++ if (REG_MULTI) ++ { ++ bp->save_start[i].se_u.pos = reg_startpos[i]; ++ bp->save_end[i].se_u.pos = reg_endpos[i]; ++ } ++ else ++ { ++ bp->save_start[i].se_u.ptr = reg_startp[i]; ++ bp->save_end[i].se_u.ptr = reg_endp[i]; ++ } ++ } ++ } ++ ++ /* ++ * Restore the subexpr from "bp". ++ */ ++ static void ++ restore_subexpr(bp) ++ regbehind_T *bp; ++ { ++ int i; ++ ++ for (i = 0; i < NSUBEXP; ++i) ++ { ++ if (REG_MULTI) ++ { ++ reg_startpos[i] = bp->save_start[i].se_u.pos; ++ reg_endpos[i] = bp->save_end[i].se_u.pos; ++ } ++ else ++ { ++ reg_startp[i] = bp->save_start[i].se_u.ptr; ++ reg_endp[i] = bp->save_end[i].se_u.ptr; ++ } ++ } ++ } ++ ++ /* + * Advance reglnum, regline and reginput to the next line. + */ + static void +*** ../vim-7.1.291/src/version.c Tue Apr 1 20:58:23 2008 +--- src/version.c Wed Apr 9 12:12:33 2008 +*************** +*** 668,669 **** +--- 673,676 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 292, + /**/ + +-- +hundred-and-one symptoms of being an internet addict: +259. When you enter your name in the AltaVista search engine, the top ten + matches do indeed refer to you. + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ download, build and distribute -- http://www.A-A-P.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///