void funcdepth_decrement(void);
int funcdepth_get(void);
void funcdepth_restore(int depth);
+int check_user_func_argcount(ufunc_T *fp, int argcount);
int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict);
void save_funccal(funccal_entry_T *entry);
void restore_funccal(void);
delete('Xscript')
enddef
+def Test_call_funcref_wrong_args()
+ var head =<< trim END
+ vim9script
+ def Func3(a1: string, a2: number, a3: list<number>)
+ echo a1 .. a2 .. a3[0]
+ enddef
+ def Testme()
+ var funcMap: dict<func> = {func: Func3}
+ END
+ var tail =<< trim END
+ enddef
+ Testme()
+ END
+ CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
+
+ CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
+ CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
+enddef
+
def Test_call_lambda_args()
CheckDefFailure(['echo {i -> 0}()'],
'E119: Not enough arguments for function: {i -> 0}()')
# FuncNo() is not redefined
writefile(first_lines + nono_lines, 'Xreloaded.vim')
source Xreloaded.vim
- g:DoCheck()
+ g:DoCheck(false)
# FuncNo() is back
writefile(first_lines + withno_lines, 'Xreloaded.vim')
source Xreloaded.vim
- g:DoCheck()
+ g:DoCheck(false)
delete('Xreloaded.vim')
enddef
cleanup_function_call(fc);
}
+/*
+ * Check the argument count for user function "fp".
+ * Return FCERR_UNKNOWN if OK, FCERR_TOOFEW or FCERR_TOOMANY otherwise.
+ */
+ int
+check_user_func_argcount(ufunc_T *fp, int argcount)
+{
+ int regular_args = fp->uf_args.ga_len;
+
+ if (argcount < regular_args - fp->uf_def_args.ga_len)
+ return FCERR_TOOFEW;
+ else if (!has_varargs(fp) && argcount > regular_args)
+ return FCERR_TOOMANY;
+ return FCERR_UNKNOWN;
+}
+
/*
* Call a user function after checking the arguments.
*/
dict_T *selfdict)
{
int error;
- int regular_args = fp->uf_args.ga_len;
if (fp->uf_flags & FC_RANGE && funcexe->doesrange != NULL)
*funcexe->doesrange = TRUE;
- if (argcount < regular_args - fp->uf_def_args.ga_len)
- error = FCERR_TOOFEW;
- else if (!has_varargs(fp) && argcount > regular_args)
- error = FCERR_TOOMANY;
- else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
+ error = check_user_func_argcount(fp, argcount);
+ if (error != FCERR_UNKNOWN)
+ return error;
+ if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
error = FCERR_DICT;
else
{
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 2172,
/**/
2171,
/**/
return FAIL;
if (ufunc->uf_def_status == UF_COMPILED)
{
+ int error = check_user_func_argcount(ufunc, argcount);
+
+ if (error != FCERR_UNKNOWN)
+ {
+ if (error == FCERR_TOOMANY)
+ semsg(_(e_toomanyarg), ufunc->uf_name);
+ else
+ semsg(_(e_toofewarg), ufunc->uf_name);
+ return FAIL;
+ }
+
// The function has been compiled, can call it quickly. For a function
// that was defined later: we can call it directly next time.
if (iptr != NULL)