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<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'])
  enddef
  
  def Test_reverse_return_type()
--- 3459,3465 ----
  enddef
  
  def Test_reverse()
!   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()
*** ../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 -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230511140330.20F1D1C1B21%40moolenaar.net.

Raspunde prin e-mail lui