patch 8.2.0035: saving and restoring called_emsg is clumsy

Problem:    Saving and restoring called_emsg is clumsy.
Solution:   Count the number of error messages.
diff --git a/src/buffer.c b/src/buffer.c
index da10579..740d31b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3746,19 +3746,17 @@
 	    if (stl_syntax & STL_IN_TITLE)
 	    {
 		int	use_sandbox = FALSE;
-		int	save_called_emsg = called_emsg;
+		int	called_emsg_before = called_emsg;
 
 # ifdef FEAT_EVAL
 		use_sandbox = was_set_insecurely((char_u *)"titlestring", 0);
 # endif
-		called_emsg = FALSE;
 		build_stl_str_hl(curwin, title_str, sizeof(buf),
 					      p_titlestring, use_sandbox,
 					      0, maxlen, NULL, NULL);
-		if (called_emsg)
+		if (called_emsg > called_emsg_before)
 		    set_string_option_direct((char_u *)"titlestring", -1,
 					   (char_u *)"", OPT_FREE, SID_ERROR);
-		called_emsg |= save_called_emsg;
 	    }
 	    else
 #endif
@@ -3879,19 +3877,17 @@
 	    if (stl_syntax & STL_IN_ICON)
 	    {
 		int	use_sandbox = FALSE;
-		int	save_called_emsg = called_emsg;
+		int	called_emsg_before = called_emsg;
 
 # ifdef FEAT_EVAL
 		use_sandbox = was_set_insecurely((char_u *)"iconstring", 0);
 # endif
-		called_emsg = FALSE;
 		build_stl_str_hl(curwin, icon_str, sizeof(buf),
 						    p_iconstring, use_sandbox,
 						    0, 0, NULL, NULL);
-		if (called_emsg)
+		if (called_emsg > called_emsg_before)
 		    set_string_option_direct((char_u *)"iconstring", -1,
 					   (char_u *)"", OPT_FREE, SID_ERROR);
-		called_emsg |= save_called_emsg;
 	    }
 	    else
 #endif
diff --git a/src/channel.c b/src/channel.c
index ebbc315..fc6a7a3 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2370,17 +2370,15 @@
 
     if (STRCMP(cmd, "ex") == 0)
     {
-	int save_called_emsg = called_emsg;
+	int called_emsg_before = called_emsg;
 
-	called_emsg = FALSE;
 	ch_log(channel, "Executing ex command '%s'", (char *)arg);
 	++emsg_silent;
 	do_cmdline_cmd(arg);
 	--emsg_silent;
-	if (called_emsg)
+	if (called_emsg > called_emsg_before)
 	    ch_log(channel, "Ex command error: '%s'",
 					  (char *)get_vim_var_str(VV_ERRMSG));
-	called_emsg = save_called_emsg;
     }
     else if (STRCMP(cmd, "normal") == 0)
     {
diff --git a/src/drawscreen.c b/src/drawscreen.c
index 3a88ee9..6b755c8 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -650,14 +650,12 @@
 #ifdef FEAT_STL_OPT
     if (*p_ruf)
     {
-	int	save_called_emsg = called_emsg;
+	int	called_emsg_before = called_emsg;
 
-	called_emsg = FALSE;
 	win_redr_custom(wp, TRUE);
-	if (called_emsg)
+	if (called_emsg > called_emsg_before)
 	    set_string_option_direct((char_u *)"rulerformat", -1,
 					   (char_u *)"", OPT_FREE, SID_ERROR);
-	called_emsg |= save_called_emsg;
 	return;
     }
 #endif
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 9a31887..4f8f7fb 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -167,7 +167,7 @@
 	    // the current scope, such as being inside a try/catch.
 	    timer_busy = timer_busy > 0 || vgetc_busy > 0;
 	    vgetc_busy = 0;
-	    called_emsg = FALSE;
+	    called_emsg = 0;
 	    did_emsg = FALSE;
 	    did_uncaught_emsg = FALSE;
 	    must_redraw = 0;
diff --git a/src/globals.h b/src/globals.h
index 9ddb164..33082d5 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -226,7 +226,7 @@
 #endif
 EXTERN int	did_emsg_syntax;	    // did_emsg set because of a
 					    // syntax error
-EXTERN int	called_emsg;		    // always set by emsg()
+EXTERN int	called_emsg;		    // always incremented by emsg()
 EXTERN int	ex_exitval INIT(= 0);	    // exit value for ex mode
 EXTERN int	emsg_on_display INIT(= FALSE);	// there is an error message
 EXTERN int	rc_did_emsg INIT(= FALSE);  // vim_regcomp() called emsg()
diff --git a/src/gui.c b/src/gui.c
index 8fd3114..7b59300 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -3704,14 +3704,12 @@
     if (**opt != NUL)
     {
 	int	use_sandbox = FALSE;
-	int	save_called_emsg = called_emsg;
+	int	called_emsg_before = called_emsg;
 	char_u	res[MAXPATHL];
 	tabpage_T *save_curtab;
 	char_u	*opt_name = (char_u *)(tooltip ? "guitabtooltip"
 							     : "guitablabel");
 
-	called_emsg = FALSE;
-
 	printer_page_num = tabpage_index(tp);
 # ifdef FEAT_EVAL
 	set_vim_var_nr(VV_LNUM, printer_page_num);
@@ -3742,10 +3740,9 @@
 	curwin = curtab->tp_curwin;
 	curbuf = curwin->w_buffer;
 
-	if (called_emsg)
+	if (called_emsg > called_emsg_before)
 	    set_string_option_direct(opt_name, -1,
 					   (char_u *)"", OPT_FREE, SID_ERROR);
-	called_emsg |= save_called_emsg;
     }
 
     // If 'guitablabel'/'guitabtooltip' is not set or the result is empty then
diff --git a/src/highlight.c b/src/highlight.c
index da2bdc6..564cf3a 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -4055,7 +4055,7 @@
     linenr_T	l;
     colnr_T	matchcol;
     long	nmatched;
-    int		save_called_emsg = called_emsg;
+    int		called_emsg_before = called_emsg;
 
     // for :{range}s/pat only highlight inside the range
     if (lnum < search_first_line || lnum > search_last_line)
@@ -4081,7 +4081,6 @@
      * Repeat searching for a match until one is found that includes "mincol"
      * or none is found in this line.
      */
-    called_emsg = FALSE;
     for (;;)
     {
 # ifdef FEAT_RELTIME
@@ -4143,7 +4142,7 @@
 	    if (regprog_is_copy)
 		cur->match.regprog = cur->hl.rm.regprog;
 
-	    if (called_emsg || got_int || timed_out)
+	    if (called_emsg > called_emsg_before || got_int || timed_out)
 	    {
 		// Error while handling regexp: stop using this regexp.
 		if (shl == search_hl)
@@ -4176,9 +4175,6 @@
 	    break;			// useful match found
 	}
     }
-
-    // Restore called_emsg for assert_fails().
-    called_emsg = save_called_emsg;
 }
 
 /*
diff --git a/src/main.c b/src/main.c
index 72e51a3..eec02ea 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4140,7 +4140,7 @@
 	    if (xterm_dpy != NULL)
 		res = serverGetVimNames(xterm_dpy);
 # endif
-	    if (called_emsg)
+	    if (did_emsg)
 		mch_errmsg("\n");
 	}
 	else if (STRICMP(argv[i], "--servername") == 0)
diff --git a/src/message.c b/src/message.c
index 522f7d6..2ea939f 100644
--- a/src/message.c
+++ b/src/message.c
@@ -581,7 +581,7 @@
 #if !defined(HAVE_STRERROR) || defined(PROTO)
 /*
  * Replacement for perror() that behaves more or less like emsg() was called.
- * v:errmsg will be set and called_emsg will be set.
+ * v:errmsg will be set and called_emsg will be incremented.
  */
     void
 do_perror(char *msg)
@@ -620,7 +620,7 @@
 	return msg_use_printf() ? FALSE : msg((char *)s);
 #endif
 
-    called_emsg = TRUE;
+    ++called_emsg;
 
 #ifdef FEAT_EVAL
     // If "emsg_severe" is TRUE: When an error exception is to be thrown,
diff --git a/src/regexp.c b/src/regexp.c
index 112f753..ef3896c 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -2556,7 +2556,7 @@
 {
     regprog_T   *prog = NULL;
     char_u	*expr = expr_arg;
-    int		save_called_emsg;
+    int		called_emsg_before;
 
     regexp_engine = p_re;
 
@@ -2592,8 +2592,7 @@
     /*
      * First try the NFA engine, unless backtracking was requested.
      */
-    save_called_emsg = called_emsg;
-    called_emsg = FALSE;
+    called_emsg_before = called_emsg;
     if (regexp_engine != BACKTRACKING_ENGINE)
 	prog = nfa_regengine.regcomp(expr,
 		re_flags + (regexp_engine == AUTOMATIC_ENGINE ? RE_AUTO : 0));
@@ -2624,13 +2623,13 @@
 	 * but are still valid patterns, thus a retry should work.
 	 * But don't try if an error message was given.
 	 */
-	if (regexp_engine == AUTOMATIC_ENGINE && !called_emsg)
+	if (regexp_engine == AUTOMATIC_ENGINE
+					  && called_emsg == called_emsg_before)
 	{
 	    regexp_engine = BACKTRACKING_ENGINE;
 	    prog = bt_regengine.regcomp(expr, re_flags);
 	}
     }
-    called_emsg |= save_called_emsg;
 
     if (prog != NULL)
     {
diff --git a/src/search.c b/src/search.c
index 1a5dc1a..3b310dc 100644
--- a/src/search.c
+++ b/src/search.c
@@ -624,7 +624,7 @@
     long	nmatched;
     int		submatch = 0;
     int		first_match = TRUE;
-    int		save_called_emsg = called_emsg;
+    int		called_emsg_before = called_emsg;
 #ifdef FEAT_SEARCH_EXTRA
     int		break_loop = FALSE;
 #endif
@@ -654,7 +654,6 @@
     /*
      * find the string
      */
-    called_emsg = FALSE;
     do	// loop for count
     {
 	// When not accepting a match at the start position set "extra_col" to
@@ -745,7 +744,7 @@
 #endif
 						      );
 		// Abort searching on an error (e.g., out of stack).
-		if (called_emsg
+		if (called_emsg > called_emsg_before
 #ifdef FEAT_RELTIME
 			|| (timed_out != NULL && *timed_out)
 #endif
@@ -1055,7 +1054,8 @@
 	     * specified, after an interrupt, after a match and after looping
 	     * twice.
 	     */
-	    if (!p_ws || stop_lnum != 0 || got_int || called_emsg
+	    if (!p_ws || stop_lnum != 0 || got_int
+					    || called_emsg > called_emsg_before
 #ifdef FEAT_RELTIME
 				|| (timed_out != NULL && *timed_out)
 #endif
@@ -1082,7 +1082,7 @@
 	    if (extra_arg != NULL)
 		extra_arg->sa_wrapped = TRUE;
 	}
-	if (got_int || called_emsg
+	if (got_int || called_emsg > called_emsg_before
 #ifdef FEAT_RELTIME
 		|| (timed_out != NULL && *timed_out)
 #endif
@@ -1096,8 +1096,6 @@
 
     vim_regfree(regmatch.regprog);
 
-    called_emsg |= save_called_emsg;
-
     if (!found)		    // did not find it
     {
 	if (got_int)
@@ -4799,7 +4797,7 @@
     int		nmatched = 0;
     int		result = -1;
     pos_T	pos;
-    int		save_called_emsg = called_emsg;
+    int		called_emsg_before = called_emsg;
     int		flag = 0;
 
     if (pattern == NULL)
@@ -4828,7 +4826,6 @@
     {
 	// Zero-width pattern should match somewhere, then we can check if
 	// start and end are in the same position.
-	called_emsg = FALSE;
 	do
 	{
 	    regmatch.startpos[0].col++;
@@ -4839,7 +4836,7 @@
 	} while (direction == FORWARD ? regmatch.startpos[0].col < pos.col
 				      : regmatch.startpos[0].col > pos.col);
 
-	if (!called_emsg)
+	if (called_emsg == called_emsg_before)
 	{
 	    result = (nmatched != 0
 		&& regmatch.startpos[0].lnum == regmatch.endpos[0].lnum
@@ -4847,7 +4844,6 @@
 	}
     }
 
-    called_emsg |= save_called_emsg;
     vim_regfree(regmatch.regprog);
     return result;
 }
diff --git a/src/testing.c b/src/testing.c
index f879f1e..569a57c 100644
--- a/src/testing.c
+++ b/src/testing.c
@@ -424,15 +424,15 @@
     char_u	*cmd = tv_get_string_chk(&argvars[0]);
     garray_T	ga;
     int		save_trylevel = trylevel;
+    int		called_emsg_before = called_emsg;
 
     // trylevel must be zero for a ":throw" command to be considered failed
     trylevel = 0;
-    called_emsg = FALSE;
     suppress_errthrow = TRUE;
     emsg_silent = TRUE;
 
     do_cmdline_cmd(cmd);
-    if (!called_emsg)
+    if (called_emsg == called_emsg_before)
     {
 	prepare_assert_error(&ga);
 	ga_concat(&ga, (char_u *)"command did not fail: ");
@@ -461,7 +461,6 @@
     }
 
     trylevel = save_trylevel;
-    called_emsg = FALSE;
     suppress_errthrow = FALSE;
     emsg_silent = FALSE;
     emsg_on_display = FALSE;
diff --git a/src/version.c b/src/version.c
index 9f369a9..b1f40d4 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    35,
+/**/
     34,
 /**/
     33,