0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 9.0.1462: recursively calling :defer function if it does :qa

Problem:    Recursively calling :defer function if it does :qa.
Solution:   Clear the defer entry before calling the function. (closes #12266)
This commit is contained in:
Bram Moolenaar 2023-04-17 19:23:45 +01:00
parent fc8a601c32
commit 42994bf678
3 changed files with 20 additions and 7 deletions

View File

@ -656,6 +656,7 @@ func Test_defer_quitall()
vim9script vim9script
func DeferLevelTwo() func DeferLevelTwo()
call writefile(['text'], 'XQuitallTwo', 'D') call writefile(['text'], 'XQuitallTwo', 'D')
call writefile(['quit'], 'XQuitallThree', 'a')
qa! qa!
endfunc endfunc
@ -671,6 +672,9 @@ func Test_defer_quitall()
call assert_equal(0, v:shell_error) call assert_equal(0, v:shell_error)
call assert_false(filereadable('XQuitallOne')) call assert_false(filereadable('XQuitallOne'))
call assert_false(filereadable('XQuitallTwo')) call assert_false(filereadable('XQuitallTwo'))
call assert_equal(['quit'], readfile('XQuitallThree'))
call delete('XQuitallThree')
endfunc endfunc
func Test_defer_quitall_in_expr_func() func Test_defer_quitall_in_expr_func()

View File

@ -6096,20 +6096,27 @@ handle_defer_one(funccall_T *funccal)
for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx) for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx)
{ {
funcexe_T funcexe;
typval_T rettv;
defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx; defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
int i;
if (dr->dr_name == NULL)
// already being called, can happen if function does ":qa"
continue;
funcexe_T funcexe;
CLEAR_FIELD(funcexe); CLEAR_FIELD(funcexe);
funcexe.fe_evaluate = TRUE; funcexe.fe_evaluate = TRUE;
typval_T rettv;
rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
call_func(dr->dr_name, -1, &rettv,
dr->dr_argcount, dr->dr_argvars, &funcexe); char_u *name = dr->dr_name;
dr->dr_name = NULL;
call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
clear_tv(&rettv); clear_tv(&rettv);
vim_free(dr->dr_name); vim_free(name);
for (i = dr->dr_argcount - 1; i >= 0; --i) for (int i = dr->dr_argcount - 1; i >= 0; --i)
clear_tv(&dr->dr_argvars[i]); clear_tv(&dr->dr_argvars[i]);
} }
ga_clear(&funccal->fc_defer); ga_clear(&funccal->fc_defer);

View File

@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1462,
/**/ /**/
1461, 1461,
/**/ /**/