summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/errors.h2
-rw-r--r--src/proto/typval.pro1
-rw-r--r--src/strings.c28
-rw-r--r--src/testdir/test_functions.vim6
-rw-r--r--src/testdir/test_vim9_builtin.vim2
-rw-r--r--src/typval.c31
-rw-r--r--src/version.c2
7 files changed, 55 insertions, 17 deletions
diff --git a/src/errors.h b/src/errors.h
index 7b1181ae94..d7ed81a16e 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3539,6 +3539,8 @@ EXTERN char e_cannot_lock_object_variable_str[]
EXTERN char e_cannot_lock_class_variable_str[]
INIT(= N_("E1392: Cannot (un)lock class variable \"%s\" in class \"%s\""));
#endif
+EXTERN char e_string_or_none_required_for_argument_nr[]
+ INIT(= N_("E1393: String or v:none required for argument %d"));
// E1393 - E1499 unused (reserved for Vim9 class support)
EXTERN char e_cannot_mix_positional_and_non_positional_str[]
INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s"));
diff --git a/src/proto/typval.pro b/src/proto/typval.pro
index db8f94ebb0..10f6e67111 100644
--- a/src/proto/typval.pro
+++ b/src/proto/typval.pro
@@ -14,6 +14,7 @@ int check_for_unknown_arg(typval_T *args, int idx);
int check_for_string_arg(typval_T *args, int idx);
int check_for_nonempty_string_arg(typval_T *args, int idx);
int check_for_opt_string_arg(typval_T *args, int idx);
+int check_for_opt_string_or_none_arg(typval_T *args, int idx, int *is_none);
int check_for_number_arg(typval_T *args, int idx);
int check_for_opt_number_arg(typval_T *args, int idx);
int check_for_float_or_nr_arg(typval_T *args, int idx);
diff --git a/src/strings.c b/src/strings.c
index c04cbe84f6..f1c8af8f99 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -1962,7 +1962,7 @@ f_trim(typval_T *argvars, typval_T *rettv)
if (in_vim9script()
&& (check_for_string_arg(argvars, 0) == FAIL
- || check_for_opt_string_arg(argvars, 1) == FAIL
+ || check_for_opt_string_or_none_arg(argvars, 1, NULL) == FAIL
|| (argvars[1].v_type != VAR_UNKNOWN
&& check_for_opt_number_arg(argvars, 2) == FAIL)))
return;
@@ -1971,26 +1971,24 @@ f_trim(typval_T *argvars, typval_T *rettv)
if (head == NULL)
return;
- if (check_for_opt_string_arg(argvars, 1) == FAIL)
+ if (check_for_opt_string_or_none_arg(argvars, 1, NULL) == FAIL)
return;
if (argvars[1].v_type == VAR_STRING)
- {
mask = tv_get_string_buf_chk(&argvars[1], buf2);
- if (argvars[2].v_type != VAR_UNKNOWN)
- {
- int error = 0;
+ if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
+ {
+ int error = 0;
- // leading or trailing characters to trim
- dir = (int)tv_get_number_chk(&argvars[2], &error);
- if (error)
- return;
- if (dir < 0 || dir > 2)
- {
- semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2]));
- return;
- }
+ // leading or trailing characters to trim
+ dir = (int)tv_get_number_chk(&argvars[2], &error);
+ if (error)
+ return;
+ if (dir < 0 || dir > 2)
+ {
+ semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2]));
+ return;
}
}
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index d598966977..85d1d22ee6 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -2231,11 +2231,15 @@ func Test_trim()
call assert_fails('eval trim(" vim ", " ", [])', 'E745:')
call assert_fails('eval trim(" vim ", " ", -1)', 'E475:')
call assert_fails('eval trim(" vim ", " ", 3)', 'E475:')
- call assert_fails('eval trim(" vim ", 0)', 'E1174:')
+ call assert_fails('eval trim(" vim ", 0)', 'E1393:')
let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '')
call assert_equal("x", trim(chars . "x" . chars))
+ call assert_equal("x", trim(chars . "x" . chars, v:none, 0))
+ call assert_equal("x" . chars, trim(chars . "x" . chars, v:none, 1))
+ call assert_equal(chars . "x", trim(chars . "x" . chars, v:none, 2))
+
call assert_fails('let c=trim([])', 'E730:')
endfunc
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 1efc47a074..206f97f2e0 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -4786,7 +4786,7 @@ enddef
def Test_trim()
v9.CheckDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1'])
- v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2'])
+ v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1393: String or v:none required for argument 2'])
v9.CheckDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3'])
trim('')->assert_equal('')
trim('', '')->assert_equal('')
diff --git a/src/typval.c b/src/typval.c
index 08dd2313f2..b6371aaa43 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -451,6 +451,37 @@ check_for_opt_string_arg(typval_T *args, int idx)
}
/*
+ * Check for an optional string argument at 'idx', that can also be 'v:none' to
+ * use the default value.
+ *
+ * If 'is_none' is non-NULL it is set to 0 and updated to 1 when "args[idx]" is
+ * 'v:none'.
+ */
+ int
+check_for_opt_string_or_none_arg(typval_T *args, int idx, int *is_none)
+{
+ if (is_none != NULL)
+ *is_none = 0;
+
+ if (args[idx].v_type == VAR_UNKNOWN)
+ return OK;
+
+ if (args[idx].v_type == VAR_SPECIAL
+ && args[idx].vval.v_number == VVAL_NONE)
+ {
+ if (is_none != NULL)
+ *is_none = 1;
+ return OK;
+ }
+
+ if (args[idx].v_type == VAR_STRING)
+ return OK;
+
+ semsg(_(e_string_or_none_required_for_argument_nr), idx + 1);
+ return FAIL;
+}
+
+/*
* Give an error and return FAIL unless "args[idx]" is a number.
*/
int
diff --git a/src/version.c b/src/version.c
index 208d7a8819..0896c643f9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2040,
+/**/
2039,
/**/
2038,