diff options
-rw-r--r-- | src/nvim/eval/funcs.c | 8 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 17 | ||||
-rw-r--r-- | test/old/testdir/test_functions.vim | 17 | ||||
-rw-r--r-- | test/old/testdir/test_listdict.vim | 2 | ||||
-rw-r--r-- | test/old/testdir/test_method.vim | 2 |
5 files changed, 33 insertions, 13 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b97e19131e..250b5c5556 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6199,6 +6199,10 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// "reverse({list})" function static void f_reverse(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { + if (tv_check_for_string_or_list_or_blob_arg(argvars, 0) == FAIL) { + return; + } + if (argvars[0].v_type == VAR_BLOB) { blob_T *const b = argvars[0].vval.v_blob; const int len = tv_blob_len(b); @@ -6216,9 +6220,7 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } else { rettv->vval.v_string = NULL; } - } else if (argvars[0].v_type != VAR_LIST) { - semsg(_(e_listblobarg), "reverse()"); - } else { + } else if (argvars[0].v_type == VAR_LIST) { list_T *const l = argvars[0].vval.v_list; if (!value_check_lock(tv_list_locked(l), N_("reverse() argument"), TV_TRANSLATE)) { diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 5f7bd98298..ba2c23ffe8 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -81,6 +81,8 @@ static const char e_blob_required_for_argument_nr[] = N_("E1238: Blob required for argument %d"); static const char e_invalid_value_for_blob_nr[] = N_("E1239: Invalid value for blob: %d"); +static const char e_string_list_or_blob_required_for_argument_nr[] + = N_("E1252: String, List or Blob required for argument %d"); static const char e_string_or_function_required_for_argument_nr[] = N_("E1256: String or function required for argument %d"); static const char e_non_null_dict_required_for_argument_nr[] @@ -4350,7 +4352,20 @@ int tv_check_for_string_or_list_arg(const typval_T *const args, const int idx) return OK; } -/// Check for an optional string or list argument at 'idx' +/// Give an error and return FAIL unless "args[idx]" is a string, a list or a blob. +int tv_check_for_string_or_list_or_blob_arg(const typval_T *const args, const int idx) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE +{ + if (args[idx].v_type != VAR_STRING + && args[idx].v_type != VAR_LIST + && args[idx].v_type != VAR_BLOB) { + semsg(_(e_string_list_or_blob_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + +/// Check for an optional string or list argument at "idx" int tv_check_for_opt_string_or_list_arg(const typval_T *const args, const int idx) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index dbd1119350..4ad01c8531 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -3150,13 +3150,16 @@ endfunc " Test for the reverse() function with a string func Test_string_reverse() - call assert_equal('', reverse(v:_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(v:_null_string)) + for [s1, s2] in [['', ''], ['a', 'a'], ['ab', 'ba'], ['abc', 'cba'], + \ ['abcd', 'dcba'], ['«-«-»-»', '»-»-«-«'], + \ ['🇦', '🇦'], ['🇦🇧', '🇧🇦'], ['🇦🇧🇨', '🇨🇧🇦'], + \ ['🇦«🇧-🇨»🇩', '🇩»🇨-🇧«🇦']] + call assert_equal(s2, reverse(s1)) + endfor + END + call CheckLegacyAndVim9Success(lines) " test in latin1 encoding let save_enc = &encoding diff --git a/test/old/testdir/test_listdict.vim b/test/old/testdir/test_listdict.vim index 3677125d68..0918e2cd98 100644 --- a/test/old/testdir/test_listdict.vim +++ b/test/old/testdir/test_listdict.vim @@ -894,7 +894,7 @@ func Test_reverse_sort_uniq() END call 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/test/old/testdir/test_method.vim b/test/old/testdir/test_method.vim index ca3b736429..88dbbd7bf4 100644 --- a/test/old/testdir/test_method.vim +++ b/test/old/testdir/test_method.vim @@ -63,7 +63,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()) |