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