diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval/typval.c | 33 | ||||
-rw-r--r-- | src/nvim/testing.c | 22 |
2 files changed, 53 insertions, 2 deletions
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 5f44cceb91..79f514bc71 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -52,6 +52,8 @@ static const char e_list_required_for_argument_nr[] = N_("E1211: List required for argument %d"); static const char e_bool_required_for_argument_nr[] = N_("E1212: Bool required for argument %d"); +static const char e_string_or_number_required_for_argument_nr[] + = N_("E1220: String or Number required for argument %d"); static const char e_string_or_list_required_for_argument_nr[] = N_("E1222: String or List required for argument %d"); static const char e_list_or_blob_required_for_argument_nr[] @@ -4160,6 +4162,17 @@ int tv_check_for_opt_number_arg(const typval_T *const args, const int idx) || tv_check_for_number_arg(args, idx) != FAIL) ? OK : FAIL; } +/// Give an error and return FAIL unless "args[idx]" is a float or a number. +int tv_check_for_float_or_nr_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_FLOAT && args[idx].v_type != VAR_NUMBER) { + semsg(_(e_number_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + /// Give an error and return FAIL unless "args[idx]" is a bool. int tv_check_for_bool_arg(const typval_T *const args, const int idx) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE @@ -4240,6 +4253,18 @@ int tv_check_for_opt_dict_arg(const typval_T *const args, const int idx) || tv_check_for_dict_arg(args, idx) != FAIL) ? OK : FAIL; } +/// Give an error and return FAIL unless "args[idx]" is a string or +/// a number. +int tv_check_for_string_or_number_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_NUMBER) { + semsg(_(e_string_or_number_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + /// Give an error and return FAIL unless "args[idx]" is a string or a list. int tv_check_for_string_or_list_arg(const typval_T *const args, const int idx) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE @@ -4251,6 +4276,14 @@ 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' +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 +{ + return (args[idx].v_type == VAR_UNKNOWN + || tv_check_for_string_or_list_arg(args, idx) != FAIL) ? OK : FAIL; +} + /// Give an error and return FAIL unless "args[idx]" is a string /// or a function reference. int tv_check_for_string_or_func_arg(const typval_T *const args, const int idx) diff --git a/src/nvim/testing.c b/src/nvim/testing.c index 0e779f9b8d..4a48743b44 100644 --- a/src/nvim/testing.c +++ b/src/nvim/testing.c @@ -500,12 +500,23 @@ void f_assert_exception(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// "assert_fails(cmd [, error [, msg]])" function void f_assert_fails(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - const char *const cmd = tv_get_string_chk(&argvars[0]); garray_T ga; - int save_trylevel = trylevel; + const int save_trylevel = trylevel; const int called_emsg_before = called_emsg; const char *wrong_arg_msg = NULL; + if (tv_check_for_string_or_number_arg(argvars, 0) == FAIL + || tv_check_for_opt_string_or_list_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && (argvars[2].v_type != VAR_UNKNOWN + && (tv_check_for_opt_number_arg(argvars, 3) == FAIL + || (argvars[3].v_type != VAR_UNKNOWN + && tv_check_for_opt_string_arg(argvars, 4) == FAIL))))) { + return; + } + + const char *const cmd = tv_get_string_chk(&argvars[0]); + // trylevel must be zero for a ":throw" command to be considered failed trylevel = 0; suppress_errthrow = true; @@ -682,6 +693,13 @@ static int assert_inrange(typval_T *argvars) /// "assert_inrange(lower, upper[, msg])" function void f_assert_inrange(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { + if (tv_check_for_float_or_nr_arg(argvars, 0) == FAIL + || tv_check_for_float_or_nr_arg(argvars, 1) == FAIL + || tv_check_for_float_or_nr_arg(argvars, 2) == FAIL + || tv_check_for_opt_string_arg(argvars, 3) == FAIL) { + return; + } + rettv->vval.v_number = assert_inrange(argvars); } |