summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2023-05-11 15:02:56 +0100
committerBram Moolenaar <Bram@vim.org>2023-05-11 15:02:56 +0100
commitf9dc278946d52235a0025fd347bd9ff571258470 (patch)
treee070d19d15b319f8f154cb0d24db48f00e49aaad
parent4ce1bda869e4ec0152d7dcbe1e491ceac5341d5e (diff)
downloadvim-git-f9dc278946d52235a0025fd347bd9ff571258470.tar.gz
patch 9.0.1540: reverse() on string doesn't work in compiled functionv9.0.1540
Problem: reverse() on string doesn't work in compiled function. Solution: Accept string in argument type check. (Yegappan Lakshmanan, closes #12377)
-rw-r--r--src/evalfunc.c15
-rw-r--r--src/list.c6
-rw-r--r--src/optionstr.c2
-rw-r--r--src/testdir/test_functions.vim17
-rw-r--r--src/testdir/test_listdict.vim2
-rw-r--r--src/testdir/test_method.vim2
-rw-r--r--src/testdir/test_vim9_builtin.vim3
-rw-r--r--src/version.c2
8 files changed, 31 insertions, 18 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 05734d25a..8f20ebee1 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -757,6 +757,17 @@ arg_string_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *co
}
/*
+ * 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,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},
diff --git a/src/list.c b/src/list.c
index 7042965ba..d52c23dea 100644
--- a/src/list.c
+++ b/src/list.c
@@ -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);
}
diff --git a/src/optionstr.c b/src/optionstr.c
index 311b069d2..cfbcf3acb 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -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.
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 4529a5e8d..8664724b5 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -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
diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim
index e29c351f4..877bb8073 100644
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -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:")
diff --git a/src/testdir/test_method.vim b/src/testdir/test_method.vim
index 2ca66fd77..120fadecb 100644
--- a/src/testdir/test_method.vim
+++ b/src/testdir/test_method.vim
@@ -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())
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index b8500c5e6..8cf16a2cf 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -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()
diff --git a/src/version.c b/src/version.c
index 5d55e4c5f..e5f4afa70 100644
--- 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 */
/**/
+ 1540,
+/**/
1539,
/**/
1538,