To: vim_dev@googlegroups.com Subject: Patch 9.0.1576 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1576 Problem: Users may not know what to do with an internal error. Solution: Add a translated message with instructions. Files: runtime/doc/message.txt, src/errors.h, src/message.c, src/channel.c, src/evalvars.c, src/ex_docmd.c, src/gui.c, src/regexp_nfa.c, src/userfunc.c, src/window.c, src/testdir/test_expr.vim, src/testdir/test_functions.vim, src/testdir/test_listdict.vim, src/testdir/test_vimscript.vim *** ../vim-9.0.1575/runtime/doc/message.txt 2022-06-28 11:21:06.000000000 +0100 --- runtime/doc/message.txt 2023-05-24 20:11:30.016041954 +0100 *************** *** 78,84 **** LIST OF MESSAGES *E222* *E228* *E232* *E293* *E298* *E304* *E317* *E318* *E356* *E438* *E439* *E440* *E316* *E320* *E322* ! *E323* *E341* *E473* *E570* *E685* *E292* Add to read buffer ~ makemap: Illegal mode ~ Cannot create BalloonEval with both message and callback ~ --- 78,84 ---- LIST OF MESSAGES *E222* *E228* *E232* *E293* *E298* *E304* *E317* *E318* *E356* *E438* *E439* *E440* *E316* *E320* *E322* ! *E323* *E341* *E473* *E570* *E292* Add to read buffer ~ makemap: Illegal mode ~ Cannot create BalloonEval with both message and callback ~ *************** *** 99,107 **** Internal error in regexp ~ fatal error in cs_manage_matches ~ Invalid count for del_bytes(): {N} ~ ! This is an internal error. If you can reproduce it, please send in a bug ! report. |bugs| ATTENTION ~ --- 99,107 ---- 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, see |bugs|. ATTENTION ~ *** ../vim-9.0.1575/src/errors.h 2023-05-14 22:05:09.809326381 +0100 --- src/errors.h 2023-05-24 20:07:48.162920389 +0100 *************** *** 840,846 **** #endif EXTERN char e_pattern_too_long[] INIT(= N_("E339: Pattern too long")); ! // E340 unused EXTERN char e_internal_error_lalloc_zero[] INIT(= N_("E341: Internal error: lalloc(0, )")); EXTERN char e_out_of_memory_allocating_nr_bytes[] --- 840,847 ---- #endif EXTERN char e_pattern_too_long[] INIT(= N_("E339: Pattern too long")); ! 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[] *** ../vim-9.0.1575/src/message.c 2023-02-16 15:03:08.505667449 +0000 --- src/message.c 2023-05-24 20:21:41.457702913 +0100 *************** *** 592,603 **** } static int ! ignore_error(char_u *msg) { int i; for (i = 0; i < ignore_error_list.ga_len; ++i) ! if (strstr((char *)msg, (char *)((char_u **)(ignore_error_list.ga_data))[i]) != NULL) return TRUE; return FALSE; --- 592,603 ---- } static int ! ignore_error(const char *msg) { int i; for (i = 0; i < ignore_error_list.ga_len; ++i) ! if (strstr(msg, (char *)((char_u **)(ignore_error_list.ga_data))[i]) != NULL) return TRUE; return FALSE; *************** *** 629,635 **** * Note: caller must check 'emsg_not_now()' before calling this. */ static int ! emsg_core(char_u *s) { int attr; char_u *p; --- 629,635 ---- * Note: caller must check 'emsg_not_now()' before calling this. */ static int ! emsg_core(const char *s) { int attr; char_u *p; *************** *** 665,671 **** * when the message should be ignored completely (used for the * interrupt message). */ ! if (cause_errthrow(s, severe, &ignore) == TRUE) { if (!ignore) ++did_emsg; --- 665,671 ---- * when the message should be ignored completely (used for the * interrupt message). */ ! if (cause_errthrow((char_u *)s, severe, &ignore) == TRUE) { if (!ignore) ++did_emsg; *************** *** 674,680 **** if (in_assert_fails && emsg_assert_fails_msg == NULL) { ! emsg_assert_fails_msg = vim_strsave(s); emsg_assert_fails_lnum = SOURCING_LNUM; vim_free(emsg_assert_fails_context); emsg_assert_fails_context = vim_strsave( --- 674,680 ---- if (in_assert_fails && emsg_assert_fails_msg == NULL) { ! 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,688 **** } // set "v:errmsg", also when using ":silent! cmd" ! set_vim_var_string(VV_ERRMSG, s, -1); #endif /* --- 682,688 ---- } // set "v:errmsg", also when using ":silent! cmd" ! set_vim_var_string(VV_ERRMSG, (char_u *)s, -1); #endif /* *************** *** 711,717 **** redir_write(p, -1); vim_free(p); } ! redir_write(s, -1); } #ifdef FEAT_EVAL // Only increment did_emsg_def when :silent! wasn't used inside the --- 711,717 ---- redir_write(p, -1); vim_free(p); } ! redir_write((char_u *)s, -1); } #ifdef FEAT_EVAL // Only increment did_emsg_def when :silent! wasn't used inside the *************** *** 720,726 **** ++did_emsg_def; #endif #ifdef FEAT_EVAL ! ch_log(NULL, "ERROR silent: %s", (char *)s); #endif return TRUE; } --- 720,726 ---- ++did_emsg_def; #endif #ifdef FEAT_EVAL ! ch_log(NULL, "ERROR silent: %s", s); #endif return TRUE; } *************** *** 778,822 **** } /* ! * Print an error message. */ 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 } #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. */ 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 } #endif --- 778,821 ---- } /* ! * 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 TRUE; ! ! return emsg_core(s); } #ifndef PROTO // manual proto with __attribute__ /* ! * 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()) ! 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,837 **** if (emsg_not_now()) return; ! emsg_core((char_u *)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 --- 830,840 ---- 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)); ! ! 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,863 **** if (emsg_not_now()) return; 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); } else { --- 856,870 ---- 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(s); } else { *************** *** 866,872 **** va_start(ap, s); vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); va_end(ap); ! emsg_core(IObuff); } # ifdef ABORT_ON_INTERNAL_ERROR msg_putchar('\n'); // avoid overwriting the error message --- 873,879 ---- va_start(ap, s); vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); va_end(ap); ! emsg_core((char *)IObuff); } # ifdef ABORT_ON_INTERNAL_ERROR msg_putchar('\n'); // avoid overwriting the error message *************** *** 882,887 **** --- 889,898 ---- 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,899 **** void internal_error_no_abort(char *where) { ! semsg(_(e_internal_error_str), where); } #endif --- 904,914 ---- void internal_error_no_abort(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)); ! ! semsg(_(e_internal_error_str), where); } #endif *** ../vim-9.0.1575/src/channel.c 2023-03-07 17:45:07.180247902 +0000 --- src/channel.c 2023-05-24 20:23:31.705882335 +0100 *************** *** 1757,1763 **** typval_T rettv; if (safe_to_invoke_callback == 0) ! iemsg("INTERNAL: Invoking callback when it is not safe"); argv[0].v_type = VAR_CHANNEL; argv[0].vval.v_channel = channel; --- 1757,1763 ---- typval_T rettv; if (safe_to_invoke_callback == 0) ! iemsg("Invoking callback when it is not safe"); argv[0].v_type = VAR_CHANNEL; argv[0].vval.v_channel = channel; *************** *** 2400,2406 **** } return; } ! siemsg("INTERNAL: channel_remove_block_id: cannot find id %d", id); } /* --- 2400,2406 ---- } return; } ! siemsg("channel_remove_block_id(): cannot find id %d", id); } /* *** ../vim-9.0.1575/src/evalvars.c 2023-04-12 21:35:59.194086825 +0100 --- src/evalvars.c 2023-05-24 20:23:51.389912123 +0100 *************** *** 206,212 **** p = &vimvars[i]; if (STRLEN(p->vv_name) > DICTITEM16_KEY_LEN) { ! iemsg("INTERNAL: name too long, increase size of dictitem16_T"); getout(1); } STRCPY(p->vv_di.di_key, p->vv_name); --- 206,212 ---- p = &vimvars[i]; if (STRLEN(p->vv_name) > DICTITEM16_KEY_LEN) { ! iemsg("Name too long, increase size of dictitem16_T"); getout(1); } STRCPY(p->vv_di.di_key, p->vv_name); *** ../vim-9.0.1575/src/ex_docmd.c 2023-05-20 14:06:56.673542805 +0100 --- src/ex_docmd.c 2023-05-24 20:24:33.373973596 +0100 *************** *** 4716,4722 **** case ADDR_NONE: case ADDR_UNSIGNED: case ADDR_QUICKFIX: ! iemsg(_("INTERNAL: Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX")); break; } } --- 4716,4722 ---- case ADDR_NONE: case ADDR_UNSIGNED: case ADDR_QUICKFIX: ! iemsg("Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"); break; } } *** ../vim-9.0.1575/src/gui.c 2023-04-13 19:15:50.027391986 +0100 --- src/gui.c 2023-05-24 20:27:11.270182972 +0100 *************** *** 142,148 **** 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) emsg(msg); #endif } --- 142,148 ---- 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 != NULL) emsg(msg); #endif } *************** *** 2786,2799 **** 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); ! } } #ifdef FEAT_GUI_GTK if (col2 + 1 < Columns && ScreenLines[off + col2 + 1] == 0) --- 2786,2793 ---- if (col1 > 0) --col1; else // FIXME: how can the first character ever be zero? ! siemsg("NUL in ScreenLines in row %ld", (long)gui.row); } #ifdef FEAT_GUI_GTK if (col2 + 1 < Columns && ScreenLines[off + col2 + 1] == 0) *************** *** 4400,4408 **** } /* ! * 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) --- 4394,4402 ---- } /* ! * 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) *** ../vim-9.0.1575/src/regexp_nfa.c 2023-05-09 14:59:55.964088966 +0100 --- src/regexp_nfa.c 2023-05-24 20:28:27.650273916 +0100 *************** *** 1401,1407 **** rc_did_emsg = TRUE; return FAIL; } ! siemsg("INTERNAL: Unknown character class char: %d", c); return FAIL; } --- 1401,1407 ---- rc_did_emsg = TRUE; return FAIL; } ! siemsg("Unknown character class char: %d", c); return FAIL; } *************** *** 6905,6911 **** #ifdef DEBUG if (c < 0) ! siemsg("INTERNAL: Negative state char: %ld", (long)c); #endif result = (c == curc); --- 6905,6911 ---- #ifdef DEBUG if (c < 0) ! siemsg("Negative state char: %ld", (long)c); #endif result = (c == curc); *************** *** 7196,7204 **** if (f != NULL) { fprintf(f, "\n\n\t=======================================================\n"); ! #ifdef DEBUG fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); ! #endif fprintf(f, "\tInput text is \"%s\" \n", rex.input); fprintf(f, "\t=======================================================\n\n"); nfa_print_state(f, start); --- 7196,7204 ---- if (f != NULL) { fprintf(f, "\n\n\t=======================================================\n"); ! # ifdef DEBUG fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); ! # endif fprintf(f, "\tInput text is \"%s\" \n", rex.input); fprintf(f, "\t=======================================================\n\n"); nfa_print_state(f, start); *** ../vim-9.0.1575/src/userfunc.c 2023-05-20 14:06:56.677542802 +0100 --- src/userfunc.c 2023-05-24 20:29:01.522312487 +0100 *************** *** 3247,3253 **** restore_funccal(void) { if (funccal_stack == NULL) ! iemsg("INTERNAL: restore_funccal()"); else { current_funccal = funccal_stack->top_funccal; --- 3247,3253 ---- restore_funccal(void) { if (funccal_stack == NULL) ! internal_error("restore_funccal()"); else { current_funccal = funccal_stack->top_funccal; *** ../vim-9.0.1575/src/window.c 2023-05-20 14:06:56.677542802 +0100 --- src/window.c 2023-05-24 20:29:28.370342326 +0100 *************** *** 1948,1954 **** { if (win1->w_frame->fr_parent != win2->w_frame->fr_parent) { ! iemsg("INTERNAL: trying to move a window into another frame"); return; } --- 1948,1954 ---- { if (win1->w_frame->fr_parent != win2->w_frame->fr_parent) { ! iemsg("Trying to move a window into another frame"); return; } *** ../vim-9.0.1575/src/testdir/test_expr.vim 2023-05-08 15:31:34.247545088 +0100 --- src/testdir/test_expr.vim 2023-05-24 20:39:52.686917134 +0100 *************** *** 25,31 **** 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:') endfunc func Test_version() --- 25,31 ---- 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()', ['E340:', 'E685:']) endfunc func Test_version() *** ../vim-9.0.1575/src/testdir/test_functions.vim 2023-05-11 15:02:52.231456894 +0100 --- src/testdir/test_functions.vim 2023-05-24 20:42:19.950472335 +0100 *************** *** 82,96 **** 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:') 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 = copy([test_void()])', 'E1031:') endfunc --- 82,96 ---- call assert_equal(0, empty(function('Test_empty'))) call assert_equal(0, empty(function('Test_empty', [0]))) ! 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())', ['E340:', 'E685:']) ! call assert_fails('let x = copy(test_void())', ['E340:', 'E685:']) call assert_fails('let x = copy([test_void()])', 'E1031:') endfunc *** ../vim-9.0.1575/src/testdir/test_listdict.vim 2023-05-11 15:02:52.231456894 +0100 --- src/testdir/test_listdict.vim 2023-05-24 20:59:08.329204474 +0100 *************** *** 1384,1390 **** 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:']) endfunc " Test for a null list --- 1384,1390 ---- 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]'], ['E340:', 'E909:', 'E340:', 'E685:']) endfunc " Test for a null list *** ../vim-9.0.1575/src/testdir/test_vimscript.vim 2022-12-05 15:24:16.552553424 +0000 --- src/testdir/test_vimscript.vim 2023-05-24 20:45:12.098026159 +0100 *************** *** 6524,6531 **** 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_equal(0, 0 + v:false) call assert_equal(1, 0 + v:true) --- 6524,6531 ---- endif call assert_equal(v:t_blob, type(test_null_blob())) ! 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) *** ../vim-9.0.1575/src/version.c 2023-05-23 18:00:53.951320727 +0100 --- src/version.c 2023-05-24 20:08:46.863259442 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1576, /**/ -- hundred-and-one symptoms of being an internet addict: 73. You give your dog used motherboards instead of bones /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///