home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.3 / 7.3.449 < prev    next >
Encoding:
Internet Message Format  |  2012-11-20  |  14.8 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.3.449
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.3.449
  11. Problem:    Crash when a BufWinLeave autocommand closes the only other window.
  12.         (Daniel Hunt)
  13. Solution:   Abort closing a buffer when it becomes the only one.
  14. Files:        src/buffer.c, src/proto/buffer.pro, src/ex_cmds.c, src/ex_getln.c,
  15.         src/misc2.c, src/quickfix.c, src/window.c, src/proto/window.pro
  16.  
  17.  
  18. *** ../vim-7.3.448/src/buffer.c    2012-01-20 20:44:38.000000000 +0100
  19. --- src/buffer.c    2012-02-22 14:50:42.000000000 +0100
  20. ***************
  21. *** 64,69 ****
  22. --- 64,72 ----
  23.   static char *msg_loclist = N_("[Location List]");
  24.   static char *msg_qflist = N_("[Quickfix List]");
  25.   #endif
  26. + #ifdef FEAT_AUTOCMD
  27. + static char *e_auabort = N_("E855: Autocommands caused command to abort");
  28. + #endif
  29.   
  30.   /*
  31.    * Open current buffer, that is: open the memfile and read the file into
  32. ***************
  33. *** 96,102 ****
  34.        * There MUST be a memfile, otherwise we can't do anything
  35.        * If we can't create one for the current buffer, take another buffer
  36.        */
  37. !     close_buffer(NULL, curbuf, 0);
  38.       for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
  39.           if (curbuf->b_ml.ml_mfp != NULL)
  40.           break;
  41. --- 99,105 ----
  42.        * There MUST be a memfile, otherwise we can't do anything
  43.        * If we can't create one for the current buffer, take another buffer
  44.        */
  45. !     close_buffer(NULL, curbuf, 0, FALSE);
  46.       for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
  47.           if (curbuf->b_ml.ml_mfp != NULL)
  48.           break;
  49. ***************
  50. *** 316,327 ****
  51.    * get a new buffer very soon!
  52.    *
  53.    * The 'bufhidden' option can force freeing and deleting.
  54.    */
  55.       void
  56. ! close_buffer(win, buf, action)
  57.       win_T    *win;        /* if not NULL, set b_last_cursor */
  58.       buf_T    *buf;
  59.       int        action;
  60.   {
  61.   #ifdef FEAT_AUTOCMD
  62.       int        is_curbuf;
  63. --- 319,335 ----
  64.    * get a new buffer very soon!
  65.    *
  66.    * The 'bufhidden' option can force freeing and deleting.
  67. +  *
  68. +  * When "abort_if_last" is TRUE then do not close the buffer if autocommands
  69. +  * cause there to be only one window with this buffer.  e.g. when ":quit" is
  70. +  * supposed to close the window but autocommands close all other windows.
  71.    */
  72.       void
  73. ! close_buffer(win, buf, action, abort_if_last)
  74.       win_T    *win;        /* if not NULL, set b_last_cursor */
  75.       buf_T    *buf;
  76.       int        action;
  77. +     int        abort_if_last;
  78.   {
  79.   #ifdef FEAT_AUTOCMD
  80.       int        is_curbuf;
  81. ***************
  82. *** 371,378 ****
  83.       {
  84.       apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
  85.                                     FALSE, buf);
  86. !     if (!buf_valid(buf))        /* autocommands may delete the buffer */
  87.           return;
  88.   
  89.       /* When the buffer becomes hidden, but is not unloaded, trigger
  90.        * BufHidden */
  91. --- 379,390 ----
  92.       {
  93.       apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
  94.                                     FALSE, buf);
  95. !     /* Return if autocommands deleted the buffer or made it the only one. */
  96. !     if (!buf_valid(buf) || (abort_if_last && one_window()))
  97. !     {
  98. !         EMSG(_(e_auabort));
  99.           return;
  100. +     }
  101.   
  102.       /* When the buffer becomes hidden, but is not unloaded, trigger
  103.        * BufHidden */
  104. ***************
  105. *** 380,387 ****
  106.       {
  107.           apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
  108.                                     FALSE, buf);
  109. !         if (!buf_valid(buf))    /* autocmds may delete the buffer */
  110.           return;
  111.       }
  112.   # ifdef FEAT_EVAL
  113.       if (aborting())        /* autocmds may abort script processing */
  114. --- 392,404 ----
  115.       {
  116.           apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
  117.                                     FALSE, buf);
  118. !         /* Return if autocommands deleted the buffer or made it the only
  119. !          * one. */
  120. !         if (!buf_valid(buf) || (abort_if_last && one_window()))
  121. !         {
  122. !         EMSG(_(e_auabort));
  123.           return;
  124. +         }
  125.       }
  126.   # ifdef FEAT_EVAL
  127.       if (aborting())        /* autocmds may abort script processing */
  128. ***************
  129. *** 775,781 ****
  130.        * open a new, empty buffer. */
  131.       swap_exists_action = SEA_NONE;    /* don't want it again */
  132.       swap_exists_did_quit = TRUE;
  133. !     close_buffer(curwin, curbuf, DOBUF_UNLOAD);
  134.       if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
  135.           old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
  136.       if (old_curbuf != NULL)
  137. --- 792,798 ----
  138.        * open a new, empty buffer. */
  139.       swap_exists_action = SEA_NONE;    /* don't want it again */
  140.       swap_exists_did_quit = TRUE;
  141. !     close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE);
  142.       if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
  143.           old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
  144.       if (old_curbuf != NULL)
  145. ***************
  146. *** 1122,1128 ****
  147.            * if the buffer still exists.
  148.            */
  149.           if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
  150. !         close_buffer(NULL, buf, action);
  151.           return retval;
  152.       }
  153.   
  154. --- 1139,1145 ----
  155.            * if the buffer still exists.
  156.            */
  157.           if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
  158. !         close_buffer(NULL, buf, action, FALSE);
  159.           return retval;
  160.       }
  161.   
  162. ***************
  163. *** 1146,1152 ****
  164.           close_windows(buf, FALSE);
  165.   #endif
  166.           if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
  167. !         close_buffer(NULL, buf, action);
  168.           return OK;
  169.       }
  170.   
  171. --- 1163,1169 ----
  172.           close_windows(buf, FALSE);
  173.   #endif
  174.           if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
  175. !         close_buffer(NULL, buf, action, FALSE);
  176.           return OK;
  177.       }
  178.   
  179. ***************
  180. *** 1378,1384 ****
  181.           close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
  182.               unload ? action : (action == DOBUF_GOTO
  183.               && !P_HID(prevbuf)
  184. !             && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0);
  185.       }
  186.       }
  187.   #ifdef FEAT_AUTOCMD
  188. --- 1395,1401 ----
  189.           close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
  190.               unload ? action : (action == DOBUF_GOTO
  191.               && !P_HID(prevbuf)
  192. !             && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, FALSE);
  193.       }
  194.       }
  195.   #ifdef FEAT_AUTOCMD
  196. ***************
  197. *** 2708,2714 ****
  198.           vim_free(ffname);
  199.           return FAIL;
  200.           }
  201. !         close_buffer(NULL, obuf, DOBUF_WIPE); /* delete from the list */
  202.       }
  203.       sfname = vim_strsave(sfname);
  204.       if (ffname == NULL || sfname == NULL)
  205. --- 2725,2732 ----
  206.           vim_free(ffname);
  207.           return FAIL;
  208.           }
  209. !         /* delete from the list */
  210. !         close_buffer(NULL, obuf, DOBUF_WIPE, FALSE);
  211.       }
  212.       sfname = vim_strsave(sfname);
  213.       if (ffname == NULL || sfname == NULL)
  214. ***************
  215. *** 5638,5644 ****
  216.       if (!aucmd)            /* Don't trigger BufDelete autocommands here. */
  217.       block_autocmds();
  218.   #endif
  219. !     close_buffer(NULL, buf, DOBUF_WIPE);
  220.   #ifdef FEAT_AUTOCMD
  221.       if (!aucmd)
  222.       unblock_autocmds();
  223. --- 5656,5662 ----
  224.       if (!aucmd)            /* Don't trigger BufDelete autocommands here. */
  225.       block_autocmds();
  226.   #endif
  227. !     close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
  228.   #ifdef FEAT_AUTOCMD
  229.       if (!aucmd)
  230.       unblock_autocmds();
  231. *** ../vim-7.3.448/src/proto/buffer.pro    2010-08-15 21:57:28.000000000 +0200
  232. --- src/proto/buffer.pro    2012-02-22 14:04:26.000000000 +0100
  233. ***************
  234. *** 1,7 ****
  235.   /* buffer.c */
  236.   int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
  237.   int buf_valid __ARGS((buf_T *buf));
  238. ! void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
  239.   void buf_clear_file __ARGS((buf_T *buf));
  240.   void buf_freeall __ARGS((buf_T *buf, int flags));
  241.   void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
  242. --- 1,7 ----
  243.   /* buffer.c */
  244.   int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
  245.   int buf_valid __ARGS((buf_T *buf));
  246. ! void close_buffer __ARGS((win_T *win, buf_T *buf, int action, int abort_if_last));
  247.   void buf_clear_file __ARGS((buf_T *buf));
  248.   void buf_freeall __ARGS((buf_T *buf, int flags));
  249.   void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
  250. *** ../vim-7.3.448/src/ex_cmds.c    2011-12-30 15:01:55.000000000 +0100
  251. --- src/ex_cmds.c    2012-02-22 14:00:32.000000000 +0100
  252. ***************
  253. *** 3387,3393 ****
  254.           /* close the link to the current buffer */
  255.           u_sync(FALSE);
  256.           close_buffer(oldwin, curbuf,
  257. !                       (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD);
  258.   
  259.   #ifdef FEAT_AUTOCMD
  260.           /* Autocommands may open a new window and leave oldwin open
  261. --- 3387,3393 ----
  262.           /* close the link to the current buffer */
  263.           u_sync(FALSE);
  264.           close_buffer(oldwin, curbuf,
  265. !                    (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD, FALSE);
  266.   
  267.   #ifdef FEAT_AUTOCMD
  268.           /* Autocommands may open a new window and leave oldwin open
  269. *** ../vim-7.3.448/src/ex_getln.c    2012-02-04 22:44:27.000000000 +0100
  270. --- src/ex_getln.c    2012-02-22 14:01:56.000000000 +0100
  271. ***************
  272. *** 6443,6449 ****
  273.       /* win_close() may have already wiped the buffer when 'bh' is
  274.        * set to 'wipe' */
  275.       if (buf_valid(bp))
  276. !         close_buffer(NULL, bp, DOBUF_WIPE);
  277.   
  278.       /* Restore window sizes. */
  279.       win_size_restore(&winsizes);
  280. --- 6443,6449 ----
  281.       /* win_close() may have already wiped the buffer when 'bh' is
  282.        * set to 'wipe' */
  283.       if (buf_valid(bp))
  284. !         close_buffer(NULL, bp, DOBUF_WIPE, FALSE);
  285.   
  286.       /* Restore window sizes. */
  287.       win_size_restore(&winsizes);
  288. *** ../vim-7.3.448/src/misc2.c    2012-02-20 22:18:22.000000000 +0100
  289. --- src/misc2.c    2012-02-22 14:02:12.000000000 +0100
  290. ***************
  291. *** 1173,1179 ****
  292.       for (buf = firstbuf; buf != NULL; )
  293.       {
  294.       nextbuf = buf->b_next;
  295. !     close_buffer(NULL, buf, DOBUF_WIPE);
  296.       if (buf_valid(buf))
  297.           buf = nextbuf;    /* didn't work, try next one */
  298.       else
  299. --- 1173,1179 ----
  300.       for (buf = firstbuf; buf != NULL; )
  301.       {
  302.       nextbuf = buf->b_next;
  303. !     close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
  304.       if (buf_valid(buf))
  305.           buf = nextbuf;    /* didn't work, try next one */
  306.       else
  307. *** ../vim-7.3.448/src/quickfix.c    2012-01-20 13:39:03.000000000 +0100
  308. --- src/quickfix.c    2012-02-22 14:02:20.000000000 +0100
  309. ***************
  310. *** 3565,3571 ****
  311.       buf_T    *buf;
  312.   {
  313.       if (curbuf != buf)        /* safety check */
  314. !     close_buffer(NULL, buf, DOBUF_UNLOAD);
  315.   }
  316.   
  317.   #if defined(FEAT_EVAL) || defined(PROTO)
  318. --- 3565,3571 ----
  319.       buf_T    *buf;
  320.   {
  321.       if (curbuf != buf)        /* safety check */
  322. !     close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE);
  323.   }
  324.   
  325.   #if defined(FEAT_EVAL) || defined(PROTO)
  326. *** ../vim-7.3.448/src/window.c    2012-01-10 22:26:12.000000000 +0100
  327. --- src/window.c    2012-02-22 14:08:13.000000000 +0100
  328. ***************
  329. *** 23,29 ****
  330.   static void win_totop __ARGS((int size, int flags));
  331.   static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));
  332.   static int last_window __ARGS((void));
  333. - static int one_window __ARGS((void));
  334.   static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
  335.   static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
  336.   static tabpage_T *alt_tabpage __ARGS((void));
  337. --- 23,28 ----
  338. ***************
  339. *** 2083,2089 ****
  340.    * Return TRUE if there is only one window other than "aucmd_win" in the
  341.    * current tab page.
  342.    */
  343. !     static int
  344.   one_window()
  345.   {
  346.   #ifdef FEAT_AUTOCMD
  347. --- 2082,2088 ----
  348.    * Return TRUE if there is only one window other than "aucmd_win" in the
  349.    * current tab page.
  350.    */
  351. !     int
  352.   one_window()
  353.   {
  354.   #ifdef FEAT_AUTOCMD
  355. ***************
  356. *** 2109,2115 ****
  357.    * Close window "win".  Only works for the current tab page.
  358.    * If "free_buf" is TRUE related buffer may be unloaded.
  359.    *
  360. !  * called by :quit, :close, :xit, :wq and findtag()
  361.    */
  362.       void
  363.   win_close(win, free_buf)
  364. --- 2108,2114 ----
  365.    * Close window "win".  Only works for the current tab page.
  366.    * If "free_buf" is TRUE related buffer may be unloaded.
  367.    *
  368. !  * Called by :quit, :close, :xit, :wq and findtag().
  369.    */
  370.       void
  371.   win_close(win, free_buf)
  372. ***************
  373. *** 2222,2228 ****
  374.        * Close the link to the buffer.
  375.        */
  376.       if (win->w_buffer != NULL)
  377. !     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
  378.   
  379.       /* Autocommands may have closed the window already, or closed the only
  380.        * other window or moved to another tab page. */
  381. --- 2221,2227 ----
  382.        * Close the link to the buffer.
  383.        */
  384.       if (win->w_buffer != NULL)
  385. !     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
  386.   
  387.       /* Autocommands may have closed the window already, or closed the only
  388.        * other window or moved to another tab page. */
  389. ***************
  390. *** 2328,2334 ****
  391.       int        free_tp = FALSE;
  392.   
  393.       /* Close the link to the buffer. */
  394. !     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
  395.   
  396.       /* Careful: Autocommands may have closed the tab page or made it the
  397.        * current tab page.  */
  398. --- 2327,2333 ----
  399.       int        free_tp = FALSE;
  400.   
  401.       /* Close the link to the buffer. */
  402. !     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
  403.   
  404.       /* Careful: Autocommands may have closed the tab page or made it the
  405.        * current tab page.  */
  406. *** ../vim-7.3.448/src/proto/window.pro    2010-08-15 21:57:28.000000000 +0200
  407. --- src/proto/window.pro    2012-02-22 14:08:28.000000000 +0100
  408. ***************
  409. *** 1,13 ****
  410.   /* window.c */
  411.   void do_window __ARGS((int nchar, long Prenum, int xchar));
  412.   int win_split __ARGS((int size, int flags));
  413. ! int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));
  414.   int win_valid __ARGS((win_T *win));
  415.   int win_count __ARGS((void));
  416.   int make_windows __ARGS((int count, int vertical));
  417.   void win_move_after __ARGS((win_T *win1, win_T *win2));
  418.   void win_equal __ARGS((win_T *next_curwin, int current, int dir));
  419.   void close_windows __ARGS((buf_T *buf, int keep_curwin));
  420.   void win_close __ARGS((win_T *win, int free_buf));
  421.   void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
  422.   void win_free_all __ARGS((void));
  423. --- 1,14 ----
  424.   /* window.c */
  425.   void do_window __ARGS((int nchar, long Prenum, int xchar));
  426.   int win_split __ARGS((int size, int flags));
  427. ! int win_split_ins __ARGS((int size, int flags, win_T *new_wp, int dir));
  428.   int win_valid __ARGS((win_T *win));
  429.   int win_count __ARGS((void));
  430.   int make_windows __ARGS((int count, int vertical));
  431.   void win_move_after __ARGS((win_T *win1, win_T *win2));
  432.   void win_equal __ARGS((win_T *next_curwin, int current, int dir));
  433.   void close_windows __ARGS((buf_T *buf, int keep_curwin));
  434. + int one_window __ARGS((void));
  435.   void win_close __ARGS((win_T *win, int free_buf));
  436.   void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
  437.   void win_free_all __ARGS((void));
  438. *** ../vim-7.3.448/src/version.c    2012-02-22 13:07:02.000000000 +0100
  439. --- src/version.c    2012-02-22 14:55:21.000000000 +0100
  440. ***************
  441. *** 716,717 ****
  442. --- 716,719 ----
  443.   {   /* Add new patch number below this line */
  444. + /**/
  445. +     449,
  446.   /**/
  447.  
  448. -- 
  449. From "know your smileys":
  450.  :-)-O    Smiling doctor with stethoscope
  451.  
  452.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  453. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  454. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  455.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  456.