From 4490ec4e839e45a2e6923c265c7e9e64c240b805 Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Tue, 27 Jul 2021 22:00:44 +0200 Subject: patch 8.2.3229: Vim9: runtime and compile time type checks are not the same Problem: Vim9: runtime and compile time type checks are not the same. Solution: Add more runtime type checks for builtin functions. (Yegappan Lakshmanan, closes #8646) --- src/typval.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 10 deletions(-) (limited to 'src/typval.c') diff --git a/src/typval.c b/src/typval.c index abda5f050..34032177d 100644 --- a/src/typval.c +++ b/src/typval.c @@ -430,7 +430,7 @@ check_for_float_or_nr_arg(typval_T *args, int idx) if (args[idx].v_type != VAR_FLOAT && args[idx].v_type != VAR_NUMBER) { if (idx >= 0) - semsg(_(e_number_required_for_argument_nr), idx + 1); + semsg(_(e_float_or_number_required_for_argument_nr), idx + 1); else emsg(_(e_numberreq)); return FAIL; @@ -567,6 +567,16 @@ check_for_job_arg(typval_T *args, int idx) return OK; } +/* + * Check for an optional job argument at 'idx'. + */ + int +check_for_opt_job_arg(typval_T *args, int idx) +{ + return (args[idx].v_type == VAR_UNKNOWN + || check_for_job_arg(args, idx) != FAIL); +} + /* * Give an error and return FAIL unless "args[idx]" is a string or * a number. @@ -577,7 +587,7 @@ check_for_string_or_number_arg(typval_T *args, int idx) if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER) { if (idx >= 0) - semsg(_(e_string_required_for_argument_nr), idx + 1); + semsg(_(e_string_or_number_required_for_argument_nr), idx + 1); else emsg(_(e_stringreq)); return FAIL; @@ -644,7 +654,7 @@ check_for_string_or_blob_arg(typval_T *args, int idx) if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_BLOB) { if (idx >= 0) - semsg(_(e_string_required_for_argument_nr), idx + 1); + semsg(_(e_string_or_blob_required_for_argument_nr), idx + 1); else emsg(_(e_stringreq)); return FAIL; @@ -661,7 +671,7 @@ check_for_string_or_list_arg(typval_T *args, int idx) if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_LIST) { if (idx >= 0) - semsg(_(e_string_required_for_argument_nr), idx + 1); + semsg(_(e_string_or_list_required_for_argument_nr), idx + 1); else emsg(_(e_stringreq)); return FAIL; @@ -679,6 +689,63 @@ check_for_opt_string_or_list_arg(typval_T *args, int idx) || check_for_string_or_list_arg(args, idx)); } +/* + * Give an error and return FAIL unless "args[idx]" is a string or a dict. + */ + int +check_for_string_or_dict_arg(typval_T *args, int idx) +{ + if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_DICT) + { + if (idx >= 0) + semsg(_(e_string_or_dict_required_for_argument_nr), idx + 1); + else + emsg(_(e_stringreq)); + return FAIL; + } + return OK; +} + +/* + * Give an error and return FAIL unless "args[idx]" is a string or a number + * or a list. + */ + int +check_for_string_or_number_or_list_arg(typval_T *args, int idx) +{ + if (args[idx].v_type != VAR_STRING + && args[idx].v_type != VAR_NUMBER + && args[idx].v_type != VAR_LIST) + { + if (idx >= 0) + semsg(_(e_string_or_number_or_list_required_for_argument_nr), idx + 1); + else + emsg(_(e_stringreq)); + return FAIL; + } + return OK; +} + +/* + * Give an error and return FAIL unless "args[idx]" is a string or a list + * or a dict. + */ + int +check_for_string_or_list_or_dict_arg(typval_T *args, int idx) +{ + if (args[idx].v_type != VAR_STRING + && args[idx].v_type != VAR_LIST + && args[idx].v_type != VAR_DICT) + { + if (idx >= 0) + semsg(_(e_string_or_list_or_dict_required_for_argument_nr), idx + 1); + else + emsg(_(e_stringreq)); + return FAIL; + } + return OK; +} + /* * Give an error and return FAIL unless "args[idx]" is a list or a blob. */ @@ -688,7 +755,25 @@ check_for_list_or_blob_arg(typval_T *args, int idx) if (args[idx].v_type != VAR_LIST && args[idx].v_type != VAR_BLOB) { if (idx >= 0) - semsg(_(e_list_required_for_argument_nr), idx + 1); + semsg(_(e_list_or_blob_required_for_argument_nr), idx + 1); + else + emsg(_(e_listreq)); + return FAIL; + } + return OK; +} + +/* + * Give an error and return FAIL unless "args[idx]" is a list or dict + */ + int +check_for_list_or_dict_arg(typval_T *args, int idx) +{ + if (args[idx].v_type != VAR_LIST + && args[idx].v_type != VAR_DICT) + { + if (idx >= 0) + semsg(_(e_list_or_dict_required_for_argument_nr), idx + 1); else emsg(_(e_listreq)); return FAIL; @@ -708,7 +793,7 @@ check_for_list_or_dict_or_blob_arg(typval_T *args, int idx) && args[idx].v_type != VAR_BLOB) { if (idx >= 0) - semsg(_(e_list_required_for_argument_nr), idx + 1); + semsg(_(e_list_or_dict_or_blob_required_for_argument_nr), idx + 1); else emsg(_(e_listreq)); return FAIL; @@ -717,13 +802,14 @@ check_for_list_or_dict_or_blob_arg(typval_T *args, int idx) } /* - * Give an error and return FAIL unless "args[idx]" is a buffer number or a - * dict. + * Give an error and return FAIL unless "args[idx]" is an optional buffer + * number or a dict. */ int -check_for_buffer_or_dict_arg(typval_T *args, int idx) +check_for_opt_buffer_or_dict_arg(typval_T *args, int idx) { - if (args[idx].v_type != VAR_STRING + if (args[idx].v_type != VAR_UNKNOWN + && args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER && args[idx].v_type != VAR_DICT) { -- cgit v1.2.1