# HG changeset patch # User Bram Moolenaar # Date 1684959306 -7200 # Node ID d6055989fa278ed9e737fd556e8435afd3bd4187 # Parent dab4184aaff91a3fd1b98852b0877c2fc8f26079 patch 9.0.1576: users may not know what to do with an internal error Commit: https://github.com/vim/vim/commit/097c5370ea8abab17ceb0f3bcd74f57b1655c7f7 Author: Bram Moolenaar Date: Wed May 24 21:02:24 2023 +0100 patch 9.0.1576: users may not know what to do with an internal error Problem: Users may not know what to do with an internal error. Solution: Add a translated message with instructions. diff --git a/runtime/doc/message.txt b/runtime/doc/message.txt --- a/runtime/doc/message.txt +++ b/runtime/doc/message.txt @@ -78,7 +78,7 @@ See `:messages` above. LIST OF MESSAGES *E222* *E228* *E232* *E293* *E298* *E304* *E317* *E318* *E356* *E438* *E439* *E440* *E316* *E320* *E322* - *E323* *E341* *E473* *E570* *E685* *E292* + *E323* *E341* *E473* *E570* *E292* Add to read buffer ~ makemap: Illegal mode ~ Cannot create BalloonEval with both message and callback ~ @@ -99,9 +99,9 @@ LIST OF MESSAGES Internal error in regexp ~ fatal error in cs_manage_matches ~ Invalid count for del_bytes(): {N} ~ - + *E340* *E685* *internal-error* This is an internal error. If you can reproduce it, please send in a bug -report. |bugs| +report, see |bugs|. ATTENTION ~ diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -1757,7 +1757,7 @@ invoke_callback(channel_T *channel, call typval_T rettv; if (safe_to_invoke_callback == 0) - iemsg("INTERNAL: Invoking callback when it is not safe"); + iemsg("Invoking callback when it is not safe"); argv[0].v_type = VAR_CHANNEL; argv[0].vval.v_channel = channel; @@ -2400,7 +2400,7 @@ channel_remove_block_id(chanpart_T *chan } return; } - siemsg("INTERNAL: channel_remove_block_id: cannot find id %d", id); + siemsg("channel_remove_block_id(): cannot find id %d", id); } /* diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -840,7 +840,8 @@ EXTERN char e_sorry_no_file_browser_in_c #endif EXTERN char e_pattern_too_long[] INIT(= N_("E339: Pattern too long")); -// E340 unused +EXTERN char e_internal_error_please_report_a_bug[] + INIT(= N_("E340: Internal error; if you can reproduce please report a bug")); EXTERN char e_internal_error_lalloc_zero[] INIT(= N_("E341: Internal error: lalloc(0, )")); EXTERN char e_out_of_memory_allocating_nr_bytes[] diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -206,7 +206,7 @@ evalvars_init(void) p = &vimvars[i]; if (STRLEN(p->vv_name) > DICTITEM16_KEY_LEN) { - iemsg("INTERNAL: name too long, increase size of dictitem16_T"); + iemsg("Name too long, increase size of dictitem16_T"); getout(1); } STRCPY(p->vv_di.di_key, p->vv_name); diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -4716,7 +4716,7 @@ address_default_all(exarg_T *eap) case ADDR_NONE: case ADDR_UNSIGNED: case ADDR_QUICKFIX: - iemsg(_("INTERNAL: Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX")); + iemsg("Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"); break; } } diff --git a/src/gui.c b/src/gui.c --- a/src/gui.c +++ b/src/gui.c @@ -142,7 +142,7 @@ gui_start(char_u *arg UNUSED) settmode(TMODE_RAW); // restart RAW mode set_title_defaults(); // set 'title' and 'icon' again #if defined(GUI_MAY_SPAWN) && defined(EXPERIMENTAL_GUI_CMD) - if (msg) + if (msg != NULL) emsg(msg); #endif } @@ -2786,14 +2786,8 @@ gui_redraw_block( if (col1 > 0) --col1; else - { // FIXME: how can the first character ever be zero? - // Make this IEMSGN when it no longer breaks Travis CI. - vim_snprintf((char *)IObuff, IOSIZE, - "INTERNAL ERROR: NUL in ScreenLines in row %ld", - (long)gui.row); - msg((char *)IObuff); - } + siemsg("NUL in ScreenLines in row %ld", (long)gui.row); } #ifdef FEAT_GUI_GTK if (col2 + 1 < Columns && ScreenLines[off + col2 + 1] == 0) @@ -4400,9 +4394,9 @@ gui_do_scrollbar( } /* - * Scroll a window according to the values set in the globals current_scrollbar - * and scrollbar_value. Return TRUE if the cursor in the current window moved - * or FALSE otherwise. + * Scroll a window according to the values set in the globals + * "current_scrollbar" and "scrollbar_value". + * Return TRUE if the cursor in the current window moved or FALSE otherwise. */ int gui_do_scroll(void) diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -592,12 +592,12 @@ ignore_error_for_testing(char_u *error) } static int -ignore_error(char_u *msg) +ignore_error(const char *msg) { int i; for (i = 0; i < ignore_error_list.ga_len; ++i) - if (strstr((char *)msg, + if (strstr(msg, (char *)((char_u **)(ignore_error_list.ga_data))[i]) != NULL) return TRUE; return FALSE; @@ -629,7 +629,7 @@ do_perror(char *msg) * Note: caller must check 'emsg_not_now()' before calling this. */ static int -emsg_core(char_u *s) +emsg_core(const char *s) { int attr; char_u *p; @@ -665,7 +665,7 @@ emsg_core(char_u *s) * when the message should be ignored completely (used for the * interrupt message). */ - if (cause_errthrow(s, severe, &ignore) == TRUE) + if (cause_errthrow((char_u *)s, severe, &ignore) == TRUE) { if (!ignore) ++did_emsg; @@ -674,7 +674,7 @@ emsg_core(char_u *s) if (in_assert_fails && emsg_assert_fails_msg == NULL) { - emsg_assert_fails_msg = vim_strsave(s); + emsg_assert_fails_msg = vim_strsave((char_u *)s); emsg_assert_fails_lnum = SOURCING_LNUM; vim_free(emsg_assert_fails_context); emsg_assert_fails_context = vim_strsave( @@ -682,7 +682,7 @@ emsg_core(char_u *s) } // set "v:errmsg", also when using ":silent! cmd" - set_vim_var_string(VV_ERRMSG, s, -1); + set_vim_var_string(VV_ERRMSG, (char_u *)s, -1); #endif /* @@ -711,7 +711,7 @@ emsg_core(char_u *s) redir_write(p, -1); vim_free(p); } - redir_write(s, -1); + redir_write((char_u *)s, -1); } #ifdef FEAT_EVAL // Only increment did_emsg_def when :silent! wasn't used inside the @@ -720,7 +720,7 @@ emsg_core(char_u *s) ++did_emsg_def; #endif #ifdef FEAT_EVAL - ch_log(NULL, "ERROR silent: %s", (char *)s); + ch_log(NULL, "ERROR silent: %s", s); #endif return TRUE; } @@ -778,45 +778,44 @@ emsg_core(char_u *s) } /* - * Print an error message. + * Print error message "s". Should already be translated. + * Return TRUE if wait_return() not called. */ int emsg(char *s) { // Skip this if not giving error messages at the moment. - if (!emsg_not_now()) - return emsg_core((char_u *)s); - return TRUE; // no error messages at the moment + if (emsg_not_now()) + return TRUE; + + return emsg_core(s); } #ifndef PROTO // manual proto with __attribute__ /* - * Print an error message with format string and variable arguments. - * Note: caller must not pass 'IObuff' as 1st argument. + * Print error message "s" with format string and variable arguments. + * "s" should already be translated. + * Note: caller must not use "IObuff" for "s"! + * Return TRUE if wait_return() not called. */ int semsg(const char *s, ...) { // Skip this if not giving error messages at the moment. - if (!emsg_not_now()) - { - if (IObuff == NULL) - { - // Very early in initialisation and already something wrong, just - // give the raw message so the user at least gets a hint. - return emsg_core((char_u *)s); - } - else - { - va_list ap; - - va_start(ap, s); - vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); - va_end(ap); - return emsg_core(IObuff); - } - } - return TRUE; // no error messages at the moment + if (emsg_not_now()) + return TRUE; + + if (IObuff == NULL) + // Very early in initialisation and already something wrong, just + // give the raw message so the user at least gets a hint. + return emsg_core(s); + + va_list ap; + + va_start(ap, s); + vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); + va_end(ap); + return emsg_core((char *)IObuff); } #endif @@ -831,7 +830,11 @@ iemsg(char *s) if (emsg_not_now()) return; - emsg_core((char_u *)s); + // Give a generic error which is translated. The error itself may not be + // translated, it almost never shows. + emsg_core(_(e_internal_error_please_report_a_bug)); + + emsg_core(s); #if defined(ABORT_ON_INTERNAL_ERROR) && defined(FEAT_EVAL) set_vim_var_string(VV_ERRMSG, (char_u *)s, -1); msg_putchar('\n'); // avoid overwriting the error message @@ -853,11 +856,15 @@ siemsg(const char *s, ...) if (emsg_not_now()) return; + // Give a generic error which is translated. The error itself may not be + // translated, it almost never shows. + emsg_core(_(e_internal_error_please_report_a_bug)); + if (IObuff == NULL) { // Very early in initialisation and already something wrong, just // give the raw message so the user at least gets a hint. - emsg_core((char_u *)s); + emsg_core(s); } else { @@ -866,7 +873,7 @@ siemsg(const char *s, ...) va_start(ap, s); vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); va_end(ap); - emsg_core(IObuff); + emsg_core((char *)IObuff); } # ifdef ABORT_ON_INTERNAL_ERROR msg_putchar('\n'); // avoid overwriting the error message @@ -882,6 +889,10 @@ siemsg(const char *s, ...) void internal_error(char *where) { + // Give a generic error which is translated. The error itself may not be + // translated, it almost never shows. + emsg_core(_(e_internal_error_please_report_a_bug)); + siemsg(_(e_internal_error_str), where); } @@ -893,7 +904,11 @@ internal_error(char *where) void internal_error_no_abort(char *where) { - semsg(_(e_internal_error_str), where); + // Give a generic error which is translated. The error itself may not be + // translated, it almost never shows. + emsg_core(_(e_internal_error_please_report_a_bug)); + + semsg(_(e_internal_error_str), where); } #endif diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -1401,7 +1401,7 @@ nfa_regatom(void) rc_did_emsg = TRUE; return FAIL; } - siemsg("INTERNAL: Unknown character class char: %d", c); + siemsg("Unknown character class char: %d", c); return FAIL; } @@ -6905,7 +6905,7 @@ nfa_regmatch( #ifdef DEBUG if (c < 0) - siemsg("INTERNAL: Negative state char: %ld", (long)c); + siemsg("Negative state char: %ld", (long)c); #endif result = (c == curc); @@ -7196,9 +7196,9 @@ nfa_regtry( if (f != NULL) { fprintf(f, "\n\n\t=======================================================\n"); -#ifdef DEBUG +# ifdef DEBUG fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); -#endif +# endif fprintf(f, "\tInput text is \"%s\" \n", rex.input); fprintf(f, "\t=======================================================\n\n"); nfa_print_state(f, start); diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim --- a/src/testdir/test_expr.vim +++ b/src/testdir/test_expr.vim @@ -25,7 +25,7 @@ func Test_equal() call assert_fails('echo base.method > instance.method') call assert_equal(0, test_null_function() == function('min')) call assert_equal(1, test_null_function() == test_null_function()) - call assert_fails('eval 10 == test_unknown()', 'E685:') + call assert_fails('eval 10 == test_unknown()', ['E340:', 'E685:']) endfunc func Test_version() diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -82,15 +82,15 @@ func Test_empty() call assert_equal(0, empty(function('Test_empty'))) call assert_equal(0, empty(function('Test_empty', [0]))) - call assert_fails("call empty(test_void())", 'E685:') - call assert_fails("call empty(test_unknown())", 'E685:') + call assert_fails("call empty(test_void())", ['E340:', 'E685:']) + call assert_fails("call empty(test_unknown())", ['E340:', 'E685:']) endfunc func Test_test_void() call assert_fails('echo 1 == test_void()', 'E1031:') call assert_fails('echo 1.0 == test_void()', 'E1031:') - call assert_fails('let x = json_encode(test_void())', 'E685:') - call assert_fails('let x = copy(test_void())', 'E685:') + call assert_fails('let x = json_encode(test_void())', ['E340:', 'E685:']) + call assert_fails('let x = copy(test_void())', ['E340:', 'E685:']) call assert_fails('let x = copy([test_void()])', 'E1031:') endfunc diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -1384,7 +1384,7 @@ func Test_listdict_index() call v9.CheckLegacyAndVim9Failure(['VAR l = [1, 2, 3]', 'LET l[1.1] = 4'], ['E805:', 'E1012:', 'E805:']) call v9.CheckLegacyAndVim9Failure(['VAR l = [1, 2, 3]', 'LET l[: i] = [4, 5]'], ['E121:', 'E1001:', 'E121:']) call v9.CheckLegacyAndVim9Failure(['VAR l = [1, 2, 3]', 'LET l[: 3.2] = [4, 5]'], ['E805:', 'E1012:', 'E805:']) - call v9.CheckLegacyAndVim9Failure(['VAR t = test_unknown()', 'echo t[0]'], ['E685:', 'E909:', 'E685:']) + call v9.CheckLegacyAndVim9Failure(['VAR t = test_unknown()', 'echo t[0]'], ['E340:', 'E909:', 'E340:', 'E685:']) endfunc " Test for a null list diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -6524,8 +6524,8 @@ func Test_type() endif call assert_equal(v:t_blob, type(test_null_blob())) - call assert_fails("call type(test_void())", 'E685:') - call assert_fails("call type(test_unknown())", 'E685:') + call assert_fails("call type(test_void())", ['E340:', 'E685:']) + call assert_fails("call type(test_unknown())", ['E340:', 'E685:']) call assert_equal(0, 0 + v:false) call assert_equal(1, 0 + v:true) diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -3247,7 +3247,7 @@ save_funccal(funccal_entry_T *entry) restore_funccal(void) { if (funccal_stack == NULL) - iemsg("INTERNAL: restore_funccal()"); + internal_error("restore_funccal()"); else { current_funccal = funccal_stack->top_funccal; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1576, +/**/ 1575, /**/ 1574, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -1948,7 +1948,7 @@ win_move_after(win_T *win1, win_T *win2) { if (win1->w_frame->fr_parent != win2->w_frame->fr_parent) { - iemsg("INTERNAL: trying to move a window into another frame"); + iemsg("Trying to move a window into another frame"); return; }