diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-07-31 21:32:31 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-07-31 21:32:31 +0200 |
commit | 620c959c6c00e469c4d3b1ab2e08e4767ee142a4 (patch) | |
tree | 9e366b7306b60f49c4fc2f37cb2236f915ff1df9 /src/ex_docmd.c | |
parent | 78db17c6f335f518752ca221ec6bde79db584e15 (diff) | |
download | vim-git-620c959c6c00e469c4d3b1ab2e08e4767ee142a4.tar.gz |
patch 8.2.3259: when 'indentexpr' causes an error did_throw may hangv8.2.3259
Problem: When 'indentexpr' causes an error the did_throw flag may remain
set.
Solution: Reset did_throw and show the error. (closes #8677)
Diffstat (limited to 'src/ex_docmd.c')
-rw-r--r-- | src/ex_docmd.c | 129 |
1 files changed, 68 insertions, 61 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index fbfba52dd..61feda257 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1268,67 +1268,7 @@ do_cmdline( * commands are executed. */ if (did_throw) - { - char *p = NULL; - msglist_T *messages = NULL; - - /* - * If the uncaught exception is a user exception, report it as an - * error. If it is an error exception, display the saved error - * message now. For an interrupt exception, do nothing; the - * interrupt message is given elsewhere. - */ - switch (current_exception->type) - { - case ET_USER: - vim_snprintf((char *)IObuff, IOSIZE, - _("E605: Exception not caught: %s"), - current_exception->value); - p = (char *)vim_strsave(IObuff); - break; - case ET_ERROR: - messages = current_exception->messages; - current_exception->messages = NULL; - break; - case ET_INTERRUPT: - break; - } - - estack_push(ETYPE_EXCEPT, current_exception->throw_name, - current_exception->throw_lnum); - ESTACK_CHECK_SETUP - current_exception->throw_name = NULL; - - discard_current_exception(); // uses IObuff if 'verbose' - suppress_errthrow = TRUE; - force_abort = TRUE; - - if (messages != NULL) - { - do - { - msglist_T *next = messages->next; - int save_compiling = estack_compiling; - - estack_compiling = messages->msg_compiling; - emsg(messages->msg); - vim_free(messages->msg); - vim_free(messages->sfile); - vim_free(messages); - messages = next; - estack_compiling = save_compiling; - } - while (messages != NULL); - } - else if (p != NULL) - { - emsg(p); - vim_free(p); - } - vim_free(SOURCING_NAME); - ESTACK_CHECK_NOW - estack_pop(); - } + handle_did_throw(); /* * On an interrupt or an aborting error not converted to an exception, @@ -1448,6 +1388,73 @@ do_cmdline( return retval; } +/* + * Handle when "did_throw" is set after executing commands. + */ + void +handle_did_throw() +{ + char *p = NULL; + msglist_T *messages = NULL; + + /* + * If the uncaught exception is a user exception, report it as an + * error. If it is an error exception, display the saved error + * message now. For an interrupt exception, do nothing; the + * interrupt message is given elsewhere. + */ + switch (current_exception->type) + { + case ET_USER: + vim_snprintf((char *)IObuff, IOSIZE, + _("E605: Exception not caught: %s"), + current_exception->value); + p = (char *)vim_strsave(IObuff); + break; + case ET_ERROR: + messages = current_exception->messages; + current_exception->messages = NULL; + break; + case ET_INTERRUPT: + break; + } + + estack_push(ETYPE_EXCEPT, current_exception->throw_name, + current_exception->throw_lnum); + ESTACK_CHECK_SETUP + current_exception->throw_name = NULL; + + discard_current_exception(); // uses IObuff if 'verbose' + suppress_errthrow = TRUE; + force_abort = TRUE; + + if (messages != NULL) + { + do + { + msglist_T *next = messages->next; + int save_compiling = estack_compiling; + + estack_compiling = messages->msg_compiling; + emsg(messages->msg); + vim_free(messages->msg); + vim_free(messages->sfile); + vim_free(messages); + messages = next; + estack_compiling = save_compiling; + } + while (messages != NULL); + } + else if (p != NULL) + { + emsg(p); + vim_free(p); + } + vim_free(SOURCING_NAME); + ESTACK_CHECK_NOW + estack_pop(); +} + #ifdef FEAT_EVAL /* * Obtain a line when inside a ":while" or ":for" loop. |