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 / 6.3 / 6.3.040 < prev    next >
Encoding:
Internet Message Format  |  2004-12-04  |  17.6 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.3.040
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 6.3.040
  11. Problem:    Error handling does not always work properly and may cause a
  12.         buffer to be marked as if it's viewed in a window while it isn't.
  13.         Also when selecting "Abort" at the attention prompt.
  14. Solution:   Add enter_cleanup() and leave_cleanup() functions to move
  15.         saving/restoring things for error handling to one place.
  16.         Clear a buffer read error when it's unloaded.
  17. Files:        src/buffer.c, src/ex_docmd.c, src/ex_eval.c,
  18.         src/proto/ex_eval.pro, src/structs.h, src/vim.h
  19.  
  20.  
  21. *** ../vim-6.3.039/src/buffer.c    Wed Jun  9 14:56:27 2004
  22. --- src/buffer.c    Sun Dec  5 16:15:05 2004
  23. ***************
  24. *** 408,415 ****
  25.       if (!buf_valid(buf))
  26.       return;
  27.   # ifdef FEAT_EVAL
  28. !     /* Autocommands may abort script processing. */
  29. !     if (aborting())
  30.       return;
  31.   # endif
  32.   
  33. --- 408,414 ----
  34.       if (!buf_valid(buf))
  35.       return;
  36.   # ifdef FEAT_EVAL
  37. !     if (aborting())        /* autocmds may abort script processing */
  38.       return;
  39.   # endif
  40.   
  41. ***************
  42. *** 564,569 ****
  43. --- 563,569 ----
  44.   #ifdef FEAT_SYN_HL
  45.       syntax_clear(buf);            /* reset syntax info */
  46.   #endif
  47. +     buf->b_flags &= ~BF_READERR;    /* a read error is no longer relevant */
  48.   }
  49.   
  50.   /*
  51. ***************
  52. *** 666,674 ****
  53. --- 666,688 ----
  54.           && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
  55.       if (swap_exists_action == SEA_QUIT && *eap->cmd == 's')
  56.       {
  57. + #  if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  58. +     cleanup_T   cs;
  59. +     /* Reset the error/interrupt/exception state here so that
  60. +      * aborting() returns FALSE when closing a window. */
  61. +     enter_cleanup(&cs);
  62. + #  endif
  63.       /* Quitting means closing the split window, nothing else. */
  64.       win_close(curwin, TRUE);
  65.       swap_exists_action = SEA_NONE;
  66. + #  if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  67. +     /* Restore the error/interrupt/exception state if not discarded by a
  68. +      * new aborting error, interrupt, or uncaught exception. */
  69. +     leave_cleanup(&cs);
  70. + #  endif
  71.       }
  72.       else
  73.       handle_swap_exists(old_curbuf);
  74. ***************
  75. *** 685,712 ****
  76.   handle_swap_exists(old_curbuf)
  77.       buf_T    *old_curbuf;
  78.   {
  79.       if (swap_exists_action == SEA_QUIT)
  80.       {
  81.       /* User selected Quit at ATTENTION prompt.  Go back to previous
  82.        * buffer.  If that buffer is gone or the same as the current one,
  83.        * open a new, empty buffer. */
  84.       swap_exists_action = SEA_NONE;    /* don't want it again */
  85.       close_buffer(curwin, curbuf, DOBUF_UNLOAD);
  86.       if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
  87. !         old_curbuf = buflist_new(NULL, NULL, 1L,
  88. !                      BLN_CURBUF | BLN_LISTED | BLN_FORCE);
  89.       if (old_curbuf != NULL)
  90.           enter_buffer(old_curbuf);
  91.       /* If "old_curbuf" is NULL we are in big trouble here... */
  92.       }
  93.       else if (swap_exists_action == SEA_RECOVER)
  94.       {
  95.       /* User selected Recover at ATTENTION prompt. */
  96.       msg_scroll = TRUE;
  97.       ml_recover();
  98.       MSG_PUTS("\n");    /* don't overwrite the last message */
  99.       cmdline_row = msg_row;
  100.       do_modelines();
  101.       }
  102.       swap_exists_action = SEA_NONE;
  103.   }
  104. --- 699,753 ----
  105.   handle_swap_exists(old_curbuf)
  106.       buf_T    *old_curbuf;
  107.   {
  108. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  109. +     cleanup_T    cs;
  110. + # endif
  111.       if (swap_exists_action == SEA_QUIT)
  112.       {
  113. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  114. +     /* Reset the error/interrupt/exception state here so that
  115. +      * aborting() returns FALSE when closing a buffer. */
  116. +     enter_cleanup(&cs);
  117. + # endif
  118.       /* User selected Quit at ATTENTION prompt.  Go back to previous
  119.        * buffer.  If that buffer is gone or the same as the current one,
  120.        * open a new, empty buffer. */
  121.       swap_exists_action = SEA_NONE;    /* don't want it again */
  122.       close_buffer(curwin, curbuf, DOBUF_UNLOAD);
  123.       if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
  124. !         old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
  125.       if (old_curbuf != NULL)
  126.           enter_buffer(old_curbuf);
  127.       /* If "old_curbuf" is NULL we are in big trouble here... */
  128. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  129. +     /* Restore the error/interrupt/exception state if not discarded by a
  130. +      * new aborting error, interrupt, or uncaught exception. */
  131. +     leave_cleanup(&cs);
  132. + # endif
  133.       }
  134.       else if (swap_exists_action == SEA_RECOVER)
  135.       {
  136. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  137. +     /* Reset the error/interrupt/exception state here so that
  138. +      * aborting() returns FALSE when closing a buffer. */
  139. +     enter_cleanup(&cs);
  140. + # endif
  141.       /* User selected Recover at ATTENTION prompt. */
  142.       msg_scroll = TRUE;
  143.       ml_recover();
  144.       MSG_PUTS("\n");    /* don't overwrite the last message */
  145.       cmdline_row = msg_row;
  146.       do_modelines();
  147. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  148. +     /* Restore the error/interrupt/exception state if not discarded by a
  149. +      * new aborting error, interrupt, or uncaught exception. */
  150. +     leave_cleanup(&cs);
  151. + # endif
  152.       }
  153.       swap_exists_action = SEA_NONE;
  154.   }
  155. ***************
  156. *** 1380,1386 ****
  157.    * If (flags & BLN_CURBUF) is TRUE, may use current buffer.
  158.    * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
  159.    * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
  160. -  * If (flags & BLN_FORCE) is TRUE, don't abort on an error.
  161.    * This is the ONLY way to create a new buffer.
  162.    */
  163.   static int  top_file_num = 1;        /* highest file number */
  164. --- 1421,1426 ----
  165. ***************
  166. *** 1455,1462 ****
  167.       if (buf == curbuf)
  168.           apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
  169.   # ifdef FEAT_EVAL
  170. !     /* autocmds may abort script processing */
  171. !     if (!(flags & BLN_FORCE) && aborting())
  172.           return NULL;
  173.   # endif
  174.   #endif
  175. --- 1495,1501 ----
  176.       if (buf == curbuf)
  177.           apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
  178.   # ifdef FEAT_EVAL
  179. !     if (aborting())        /* autocmds may abort script processing */
  180.           return NULL;
  181.   # endif
  182.   #endif
  183. ***************
  184. *** 1509,1516 ****
  185.       if (buf != curbuf)     /* autocommands deleted the buffer! */
  186.           return NULL;
  187.   #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  188. !     /* autocmds may abort script processing */
  189. !     if (!(flags & BLN_FORCE) && aborting())
  190.           return NULL;
  191.   #endif
  192.       /* buf->b_nwindows = 0; why was this here? */
  193. --- 1548,1554 ----
  194.       if (buf != curbuf)     /* autocommands deleted the buffer! */
  195.           return NULL;
  196.   #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  197. !     if (aborting())        /* autocmds may abort script processing */
  198.           return NULL;
  199.   #endif
  200.       /* buf->b_nwindows = 0; why was this here? */
  201. ***************
  202. *** 1586,1593 ****
  203.       if (flags & BLN_LISTED)
  204.           apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
  205.   # ifdef FEAT_EVAL
  206. !     /* autocmds may abort script processing */
  207. !     if (!(flags & BLN_FORCE) && aborting())
  208.           return NULL;
  209.   # endif
  210.       }
  211. --- 1624,1630 ----
  212.       if (flags & BLN_LISTED)
  213.           apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
  214.   # ifdef FEAT_EVAL
  215. !     if (aborting())        /* autocmds may abort script processing */
  216.           return NULL;
  217.   # endif
  218.       }
  219. ***************
  220. *** 4217,4229 ****
  221.   #endif
  222.           set_curbuf(buf, DOBUF_GOTO);
  223.   #ifdef FEAT_AUTOCMD
  224. - # ifdef FEAT_EVAL
  225. -         /* Autocommands deleted the buffer or aborted script
  226. -          * processing!!! */
  227. -         if (!buf_valid(buf) || aborting())
  228. - # else
  229.           if (!buf_valid(buf))    /* autocommands deleted the buffer!!! */
  230. - # endif
  231.           {
  232.   #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  233.           swap_exists_action = SEA_NONE;
  234. --- 4254,4260 ----
  235. ***************
  236. *** 4234,4243 ****
  237. --- 4265,4289 ----
  238.   #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  239.           if (swap_exists_action == SEA_QUIT)
  240.           {
  241. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  242. +         cleanup_T   cs;
  243. +         /* Reset the error/interrupt/exception state here so that
  244. +          * aborting() returns FALSE when closing a window. */
  245. +         enter_cleanup(&cs);
  246. + # endif
  247.           /* User selected Quit at ATTENTION prompt; close this window. */
  248.           win_close(curwin, TRUE);
  249.           --open_wins;
  250.           swap_exists_action = SEA_NONE;
  251. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  252. +         /* Restore the error/interrupt/exception state if not
  253. +          * discarded by a new aborting error, interrupt, or uncaught
  254. +          * exception. */
  255. +         leave_cleanup(&cs);
  256. + # endif
  257.           }
  258.           else
  259.           handle_swap_exists(NULL);
  260. ***************
  261. *** 4250,4255 ****
  262. --- 4296,4306 ----
  263.           (void)vgetc();    /* only break the file loading, not the rest */
  264.           break;
  265.       }
  266. + #ifdef FEAT_EVAL
  267. +     /* Autocommands deleted the buffer or aborted script processing!!! */
  268. +     if (aborting())
  269. +         break;
  270. + #endif
  271.       }
  272.   #ifdef FEAT_AUTOCMD
  273.       --autocmd_no_enter;
  274. *** ../vim-6.3.039/src/ex_docmd.c    Wed Jun  9 14:59:11 2004
  275. --- src/ex_docmd.c    Sun Dec  5 15:24:08 2004
  276. ***************
  277. *** 6610,6619 ****
  278. --- 6610,6633 ----
  279.           need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
  280.           if (!need_hide || P_HID(curbuf))
  281.           {
  282. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  283. +             cleanup_T   cs;
  284. +             /* Reset the error/interrupt/exception state here so that
  285. +              * aborting() returns FALSE when closing a window. */
  286. +             enter_cleanup(&cs);
  287. + # endif
  288.   # ifdef FEAT_GUI
  289.               need_mouse_correct = TRUE;
  290.   # endif
  291.               win_close(curwin, !need_hide && !P_HID(curbuf));
  292. + # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  293. +             /* Restore the error/interrupt/exception state if not
  294. +              * discarded by a new aborting error, interrupt, or
  295. +              * uncaught exception. */
  296. +             leave_cleanup(&cs);
  297. + # endif
  298.           }
  299.           }
  300.   #endif
  301. *** ../vim-6.3.039/src/ex_eval.c    Wed Jun  9 14:56:26 2004
  302. --- src/ex_eval.c    Sun Dec  5 15:25:04 2004
  303. ***************
  304. *** 1820,1825 ****
  305. --- 1820,1979 ----
  306.   }
  307.   
  308.   /*
  309. +  * enter_cleanup() and leave_cleanup()
  310. +  *
  311. +  * Functions to be called before/after invoking a sequence of autocommands for
  312. +  * cleanup for a failed command.  (Failure means here that a call to emsg()
  313. +  * has been made, an interrupt occurred, or there is an uncaught exception
  314. +  * from a previous autocommand execution of the same command.)
  315. +  *
  316. +  * Call enter_cleanup() with a pointer to a cleanup_T and pass the same
  317. +  * pointer to leave_cleanup().  The cleanup_T structure stores the pending
  318. +  * error/interrupt/exception state.
  319. +  */
  320. + /*
  321. +  * This function works a bit like ex_finally() except that there was not
  322. +  * actually an extra try block around the part that failed and an error or
  323. +  * interrupt has not (yet) been converted to an exception.  This function
  324. +  * saves the error/interrupt/ exception state and prepares for the call to
  325. +  * do_cmdline() that is going to be made for the cleanup autocommand
  326. +  * execution.
  327. +  */
  328. +     void
  329. + enter_cleanup(csp)
  330. +     cleanup_T    *csp;
  331. + {
  332. +     int        pending = CSTP_NONE;
  333. +     /*
  334. +      * Postpone did_emsg, got_int, did_throw.  The pending values will be
  335. +      * restored by leave_cleanup() except if there was an aborting error,
  336. +      * interrupt, or uncaught exception after this function ends.
  337. +      */
  338. +     if (did_emsg || got_int || did_throw || need_rethrow)
  339. +     {
  340. +     csp->pending = (did_emsg     ? CSTP_ERROR     : 0)
  341. +              | (got_int      ? CSTP_INTERRUPT : 0)
  342. +              | (did_throw    ? CSTP_THROW     : 0)
  343. +              | (need_rethrow ? CSTP_THROW     : 0);
  344. +     /* If we are currently throwing an exception (did_throw), save it as
  345. +      * well.  On an error not yet converted to an exception, update
  346. +      * "force_abort" and reset "cause_abort" (as do_errthrow() would do).
  347. +      * This is needed for the do_cmdline() call that is going to be made
  348. +      * for autocommand execution.  We need not save *msg_list because
  349. +      * there is an extra instance for every call of do_cmdline(), anyway.
  350. +      */
  351. +     if (did_throw || need_rethrow)
  352. +         csp->exception = current_exception;
  353. +     else
  354. +     {
  355. +         csp->exception = NULL;
  356. +         if (did_emsg)
  357. +         {
  358. +         force_abort |= cause_abort;
  359. +         cause_abort = FALSE;
  360. +         }
  361. +     }
  362. +     did_emsg = got_int = did_throw = need_rethrow = FALSE;
  363. +     /* Report if required by the 'verbose' option or when debugging.  */
  364. +     report_make_pending(pending, csp->exception);
  365. +     }
  366. +     else
  367. +     {
  368. +     csp->pending = CSTP_NONE;
  369. +     csp->exception = NULL;
  370. +     }
  371. + }
  372. + /*
  373. +  * See comment above enter_cleanup() for how this function is used.
  374. +  *
  375. +  * This function is a bit like ex_endtry() except that there was not actually
  376. +  * an extra try block around the part that failed and an error or interrupt
  377. +  * had not (yet) been converted to an exception when the cleanup autocommand
  378. +  * sequence was invoked.
  379. +  *
  380. +  * This function has to be called with the address of the cleanup_T structure
  381. +  * filled by enter_cleanup() as an argument; it restores the error/interrupt/
  382. +  * exception state saved by that function - except there was an aborting
  383. +  * error, an interrupt or an uncaught exception during execution of the
  384. +  * cleanup autocommands.  In the latter case, the saved error/interrupt/
  385. +  * exception state is discarded.
  386. +  */
  387. +     void
  388. + leave_cleanup(csp)
  389. +     cleanup_T    *csp;
  390. + {
  391. +     int        pending = csp->pending;
  392. +     if (pending == CSTP_NONE)    /* nothing to do */
  393. +     return;
  394. +     /* If there was an aborting error, an interrupt, or an uncaught exception
  395. +      * after the corresponding call to enter_cleanup(), discard what has been
  396. +      * made pending by it.  Report this to the user if required by the
  397. +      * 'verbose' option or when debugging. */
  398. +     if (aborting() || need_rethrow)
  399. +     {
  400. +     if (pending & CSTP_THROW)
  401. +         /* Cancel the pending exception (includes report). */
  402. +         discard_exception((except_T *)csp->exception, FALSE);
  403. +     else
  404. +         report_discard_pending(pending, NULL);
  405. +     /* If an error was about to be converted to an exception when
  406. +      * enter_cleanup() was called, free the message list. */
  407. +     free_msglist(*msg_list);
  408. +     *msg_list = NULL;
  409. +     }
  410. +     /*
  411. +      * If there was no new error, interrupt, or throw between the calls
  412. +      * to enter_cleanup() and leave_cleanup(), restore the pending
  413. +      * error/interrupt/exception state.
  414. +      */
  415. +     else
  416. +     {
  417. +     /*
  418. +      * If there was an exception being thrown when enter_cleanup() was
  419. +      * called, we need to rethrow it.  Make it the exception currently
  420. +      * being thrown.
  421. +      */
  422. +     if (pending & CSTP_THROW)
  423. +         current_exception = csp->exception;
  424. +     /*
  425. +      * If an error was about to be converted to an exception when
  426. +      * enter_cleanup() was called, let "cause_abort" take the part of
  427. +      * "force_abort" (as done by cause_errthrow()).
  428. +      */
  429. +     else if (pending & CSTP_ERROR)
  430. +     {
  431. +         cause_abort = force_abort;
  432. +         force_abort = FALSE;
  433. +     }
  434. +     /*
  435. +      * Restore the pending values of did_emsg, got_int, and did_throw.
  436. +      */
  437. +     if (pending & CSTP_ERROR)
  438. +         did_emsg = TRUE;
  439. +     if (pending & CSTP_INTERRUPT)
  440. +         got_int = TRUE;
  441. +     if (pending & CSTP_THROW)
  442. +         need_rethrow = TRUE;    /* did_throw will be set by do_one_cmd() */
  443. +     /* Report if required by the 'verbose' option or when debugging. */
  444. +     report_resume_pending(pending,
  445. +            (pending & CSTP_THROW) ? (void *)current_exception : NULL);
  446. +     }
  447. + }
  448. + /*
  449.    * Make conditionals inactive and discard what's pending in finally clauses
  450.    * until the conditional type searched for or a try conditional not in its
  451.    * finally clause is reached.  If this is in an active catch clause, finish the
  452. *** ../vim-6.3.039/src/proto/ex_eval.pro    Wed Jun  9 14:56:24 2004
  453. --- src/proto/ex_eval.pro    Sun Dec  5 15:25:27 2004
  454. ***************
  455. *** 23,28 ****
  456. --- 23,30 ----
  457.   void ex_catch __ARGS((exarg_T *eap));
  458.   void ex_finally __ARGS((exarg_T *eap));
  459.   void ex_endtry __ARGS((exarg_T *eap));
  460. + void enter_cleanup __ARGS((cleanup_T *csp));
  461. + void leave_cleanup __ARGS((cleanup_T *csp));
  462.   int cleanup_conditionals __ARGS((struct condstack *cstack, int searched_cond, int inclusive));
  463.   void ex_endfunction __ARGS((exarg_T *eap));
  464.   int has_while_cmd __ARGS((char_u *p));
  465. *** ../vim-6.3.039/src/structs.h    Sat Sep 18 20:28:07 2004
  466. --- src/structs.h    Sun Dec  5 15:26:11 2004
  467. ***************
  468. *** 665,670 ****
  469. --- 665,681 ----
  470.   #define ET_ERROR    1    /* error exception */
  471.   #define ET_INTERRUPT    2    /* interrupt exception triggered by Ctrl-C */
  472.   
  473. + /*
  474. +  * Structure to save the error/interrupt/exception state between calls to
  475. +  * enter_cleanup() and leave_cleanup().  Must be allocated as an automatic
  476. +  * variable by the (common) caller of these functions.
  477. +  */
  478. + typedef struct cleanup_stuff cleanup_T;
  479. + struct cleanup_stuff
  480. + {
  481. +     int pending;        /* error/interrupt/exception state */
  482. +     except_T *exception;    /* exception value */
  483. + };
  484.   
  485.   #ifdef FEAT_SYN_HL
  486.   /* struct passed to in_id_list() */
  487. *** ../vim-6.3.039/src/vim.h    Sat Sep  4 19:43:59 2004
  488. --- src/vim.h    Sun Dec  5 15:26:56 2004
  489. ***************
  490. *** 714,720 ****
  491.   #define BLN_CURBUF    1    /* May re-use curbuf for new buffer */
  492.   #define BLN_LISTED    2    /* Put new buffer in buffer list */
  493.   #define BLN_DUMMY    4    /* Allocating dummy buffer */
  494. - #define BLN_FORCE    8    /* Don't abort on error */
  495.   
  496.   /* Values for in_cinkeys() */
  497.   #define KEY_OPEN_FORW    0x101
  498. --- 714,719 ----
  499. *** ../vim-6.3.039/src/version.c    Sun Dec  5 14:57:15 2004
  500. --- src/version.c    Sun Dec  5 16:16:22 2004
  501. ***************
  502. *** 643,644 ****
  503. --- 643,646 ----
  504.   {   /* Add new patch number below this line */
  505. + /**/
  506. +     40,
  507.   /**/
  508.  
  509. -- 
  510. If your company is not involved in something called "ISO 9000" you probably
  511. have no idea what it is.  If your company _is_ involved in ISO 9000 then you
  512. definitely have no idea what it is.
  513.                 (Scott Adams - The Dilbert principle)
  514.  
  515.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  516. ///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  517. \\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
  518.  \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
  519.