To:
[email protected]
Subject: Patch 5.6a.024
Fcc: outbox
From: Bram Moolenaar <
[email protected]>
------------
Patch 5.6a.024
Problem: Using an autocommand to delete a buffer when leaving it can cause
a crash when jumping to a tag. (Franz Gorkotte)
Solution: In do_tag(), store tagstacklen before jumping to another buffer.
Check tagstackidx after jumping to another buffer.
Add extra check in win_split() if tagname isn't NULL.
Files: src/tag.c, src/window.c
*** ../vim-5.6a.23/src/tag.c Mon Dec 20 09:59:16 1999
--- src/tag.c Thu Jan 13 14:14:32 2000
***************
*** 203,211 ****
*/
if ((tagstack[tagstackidx].tagname = vim_strsave(tag)) == NULL)
{
! --tagstacklen;
goto end_do_tag;
}
new_tag = TRUE;
save_pos = TRUE; /* save the cursor position below */
}
--- 203,213 ----
*/
if ((tagstack[tagstackidx].tagname = vim_strsave(tag)) == NULL)
{
! curwin->w_tagstacklen = tagstacklen - 1;
goto end_do_tag;
}
+ curwin->w_tagstacklen = tagstacklen;
+
new_tag = TRUE;
save_pos = TRUE; /* save the cursor position below */
}
***************
*** 238,262 ****
emsg(topmsg);
goto end_do_tag;
}
! if (tagstack[tagstackidx].fmark.fnum != curbuf->b_fnum)
{
/*
* Jump to other file. If this fails (e.g. because the
* file was changed) keep original position in tag stack.
*/
! if (buflist_getfile(tagstack[tagstackidx].fmark.fnum,
! tagstack[tagstackidx].fmark.mark.lnum,
! GETF_SETMARK, forceit) == FAIL)
{
tagstackidx = oldtagstackidx; /* back to old posn */
goto end_do_tag;
}
}
else
! curwin->w_cursor.lnum
! = tagstack[tagstackidx].fmark.mark.lnum;
! curwin->w_cursor.col = tagstack[tagstackidx].fmark.mark.col;
curwin->w_set_curswant = TRUE;
/* remove the old list of matches */
FreeWild(num_matches, matches);
#ifdef USE_CSCOPE
--- 240,268 ----
emsg(topmsg);
goto end_do_tag;
}
!
! /* Make a copy of the fmark, autocommands may invalidate the
! * tagstack before it's used. */
! saved_fmark = tagstack[tagstackidx].fmark;
! if (saved_fmark.fnum != curbuf->b_fnum)
{
/*
* Jump to other file. If this fails (e.g. because the
* file was changed) keep original position in tag stack.
*/
! if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum,
! GETF_SETMARK, forceit) == FAIL)
{
tagstackidx = oldtagstackidx; /* back to old posn */
goto end_do_tag;
}
}
else
! curwin->w_cursor.lnum = saved_fmark.mark.lnum;
! curwin->w_cursor.col = saved_fmark.mark.col;
curwin->w_set_curswant = TRUE;
+ adjust_cursor();
+
/* remove the old list of matches */
FreeWild(num_matches, matches);
#ifdef USE_CSCOPE
***************
*** 322,330 ****
tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
}
! /* curwin will change in the call to jumpto_tag() if ":stag" was used */
curwin->w_tagstackidx = tagstackidx;
- curwin->w_tagstacklen = tagstacklen;
if (type != DT_SELECT && type != DT_JUMP)
curwin->w_tagstack[tagstackidx].cur_match = cur_match;
}
--- 328,337 ----
tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
}
! /* Curwin will change in the call to jumpto_tag() if ":stag" was used
! * or an autocommand jumps to another window; store value of
! * tagstackidx now. */
curwin->w_tagstackidx = tagstackidx;
if (type != DT_SELECT && type != DT_JUMP)
curwin->w_tagstack[tagstackidx].cur_match = cur_match;
}
***************
*** 695,714 ****
}
EMSG2("File \"%s\" does not exist", nofile_fname);
}
- #ifdef USE_CSCOPE
else
jumped_to_tag = TRUE;
#endif
}
break;
}
end_do_tag:
! if (use_tagstack)
! {
curwin->w_tagstackidx = tagstackidx;
- curwin->w_tagstacklen = tagstacklen;
- }
postponed_split = 0; /* don't split next time */
#ifdef USE_CSCOPE
--- 702,725 ----
}
EMSG2("File \"%s\" does not exist", nofile_fname);
}
else
+ {
+ /* We may have jumped to another window, check that
+ * tagstackidx is still valid. */
+ if (tagstackidx > curwin->w_tagstacklen)
+ tagstackidx = curwin->w_tagstackidx;
+ #ifdef USE_CSCOPE
jumped_to_tag = TRUE;
#endif
+ }
}
break;
}
end_do_tag:
! /* Only store the new index when using tha tagstack and it's valid. */
! if (use_tagstack && tagstackidx <= curwin->w_tagstacklen)
curwin->w_tagstackidx = tagstackidx;
postponed_split = 0; /* don't split next time */
#ifdef USE_CSCOPE
*** ../vim-5.6a.23/src/window.c Mon Dec 20 09:59:07 1999
--- src/window.c Thu Jan 13 10:59:45 2000
***************
*** 473,480 ****
*/
for (i = 0; i < curwin->w_tagstacklen; i++)
{
! wp->w_tagstack[i].fmark = curwin->w_tagstack[i].fmark;
! wp->w_tagstack[i].tagname = vim_strsave(curwin->w_tagstack[i].tagname);
}
wp->w_tagstackidx = curwin->w_tagstackidx;
wp->w_tagstacklen = curwin->w_tagstacklen;
--- 473,481 ----
*/
for (i = 0; i < curwin->w_tagstacklen; i++)
{
! wp->w_tagstack[i] = curwin->w_tagstack[i];
! if (wp->w_tagstack[i].tagname != NULL)
! wp->w_tagstack[i].tagname = vim_strsave(wp->w_tagstack[i].tagname);
}
wp->w_tagstackidx = curwin->w_tagstackidx;
wp->w_tagstacklen = curwin->w_tagstacklen;
*** ../vim-5.6a.23/src/version.c Wed Jan 12 21:22:23 2000
--- src/version.c Thu Jan 13 14:15:59 2000
***************
*** 420,421 ****
--- 420,423 ----
{ /* Add new patch number below this line */
+ /**/
+ 24,
/**/
--
hundred-and-one symptoms of being an internet addict:
141. You'd rather go to
http://www.weather.com/ than look out your window.
--/-/---- Bram Moolenaar ----
[email protected] ----
[email protected] ---\-\--
\ \ www.vim.org/iccf www.moolenaar.net www.vim.org / /