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    / /