diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2021-07-27 22:00:44 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-07-27 22:00:44 +0200 |
commit | 4490ec4e839e45a2e6923c265c7e9e64c240b805 (patch) | |
tree | 3ef2dc127890ac6a644f38ae7932b7e70071544a | |
parent | 5d7c2df536c17db4a9c61e0760bdcf78d0db7330 (diff) |
patch 8.2.3229: Vim9: runtime and compile time type checks are not the samev8.2.3229
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)
55 files changed, 1710 insertions, 630 deletions
diff --git a/src/arglist.c b/src/arglist.c index 863b1cc6a9..5370142a7f 100644 --- a/src/arglist.c +++ b/src/arglist.c @@ -1271,6 +1271,9 @@ f_argc(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) // use the current window rettv->vval.v_number = ARGCOUNT; @@ -1306,6 +1309,12 @@ f_arglistid(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + rettv->vval.v_number = -1; wp = find_tabwin(&argvars[0], &argvars[1], NULL); if (wp != NULL) @@ -1336,6 +1345,12 @@ f_argv(typval_T *argvars, typval_T *rettv) aentry_T *arglist = NULL; int argcount = -1; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { if (argvars[1].v_type == VAR_UNKNOWN) diff --git a/src/change.c b/src/change.c index f77b48c742..799aa5efbc 100644 --- a/src/change.c +++ b/src/change.c @@ -281,6 +281,9 @@ f_listener_flush(typval_T *argvars, typval_T *rettv UNUSED) { buf_T *buf = curbuf; + if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { buf = get_buf_arg(&argvars[0]); @@ -299,9 +302,13 @@ f_listener_remove(typval_T *argvars, typval_T *rettv) listener_T *lnr; listener_T *next; listener_T *prev; - int id = tv_get_number(argvars); + int id; buf_T *buf; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + + id = tv_get_number(argvars); FOR_ALL_BUFFERS(buf) { prev = NULL; diff --git a/src/channel.c b/src/channel.c index 46bdc0ec8a..5307792e8c 100644 --- a/src/channel.c +++ b/src/channel.c @@ -3865,6 +3865,11 @@ common_channel_read(typval_T *argvars, typval_T *rettv, int raw, int blob) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (in_vim9script() + && (check_for_chan_or_job_arg(argvars, 0) == FAIL + || check_for_opt_dict_arg(argvars, 1) == FAIL)) + return; + clear_job_options(&opt); if (get_job_options(&argvars[1], &opt, JO_TIMEOUT + JO_PART + JO_ID, 0) == FAIL) @@ -4784,9 +4789,13 @@ channel_get_timeout(channel_T *channel, ch_part_T part) void f_ch_canread(typval_T *argvars, typval_T *rettv) { - channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); + channel_T *channel; rettv->vval.v_number = 0; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL) rettv->vval.v_number = channel_has_readahead(channel, PART_SOCK) || channel_has_readahead(channel, PART_OUT) @@ -4799,8 +4808,12 @@ f_ch_canread(typval_T *argvars, typval_T *rettv) void f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel != NULL) { channel_close(channel, FALSE); @@ -4814,8 +4827,12 @@ f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) void f_ch_close_in(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel != NULL) channel_close_in(channel); } @@ -4861,8 +4878,12 @@ f_ch_getbufnr(typval_T *argvars, typval_T *rettv) void f_ch_getjob(typval_T *argvars, typval_T *rettv) { - channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL) { rettv->v_type = VAR_JOB; @@ -4878,8 +4899,12 @@ f_ch_getjob(typval_T *argvars, typval_T *rettv) void f_ch_info(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL && rettv_dict_alloc(rettv) != FAIL) channel_info(channel, rettv->vval.v_dict); } @@ -4921,7 +4946,7 @@ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL - || check_for_string_arg(argvars, 1) == FAIL)) + || check_for_opt_string_arg(argvars, 1) == FAIL)) return; fname = tv_get_string(&argvars[0]); @@ -5014,6 +5039,11 @@ f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED) channel_T *channel; jobopt_T opt; + if (in_vim9script() + && (check_for_chan_or_job_arg(argvars, 0) == FAIL + || check_for_dict_arg(argvars, 1) == FAIL)) + return; + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel == NULL) return; @@ -5038,6 +5068,11 @@ f_ch_status(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (in_vim9script() + && (check_for_chan_or_job_arg(argvars, 0) == FAIL + || check_for_opt_dict_arg(argvars, 1) == FAIL)) + return; + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (argvars[1].v_type != VAR_UNKNOWN) diff --git a/src/cindent.c b/src/cindent.c index ce02402c22..b751206532 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -4129,6 +4129,9 @@ f_cindent(typval_T *argvars UNUSED, typval_T *rettv) pos_T pos; linenr_T lnum; + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + pos = curwin->w_cursor; lnum = tv_get_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) diff --git a/src/clientserver.c b/src/clientserver.c index 3c0a930ed1..4ad17f4f93 100644 --- a/src/clientserver.c +++ b/src/clientserver.c @@ -814,6 +814,9 @@ f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv) f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { #ifdef FEAT_CLIENTSERVER + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + # ifdef MSWIN // On Win32 it's done in this application. { @@ -846,17 +849,18 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) # endif char_u *serverid; + rettv->vval.v_number = -1; if (check_restricted() || check_secure()) - { - rettv->vval.v_number = -1; return; - } + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + serverid = tv_get_string_chk(&argvars[0]); if (serverid == NULL) - { - rettv->vval.v_number = -1; return; // type error; errmsg already given - } # ifdef MSWIN sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); if (n == 0) @@ -959,8 +963,12 @@ f_remote_send(typval_T *argvars UNUSED, typval_T *rettv) f_remote_startserver(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { #ifdef FEAT_CLIENTSERVER - char_u *server = tv_get_string_chk(&argvars[0]); + char_u *server; + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + server = tv_get_string_chk(&argvars[0]); if (server == NULL) return; // type error; errmsg already given if (serverName != NULL) @@ -984,14 +992,23 @@ f_server2client(typval_T *argvars UNUSED, typval_T *rettv) { #ifdef FEAT_CLIENTSERVER char_u buf[NUMBUFLEN]; - char_u *server = tv_get_string_chk(&argvars[0]); - char_u *reply = tv_get_string_buf_chk(&argvars[1], buf); + char_u *server; + char_u *reply; rettv->vval.v_number = -1; - if (server == NULL || reply == NULL) - return; if (check_restricted() || check_secure()) return; + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + + server = tv_get_string_chk(&argvars[0]); + reply = tv_get_string_buf_chk(&argvars[1], buf); + if (server == NULL || reply == NULL) + return; + # ifdef FEAT_X11 if (check_connection() == FAIL) return; diff --git a/src/cmdhist.c b/src/cmdhist.c index f3b8b007eb..0ac3ff6949 100644 --- a/src/cmdhist.c +++ b/src/cmdhist.c @@ -545,6 +545,12 @@ f_histadd(typval_T *argvars UNUSED, typval_T *rettv) rettv->vval.v_number = FALSE; if (check_secure()) return; + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + str = tv_get_string_chk(&argvars[0]); // NULL on type error histype = str != NULL ? get_histtype(str) : -1; if (histype >= 0) @@ -630,9 +636,12 @@ f_histget(typval_T *argvars UNUSED, typval_T *rettv) f_histnr(typval_T *argvars UNUSED, typval_T *rettv) { int i; + char_u *histname; - char_u *histname = tv_get_string_chk(&argvars[0]); + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + histname = tv_get_string_chk(&argvars[0]); i = histname == NULL ? HIST_CMD - 1 : get_histtype(histname); if (i >= HIST_CMD && i < HIST_COUNT) i = get_history_idx(i); diff --git a/src/dict.c b/src/dict.c index 768adf0de5..82397d5126 100644 --- a/src/dict.c +++ b/src/dict.c @@ -1201,6 +1201,9 @@ dict_list(typval_T *argvars, typval_T *rettv, int what) dict_T *d; int todo; + if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -1318,6 +1321,11 @@ dict_set_items_ro(dict_T *di) void f_has_key(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_dict_arg(argvars, 0) == FAIL + || check_for_string_or_number_arg(argvars, 1) == FAIL)) + return; + if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); diff --git a/src/diff.c b/src/diff.c index a47259e1af..aea1c0e70a 100644 --- a/src/diff.c +++ b/src/diff.c @@ -3272,6 +3272,9 @@ xdiff_out(void *priv, mmbuffer_t *mb, int nbuf) f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { #ifdef FEAT_DIFF + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars)); #endif } diff --git a/src/digraph.c b/src/digraph.c index 745cbbb746..4a185399da 100644 --- a/src/digraph.c +++ b/src/digraph.c @@ -2406,6 +2406,10 @@ f_digraph_get(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; // Return empty string for failure + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + digraphs = tv_get_string_chk(&argvars[0]); if (digraphs == NULL) @@ -2439,6 +2443,9 @@ f_digraph_getlist(typval_T *argvars, typval_T *rettv) # ifdef FEAT_DIGRAPHS int flag_list_all; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) flag_list_all = FALSE; else @@ -2466,6 +2473,11 @@ f_digraph_set(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_BOOL; rettv->vval.v_number = VVAL_FALSE; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + if (!digraph_set_common(&argvars[0], &argvars[1])) return; diff --git a/src/errors.h b/src/errors.h index 7e4a465223..b76b92fa5f 100644 --- a/src/errors.h +++ b/src/errors.h @@ -617,3 +617,23 @@ EXTERN char e_chan_or_job_required_for_argument_nr[] INIT(= N_("E1217: Channel or Job required for argument %d")); EXTERN char e_job_required_for_argument_nr[] INIT(= N_("E1218: Job required for argument %d")); +EXTERN char e_float_or_number_required_for_argument_nr[] + INIT(= N_("E1219: Float or Number required for argument %d")); +EXTERN char e_string_or_number_required_for_argument_nr[] + INIT(= N_("E1220: String or Number required for argument %d")); +EXTERN char e_string_or_blob_required_for_argument_nr[] + INIT(= N_("E1221: String or Blob required for argument %d")); +EXTERN char e_string_or_list_required_for_argument_nr[] + INIT(= N_("E1222: String or List required for argument %d")); +EXTERN char e_string_or_dict_required_for_argument_nr[] + INIT(= N_("E1223: String or List required for argument %d")); +EXTERN char e_string_or_number_or_list_required_for_argument_nr[] + INIT(= N_("E1224: String or List required for argument %d")); +EXTERN char e_string_or_list_or_dict_required_for_argument_nr[] + INIT(= N_("E1225: String or List required for argument %d")); +EXTERN char e_list_or_blob_required_for_argument_nr[] + INIT(= N_("E1226: String or List required for argument %d")); +EXTERN char e_list_or_dict_required_for_argument_nr[] + INIT(= N_("E1227: List or Dictionary required for argument %d")); +EXTERN char e_list_or_dict_or_blob_required_for_argument_nr[] + INIT(= N_("E1228: List or Dictionary or Blob required for argument %d")); diff --git a/src/eval.c b/src/eval.c index 8050bbbbe9..0d41f17805 100644 --- a/src/eval.c +++ b/src/eval.c @@ -4190,9 +4190,9 @@ check_can_index(typval_T *rettv, int evaluate, int verbose) f_slice(typval_T *argvars, typval_T *rettv) { if (in_vim9script() - && ((argvars[0].v_type != VAR_LIST + && ((argvars[0].v_type != VAR_STRING + && argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB - && argvars[0].v_type != VAR_STRING && check_for_list_arg(argvars, 0) == FAIL) || check_for_number_arg(argvars, 1) == FAIL || check_for_opt_number_arg(argvars, 2) == FAIL)) diff --git a/src/evalbuffer.c b/src/evalbuffer.c index bb6ff63dfe..3fb037c5f1 100644 --- a/src/evalbuffer.c +++ b/src/evalbuffer.c @@ -277,8 +277,12 @@ done: void f_append(typval_T *argvars, typval_T *rettv) { - linenr_T lnum = tv_get_lnum(&argvars[0]); + linenr_T lnum; + + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + lnum = tv_get_lnum(&argvars[0]); set_buffer_lines(curbuf, lnum, TRUE, &argvars[1], rettv); } @@ -291,6 +295,12 @@ f_appendbufline(typval_T *argvars, typval_T *rettv) linenr_T lnum; buf_T *buf; + if (in_vim9script() + && (check_for_buffer_arg(argvars, 0) == FAIL + || check_for_lnum_arg(argvars, 1) == FAIL + || check_for_string_or_number_or_list_arg(argvars, 2) == FAIL)) + return; + buf = tv_get_buf(&argvars[0], FALSE); if (buf == NULL) rettv->vval.v_number = 1; // FAIL @@ -307,8 +317,12 @@ f_appendbufline(typval_T *argvars, typval_T *rettv) void f_bufadd(typval_T *argvars, typval_T *rettv) { - char_u *name = tv_get_string(&argvars[0]); + char_u *name; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + + name = tv_get_string(&argvars[0]); rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0); } @@ -318,6 +332,9 @@ f_bufadd(typval_T *argvars, typval_T *rettv) void f_bufexists(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); } @@ -329,6 +346,9 @@ f_buflisted(typval_T *argvars, typval_T *rettv) { buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = find_buffer(&argvars[0]); rettv->vval.v_number = (buf != NULL && buf->b_p_bl); } @@ -339,8 +359,12 @@ f_buflisted(typval_T *argvars, typval_T *rettv) void f_bufload(typval_T *argvars, typval_T *rettv UNUSED) { - buf_T *buf = get_buf_arg(&argvars[0]); + buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + + buf = get_buf_arg(&argvars[0]); if (buf != NULL) buffer_ensure_loaded(buf); } @@ -353,6 +377,9 @@ f_bufloaded(typval_T *argvars, typval_T *rettv) { buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = find_buffer(&argvars[0]); rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); } @@ -366,6 +393,9 @@ f_bufname(typval_T *argvars, typval_T *rettv) buf_T *buf; typval_T *tv = &argvars[0]; + if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) + return; + if (tv->v_type == VAR_UNKNOWN) buf = curbuf; else @@ -421,6 +451,9 @@ buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr) int winnr = 0; buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = tv_get_buf_from_arg(&argvars[0]); FOR_ALL_WINDOWS(wp) { @@ -636,8 +669,7 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv) return; if (in_vim9script() - && argvars[0].v_type != VAR_UNKNOWN - && check_for_buffer_or_dict_arg(argvars, 0) == FAIL) + && check_for_opt_buffer_or_dict_arg(argvars, 0) == FAIL) return; // List of all the buffers or selected buffers @@ -808,6 +840,12 @@ f_setbufline(typval_T *argvars, typval_T *rettv) linenr_T lnum; buf_T *buf; + if (in_vim9script() + && (check_for_buffer_arg(argvars, 0) == FAIL + || check_for_lnum_arg(argvars, 1) == FAIL + || check_for_string_or_number_or_list_arg(argvars, 2) == FAIL)) + return; + buf = tv_get_buf(&argvars[0], FALSE); if (buf == NULL) rettv->vval.v_number = 1; // FAIL @@ -824,8 +862,12 @@ f_setbufline(typval_T *argvars, typval_T *rettv) void f_setline(typval_T *argvars, typval_T *rettv) { - linenr_T lnum = tv_get_lnum(&argvars[0]); + linenr_T lnum; + + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + lnum = tv_get_lnum(&argvars[0]); set_buffer_lines(curbuf, lnum, FALSE, &argvars[1], rettv); } #endif // FEAT_EVAL diff --git a/src/evalfunc.c b/src/evalfunc.c index 2a9c972f99..7fc1821c6c 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -762,7 +762,7 @@ static argcheck_T arg3_string_number_bool[] = {arg_string, arg_number, arg_bool} static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number}; static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool}; static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any}; -static argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number}; +static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number}; static argcheck_T arg4_list_number_number_number[] = {arg_list_string, arg_number, arg_number, arg_number}; static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL}; static argcheck_T arg4_string_string_any_string[] = {arg_string, arg_string, NULL, arg_string}; @@ -811,7 +811,7 @@ static argcheck_T arg24_strpart[] = {arg_string, arg_number, arg_number, arg_boo static argcheck_T arg12_system[] = {arg_string, arg_str_or_nr_or_list}; static argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string}; static argcheck_T arg23_writefile[] = {arg_list_or_blob, arg_string, arg_string}; -static argcheck_T arg4_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number}; +static argcheck_T arg24_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number}; /* @@ -1340,9 +1340,9 @@ static funcentry_T global_functions[] = ret_number, f_filewritable}, {"filter", 2, 2, FEARG_1, arg2_mapfilter, ret_first_arg, f_filter}, - {"finddir", 1, 3, FEARG_1, arg3_string_string_nr, + {"finddir", 1, 3, FEARG_1, arg3_string_string_number, ret_string, f_finddir}, - {"findfile", 1, 3, FEARG_1, arg3_string_string_nr, + {"findfile", 1, 3, FEARG_1, arg3_string_string_number, ret_string, f_findfile}, {"flatten", 1, 2, FEARG_1, arg2_list_any_number, ret_list_any, f_flatten}, @@ -1608,7 +1608,7 @@ static funcentry_T global_functions[] = ret_first_cont, f_mapnew}, {"mapset", 3, 3, FEARG_1, arg3_string_bool_dict, ret_void, f_mapset}, - {"match", 2, 4, FEARG_1, arg4_match_func, + {"match", 2, 4, FEARG_1, arg24_match_func, ret_any, f_match}, {"matchadd", 2, 5, FEARG_1, arg25_matchadd, ret_number, f_matchadd}, @@ -1618,17 +1618,17 @@ static funcentry_T global_functions[] = ret_list_string, f_matcharg}, {"matchdelete", 1, 2, FEARG_1, arg2_number, |