@@ -276,6 +276,9 @@ typedef struct {
276276// E.g. if "arg_idx" is 1, then (type - 1) is the first argument type.
277277typedef int (* argcheck_T )(type_T * , argcontext_T * );
278278
279+ /*
280+ * Check "type" is a float or a number.
281+ */
279282 static int
280283arg_float_or_nr (type_T * type , argcontext_T * context )
281284{
@@ -286,12 +289,27 @@ arg_float_or_nr(type_T *type, argcontext_T *context)
286289 return FAIL ;
287290}
288291
292+ /*
293+ * Check "type" is a number.
294+ */
289295 static int
290296arg_number (type_T * type , argcontext_T * context )
291297{
292298 return check_type (& t_number , type , TRUE, context -> arg_idx + 1 );
293299}
294300
301+ /*
302+ * Check "type" is a string.
303+ */
304+ static int
305+ arg_string (type_T * type , argcontext_T * context )
306+ {
307+ return check_type (& t_string , type , TRUE, context -> arg_idx + 1 );
308+ }
309+
310+ /*
311+ * Check "type" is a list or a blob.
312+ */
295313 static int
296314arg_list_or_blob (type_T * type , argcontext_T * context )
297315{
@@ -303,7 +321,32 @@ arg_list_or_blob(type_T *type, argcontext_T *context)
303321}
304322
305323/*
306- * Check the type is an item of the list or blob of the previous arg.
324+ * Check "type" is a list or a dict.
325+ */
326+ static int
327+ arg_list_or_dict (type_T * type , argcontext_T * context )
328+ {
329+ if (type -> tt_type == VAR_ANY
330+ || type -> tt_type == VAR_LIST || type -> tt_type == VAR_DICT )
331+ return OK ;
332+ arg_type_mismatch (& t_list_any , type , context -> arg_idx + 1 );
333+ return FAIL ;
334+ }
335+
336+ /*
337+ * Check "type" is the same type as the previous argument
338+ * Must not be used for the first argcheck_T entry.
339+ */
340+ static int
341+ arg_same_as_prev (type_T * type , argcontext_T * context )
342+ {
343+ type_T * prev_type = context -> arg_types [context -> arg_idx - 1 ];
344+
345+ return check_type (prev_type , type , TRUE, context -> arg_idx + 1 );
346+ }
347+
348+ /*
349+ * Check "type" is an item of the list or blob of the previous arg.
307350 * Must not be used for the first argcheck_T entry.
308351 */
309352 static int
@@ -323,10 +366,28 @@ arg_item_of_prev(type_T *type, argcontext_T *context)
323366 return check_type (expected , type , TRUE, context -> arg_idx + 1 );
324367}
325368
369+ /*
370+ * Check "type" which is the third argument of extend().
371+ */
372+ static int
373+ arg_extend3 (type_T * type , argcontext_T * context )
374+ {
375+ type_T * first_type = context -> arg_types [context -> arg_idx - 2 ];
376+
377+ if (first_type -> tt_type == VAR_LIST )
378+ return arg_number (type , context );
379+ if (first_type -> tt_type == VAR_DICT )
380+ return arg_string (type , context );
381+ return OK ;
382+ }
383+
384+
326385/*
327386 * Lists of functions that check the argument types of a builtin function.
328387 */
329388argcheck_T arg1_float_or_nr [] = {arg_float_or_nr };
389+ argcheck_T arg2_listblob_item [] = {arg_list_or_blob , arg_item_of_prev };
390+ argcheck_T arg23_extend [] = {arg_list_or_dict , arg_same_as_prev , arg_extend3 };
330391argcheck_T arg3_insert [] = {arg_list_or_blob , arg_item_of_prev , arg_number };
331392
332393/*
@@ -567,7 +628,7 @@ static funcentry_T global_functions[] =
567628 ret_any , FLOAT_FUNC (f_abs )},
568629 {"acos" , 1 , 1 , FEARG_1 , NULL ,
569630 ret_float , FLOAT_FUNC (f_acos )},
570- {"add" , 2 , 2 , FEARG_1 , NULL ,
631+ {"add" , 2 , 2 , FEARG_1 , NULL /* arg2_listblob_item */ ,
571632 ret_first_arg , f_add },
572633 {"and" , 2 , 2 , FEARG_1 , NULL ,
573634 ret_number , f_and },
@@ -793,7 +854,7 @@ static funcentry_T global_functions[] =
793854 ret_any , f_expand },
794855 {"expandcmd" , 1 , 1 , FEARG_1 , NULL ,
795856 ret_string , f_expandcmd },
796- {"extend" , 2 , 3 , FEARG_1 , NULL ,
857+ {"extend" , 2 , 3 , FEARG_1 , arg23_extend ,
797858 ret_first_arg , f_extend },
798859 {"feedkeys" , 1 , 2 , FEARG_1 , NULL ,
799860 ret_void , f_feedkeys },
0 commit comments