]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1540: reverse() on string doesn't work in compiled function v9.0.1540
authorYegappan Lakshmanan <yegappan@yahoo.com>
Thu, 11 May 2023 14:02:56 +0000 (15:02 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 11 May 2023 14:02:56 +0000 (15:02 +0100)
Problem:    reverse() on string doesn't work in compiled function.
Solution:   Accept string in argument type check. (Yegappan Lakshmanan,
            closes #12377)

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
src/version.c

index 05734d25acedd9bda258588a26eb5184e4bc4294..8f20ebee176414b5ea12e814e7e2d25458ee7233 100644 (file)
@@ -756,6 +756,17 @@ arg_string_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *co
     return FAIL;
 }
 
+/*
+ * 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.
  */
@@ -1010,7 +1021,7 @@ static argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
 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_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,7 +2424,7 @@ static funcentry_T global_functions[] =
                        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,
+    {"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},
index 7042965ba3c8a43319fc0f093bf8781c21c3db05..d52c23dea1c84101552bc7e51f83ef8163342c12 100644 (file)
@@ -2994,16 +2994,14 @@ list_reverse(list_T *l, typval_T *rettv)
     void
 f_reverse(typval_T *argvars, typval_T *rettv)
 {
-    if (in_vim9script() && check_for_list_or_blob_arg(argvars, 0) == FAIL)
+    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)
-       semsg(_(e_argument_of_str_must_be_list_or_blob), "reverse()");
-    else
+    else if (argvars[0].v_type == VAR_LIST)
        list_reverse(argvars[0].vval.v_list, rettv);
 }
 
index 311b069d27e5ca653dfefd249a591339b072eb41..cfbcf3acba9841609aca534366f1153eedd2db59 100644 (file)
@@ -134,7 +134,7 @@ didset_string_options(void)
     (void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE);
 }
 
-#if defined(FEAT_EVAL)
+#if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Trigger the OptionSet autocommand.
  * "opt_idx"   is the index of the option being set.
index 4529a5e8d5fb6ad66c06c3bc9a8350093668266c..8664724b5c6e2ba39275213043ceba713ae7fcf7 100644 (file)
@@ -3475,13 +3475,16 @@ endfunc
 
 " 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
+  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
index e29c351f41c5c5ddb5ecea8180a905a4284539a9..877bb80739a2eaeb841af192384e88d91b6fdabc 100644 (file)
@@ -981,7 +981,7 @@ func Test_reverse_sort_uniq()
   END
   call v9.CheckLegacyAndVim9Success(lines)
 
-  call assert_fails('call reverse({})', 'E899:')
+  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:")
index 2ca66fd77e4fdc02165d6de2f54024d69f5cdc29..120fadecbc438b59de8e7ad396305d10e04386cc 100644 (file)
@@ -62,7 +62,7 @@ func Test_dict_method()
   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->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())
index b8500c5e61d09eed59715fde188425c1a234f6ee..8cf16a2cf644863a42a5c6de01079e25b0375af5 100644 (file)
@@ -3459,8 +3459,7 @@ def Test_resolve()
 enddef
 
 def Test_reverse()
-  v9.CheckDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1226: List or Blob required for argument 1'])
-  v9.CheckDefAndScriptFailure(['reverse("abc")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1'])
+  v9.CheckDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1252: String, List or Blob required for argument 1'])
 enddef
 
 def Test_reverse_return_type()
index 5d55e4c5ff921434f3b95b5e1c7f5e5dfee9eb19..e5f4afa70a04fd110f0632334d4960e0670118fd 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1540,
 /**/
     1539,
 /**/