]> git.pld-linux.org Git - packages/vim.git/blame - 6.3.040
- new
[packages/vim.git] / 6.3.040
CommitLineData
c9e2e521
AG
1To: vim-dev@vim.org
2Subject: Patch 6.3.040
3Fcc: outbox
4From: Bram Moolenaar <Bram@moolenaar.net>
5Mime-Version: 1.0
6Content-Type: text/plain; charset=ISO-8859-1
7Content-Transfer-Encoding: 8bit
8------------
9
10Patch 6.3.040
11Problem: 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.
14Solution: 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.
17Files: 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--
537If your company is not involved in something called "ISO 9000" you probably
538have no idea what it is. If your company _is_ involved in ISO 9000 then you
539definitely 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.081354 seconds and 4 git commands to generate.