1
0
forked from aniani/vim

patch 8.2.3259: when 'indentexpr' causes an error did_throw may hang

Problem:    When 'indentexpr' causes an error the did_throw flag may remain
            set.
Solution:   Reset did_throw and show the error. (closes #8677)
This commit is contained in:
Bram Moolenaar
2021-07-31 21:32:31 +02:00
parent 78db17c6f3
commit 620c959c6c
4 changed files with 78 additions and 61 deletions

View File

@@ -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.