summaryrefslogtreecommitdiffstats
path: root/src/ex_docmd.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-07-31 21:32:31 +0200
committerBram Moolenaar <Bram@vim.org>2021-07-31 21:32:31 +0200
commit620c959c6c00e469c4d3b1ab2e08e4767ee142a4 (patch)
tree9e366b7306b60f49c4fc2f37cb2236f915ff1df9 /src/ex_docmd.c
parent78db17c6f335f518752ca221ec6bde79db584e15 (diff)
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.c129
1 files changed, 68 insertions, 61 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index fbfba52dd4..61feda257d 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.