To: vim_dev@googlegroups.com Subject: Patch 9.0.1540 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1540 Problem: reverse() on string doesn't work in compiled function. Solution: Accept string in argument type check. (Yegappan Lakshmanan, closes #12377) Files: src/evalfunc.c, src/list.c, src/optionstr.c, src/testdir/test_functions.vim, src/testdir/test_listdict.vim, src/testdir/test_method.vim, src/testdir/test_vim9_builtin.vim *** ../vim-9.0.1539/src/evalfunc.c 2023-04-27 16:24:03.592501355 +0100 --- src/evalfunc.c 2023-05-11 14:58:51.187438722 +0100 *************** *** 757,762 **** --- 757,773 ---- } /* + * Check "type" is a modifiable list of 'any' or a blob or a string. + */ + static int + arg_string_list_or_blob_mod(type_T *type, type_T *decl_type, argcontext_T *context) + { + if (arg_string_list_or_blob(type, decl_type, context) == FAIL) + return FAIL; + return arg_type_modifiable(type, context->arg_idx + 1); + } + + /* * Check "type" is a job. */ static int *************** *** 1010,1016 **** static argcheck_T arg1_job[] = {arg_job}; static argcheck_T arg1_list_any[] = {arg_list_any}; static argcheck_T arg1_list_number[] = {arg_list_number}; ! static argcheck_T arg1_list_or_blob_mod[] = {arg_list_or_blob_mod}; static argcheck_T arg1_list_or_dict[] = {arg_list_or_dict}; static argcheck_T arg1_list_string[] = {arg_list_string}; static argcheck_T arg1_string_or_list_or_dict[] = {arg_string_or_list_or_dict}; --- 1021,1027 ---- static argcheck_T arg1_job[] = {arg_job}; static argcheck_T arg1_list_any[] = {arg_list_any}; static argcheck_T arg1_list_number[] = {arg_list_number}; ! static argcheck_T arg1_string_or_list_or_blob_mod[] = {arg_string_list_or_blob_mod}; static argcheck_T arg1_list_or_dict[] = {arg_list_or_dict}; static argcheck_T arg1_list_string[] = {arg_list_string}; static argcheck_T arg1_string_or_list_or_dict[] = {arg_string_or_list_or_dict}; *************** *** 2413,2419 **** ret_repeat, f_repeat}, {"resolve", 1, 1, FEARG_1, arg1_string, ret_string, f_resolve}, ! {"reverse", 1, 1, FEARG_1, arg1_list_or_blob_mod, ret_first_arg, f_reverse}, {"round", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, f_round}, --- 2424,2430 ---- ret_repeat, f_repeat}, {"resolve", 1, 1, FEARG_1, arg1_string, ret_string, f_resolve}, ! {"reverse", 1, 1, FEARG_1, arg1_string_or_list_or_blob_mod, ret_first_arg, f_reverse}, {"round", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, f_round}, *** ../vim-9.0.1539/src/list.c 2023-05-06 14:08:10.139045046 +0100 --- src/list.c 2023-05-11 14:58:51.187438722 +0100 *************** *** 2994,3009 **** void f_reverse(typval_T *argvars, typval_T *rettv) { ! if (in_vim9script() && check_for_list_or_blob_arg(argvars, 0) == FAIL) return; if (argvars[0].v_type == VAR_BLOB) blob_reverse(argvars[0].vval.v_blob, rettv); else if (argvars[0].v_type == VAR_STRING) string_reverse(argvars[0].vval.v_string, rettv); ! else if (argvars[0].v_type != VAR_LIST) ! semsg(_(e_argument_of_str_must_be_list_or_blob), "reverse()"); ! else list_reverse(argvars[0].vval.v_list, rettv); } --- 2994,3007 ---- void f_reverse(typval_T *argvars, typval_T *rettv) { ! if (check_for_string_or_list_or_blob_arg(argvars, 0) == FAIL) return; if (argvars[0].v_type == VAR_BLOB) blob_reverse(argvars[0].vval.v_blob, rettv); else if (argvars[0].v_type == VAR_STRING) string_reverse(argvars[0].vval.v_string, rettv); ! else if (argvars[0].v_type == VAR_LIST) list_reverse(argvars[0].vval.v_list, rettv); } *** ../vim-9.0.1539/src/optionstr.c 2023-04-23 17:50:14.857935970 +0100 --- src/optionstr.c 2023-05-11 14:58:51.187438722 +0100 *************** *** 134,140 **** (void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE); } ! #if defined(FEAT_EVAL) /* * Trigger the OptionSet autocommand. * "opt_idx" is the index of the option being set. --- 134,140 ---- (void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE); } ! #if defined(FEAT_EVAL) || defined(PROTO) /* * Trigger the OptionSet autocommand. * "opt_idx" is the index of the option being set. *** ../vim-9.0.1539/src/testdir/test_functions.vim 2023-05-08 15:31:34.247545088 +0100 --- src/testdir/test_functions.vim 2023-05-11 14:58:51.191438722 +0100 *************** *** 3475,3487 **** " Test for the reverse() function with a string func Test_string_reverse() ! call assert_equal('', reverse(test_null_string())) ! for [s1, s2] in [['', ''], ['a', 'a'], ['ab', 'ba'], ['abc', 'cba'], ! \ ['abcd', 'dcba'], ['«-«-»-»', '»-»-«-«'], ! \ ['🇦', '🇦'], ['🇦🇧', '🇧🇦'], ['🇦🇧🇨', '🇨🇧🇦'], ! \ ['🇦«🇧-🇨»🇩', '🇩»🇨-🇧«🇦']] ! call assert_equal(s2, reverse(s1)) ! endfor " test in latin1 encoding let save_enc = &encoding --- 3475,3490 ---- " Test for the reverse() function with a string func Test_string_reverse() ! let lines =<< trim END ! call assert_equal('', reverse(test_null_string())) ! for [s1, s2] in [['', ''], ['a', 'a'], ['ab', 'ba'], ['abc', 'cba'], ! \ ['abcd', 'dcba'], ['«-«-»-»', '»-»-«-«'], ! \ ['🇦', '🇦'], ['🇦🇧', '🇧🇦'], ['🇦🇧🇨', '🇨🇧🇦'], ! \ ['🇦«🇧-🇨»🇩', '🇩»🇨-🇧«🇦']] ! call assert_equal(s2, reverse(s1)) ! endfor ! END ! call v9.CheckLegacyAndVim9Success(lines) " test in latin1 encoding let save_enc = &encoding *** ../vim-9.0.1539/src/testdir/test_listdict.vim 2023-05-06 14:08:10.143045044 +0100 --- src/testdir/test_listdict.vim 2023-05-11 14:58:51.191438722 +0100 *************** *** 981,987 **** END call v9.CheckLegacyAndVim9Success(lines) ! call assert_fails('call reverse({})', 'E899:') call assert_fails('call uniq([1, 2], {x, y -> []})', 'E745:') call assert_fails("call sort([1, 2], function('min'), 1)", "E1206:") call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:") --- 981,987 ---- END call v9.CheckLegacyAndVim9Success(lines) ! call assert_fails('call reverse({})', 'E1252:') call assert_fails('call uniq([1, 2], {x, y -> []})', 'E745:') call assert_fails("call sort([1, 2], function('min'), 1)", "E1206:") call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:") *** ../vim-9.0.1539/src/testdir/test_method.vim 2023-01-28 19:18:56.729720605 +0000 --- src/testdir/test_method.vim 2023-05-11 14:58:51.191438722 +0100 *************** *** 62,68 **** call assert_equal(2, d->remove("two")) let d.two = 2 call assert_fails('let x = d->repeat(2)', 'E731:') ! call assert_fails('let x = d->reverse()', 'E899:') call assert_fails('let x = d->sort()', 'E686:') call assert_equal("{'one': 1, 'two': 2, 'three': 3}", d->string()) call assert_equal(v:t_dict, d->type()) --- 62,68 ---- call assert_equal(2, d->remove("two")) let d.two = 2 call assert_fails('let x = d->repeat(2)', 'E731:') ! call assert_fails('let x = d->reverse()', 'E1252:') call assert_fails('let x = d->sort()', 'E686:') call assert_equal("{'one': 1, 'two': 2, 'three': 3}", d->string()) call assert_equal(v:t_dict, d->type()) *** ../vim-9.0.1539/src/testdir/test_vim9_builtin.vim 2023-03-05 19:27:43.646982550 +0000 --- src/testdir/test_vim9_builtin.vim 2023-05-11 14:58:51.191438722 +0100 *************** *** 3459,3466 **** enddef def Test_reverse() ! v9.CheckDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list but got number', 'E1226: List or Blob required for argument 1']) ! v9.CheckDefAndScriptFailure(['reverse("abc")'], ['E1013: Argument 1: type mismatch, expected list but got string', 'E1226: List or Blob required for argument 1']) enddef def Test_reverse_return_type() --- 3459,3465 ---- enddef def Test_reverse() ! v9.CheckDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list but got number', 'E1252: String, List or Blob required for argument 1']) enddef def Test_reverse_return_type() *** ../vim-9.0.1539/src/version.c 2023-05-10 22:01:51.308844691 +0100 --- src/version.c 2023-05-11 15:00:34.455443234 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1540, /**/ -- How To Keep A Healthy Level Of Insanity: 10. Ask people what sex they are. Laugh hysterically after they answer. /// 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 ///