comparison src/evalfunc.c @ 33938:ed2267e507ff v9.0.2165

patch 9.0.2165: Vim9: can simplify arg type checking code Commit: https://github.com/vim/vim/commit/a8f7f92b56b42ea6a568eca889c48091f47fb429 Author: Ernie Rael <errael@raelity.com> Date: Thu Dec 14 20:17:04 2023 +0100 patch 9.0.2165: Vim9: can simplify arg type checking code Problem: Vim9: can simplify arg type checking code Solution: In `f_argcheck` array use `arg_any`, instead of NULL closes: #13674 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Thu, 14 Dec 2023 20:30:04 +0100
parents ccdb948c7273
children 84b93d95a952
comparison
equal deleted inserted replaced
33937:d4819efdf3ed 33938:ed2267e507ff
203 } argcontext_T; 203 } argcontext_T;
204 204
205 // A function to check one argument type. The first argument is the type to 205 // A function to check one argument type. The first argument is the type to
206 // check. If needed, other argument types can be obtained with the context. 206 // check. If needed, other argument types can be obtained with the context.
207 // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type. 207 // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type.
208 // NOTE: Use "arg_any", not NULL, in funcentry_T.f_argcheck array
209 // to accept an argument of any type.
208 typedef int (*argcheck_T)(type_T *, type_T *, argcontext_T *); 210 typedef int (*argcheck_T)(type_T *, type_T *, argcontext_T *);
209 211
210 /* 212 /*
211 * Call need_type() to check an argument type. 213 * Call need_type() to check an argument type.
212 */ 214 */
249 return OK; 251 return OK;
250 semsg(_(e_argument_nr_trying_to_modify_const_str), 252 semsg(_(e_argument_nr_trying_to_modify_const_str),
251 arg_idx, type_name(type, &tofree)); 253 arg_idx, type_name(type, &tofree));
252 vim_free(tofree); 254 vim_free(tofree);
253 return FAIL; 255 return FAIL;
256 }
257
258 /*
259 * Return OK for any type unconditionally.
260 */
261 static int
262 arg_any(type_T *type UNUSED,
263 type_T *decl_type UNUSED,
264 argcontext_T *context UNUSED)
265 {
266 return OK;
254 } 267 }
255 268
256 /* 269 /*
257 * Check "type" is a float or a number. 270 * Check "type" is a float or a number.
258 */ 271 */
1065 static argcheck_T arg1_number[] = {arg_number}; 1078 static argcheck_T arg1_number[] = {arg_number};
1066 static argcheck_T arg1_string[] = {arg_string}; 1079 static argcheck_T arg1_string[] = {arg_string};
1067 static argcheck_T arg1_string_or_list_any[] = {arg_string_or_list_any}; 1080 static argcheck_T arg1_string_or_list_any[] = {arg_string_or_list_any};
1068 static argcheck_T arg1_string_or_list_string[] = {arg_string_or_list_string}; 1081 static argcheck_T arg1_string_or_list_string[] = {arg_string_or_list_string};
1069 static argcheck_T arg1_string_or_nr[] = {arg_string_or_nr}; 1082 static argcheck_T arg1_string_or_nr[] = {arg_string_or_nr};
1070 static argcheck_T arg2_any_buffer[] = {NULL, arg_buffer}; 1083 static argcheck_T arg2_any_buffer[] = {arg_any, arg_buffer};
1071 static argcheck_T arg2_buffer_any[] = {arg_buffer, NULL}; 1084 static argcheck_T arg2_buffer_any[] = {arg_buffer, arg_any};
1072 static argcheck_T arg2_buffer_bool[] = {arg_buffer, arg_bool}; 1085 static argcheck_T arg2_buffer_bool[] = {arg_buffer, arg_bool};
1073 static argcheck_T arg2_buffer_list_any[] = {arg_buffer, arg_list_any}; 1086 static argcheck_T arg2_buffer_list_any[] = {arg_buffer, arg_list_any};
1074 static argcheck_T arg2_buffer_lnum[] = {arg_buffer, arg_lnum}; 1087 static argcheck_T arg2_buffer_lnum[] = {arg_buffer, arg_lnum};
1075 static argcheck_T arg2_buffer_number[] = {arg_buffer, arg_number}; 1088 static argcheck_T arg2_buffer_number[] = {arg_buffer, arg_number};
1076 static argcheck_T arg2_buffer_string[] = {arg_buffer, arg_string}; 1089 static argcheck_T arg2_buffer_string[] = {arg_buffer, arg_string};
1088 static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool}; 1101 static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool};
1089 static argcheck_T arg2_listblobmod_item[] = {arg_list_or_blob_mod, arg_item_of_prev}; 1102 static argcheck_T arg2_listblobmod_item[] = {arg_list_or_blob_mod, arg_item_of_prev};
1090 static argcheck_T arg2_lnum[] = {arg_lnum, arg_lnum}; 1103 static argcheck_T arg2_lnum[] = {arg_lnum, arg_lnum};
1091 static argcheck_T arg2_lnum_number[] = {arg_lnum, arg_number}; 1104 static argcheck_T arg2_lnum_number[] = {arg_lnum, arg_number};
1092 static argcheck_T arg2_number[] = {arg_number, arg_number}; 1105 static argcheck_T arg2_number[] = {arg_number, arg_number};
1093 static argcheck_T arg2_number_any[] = {arg_number, NULL}; 1106 static argcheck_T arg2_number_any[] = {arg_number, arg_any};
1094 static argcheck_T arg2_number_bool[] = {arg_number, arg_bool}; 1107 static argcheck_T arg2_number_bool[] = {arg_number, arg_bool};
1095 static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any}; 1108 static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any};
1096 static argcheck_T arg2_number_list[] = {arg_number, arg_list_any}; 1109 static argcheck_T arg2_number_list[] = {arg_number, arg_list_any};
1097 static argcheck_T arg2_number_string[] = {arg_number, arg_string}; 1110 static argcheck_T arg2_number_string[] = {arg_number, arg_string};
1098 static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any}; 1111 static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any};
1099 static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any}; 1112 static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any};
1100 static argcheck_T arg2_string[] = {arg_string, arg_string}; 1113 static argcheck_T arg2_string[] = {arg_string, arg_string};
1101 static argcheck_T arg2_string_any[] = {arg_string, NULL}; 1114 static argcheck_T arg2_string_any[] = {arg_string, arg_any};
1102 static argcheck_T arg2_string_bool[] = {arg_string, arg_bool}; 1115 static argcheck_T arg2_string_bool[] = {arg_string, arg_bool};
1103 static argcheck_T arg2_string_chan_or_job[] = {arg_string, arg_chan_or_job}; 1116 static argcheck_T arg2_string_chan_or_job[] = {arg_string, arg_chan_or_job};
1104 static argcheck_T arg2_string_dict[] = {arg_string, arg_dict_any}; 1117 static argcheck_T arg2_string_dict[] = {arg_string, arg_dict_any};
1105 static argcheck_T arg2_string_list_number[] = {arg_string, arg_list_number}; 1118 static argcheck_T arg2_string_list_number[] = {arg_string, arg_list_number};
1106 static argcheck_T arg2_string_number[] = {arg_string, arg_number}; 1119 static argcheck_T arg2_string_number[] = {arg_string, arg_number};
1107 static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any}; 1120 static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
1108 static argcheck_T arg2_string_or_list_number[] = {arg_string_or_list_any, arg_number}; 1121 static argcheck_T arg2_string_or_list_number[] = {arg_string_or_list_any, arg_number};
1109 static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr}; 1122 static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr};
1110 static argcheck_T arg3_any_list_dict[] = {NULL, arg_list_any, arg_dict_any}; 1123 static argcheck_T arg3_any_list_dict[] = {arg_any, arg_list_any, arg_dict_any};
1111 static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum}; 1124 static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
1112 static argcheck_T arg3_buffer_number_number[] = {arg_buffer, arg_number, arg_number}; 1125 static argcheck_T arg3_buffer_number_number[] = {arg_buffer, arg_number, arg_number};
1113 static argcheck_T arg3_buffer_string_any[] = {arg_buffer, arg_string, NULL}; 1126 static argcheck_T arg3_buffer_string_any[] = {arg_buffer, arg_string, arg_any};
1114 static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any}; 1127 static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any};
1115 static argcheck_T arg3_dict_number_number[] = {arg_dict_any, arg_number, arg_number}; 1128 static argcheck_T arg3_dict_number_number[] = {arg_dict_any, arg_number, arg_number};
1116 static argcheck_T arg3_list_string_dict[] = {arg_list_any, arg_string, arg_dict_any}; 1129 static argcheck_T arg3_list_string_dict[] = {arg_list_any, arg_string, arg_dict_any};
1117 static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool}; 1130 static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool};
1118 static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number}; 1131 static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
1119 static argcheck_T arg3_number_any_dict[] = {arg_number, NULL, arg_dict_any}; 1132 static argcheck_T arg3_number_any_dict[] = {arg_number, arg_any, arg_dict_any};
1120 static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any}; 1133 static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any};
1121 static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, NULL}; 1134 static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, arg_any};
1122 static argcheck_T arg3_number_string_buffer[] = {arg_number, arg_string, arg_buffer}; 1135 static argcheck_T arg3_number_string_buffer[] = {arg_number, arg_string, arg_buffer};
1123 static argcheck_T arg3_number_string_string[] = {arg_number, arg_string, arg_string}; 1136 static argcheck_T arg3_number_string_string[] = {arg_number, arg_string, arg_string};
1124 static argcheck_T arg3_string[] = {arg_string, arg_string, arg_string}; 1137 static argcheck_T arg3_string[] = {arg_string, arg_string, arg_string};
1125 static argcheck_T arg3_string_any_dict[] = {arg_string, NULL, arg_dict_any}; 1138 static argcheck_T arg3_string_any_dict[] = {arg_string, arg_any, arg_dict_any};
1126 static argcheck_T arg3_string_any_string[] = {arg_string, NULL, arg_string}; 1139 static argcheck_T arg3_string_any_string[] = {arg_string, arg_any, arg_string};
1127 static argcheck_T arg3_string_bool_bool[] = {arg_string, arg_bool, arg_bool}; 1140 static argcheck_T arg3_string_bool_bool[] = {arg_string, arg_bool, arg_bool};
1128 static argcheck_T arg3_string_number_bool[] = {arg_string, arg_number, arg_bool}; 1141 static argcheck_T arg3_string_number_bool[] = {arg_string, arg_number, arg_bool};
1129 static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number}; 1142 static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number};
1130 static argcheck_T arg3_string_or_dict_bool_dict[] = {arg_string_or_dict_any, arg_bool, arg_dict_any}; 1143 static argcheck_T arg3_string_or_dict_bool_dict[] = {arg_string_or_dict_any, arg_bool, arg_dict_any};
1131 static argcheck_T arg3_string_or_list_bool_number[] = {arg_string_or_list_any, arg_bool, arg_number}; 1144 static argcheck_T arg3_string_or_list_bool_number[] = {arg_string_or_list_any, arg_bool, arg_number};
1132 static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool}; 1145 static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool};
1133 static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any}; 1146 static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any};
1134 static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number}; 1147 static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number};
1135 static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL}; 1148 static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, arg_any};
1136 static argcheck_T arg4_string_string_any_string[] = {arg_string, arg_string, NULL, arg_string}; 1149 static argcheck_T arg4_string_string_any_string[] = {arg_string, arg_string, arg_any, arg_string};
1137 static argcheck_T arg4_string_string_number_string[] = {arg_string, arg_string, arg_number, arg_string}; 1150 static argcheck_T arg4_string_string_number_string[] = {arg_string, arg_string, arg_number, arg_string};
1138 static argcheck_T arg4_string_number_bool_bool[] = {arg_string, arg_number, arg_bool, arg_bool}; 1151 static argcheck_T arg4_string_number_bool_bool[] = {arg_string, arg_number, arg_bool, arg_bool};
1139 /* Function specific argument types (not covered by the above) */ 1152 /* Function specific argument types (not covered by the above) */
1140 static argcheck_T arg15_assert_fails[] = {arg_string_or_nr, arg_string_or_list_any, NULL, arg_number, arg_string}; 1153 static argcheck_T arg15_assert_fails[] = {arg_string_or_nr, arg_string_or_list_any, arg_any, arg_number, arg_string};
1141 static argcheck_T arg34_assert_inrange[] = {arg_float_or_nr, arg_float_or_nr, arg_float_or_nr, arg_string}; 1154 static argcheck_T arg34_assert_inrange[] = {arg_float_or_nr, arg_float_or_nr, arg_float_or_nr, arg_string};
1142 static argcheck_T arg4_browse[] = {arg_bool, arg_string, arg_string, arg_string}; 1155 static argcheck_T arg4_browse[] = {arg_bool, arg_string, arg_string, arg_string};
1143 static argcheck_T arg23_chanexpr[] = {arg_chan_or_job, NULL, arg_dict_any}; 1156 static argcheck_T arg23_chanexpr[] = {arg_chan_or_job, arg_any, arg_dict_any};
1144 static argcheck_T arg23_chanraw[] = {arg_chan_or_job, arg_string_or_blob, arg_dict_any}; 1157 static argcheck_T arg23_chanraw[] = {arg_chan_or_job, arg_string_or_blob, arg_dict_any};
1145 static argcheck_T arg24_count[] = {arg_string_or_list_or_dict, NULL, arg_bool, arg_number}; 1158 static argcheck_T arg24_count[] = {arg_string_or_list_or_dict, arg_any, arg_bool, arg_number};
1146 static argcheck_T arg13_cursor[] = {arg_cursor1, arg_number, arg_number}; 1159 static argcheck_T arg13_cursor[] = {arg_cursor1, arg_number, arg_number};
1147 static argcheck_T arg12_deepcopy[] = {NULL, arg_bool}; 1160 static argcheck_T arg12_deepcopy[] = {arg_any, arg_bool};
1148 static argcheck_T arg12_execute[] = {arg_string_or_list_string, arg_string}; 1161 static argcheck_T arg12_execute[] = {arg_string_or_list_string, arg_string};
1149 static argcheck_T arg23_extend[] = {arg_list_or_dict_mod, arg_same_as_prev, arg_extend3}; 1162 static argcheck_T arg23_extend[] = {arg_list_or_dict_mod, arg_same_as_prev, arg_extend3};
1150 static argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3}; 1163 static argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3};
1151 static argcheck_T arg23_get[] = {arg_get1, arg_string_or_nr, NULL}; 1164 static argcheck_T arg23_get[] = {arg_get1, arg_string_or_nr, arg_any};
1152 static argcheck_T arg14_glob[] = {arg_string, arg_bool, arg_bool, arg_bool}; 1165 static argcheck_T arg14_glob[] = {arg_string, arg_bool, arg_bool, arg_bool};
1153 static argcheck_T arg25_globpath[] = {arg_string, arg_string, arg_bool, arg_bool, arg_bool}; 1166 static argcheck_T arg25_globpath[] = {arg_string, arg_string, arg_bool, arg_bool, arg_bool};
1154 static argcheck_T arg24_index[] = {arg_list_or_blob, arg_item_of_prev, arg_number, arg_bool}; 1167 static argcheck_T arg24_index[] = {arg_list_or_blob, arg_item_of_prev, arg_number, arg_bool};
1155 static argcheck_T arg23_index[] = {arg_list_or_blob, arg_filter_func, arg_dict_any}; 1168 static argcheck_T arg23_index[] = {arg_list_or_blob, arg_filter_func, arg_dict_any};
1156 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number}; 1169 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
1158 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr}; 1171 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr};
1159 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool}; 1172 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
1160 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string_mod, arg_filter_func}; 1173 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string_mod, arg_filter_func};
1161 static argcheck_T arg2_instanceof[] = {arg_object, varargs_class, NULL }; 1174 static argcheck_T arg2_instanceof[] = {arg_object, varargs_class, NULL };
1162 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string_mod, arg_map_func}; 1175 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string_mod, arg_map_func};
1163 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, NULL}; 1176 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, arg_any};
1164 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any}; 1177 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any};
1165 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any}; 1178 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any};
1166 static argcheck_T arg119_printf[] = {arg_string_or_nr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 1179 static argcheck_T arg119_printf[] = {arg_string_or_nr, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any, arg_any};
1167 static argcheck_T arg23_reduce[] = {arg_string_list_or_blob, NULL, NULL}; 1180 static argcheck_T arg23_reduce[] = {arg_string_list_or_blob, arg_any, arg_any};
1168 static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number}; 1181 static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number};
1169 static argcheck_T arg23_remove[] = {arg_list_or_dict_or_blob_mod, arg_remove2, arg_number}; 1182 static argcheck_T arg23_remove[] = {arg_list_or_dict_or_blob_mod, arg_remove2, arg_number};
1170 static argcheck_T arg2_repeat[] = {arg_repeat1, arg_number}; 1183 static argcheck_T arg2_repeat[] = {arg_repeat1, arg_number};
1171 static argcheck_T arg15_search[] = {arg_string, arg_string, arg_number, arg_number, arg_string_or_func}; 1184 static argcheck_T arg15_search[] = {arg_string, arg_string, arg_number, arg_number, arg_string_or_func};
1172 static argcheck_T arg37_searchpair[] = {arg_string, arg_string, arg_string, arg_string, arg_string_or_func, arg_number, arg_number}; 1185 static argcheck_T arg37_searchpair[] = {arg_string, arg_string, arg_string, arg_string, arg_string_or_func, arg_number, arg_number};
1173 static argcheck_T arg3_setbufline[] = {arg_buffer, arg_lnum, arg_str_or_nr_or_list}; 1186 static argcheck_T arg3_setbufline[] = {arg_buffer, arg_lnum, arg_str_or_nr_or_list};
1174 static argcheck_T arg2_setline[] = {arg_lnum, NULL}; 1187 static argcheck_T arg2_setline[] = {arg_lnum, arg_any};
1175 static argcheck_T arg24_setloclist[] = {arg_number, arg_list_any, arg_string, arg_dict_any}; 1188 static argcheck_T arg24_setloclist[] = {arg_number, arg_list_any, arg_string, arg_dict_any};
1176 static argcheck_T arg13_setqflist[] = {arg_list_any, arg_string, arg_dict_any}; 1189 static argcheck_T arg13_setqflist[] = {arg_list_any, arg_string, arg_dict_any};
1177 static argcheck_T arg23_settagstack[] = {arg_number, arg_dict_any, arg_string}; 1190 static argcheck_T arg23_settagstack[] = {arg_number, arg_dict_any, arg_string};
1178 static argcheck_T arg02_sign_getplaced[] = {arg_buffer, arg_dict_any}; 1191 static argcheck_T arg02_sign_getplaced[] = {arg_buffer, arg_dict_any};
1179 static argcheck_T arg45_sign_place[] = {arg_number, arg_string, arg_string, arg_buffer, arg_dict_any}; 1192 static argcheck_T arg45_sign_place[] = {arg_number, arg_string, arg_string, arg_buffer, arg_dict_any};
1626 1639
1627 /* 1640 /*
1628 * Array with names and number of arguments of all internal functions 1641 * Array with names and number of arguments of all internal functions
1629 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 1642 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
1630 * 1643 *
1631 * The function may be varargs. In that case 1644 * The builtin function may be varargs. In that case
1632 * - f_max_argc == VARGS 1645 * - f_max_argc == VARGS
1633 * - f_argcheck must be NULL terminated. Last non-null argument 1646 * - For varargs, f_argcheck must be NULL terminated. The last non-null
1634 * should check all the remaining args. 1647 * entry in f_argcheck should validate all the remaining args.
1635 * NOTE: if varargs, there can only be one NULL in f_argcheck array.
1636 */ 1648 */
1637 typedef struct 1649 typedef struct
1638 { 1650 {
1639 char *f_name; // function name 1651 char *f_name; // function name
1640 char f_min_argc; // minimal number of arguments 1652 char f_min_argc; // minimal number of arguments
1641 char f_max_argc; // maximal number of arguments 1653 char f_max_argc; // maximal number of arguments
1642 char f_argtype; // for method: FEARG_ values 1654 char f_argtype; // for method: FEARG_ values
1643 argcheck_T *f_argcheck; // list of functions to check argument types 1655 argcheck_T *f_argcheck; // list of functions to check argument types;
1656 // use "arg_any" (not NULL) to accept an
1657 // argument of any type
1644 type_T *(*f_retfunc)(int argcount, type2_T *argtypes, 1658 type_T *(*f_retfunc)(int argcount, type2_T *argtypes,
1645 type_T **decl_type); 1659 type_T **decl_type);
1646 // return type function 1660 // return type function
1647 void (*f_func)(typval_T *args, typval_T *rvar); 1661 void (*f_func)(typval_T *args, typval_T *rvar);
1648 // implementation of function 1662 // implementation of function
3048 argcheck_T *argchecks = global_functions[idx].f_argcheck; 3062 argcheck_T *argchecks = global_functions[idx].f_argcheck;
3049 3063
3050 if (argchecks == NULL) 3064 if (argchecks == NULL)
3051 return OK; 3065 return OK;
3052 3066
3053 int has_varargs = global_functions[idx].f_max_argc == VARGS;
3054
3055 argcontext_T context; 3067 argcontext_T context;
3056 3068
3057 context.arg_count = argcount; 3069 context.arg_count = argcount;
3058 context.arg_types = types; 3070 context.arg_types = types;
3059 context.arg_cctx = cctx; 3071 context.arg_cctx = cctx;
3060 for (int i = 0; i < argcount; ++i) 3072 for (int i = 0; i < argcount && argchecks[i] != NULL; ++i)
3061 if (argchecks[i] == NULL) 3073 {
3062 { 3074 context.arg_idx = i;
3063 if (has_varargs) 3075 if (argchecks[i](types[i].type_curr, types[i].type_decl,
3064 break; 3076 &context) == FAIL)
3065 } 3077 return FAIL;
3066 else 3078 }
3067 {
3068 context.arg_idx = i;
3069 if (argchecks[i](types[i].type_curr, types[i].type_decl,
3070 &context) == FAIL)
3071 return FAIL;
3072 }
3073 return OK; 3079 return OK;
3074 } 3080 }
3075 3081
3076 /* 3082 /*
3077 * Get the argument count for function "idx". 3083 * Get the argument count for function "idx".