4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
11 Problem: When using a pattern with "\@<=" the submatches can be wrong.
13 Solution: Save the submatches when attempting a look-behind match.
17 *** ../vim-7.1.291/src/regexp.c Sat Jan 19 15:55:51 2008
18 --- src/regexp.c Tue Apr 1 18:15:47 2008
25 + /* used for BEHIND and NOBEHIND matching */
26 + typedef struct regbehind_S
28 + regsave_T save_after;
29 + regsave_T save_behind;
30 + save_se_T save_start[NSUBEXP];
31 + save_se_T save_end[NSUBEXP];
34 static char_u *reg_getline __ARGS((linenr_T lnum));
35 static long vim_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm));
36 static long regtry __ARGS((regprog_T *prog, colnr_T col));
41 static void cleanup_zsubexpr __ARGS((void));
43 + static void save_subexpr __ARGS((regbehind_T *bp));
44 + static void restore_subexpr __ARGS((regbehind_T *bp));
45 static void reg_nextline __ARGS((void));
46 static void reg_save __ARGS((regsave_T *save, garray_T *gap));
47 static void reg_restore __ARGS((regsave_T *save, garray_T *gap));
52 } rs_un; /* room for saving reginput */
53 ! short rs_no; /* submatch nr */
56 static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
57 static void regstack_pop __ARGS((char_u **scan));
59 - /* used for BEHIND and NOBEHIND matching */
60 - typedef struct regbehind_S
62 - regsave_T save_after;
63 - regsave_T save_behind;
66 /* used for STAR, PLUS and BRACE_SIMPLE matching */
67 typedef struct regstar_S
72 } rs_un; /* room for saving reginput */
73 ! short rs_no; /* submatch nr or BEHIND/NOBEHIND */
76 static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
77 static void regstack_pop __ARGS((char_u **scan));
79 /* used for STAR, PLUS and BRACE_SIMPLE matching */
80 typedef struct regstar_S
88 + /* Need to save the subexpr to be able to restore them
89 + * when there is a match but we don't use it. */
90 + save_subexpr(((regbehind_T *)rp) - 1);
93 reg_save(&rp->rs_un.regsave, &backpos);
94 /* First try if what follows matches. If it does then we
97 reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
100 ! /* But we didn't want a match. */
103 regstack.ga_len -= sizeof(regbehind_T);
107 ! /* No match: Go back one character. May go to previous
113 reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
117 ! /* But we didn't want a match. Need to restore the
118 ! * subexpr, because what follows matched, so they have
121 + restore_subexpr(((regbehind_T *)rp) - 1);
124 regstack.ga_len -= sizeof(regbehind_T);
128 ! /* No match or a match that doesn't end where we want it: Go
129 ! * back one character. May go to previous line once. */
136 /* Advanced, prepare for finding match again. */
137 reg_restore(&rp->rs_un.regsave, &backpos);
138 scan = OPERAND(rp->rs_scan);
139 + if (status == RA_MATCH)
141 + /* We did match, so subexpr may have been changed,
142 + * need to restore them for the next try. */
143 + status = RA_NOMATCH;
144 + restore_subexpr(((regbehind_T *)rp) - 1);
154 ! status = RA_NOMATCH;
156 regstack.ga_len -= sizeof(regbehind_T);
163 ! /* We do want a proper match. Need to restore the
164 ! * subexpr if we had a match, because they may have
166 ! if (status == RA_MATCH)
168 ! status = RA_NOMATCH;
169 ! restore_subexpr(((regbehind_T *)rp) - 1);
173 regstack.ga_len -= sizeof(regbehind_T);
181 + * Save the current subexpr to "bp", so that they can be restored
182 + * later by restore_subexpr().
190 + for (i = 0; i < NSUBEXP; ++i)
194 + bp->save_start[i].se_u.pos = reg_startpos[i];
195 + bp->save_end[i].se_u.pos = reg_endpos[i];
199 + bp->save_start[i].se_u.ptr = reg_startp[i];
200 + bp->save_end[i].se_u.ptr = reg_endp[i];
206 + * Restore the subexpr from "bp".
209 + restore_subexpr(bp)
214 + for (i = 0; i < NSUBEXP; ++i)
218 + reg_startpos[i] = bp->save_start[i].se_u.pos;
219 + reg_endpos[i] = bp->save_end[i].se_u.pos;
223 + reg_startp[i] = bp->save_start[i].se_u.ptr;
224 + reg_endp[i] = bp->save_end[i].se_u.ptr;
230 * Advance reglnum, regline and reginput to the next line.
233 *** ../vim-7.1.291/src/version.c Tue Apr 1 20:58:23 2008
234 --- src/version.c Wed Apr 9 12:12:33 2008
238 { /* Add new patch number below this line */
244 hundred-and-one symptoms of being an internet addict:
245 259. When you enter your name in the AltaVista search engine, the top ten
246 matches do indeed refer to you.
248 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
249 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
250 \\\ download, build and distribute -- http://www.A-A-P.org ///
251 \\\ help me help AIDS victims -- http://ICCF-Holland.org ///