blob: 0ebd61872de87387d8016d561a4ac7ca5e19c185 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
Bram Moolenaar14c01f82019-10-09 22:53:08 +020011 * userfunc.c: User defined function support
Bram Moolenaara9b579f2016-07-17 18:29:19 +020012 */
13
14#include "vim.h"
15
16#if defined(FEAT_EVAL) || defined(PROTO)
Bram Moolenaara9b579f2016-07-17 18:29:19 +020017/*
18 * All user-defined functions are found in this hashtable.
19 */
20static hashtab_T func_hashtab;
21
Bram Moolenaare38eab22019-12-05 21:50:01 +010022// Used by get_func_tv()
Bram Moolenaara9b579f2016-07-17 18:29:19 +020023static garray_T funcargs = GA_EMPTY;
24
Bram Moolenaar209b8e32019-03-14 13:43:24 +010025// pointer to funccal for currently active function
26static funccall_T *current_funccal = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +020027
Bram Moolenaar209b8e32019-03-14 13:43:24 +010028// Pointer to list of previously used funccal, still around because some
29// item in it is still being used.
30static funccall_T *previous_funccal = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +020031
Bram Moolenaarbc7ce672016-08-01 22:49:22 +020032static void funccal_unref(funccall_T *fc, ufunc_T *fp, int force);
Bram Moolenaar79efa2e2021-03-27 15:40:11 +010033static void func_clear(ufunc_T *fp, int force);
34static int func_free(ufunc_T *fp, int force);
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +010035static char_u *untrans_function_name(char_u *name);
Bram Moolenaar58779852022-09-06 18:31:14 +010036static void handle_defer_one(funccall_T *funccal);
Bram Moolenaara9b579f2016-07-17 18:29:19 +020037
38 void
Yegappan Lakshmanana23a11b2023-02-21 14:27:41 +000039func_init(void)
Bram Moolenaara9b579f2016-07-17 18:29:19 +020040{
41 hash_init(&func_hashtab);
42}
43
Bram Moolenaar4f0383b2016-07-19 22:43:11 +020044/*
Bram Moolenaar660a10a2019-07-14 15:48:38 +020045 * Return the function hash table
46 */
47 hashtab_T *
48func_tbl_get(void)
49{
50 return &func_hashtab;
51}
52
53/*
Bram Moolenaar6e949782020-04-13 17:21:00 +020054 * Get one function argument.
Bram Moolenaar51e7e782021-04-10 17:46:52 +020055 * If "argtypes" is not NULL also get the type: "arg: type" (:def function).
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +010056 * If "types_optional" is TRUE a missing type is OK, use "any".
Bram Moolenaar057e84a2021-02-28 16:55:11 +010057 * If "evalarg" is not NULL use it to check for an already declared name.
Bram Moolenaardce24412022-02-08 20:35:30 +000058 * If "eap" is not NULL use it to check for an already declared name.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010059 * Return a pointer to after the type.
60 * When something is wrong return "arg".
61 */
62 static char_u *
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +010063one_function_arg(
64 char_u *arg,
65 garray_T *newargs,
66 garray_T *argtypes,
67 int types_optional,
Bram Moolenaar057e84a2021-02-28 16:55:11 +010068 evalarg_T *evalarg,
Bram Moolenaardce24412022-02-08 20:35:30 +000069 exarg_T *eap,
Bram Moolenaar2a389082021-04-09 20:24:31 +020070 int is_vararg,
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +010071 int skip)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010072{
Bram Moolenaar6e949782020-04-13 17:21:00 +020073 char_u *p = arg;
74 char_u *arg_copy = NULL;
Bram Moolenaar51e7e782021-04-10 17:46:52 +020075 int is_underscore = FALSE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010076
77 while (ASCII_ISALNUM(*p) || *p == '_')
78 ++p;
79 if (arg == p || isdigit(*arg)
Bram Moolenaarb816dae2020-09-20 22:04:00 +020080 || (argtypes == NULL
81 && ((p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
82 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0))))
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010083 {
84 if (!skip)
Bram Moolenaarc553a212021-12-26 20:20:34 +000085 semsg(_(e_illegal_argument_str), arg);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010086 return arg;
87 }
Bram Moolenaarb4893b82021-02-21 22:20:24 +010088
Bram Moolenaarce723f32023-06-10 19:00:12 +010089 // Extra checks in Vim9 script.
90 if (!skip && argtypes != NULL)
91 {
92 int c = *p;
93 *p = NUL;
94 int r = check_reserved_name(arg, FALSE);
95 *p = c;
96 if (r == FAIL)
97 return arg;
98
99 // Cannot use script var name for argument. In function: also check
100 // local vars and arguments.
101 if (check_defined(arg, p - arg,
102 evalarg == NULL ? NULL : evalarg->eval_cctx,
Bram Moolenaardce24412022-02-08 20:35:30 +0000103 eap == NULL ? NULL : eap->cstack, TRUE) == FAIL)
Bram Moolenaarce723f32023-06-10 19:00:12 +0100104 return arg;
105 }
Bram Moolenaarb4893b82021-02-21 22:20:24 +0100106
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100107 if (newargs != NULL && ga_grow(newargs, 1) == FAIL)
108 return arg;
109 if (newargs != NULL)
110 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100111 int c;
112 int i;
113
114 c = *p;
115 *p = NUL;
116 arg_copy = vim_strsave(arg);
117 if (arg_copy == NULL)
118 {
119 *p = c;
120 return arg;
121 }
Bram Moolenaar51e7e782021-04-10 17:46:52 +0200122 is_underscore = arg_copy[0] == '_' && arg_copy[1] == NUL;
Bram Moolenaar87795932021-04-10 18:21:30 +0200123 if (argtypes == NULL || !is_underscore)
Bram Moolenaar51e7e782021-04-10 17:46:52 +0200124 // Check for duplicate argument name.
125 for (i = 0; i < newargs->ga_len; ++i)
126 if (STRCMP(((char_u **)(newargs->ga_data))[i], arg_copy) == 0)
127 {
Bram Moolenaar9d00e4a2022-01-05 17:49:15 +0000128 semsg(_(e_duplicate_argument_name_str), arg_copy);
Bram Moolenaar51e7e782021-04-10 17:46:52 +0200129 vim_free(arg_copy);
130 return arg;
131 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100132 ((char_u **)(newargs->ga_data))[newargs->ga_len] = arg_copy;
133 newargs->ga_len++;
134
135 *p = c;
136 }
137
138 // get any type from "arg: type"
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100139 if (argtypes != NULL && (skip || ga_grow(argtypes, 1) == OK))
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100140 {
141 char_u *type = NULL;
142
Bram Moolenaar6e949782020-04-13 17:21:00 +0200143 if (VIM_ISWHITE(*p) && *skipwhite(p) == ':')
144 {
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200145 semsg(_(e_no_white_space_allowed_before_colon_str),
Bram Moolenaar6e949782020-04-13 17:21:00 +0200146 arg_copy == NULL ? arg : arg_copy);
147 p = skipwhite(p);
148 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100149 if (*p == ':')
150 {
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200151 ++p;
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100152 if (!skip && !VIM_ISWHITE(*p))
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200153 {
Bram Moolenaarc3fc75d2021-02-07 15:28:09 +0100154 semsg(_(e_white_space_required_after_str_str), ":", p - 1);
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200155 return arg;
156 }
157 type = skipwhite(p);
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200158 p = skip_type(type, TRUE);
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100159 if (!skip)
160 type = vim_strnsave(type, p - type);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100161 }
Bram Moolenaar51e7e782021-04-10 17:46:52 +0200162 else if (*skipwhite(p) != '=' && !types_optional && !is_underscore)
Bram Moolenaar6e949782020-04-13 17:21:00 +0200163 {
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200164 semsg(_(e_missing_argument_type_for_str),
Bram Moolenaar6e949782020-04-13 17:21:00 +0200165 arg_copy == NULL ? arg : arg_copy);
166 return arg;
167 }
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100168 if (!skip)
169 {
170 if (type == NULL && types_optional)
171 // lambda arguments default to "any" type
Bram Moolenaar2a389082021-04-09 20:24:31 +0200172 type = vim_strsave((char_u *)
173 (is_vararg ? "list<any>" : "any"));
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100174 ((char_u **)argtypes->ga_data)[argtypes->ga_len++] = type;
175 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100176 }
177
178 return p;
179}
180
181/*
Bram Moolenaar7473a842021-12-28 17:55:26 +0000182 * Handle line continuation in function arguments or body.
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000183 * Get a next line, store it in "eap" if appropriate and put the line in
184 * "lines_to_free" to free the line later.
Bram Moolenaar7473a842021-12-28 17:55:26 +0000185 */
186 static char_u *
187get_function_line(
188 exarg_T *eap,
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000189 garray_T *lines_to_free,
Bram Moolenaar11ceb7d2021-12-28 20:49:56 +0000190 int indent,
191 getline_opt_T getline_options)
Bram Moolenaar7473a842021-12-28 17:55:26 +0000192{
193 char_u *theline;
194
195 if (eap->getline == NULL)
Bram Moolenaarc97f9a52021-12-28 20:59:56 +0000196 theline = getcmdline(':', 0L, indent, 0);
Bram Moolenaar7473a842021-12-28 17:55:26 +0000197 else
198 theline = eap->getline(':', eap->cookie, indent, getline_options);
199 if (theline != NULL)
200 {
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000201 if (lines_to_free->ga_len > 0
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000202 && eap->cmdlinep != NULL
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000203 && *eap->cmdlinep == ((char_u **)lines_to_free->ga_data)
204 [lines_to_free->ga_len - 1])
Bram Moolenaar7473a842021-12-28 17:55:26 +0000205 *eap->cmdlinep = theline;
Bram Moolenaarb5820102023-01-25 12:27:13 +0000206 (void)ga_add_string(lines_to_free, theline);
Bram Moolenaar7473a842021-12-28 17:55:26 +0000207 }
208
209 return theline;
210}
211
212/*
Bram Moolenaar4f0383b2016-07-19 22:43:11 +0200213 * Get function arguments.
Bram Moolenaarcef12702021-01-04 14:09:43 +0100214 * "argp" should point to just after the "(", possibly to white space.
Bram Moolenaar65c44152020-12-24 15:14:01 +0100215 * "argp" is advanced just after "endchar".
Bram Moolenaar4f0383b2016-07-19 22:43:11 +0200216 */
Bram Moolenaarcef12702021-01-04 14:09:43 +0100217 static int
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200218get_function_args(
219 char_u **argp,
220 char_u endchar,
221 garray_T *newargs,
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100222 garray_T *argtypes, // NULL unless using :def
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100223 int types_optional, // types optional if "argtypes" is not NULL
Bram Moolenaar057e84a2021-02-28 16:55:11 +0100224 evalarg_T *evalarg, // context or NULL
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200225 int *varargs,
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200226 garray_T *default_args,
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200227 int skip,
Bram Moolenaardce24412022-02-08 20:35:30 +0000228 exarg_T *eap, // can be NULL
Bram Moolenaar554d0312023-01-05 19:59:18 +0000229 int in_class, // non-zero when inside a class or interface
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000230 garray_T *newlines, // function body lines
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000231 garray_T *lines_to_free)
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200232{
233 int mustend = FALSE;
Bram Moolenaarcef12702021-01-04 14:09:43 +0100234 char_u *arg;
235 char_u *p;
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200236 int c;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200237 int any_default = FALSE;
Bram Moolenaarcef12702021-01-04 14:09:43 +0100238 char_u *whitep = *argp;
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200239
240 if (newargs != NULL)
Bram Moolenaar04935fb2022-01-08 16:19:22 +0000241 ga_init2(newargs, sizeof(char_u *), 3);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100242 if (argtypes != NULL)
Bram Moolenaar04935fb2022-01-08 16:19:22 +0000243 ga_init2(argtypes, sizeof(char_u *), 3);
Bram Moolenaare3ffaa62021-06-26 22:17:35 +0200244 if (!skip && default_args != NULL)
Bram Moolenaar04935fb2022-01-08 16:19:22 +0000245 ga_init2(default_args, sizeof(char_u *), 3);
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200246
247 if (varargs != NULL)
248 *varargs = FALSE;
249
250 /*
251 * Isolate the arguments: "arg1, arg2, ...)"
252 */
Bram Moolenaarcef12702021-01-04 14:09:43 +0100253 arg = skipwhite(*argp);
254 p = arg;
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200255 while (*p != endchar)
256 {
Bram Moolenaar2c330432020-04-13 14:41:35 +0200257 while (eap != NULL && eap->getline != NULL
258 && (*p == NUL || (VIM_ISWHITE(*whitep) && *p == '#')))
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200259 {
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200260 // End of the line, get the next one.
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000261 char_u *theline = get_function_line(eap, lines_to_free, 0,
Bram Moolenaar11ceb7d2021-12-28 20:49:56 +0000262 GETLINE_CONCAT_CONT);
Bram Moolenaar7473a842021-12-28 17:55:26 +0000263
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200264 if (theline == NULL)
265 break;
Bram Moolenaar2c330432020-04-13 14:41:35 +0200266 whitep = (char_u *)" ";
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200267 p = skipwhite(theline);
268 }
269
270 if (mustend && *p != endchar)
271 {
272 if (!skip)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000273 semsg(_(e_invalid_argument_str), *argp);
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100274 goto err_ret;
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200275 }
276 if (*p == endchar)
277 break;
278
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200279 if (p[0] == '.' && p[1] == '.' && p[2] == '.')
280 {
281 if (varargs != NULL)
282 *varargs = TRUE;
283 p += 3;
284 mustend = TRUE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100285
286 if (argtypes != NULL)
287 {
288 // ...name: list<type>
Bram Moolenaar28022722020-09-21 22:02:49 +0200289 if (!eval_isnamec1(*p))
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100290 {
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100291 if (!skip)
292 emsg(_(e_missing_name_after_dots));
293 goto err_ret;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100294 }
295
296 arg = p;
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100297 p = one_function_arg(p, newargs, argtypes, types_optional,
Bram Moolenaardce24412022-02-08 20:35:30 +0000298 evalarg, eap, TRUE, skip);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100299 if (p == arg)
300 break;
Bram Moolenaar4f53b792021-02-07 15:59:49 +0100301 if (*skipwhite(p) == '=')
302 {
303 emsg(_(e_cannot_use_default_for_variable_arguments));
304 break;
305 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100306 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200307 }
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000308 else if (in_class && STRNCMP(p, "this.", 5) == 0)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000309 {
310 // this.memberName
311 p += 5;
312 arg = p;
313 while (ASCII_ISALNUM(*p) || *p == '_')
314 ++p;
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000315 char_u *argend = p;
316
317 if (*skipwhite(p) == '=')
318 {
319 char_u *defval = skipwhite(skipwhite(p) + 1);
320 if (STRNCMP(defval, "v:none", 6) != 0)
321 {
322 semsg(_(e_constructor_default_value_must_be_vnone_str), p);
323 goto err_ret;
324 }
325 any_default = TRUE;
326 p = defval + 6;
327
328 if (ga_grow(default_args, 1) == FAIL)
329 goto err_ret;
330
331 char_u *expr = vim_strsave((char_u *)"v:none");
332 if (expr == NULL)
333 goto err_ret;
334 ((char_u **)(default_args->ga_data))
335 [default_args->ga_len] = expr;
336 default_args->ga_len++;
337 }
338 else if (any_default)
339 {
340 emsg(_(e_non_default_argument_follows_default_argument));
341 goto err_ret;
342 }
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000343
344 // TODO: check the argument is indeed a member
345 if (newargs != NULL && ga_grow(newargs, 1) == FAIL)
346 return FAIL;
347 if (newargs != NULL)
348 {
349 ((char_u **)(newargs->ga_data))[newargs->ga_len] =
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000350 vim_strnsave(arg, argend - arg);
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000351 newargs->ga_len++;
352
353 if (argtypes != NULL && ga_grow(argtypes, 1) == OK)
354 {
355 // TODO: use the actual type
356 ((char_u **)argtypes->ga_data)[argtypes->ga_len++] =
357 vim_strsave((char_u *)"any");
358
359 // Add a line to the function body for the assignment.
360 if (ga_grow(newlines, 1) == OK)
361 {
362 // "this.name = name"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000363 int len = 5 + (argend - arg) + 3 + (argend - arg) + 1;
364 if (any_default)
365 len += 14 + 10;
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000366 char_u *assignment = alloc(len);
367 if (assignment != NULL)
368 {
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000369 c = *argend;
370 *argend = NUL;
371 if (any_default)
372 vim_snprintf((char *)assignment, len,
373 "ifargisset %d this.%s = %s",
374 default_args->ga_len - 1, arg, arg);
375 else
376 vim_snprintf((char *)assignment, len,
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000377 "this.%s = %s", arg, arg);
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000378 *argend = c;
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000379 ((char_u **)(newlines->ga_data))[
380 newlines->ga_len++] = assignment;
381 }
382 }
383 }
384 }
385 if (*p == ',')
386 ++p;
387 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200388 else
389 {
Bram Moolenaar015cf102021-06-26 21:52:02 +0200390 char_u *np;
391
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200392 arg = p;
Bram Moolenaar057e84a2021-02-28 16:55:11 +0100393 p = one_function_arg(p, newargs, argtypes, types_optional,
Bram Moolenaardce24412022-02-08 20:35:30 +0000394 evalarg, eap, FALSE, skip);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100395 if (p == arg)
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200396 break;
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200397
Bram Moolenaar015cf102021-06-26 21:52:02 +0200398 // Recognize " = expr" but not " == expr". A lambda can have
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +0200399 // "(a = expr" but "(a == expr" and "(a =~ expr" are not a lambda.
Bram Moolenaar015cf102021-06-26 21:52:02 +0200400 np = skipwhite(p);
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +0200401 if (*np == '=' && np[1] != '=' && np[1] != '~'
402 && default_args != NULL)
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200403 {
404 typval_T rettv;
405
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100406 // find the end of the expression (doesn't evaluate it)
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200407 any_default = TRUE;
Bram Moolenaareb5adf12022-09-04 13:41:37 +0100408 p = skipwhite(np + 1);
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000409 char_u *expr = p;
Bram Moolenaar5409f5d2020-06-24 18:37:35 +0200410 if (eval1(&p, &rettv, NULL) != FAIL)
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200411 {
Bram Moolenaare3ffaa62021-06-26 22:17:35 +0200412 if (!skip)
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200413 {
Bram Moolenaare3ffaa62021-06-26 22:17:35 +0200414 if (ga_grow(default_args, 1) == FAIL)
415 goto err_ret;
416
417 // trim trailing whitespace
418 while (p > expr && VIM_ISWHITE(p[-1]))
419 p--;
420 c = *p;
421 *p = NUL;
422 expr = vim_strsave(expr);
423 if (expr == NULL)
424 {
425 *p = c;
426 goto err_ret;
427 }
428 ((char_u **)(default_args->ga_data))
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200429 [default_args->ga_len] = expr;
Bram Moolenaare3ffaa62021-06-26 22:17:35 +0200430 default_args->ga_len++;
431 *p = c;
432 }
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200433 }
434 else
435 mustend = TRUE;
436 }
437 else if (any_default)
438 {
Bram Moolenaard82a47d2022-01-05 20:24:39 +0000439 emsg(_(e_non_default_argument_follows_default_argument));
Bram Moolenaar914e7ea2020-07-11 15:20:48 +0200440 goto err_ret;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200441 }
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +0200442
443 if (VIM_ISWHITE(*p) && *skipwhite(p) == ',')
444 {
445 // Be tolerant when skipping
446 if (!skip)
447 {
448 semsg(_(e_no_white_space_allowed_before_str_str), ",", p);
449 goto err_ret;
450 }
451 p = skipwhite(p);
452 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200453 if (*p == ',')
Bram Moolenaar914e7ea2020-07-11 15:20:48 +0200454 {
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200455 ++p;
Bram Moolenaar914e7ea2020-07-11 15:20:48 +0200456 // Don't give this error when skipping, it makes the "->" not
457 // found in "{k,v -> x}" and give a confusing error.
Bram Moolenaar608d78f2021-03-06 22:33:12 +0100458 // Allow missing space after comma in legacy functions.
459 if (!skip && argtypes != NULL
Bram Moolenaar914e7ea2020-07-11 15:20:48 +0200460 && !IS_WHITE_OR_NUL(*p) && *p != endchar)
461 {
Bram Moolenaarc3fc75d2021-02-07 15:28:09 +0100462 semsg(_(e_white_space_required_after_str_str), ",", p - 1);
Bram Moolenaar914e7ea2020-07-11 15:20:48 +0200463 goto err_ret;
464 }
465 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200466 else
467 mustend = TRUE;
468 }
Bram Moolenaar2c330432020-04-13 14:41:35 +0200469 whitep = p;
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200470 p = skipwhite(p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200471 }
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200472
Bram Moolenaar4f0383b2016-07-19 22:43:11 +0200473 if (*p != endchar)
474 goto err_ret;
Bram Moolenaare38eab22019-12-05 21:50:01 +0100475 ++p; // skip "endchar"
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200476
477 *argp = p;
478 return OK;
479
480err_ret:
481 if (newargs != NULL)
482 ga_clear_strings(newargs);
Bram Moolenaare3ffaa62021-06-26 22:17:35 +0200483 if (!skip && default_args != NULL)
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200484 ga_clear_strings(default_args);
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200485 return FAIL;
486}
487
488/*
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100489 * Parse the argument types, filling "fp->uf_arg_types".
490 * Return OK or FAIL.
491 */
492 static int
493parse_argument_types(ufunc_T *fp, garray_T *argtypes, int varargs)
494{
Bram Moolenaar2a389082021-04-09 20:24:31 +0200495 int len = 0;
496
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100497 ga_init2(&fp->uf_type_list, sizeof(type_T *), 10);
498 if (argtypes->ga_len > 0)
499 {
500 // When "varargs" is set the last name/type goes into uf_va_name
501 // and uf_va_type.
Bram Moolenaar2a389082021-04-09 20:24:31 +0200502 len = argtypes->ga_len - (varargs ? 1 : 0);
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100503
504 if (len > 0)
505 fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len);
506 if (fp->uf_arg_types != NULL)
507 {
508 int i;
509 type_T *type;
510
511 for (i = 0; i < len; ++ i)
512 {
513 char_u *p = ((char_u **)argtypes->ga_data)[i];
514
515 if (p == NULL)
516 // will get the type from the default value
517 type = &t_unknown;
518 else
Bram Moolenaar9e68c322020-12-25 12:38:04 +0100519 type = parse_type(&p, &fp->uf_type_list, TRUE);
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100520 if (type == NULL)
521 return FAIL;
522 fp->uf_arg_types[i] = type;
Bram Moolenaar1d9cef72022-03-17 16:30:03 +0000523 if (i < fp->uf_args.ga_len
524 && (type->tt_type == VAR_FUNC
525 || type->tt_type == VAR_PARTIAL)
526 && var_wrong_func_name(
527 ((char_u **)fp->uf_args.ga_data)[i], TRUE))
528 return FAIL;
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100529 }
530 }
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100531 }
Bram Moolenaar2a389082021-04-09 20:24:31 +0200532
533 if (varargs)
534 {
535 char_u *p;
536
537 // Move the last argument "...name: type" to uf_va_name and
538 // uf_va_type.
Bram Moolenaar2a389082021-04-09 20:24:31 +0200539 --fp->uf_args.ga_len;
Bram Moolenaarf0571712023-01-04 13:16:20 +0000540 fp->uf_va_name = ((char_u **)fp->uf_args.ga_data)[fp->uf_args.ga_len];
541 ((char_u **)fp->uf_args.ga_data)[fp->uf_args.ga_len] = NULL;
Bram Moolenaar2a389082021-04-09 20:24:31 +0200542 p = ((char_u **)argtypes->ga_data)[len];
543 if (p == NULL)
544 // TODO: get type from default value
545 fp->uf_va_type = &t_list_any;
546 else
547 {
548 fp->uf_va_type = parse_type(&p, &fp->uf_type_list, TRUE);
549 if (fp->uf_va_type != NULL && fp->uf_va_type->tt_type != VAR_LIST)
550 {
551 semsg(_(e_variable_arguments_type_must_be_list_str),
552 ((char_u **)argtypes->ga_data)[len]);
553 return FAIL;
554 }
555 }
556 if (fp->uf_va_type == NULL)
557 return FAIL;
558 }
559
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100560 return OK;
561}
562
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100563 static int
564parse_return_type(ufunc_T *fp, char_u *ret_type)
565{
566 if (ret_type == NULL)
567 fp->uf_ret_type = &t_void;
568 else
569 {
570 char_u *p = ret_type;
571
572 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list, TRUE);
573 if (fp->uf_ret_type == NULL)
574 {
575 fp->uf_ret_type = &t_void;
576 return FAIL;
577 }
578 }
579 return OK;
580}
581
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100582/*
Bram Moolenaar58016442016-07-31 18:30:22 +0200583 * Register function "fp" as using "current_funccal" as its scope.
584 */
585 static int
586register_closure(ufunc_T *fp)
587{
Bram Moolenaar8dd3a432016-08-01 20:46:25 +0200588 if (fp->uf_scoped == current_funccal)
Bram Moolenaare38eab22019-12-05 21:50:01 +0100589 // no change
Bram Moolenaar8dd3a432016-08-01 20:46:25 +0200590 return OK;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +0200591 funccal_unref(fp->uf_scoped, fp, FALSE);
Bram Moolenaar58016442016-07-31 18:30:22 +0200592 fp->uf_scoped = current_funccal;
593 current_funccal->fc_refcount++;
Bram Moolenaar8dd3a432016-08-01 20:46:25 +0200594
Bram Moolenaarca16c602022-09-06 18:57:08 +0100595 if (ga_grow(&current_funccal->fc_ufuncs, 1) == FAIL)
Bram Moolenaar58016442016-07-31 18:30:22 +0200596 return FAIL;
Bram Moolenaarca16c602022-09-06 18:57:08 +0100597 ((ufunc_T **)current_funccal->fc_ufuncs.ga_data)
598 [current_funccal->fc_ufuncs.ga_len++] = fp;
Bram Moolenaar58016442016-07-31 18:30:22 +0200599 return OK;
600}
601
Bram Moolenaar1a47ae32019-12-29 23:04:25 +0100602 static void
603set_ufunc_name(ufunc_T *fp, char_u *name)
604{
Bram Moolenaar7b6903f2021-02-03 19:31:29 +0100605 // Add a type cast to avoid a warning for an overflow, the uf_name[] array
606 // actually extends beyond the struct.
607 STRCPY((void *)fp->uf_name, name);
Bram Moolenaar1a47ae32019-12-29 23:04:25 +0100608
609 if (name[0] == K_SPECIAL)
610 {
611 fp->uf_name_exp = alloc(STRLEN(name) + 3);
612 if (fp->uf_name_exp != NULL)
613 {
614 STRCPY(fp->uf_name_exp, "<SNR>");
615 STRCAT(fp->uf_name_exp, fp->uf_name + 3);
616 }
617 }
618}
619
Bram Moolenaar58016442016-07-31 18:30:22 +0200620/*
Bram Moolenaara6c18d32022-03-31 20:02:56 +0100621 * If "name" starts with K_SPECIAL and "buf[bufsize]" is big enough
622 * return "buf" filled with a readable function name.
623 * Otherwise just return "name", thus the return value can always be used.
624 * "name" and "buf" may be equal.
625 */
626 char_u *
627make_ufunc_name_readable(char_u *name, char_u *buf, size_t bufsize)
628{
629 size_t len;
630
631 if (name[0] != K_SPECIAL)
632 return name;
633 len = STRLEN(name);
634 if (len + 3 > bufsize)
635 return name;
636
Bram Moolenaar96e08e02022-03-31 21:40:33 +0100637 mch_memmove(buf + 5, name + 3, len - 2); // Include trailing NUL
Bram Moolenaara6c18d32022-03-31 20:02:56 +0100638 mch_memmove(buf, "<SNR>", 5);
639 return buf;
640}
641
642/*
Bram Moolenaar04b12692020-05-04 23:24:44 +0200643 * Get a name for a lambda. Returned in static memory.
644 */
645 char_u *
646get_lambda_name(void)
647{
648 static char_u name[30];
649 static int lambda_no = 0;
650
651 sprintf((char*)name, "<lambda>%d", ++lambda_no);
652 return name;
653}
654
Bram Moolenaare01e5212023-01-08 20:31:18 +0000655/*
656 * Allocate a "ufunc_T" for a function called "name".
657 * Makes sure the size is right.
658 */
659 static ufunc_T *
660alloc_ufunc(char_u *name)
661{
662 // When the name is short we need to make sure we allocate enough bytes for
663 // the whole struct, including any padding.
664 size_t len = offsetof(ufunc_T, uf_name) + STRLEN(name) + 1;
665 return alloc_clear(len < sizeof(ufunc_T) ? sizeof(ufunc_T) : len);
666}
667
Bram Moolenaar801ab062020-06-25 19:27:56 +0200668#if defined(FEAT_LUA) || defined(PROTO)
669/*
670 * Registers a native C callback which can be called from Vim script.
671 * Returns the name of the Vim script function.
672 */
673 char_u *
674register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state)
675{
676 char_u *name = get_lambda_name();
Bram Moolenaar7d2ac922020-06-29 20:20:33 +0200677 ufunc_T *fp;
Bram Moolenaar801ab062020-06-25 19:27:56 +0200678
Bram Moolenaare01e5212023-01-08 20:31:18 +0000679 fp = alloc_ufunc(name);
Bram Moolenaar801ab062020-06-25 19:27:56 +0200680 if (fp == NULL)
Bram Moolenaar7d2ac922020-06-29 20:20:33 +0200681 return NULL;
Bram Moolenaar801ab062020-06-25 19:27:56 +0200682
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200683 fp->uf_def_status = UF_NOT_COMPILED;
Bram Moolenaar801ab062020-06-25 19:27:56 +0200684 fp->uf_refcount = 1;
685 fp->uf_varargs = TRUE;
Bram Moolenaar38453522021-11-28 22:00:12 +0000686 fp->uf_flags = FC_CFUNC | FC_LAMBDA;
Bram Moolenaar801ab062020-06-25 19:27:56 +0200687 fp->uf_calls = 0;
688 fp->uf_script_ctx = current_sctx;
Bram Moolenaar801ab062020-06-25 19:27:56 +0200689 fp->uf_cb = cb;
690 fp->uf_cb_free = cb_free;
691 fp->uf_cb_state = state;
692
693 set_ufunc_name(fp, name);
Bram Moolenaaref2c3252022-11-25 16:31:51 +0000694 hash_add(&func_hashtab, UF2HIKEY(fp), "add C function");
Bram Moolenaar801ab062020-06-25 19:27:56 +0200695
696 return name;
Bram Moolenaar801ab062020-06-25 19:27:56 +0200697}
698#endif
699
Bram Moolenaar04b12692020-05-04 23:24:44 +0200700/*
Bram Moolenaar65c44152020-12-24 15:14:01 +0100701 * Skip over "->" or "=>" after the arguments of a lambda.
Bram Moolenaar9e68c322020-12-25 12:38:04 +0100702 * If ": type" is found make "ret_type" point to "type".
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100703 * If "white_error" is not NULL check for correct use of white space and set
704 * "white_error" to TRUE if there is an error.
Bram Moolenaar65c44152020-12-24 15:14:01 +0100705 * Return NULL if no valid arrow found.
706 */
707 static char_u *
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100708skip_arrow(
709 char_u *start,
710 int equal_arrow,
711 char_u **ret_type,
712 int *white_error)
Bram Moolenaar65c44152020-12-24 15:14:01 +0100713{
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100714 char_u *s = start;
715 char_u *bef = start - 2; // "start" points to > of ->
Bram Moolenaar65c44152020-12-24 15:14:01 +0100716
717 if (equal_arrow)
718 {
719 if (*s == ':')
Bram Moolenaar9e68c322020-12-25 12:38:04 +0100720 {
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100721 if (white_error != NULL && !VIM_ISWHITE(s[1]))
722 {
723 *white_error = TRUE;
Bram Moolenaarc3fc75d2021-02-07 15:28:09 +0100724 semsg(_(e_white_space_required_after_str_str), ":", s);
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100725 return NULL;
726 }
Bram Moolenaar9e68c322020-12-25 12:38:04 +0100727 s = skipwhite(s + 1);
728 *ret_type = s;
729 s = skip_type(s, TRUE);
Bram Moolenaar0346b792021-01-31 22:18:29 +0100730 if (s == *ret_type)
731 {
732 emsg(_(e_missing_return_type));
733 return NULL;
734 }
Bram Moolenaar9e68c322020-12-25 12:38:04 +0100735 }
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100736 bef = s;
Bram Moolenaar65c44152020-12-24 15:14:01 +0100737 s = skipwhite(s);
738 if (*s != '=')
739 return NULL;
740 ++s;
741 }
742 if (*s != '>')
743 return NULL;
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100744 if (white_error != NULL && ((!VIM_ISWHITE(*bef) && *bef != '{')
745 || !IS_WHITE_OR_NUL(s[1])))
746 {
747 *white_error = TRUE;
Bram Moolenaare7a73e02021-01-01 19:17:55 +0100748 semsg(_(e_white_space_required_before_and_after_str_at_str),
749 equal_arrow ? "=>" : "->", bef);
Bram Moolenaarc754b4c2020-12-25 15:24:23 +0100750 return NULL;
751 }
Bram Moolenaar65c44152020-12-24 15:14:01 +0100752 return skipwhite(s + 1);
753}
754
755/*
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100756 * Check if "*cmd" points to a function command and if so advance "*cmd" and
757 * return TRUE.
758 * Otherwise return FALSE;
759 * Do not consider "function(" to be a command.
760 */
761 static int
762is_function_cmd(char_u **cmd)
763{
764 char_u *p = *cmd;
765
766 if (checkforcmd(&p, "function", 2))
767 {
768 if (*p == '(')
769 return FALSE;
770 *cmd = p;
771 return TRUE;
772 }
773 return FALSE;
774}
775
776/*
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +0200777 * Called when defining a function: The context may be needed for script
778 * variables declared in a block that is visible now but not when the function
779 * is compiled or called later.
780 */
781 static void
782function_using_block_scopes(ufunc_T *fp, cstack_T *cstack)
783{
Yegappan Lakshmanan142ed772023-01-26 12:00:00 +0000784 if (cstack == NULL || cstack->cs_idx < 0)
785 return;
786
787 int count = cstack->cs_idx + 1;
788 int i;
789
790 fp->uf_block_ids = ALLOC_MULT(int, count);
791 if (fp->uf_block_ids != NULL)
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +0200792 {
Yegappan Lakshmanan142ed772023-01-26 12:00:00 +0000793 mch_memmove(fp->uf_block_ids, cstack->cs_block_id,
794 sizeof(int) * count);
795 fp->uf_block_depth = count;
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +0200796 }
Yegappan Lakshmanan142ed772023-01-26 12:00:00 +0000797
798 // Set flag in each block to indicate a function was defined. This
799 // is used to keep the variable when leaving the block, see
800 // hide_script_var().
801 for (i = 0; i <= cstack->cs_idx; ++i)
802 cstack->cs_flags[i] |= CSF_FUNC_DEF;
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +0200803}
804
805/*
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100806 * Read the body of a function, put every line in "newlines".
Bram Moolenaar074f84c2021-05-18 11:47:44 +0200807 * This stops at "}", "endfunction" or "enddef".
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100808 * "newlines" must already have been initialized.
809 * "eap->cmdidx" is CMD_function, CMD_def or CMD_block;
810 */
811 static int
812get_function_body(
813 exarg_T *eap,
814 garray_T *newlines,
815 char_u *line_arg_in,
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000816 garray_T *lines_to_free)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100817{
818 linenr_T sourcing_lnum_top = SOURCING_LNUM;
819 linenr_T sourcing_lnum_off;
820 int saved_wait_return = need_wait_return;
821 char_u *line_arg = line_arg_in;
822 int vim9_function = eap->cmdidx == CMD_def
823 || eap->cmdidx == CMD_block;
824#define MAX_FUNC_NESTING 50
825 char nesting_def[MAX_FUNC_NESTING];
Bram Moolenaar5245beb2021-07-15 22:03:50 +0200826 char nesting_inline[MAX_FUNC_NESTING];
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100827 int nesting = 0;
828 getline_opt_T getline_options;
829 int indent = 2;
830 char_u *skip_until = NULL;
831 int ret = FAIL;
832 int is_heredoc = FALSE;
Bram Moolenaar20677332021-06-06 17:02:53 +0200833 int heredoc_concat_len = 0;
834 garray_T heredoc_ga;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100835 char_u *heredoc_trimmed = NULL;
836
Bram Moolenaar20677332021-06-06 17:02:53 +0200837 ga_init2(&heredoc_ga, 1, 500);
838
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100839 // Detect having skipped over comment lines to find the return
840 // type. Add NULL lines to keep the line count correct.
841 sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
842 if (SOURCING_LNUM < sourcing_lnum_off)
843 {
844 sourcing_lnum_off -= SOURCING_LNUM;
845 if (ga_grow(newlines, sourcing_lnum_off) == FAIL)
846 goto theend;
847 while (sourcing_lnum_off-- > 0)
848 ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL;
849 }
850
Bram Moolenaar5245beb2021-07-15 22:03:50 +0200851 nesting_def[0] = vim9_function;
852 nesting_inline[0] = eap->cmdidx == CMD_block;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100853 getline_options = vim9_function
854 ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT;
855 for (;;)
856 {
857 char_u *theline;
858 char_u *p;
859 char_u *arg;
860
861 if (KeyTyped)
862 {
863 msg_scroll = TRUE;
864 saved_wait_return = FALSE;
865 }
866 need_wait_return = FALSE;
867
868 if (line_arg != NULL)
869 {
870 // Use eap->arg, split up in parts by line breaks.
871 theline = line_arg;
872 p = vim_strchr(theline, '\n');
873 if (p == NULL)
874 line_arg += STRLEN(line_arg);
875 else
876 {
877 *p = NUL;
878 line_arg = p + 1;
879 }
880 }
881 else
882 {
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000883 theline = get_function_line(eap, lines_to_free, indent,
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100884 getline_options);
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100885 }
886 if (KeyTyped)
887 lines_left = Rows - 1;
888 if (theline == NULL)
889 {
890 // Use the start of the function for the line number.
891 SOURCING_LNUM = sourcing_lnum_top;
892 if (skip_until != NULL)
893 semsg(_(e_missing_heredoc_end_marker_str), skip_until);
Bram Moolenaar5245beb2021-07-15 22:03:50 +0200894 else if (nesting_inline[nesting])
895 emsg(_(e_missing_end_block));
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100896 else if (eap->cmdidx == CMD_def)
897 emsg(_(e_missing_enddef));
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100898 else
Bram Moolenaarc553a212021-12-26 20:20:34 +0000899 emsg(_(e_missing_endfunction));
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100900 goto theend;
901 }
902
903 // Detect line continuation: SOURCING_LNUM increased more than one.
904 sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
905 if (SOURCING_LNUM < sourcing_lnum_off)
906 sourcing_lnum_off -= SOURCING_LNUM;
907 else
908 sourcing_lnum_off = 0;
909
910 if (skip_until != NULL)
911 {
912 // Don't check for ":endfunc"/":enddef" between
913 // * ":append" and "."
914 // * ":python <<EOF" and "EOF"
915 // * ":let {var-name} =<< [trim] {marker}" and "{marker}"
916 if (heredoc_trimmed == NULL
917 || (is_heredoc && skipwhite(theline) == theline)
918 || STRNCMP(theline, heredoc_trimmed,
919 STRLEN(heredoc_trimmed)) == 0)
920 {
921 if (heredoc_trimmed == NULL)
922 p = theline;
923 else if (is_heredoc)
924 p = skipwhite(theline) == theline
925 ? theline : theline + STRLEN(heredoc_trimmed);
926 else
927 p = theline + STRLEN(heredoc_trimmed);
928 if (STRCMP(p, skip_until) == 0)
929 {
930 VIM_CLEAR(skip_until);
931 VIM_CLEAR(heredoc_trimmed);
932 getline_options = vim9_function
933 ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT;
934 is_heredoc = FALSE;
Bram Moolenaar20677332021-06-06 17:02:53 +0200935
936 if (heredoc_concat_len > 0)
937 {
938 // Replace the starting line with all the concatenated
939 // lines.
940 ga_concat(&heredoc_ga, theline);
941 vim_free(((char_u **)(newlines->ga_data))[
942 heredoc_concat_len - 1]);
943 ((char_u **)(newlines->ga_data))[
944 heredoc_concat_len - 1] = heredoc_ga.ga_data;
945 ga_init(&heredoc_ga);
946 heredoc_concat_len = 0;
947 theline += STRLEN(theline); // skip the "EOF"
948 }
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100949 }
950 }
951 }
952 else
953 {
Bram Moolenaar5245beb2021-07-15 22:03:50 +0200954 int c;
955 char_u *end;
Bram Moolenaarb2175222022-03-05 20:24:41 +0000956 char_u *cmd;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100957
958 // skip ':' and blanks
959 for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p)
960 ;
961
962 // Check for "endfunction", "enddef" or "}".
963 // When a ":" follows it must be a dict key; "enddef: value,"
Bram Moolenaarb2175222022-03-05 20:24:41 +0000964 cmd = p;
Bram Moolenaar5245beb2021-07-15 22:03:50 +0200965 if (nesting_inline[nesting]
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100966 ? *p == '}'
967 : (checkforcmd(&p, nesting_def[nesting]
968 ? "enddef" : "endfunction", 4)
969 && *p != ':'))
970 {
Bram Moolenaarb2175222022-03-05 20:24:41 +0000971 if (!nesting_inline[nesting] && nesting_def[nesting]
972 && p < cmd + 6)
973 semsg(_(e_command_cannot_be_shortened_str), "enddef");
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100974 if (nesting-- == 0)
975 {
976 char_u *nextcmd = NULL;
977
978 if (*p == '|' || *p == '}')
979 nextcmd = p + 1;
980 else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
981 nextcmd = line_arg;
982 else if (*p != NUL && *p != (vim9_function ? '#' : '"')
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100983 && (vim9_function || p_verbose > 0))
984 {
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200985 SOURCING_LNUM = sourcing_lnum_top
986 + newlines->ga_len + 1;
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100987 if (eap->cmdidx == CMD_def)
Bram Moolenaar7473a842021-12-28 17:55:26 +0000988 semsg(_(e_text_found_after_str_str), "enddef", p);
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100989 else
990 give_warning2((char_u *)
991 _("W22: Text found after :endfunction: %s"),
992 p, TRUE);
993 }
994 if (nextcmd != NULL && *skipwhite(nextcmd) != NUL)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +0100995 {
996 // Another command follows. If the line came from "eap"
997 // we can simply point into it, otherwise we need to
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +0000998 // change "eap->cmdlinep" to point to the last fetched
999 // line.
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001000 eap->nextcmd = nextcmd;
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00001001 if (lines_to_free->ga_len > 0
1002 && *eap->cmdlinep !=
1003 ((char_u **)lines_to_free->ga_data)
1004 [lines_to_free->ga_len - 1])
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001005 {
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00001006 // *cmdlinep will be freed later, thus remove the
1007 // line from lines_to_free.
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001008 vim_free(*eap->cmdlinep);
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00001009 *eap->cmdlinep = ((char_u **)lines_to_free->ga_data)
1010 [lines_to_free->ga_len - 1];
1011 --lines_to_free->ga_len;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001012 }
1013 }
1014 break;
1015 }
1016 }
1017
1018 // Check for mismatched "endfunc" or "enddef".
1019 // We don't check for "def" inside "func" thus we also can't check
1020 // for "enddef".
1021 // We continue to find the end of the function, although we might
1022 // not find it.
1023 else if (nesting_def[nesting])
1024 {
1025 if (checkforcmd(&p, "endfunction", 4) && *p != ':')
1026 emsg(_(e_mismatched_endfunction));
1027 }
1028 else if (eap->cmdidx == CMD_def && checkforcmd(&p, "enddef", 4))
1029 emsg(_(e_mismatched_enddef));
1030
1031 // Increase indent inside "if", "while", "for" and "try", decrease
1032 // at "end".
1033 if (indent > 2 && (*p == '}' || STRNCMP(p, "end", 3) == 0))
1034 indent -= 2;
1035 else if (STRNCMP(p, "if", 2) == 0
1036 || STRNCMP(p, "wh", 2) == 0
1037 || STRNCMP(p, "for", 3) == 0
1038 || STRNCMP(p, "try", 3) == 0)
1039 indent += 2;
1040
1041 // Check for defining a function inside this function.
1042 // Only recognize "def" inside "def", not inside "function",
1043 // For backwards compatibility, see Test_function_python().
1044 c = *p;
1045 if (is_function_cmd(&p)
1046 || (eap->cmdidx == CMD_def && checkforcmd(&p, "def", 3)))
1047 {
1048 if (*p == '!')
1049 p = skipwhite(p + 1);
1050 p += eval_fname_script(p);
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001051 vim_free(trans_function_name(&p, NULL, TRUE, 0));
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001052 if (*skipwhite(p) == '(')
1053 {
1054 if (nesting == MAX_FUNC_NESTING - 1)
1055 emsg(_(e_function_nesting_too_deep));
1056 else
1057 {
1058 ++nesting;
1059 nesting_def[nesting] = (c == 'd');
Bram Moolenaar5245beb2021-07-15 22:03:50 +02001060 nesting_inline[nesting] = FALSE;
1061 indent += 2;
1062 }
1063 }
1064 }
1065
Bram Moolenaarac2cd2b2021-07-19 21:04:23 +02001066 if (nesting_def[nesting] ? *p != '#' : *p != '"')
Bram Moolenaar5245beb2021-07-15 22:03:50 +02001067 {
Bram Moolenaarac2cd2b2021-07-19 21:04:23 +02001068 // Not a comment line: check for nested inline function.
1069 end = p + STRLEN(p) - 1;
Bram Moolenaar5245beb2021-07-15 22:03:50 +02001070 while (end > p && VIM_ISWHITE(*end))
1071 --end;
Bram Moolenaar13212572021-08-01 22:01:30 +02001072 if (end > p + 1 && *end == '{' && VIM_ISWHITE(end[-1]))
Bram Moolenaar5245beb2021-07-15 22:03:50 +02001073 {
Bram Moolenaare4db17f2021-08-01 21:19:43 +02001074 int is_block;
1075
1076 // check for trailing "=> {": start of an inline function
Bram Moolenaarac2cd2b2021-07-19 21:04:23 +02001077 --end;
1078 while (end > p && VIM_ISWHITE(*end))
1079 --end;
Bram Moolenaare4db17f2021-08-01 21:19:43 +02001080 is_block = end > p + 2 && end[-1] == '=' && end[0] == '>';
1081 if (!is_block)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02001082 {
Bram Moolenaare4db17f2021-08-01 21:19:43 +02001083 char_u *s = p;
1084
1085 // check for line starting with "au" for :autocmd or
1086 // "com" for :command, these can use a {} block
1087 is_block = checkforcmd_noparen(&s, "autocmd", 2)
1088 || checkforcmd_noparen(&s, "command", 3);
1089 }
1090
1091 if (is_block)
1092 {
Bram Moolenaarac2cd2b2021-07-19 21:04:23 +02001093 if (nesting == MAX_FUNC_NESTING - 1)
1094 emsg(_(e_function_nesting_too_deep));
1095 else
1096 {
1097 ++nesting;
1098 nesting_def[nesting] = TRUE;
1099 nesting_inline[nesting] = TRUE;
1100 indent += 2;
1101 }
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001102 }
1103 }
1104 }
1105
1106 // Check for ":append", ":change", ":insert". Not for :def.
1107 p = skip_range(p, FALSE, NULL);
1108 if (!vim9_function
1109 && ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
1110 || (p[0] == 'c'
1111 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'h'
1112 && (!ASCII_ISALPHA(p[2]) || (p[2] == 'a'
1113 && (STRNCMP(&p[3], "nge", 3) != 0
1114 || !ASCII_ISALPHA(p[6])))))))
1115 || (p[0] == 'i'
1116 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
1117 && (!ASCII_ISALPHA(p[2])
1118 || (p[2] == 's'
1119 && (!ASCII_ISALPHA(p[3])
1120 || p[3] == 'e'))))))))
1121 skip_until = vim_strsave((char_u *)".");
1122
1123 // Check for ":python <<EOF", ":tcl <<EOF", etc.
1124 arg = skipwhite(skiptowhite(p));
1125 if (arg[0] == '<' && arg[1] =='<'
1126 && ((p[0] == 'p' && p[1] == 'y'
1127 && (!ASCII_ISALNUM(p[2]) || p[2] == 't'
1128 || ((p[2] == '3' || p[2] == 'x')
1129 && !ASCII_ISALPHA(p[3]))))
1130 || (p[0] == 'p' && p[1] == 'e'
1131 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
1132 || (p[0] == 't' && p[1] == 'c'
1133 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
1134 || (p[0] == 'l' && p[1] == 'u' && p[2] == 'a'
1135 && !ASCII_ISALPHA(p[3]))
1136 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
1137 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
1138 || (p[0] == 'm' && p[1] == 'z'
1139 && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
1140 ))
1141 {
1142 // ":python <<" continues until a dot, like ":append"
1143 p = skipwhite(arg + 2);
1144 if (STRNCMP(p, "trim", 4) == 0)
1145 {
1146 // Ignore leading white space.
1147 p = skipwhite(p + 4);
1148 heredoc_trimmed = vim_strnsave(theline,
1149 skipwhite(theline) - theline);
1150 }
1151 if (*p == NUL)
1152 skip_until = vim_strsave((char_u *)".");
1153 else
1154 skip_until = vim_strnsave(p, skiptowhite(p) - p);
1155 getline_options = GETLINE_NONE;
1156 is_heredoc = TRUE;
zeertzjqa93d9cd2023-05-02 16:25:47 +01001157 if (vim9_function && nesting == 0)
Bram Moolenaar20677332021-06-06 17:02:53 +02001158 heredoc_concat_len = newlines->ga_len + 1;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001159 }
1160
Bram Moolenaard881d152022-05-13 13:50:36 +01001161 if (!is_heredoc)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001162 {
Bram Moolenaard881d152022-05-13 13:50:36 +01001163 // Check for ":cmd v =<< [trim] EOF"
1164 // and ":cmd [a, b] =<< [trim] EOF"
1165 // and "lines =<< [trim] EOF" for Vim9
1166 // Where "cmd" can be "let", "var", "final" or "const".
zeertzjqa93d9cd2023-05-02 16:25:47 +01001167 arg = p;
1168 if (checkforcmd(&arg, "let", 2)
1169 || checkforcmd(&arg, "var", 3)
1170 || checkforcmd(&arg, "final", 5)
1171 || checkforcmd(&arg, "const", 5)
1172 || vim9_function)
Bram Moolenaard881d152022-05-13 13:50:36 +01001173 {
zeertzjqa93d9cd2023-05-02 16:25:47 +01001174 while (vim_strchr((char_u *)"$@&", *arg) != NULL)
1175 ++arg;
1176 arg = skipwhite(find_name_end(arg, NULL, NULL,
1177 FNE_INCL_BR | FNE_ALLOW_CURLY));
1178 if (vim9_function && *arg == ':')
1179 arg = skipwhite(skip_type(skipwhite(arg + 1), FALSE));
1180 if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<')
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001181 {
Bram Moolenaard881d152022-05-13 13:50:36 +01001182 p = skipwhite(arg + 3);
1183 while (TRUE)
Yegappan Lakshmananefbfa862022-04-17 12:47:40 +01001184 {
Bram Moolenaard881d152022-05-13 13:50:36 +01001185 if (STRNCMP(p, "trim", 4) == 0)
1186 {
1187 // Ignore leading white space.
1188 p = skipwhite(p + 4);
1189 heredoc_trimmed = vim_strnsave(theline,
1190 skipwhite(theline) - theline);
1191 continue;
1192 }
1193 if (STRNCMP(p, "eval", 4) == 0)
1194 {
1195 // Ignore leading white space.
1196 p = skipwhite(p + 4);
1197 continue;
1198 }
1199 break;
Yegappan Lakshmananefbfa862022-04-17 12:47:40 +01001200 }
Bram Moolenaard881d152022-05-13 13:50:36 +01001201 skip_until = vim_strnsave(p, skiptowhite(p) - p);
1202 getline_options = GETLINE_NONE;
1203 is_heredoc = TRUE;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001204 }
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001205 }
1206 }
1207 }
1208
1209 // Add the line to the function.
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01001210 if (ga_grow_id(newlines, 1 + sourcing_lnum_off, aid_get_func) == FAIL)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001211 goto theend;
1212
Bram Moolenaar20677332021-06-06 17:02:53 +02001213 if (heredoc_concat_len > 0)
1214 {
Dominique Pelleaf4a61a2021-12-27 17:21:41 +00001215 // For a :def function "python << EOF" concatenates all the lines,
Bram Moolenaar20677332021-06-06 17:02:53 +02001216 // to be used for the instruction later.
1217 ga_concat(&heredoc_ga, theline);
1218 ga_concat(&heredoc_ga, (char_u *)"\n");
1219 p = vim_strsave((char_u *)"");
1220 }
1221 else
1222 {
1223 // Copy the line to newly allocated memory. get_one_sourceline()
1224 // allocates 250 bytes per line, this saves 80% on average. The
1225 // cost is an extra alloc/free.
1226 p = vim_strsave(theline);
1227 }
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001228 if (p == NULL)
1229 goto theend;
1230 ((char_u **)(newlines->ga_data))[newlines->ga_len++] = p;
1231
1232 // Add NULL lines for continuation lines, so that the line count is
1233 // equal to the index in the growarray.
1234 while (sourcing_lnum_off-- > 0)
1235 ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL;
1236
1237 // Check for end of eap->arg.
1238 if (line_arg != NULL && *line_arg == NUL)
1239 line_arg = NULL;
1240 }
1241
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001242 // Return OK when no error was detected.
1243 if (!did_emsg)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001244 ret = OK;
1245
1246theend:
1247 vim_free(skip_until);
1248 vim_free(heredoc_trimmed);
Bram Moolenaar20677332021-06-06 17:02:53 +02001249 vim_free(heredoc_ga.ga_data);
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001250 need_wait_return |= saved_wait_return;
1251 return ret;
1252}
1253
1254/*
1255 * Handle the body of a lambda. *arg points to the "{", process statements
1256 * until the matching "}".
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001257 * When not evaluating "newargs" is NULL.
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001258 * When successful "rettv" is set to a funcref.
1259 */
1260 static int
1261lambda_function_body(
1262 char_u **arg,
1263 typval_T *rettv,
1264 evalarg_T *evalarg,
1265 garray_T *newargs,
1266 garray_T *argtypes,
1267 int varargs,
1268 garray_T *default_args,
1269 char_u *ret_type)
1270{
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001271 char_u *start = *arg;
Bram Moolenaarfed9e832021-04-10 21:38:38 +02001272 int evaluate = (evalarg->eval_flags & EVAL_EVALUATE);
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001273 garray_T *gap = &evalarg->eval_ga;
Bram Moolenaarecb66452021-05-18 15:09:18 +02001274 garray_T *freegap = &evalarg->eval_freega;
Bram Moolenaar79efa2e2021-03-27 15:40:11 +01001275 ufunc_T *ufunc = NULL;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001276 exarg_T eap;
1277 garray_T newlines;
1278 char_u *cmdline = NULL;
1279 int ret = FAIL;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001280 partial_T *pt;
1281 char_u *name;
1282 int lnum_save = -1;
1283 linenr_T sourcing_lnum_top = SOURCING_LNUM;
1284
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001285 *arg = skipwhite(*arg + 1);
1286 if (**arg == '|' || !ends_excmd2(start, *arg))
Bram Moolenaare98f60a2021-03-22 18:22:30 +01001287 {
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001288 semsg(_(e_trailing_characters_str), *arg);
Bram Moolenaare98f60a2021-03-22 18:22:30 +01001289 return FAIL;
1290 }
1291
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001292 CLEAR_FIELD(eap);
1293 eap.cmdidx = CMD_block;
1294 eap.forceit = FALSE;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001295 eap.cmdlinep = &cmdline;
1296 eap.skip = !evaluate;
1297 if (evalarg->eval_cctx != NULL)
1298 fill_exarg_from_cctx(&eap, evalarg->eval_cctx);
1299 else
1300 {
1301 eap.getline = evalarg->eval_getline;
1302 eap.cookie = evalarg->eval_cookie;
1303 }
1304
Bram Moolenaar04935fb2022-01-08 16:19:22 +00001305 ga_init2(&newlines, sizeof(char_u *), 10);
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00001306 if (get_function_body(&eap, &newlines, NULL,
1307 &evalarg->eval_tofree_ga) == FAIL)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001308 goto erret;
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001309
1310 // When inside a lambda must add the function lines to evalarg.eval_ga.
1311 evalarg->eval_break_count += newlines.ga_len;
1312 if (gap->ga_itemsize > 0)
1313 {
1314 int idx;
1315 char_u *last;
1316 size_t plen;
1317 char_u *pnl;
1318
1319 for (idx = 0; idx < newlines.ga_len; ++idx)
1320 {
1321 char_u *p = skipwhite(((char_u **)newlines.ga_data)[idx]);
1322
Bram Moolenaarecb66452021-05-18 15:09:18 +02001323 if (ga_grow(gap, 1) == FAIL || ga_grow(freegap, 1) == FAIL)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001324 goto erret;
1325
1326 // Going to concatenate the lines after parsing. For an empty or
1327 // comment line use an empty string.
1328 // Insert NL characters at the start of each line, the string will
1329 // be split again later in .get_lambda_tv().
1330 if (*p == NUL || vim9_comment_start(p))
1331 p = (char_u *)"";
1332 plen = STRLEN(p);
1333 pnl = vim_strnsave((char_u *)"\n", plen + 1);
1334 if (pnl != NULL)
1335 mch_memmove(pnl + 1, p, plen + 1);
Bram Moolenaarecb66452021-05-18 15:09:18 +02001336 ((char_u **)gap->ga_data)[gap->ga_len++] = pnl;
1337 ((char_u **)freegap->ga_data)[freegap->ga_len++] = pnl;
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001338 }
Bram Moolenaarecb66452021-05-18 15:09:18 +02001339 if (ga_grow(gap, 1) == FAIL || ga_grow(freegap, 1) == FAIL)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001340 goto erret;
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00001341 if (eap.nextcmd != NULL)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001342 // more is following after the "}", which was skipped
1343 last = cmdline;
1344 else
1345 // nothing is following the "}"
1346 last = (char_u *)"}";
1347 plen = STRLEN(last);
1348 pnl = vim_strnsave((char_u *)"\n", plen + 1);
1349 if (pnl != NULL)
1350 mch_memmove(pnl + 1, last, plen + 1);
Bram Moolenaarecb66452021-05-18 15:09:18 +02001351 ((char_u **)gap->ga_data)[gap->ga_len++] = pnl;
1352 ((char_u **)freegap->ga_data)[freegap->ga_len++] = pnl;
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001353 }
1354
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00001355 if (eap.nextcmd != NULL)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001356 {
Bram Moolenaar844fb642021-10-23 13:32:30 +01001357 garray_T *tfgap = &evalarg->eval_tofree_ga;
1358
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001359 // Something comes after the "}".
1360 *arg = eap.nextcmd;
Bram Moolenaar67da21a2021-03-21 22:12:34 +01001361
1362 // "arg" points into cmdline, need to keep the line and free it later.
Bram Moolenaar844fb642021-10-23 13:32:30 +01001363 if (ga_grow(tfgap, 1) == OK)
1364 {
1365 ((char_u **)(tfgap->ga_data))[tfgap->ga_len++] = cmdline;
1366 evalarg->eval_using_cmdline = TRUE;
1367 }
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001368 }
1369 else
1370 *arg = (char_u *)"";
1371
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001372 if (!evaluate)
1373 {
1374 ret = OK;
1375 goto erret;
1376 }
1377
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001378 name = get_lambda_name();
Bram Moolenaare01e5212023-01-08 20:31:18 +00001379 ufunc = alloc_ufunc(name);
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001380 if (ufunc == NULL)
1381 goto erret;
1382 set_ufunc_name(ufunc, name);
Bram Moolenaaref2c3252022-11-25 16:31:51 +00001383 if (hash_add(&func_hashtab, UF2HIKEY(ufunc), "add function") == FAIL)
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001384 goto erret;
Bram Moolenaar38453522021-11-28 22:00:12 +00001385 ufunc->uf_flags = FC_LAMBDA;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001386 ufunc->uf_refcount = 1;
1387 ufunc->uf_args = *newargs;
1388 newargs->ga_data = NULL;
1389 ufunc->uf_def_args = *default_args;
1390 default_args->ga_data = NULL;
1391 ufunc->uf_func_type = &t_func_any;
1392
1393 // error messages are for the first function line
1394 lnum_save = SOURCING_LNUM;
1395 SOURCING_LNUM = sourcing_lnum_top;
1396
1397 // parse argument types
1398 if (parse_argument_types(ufunc, argtypes, varargs) == FAIL)
1399 {
1400 SOURCING_LNUM = lnum_save;
1401 goto erret;
1402 }
1403
1404 // parse the return type, if any
1405 if (parse_return_type(ufunc, ret_type) == FAIL)
1406 goto erret;
1407
1408 pt = ALLOC_CLEAR_ONE(partial_T);
1409 if (pt == NULL)
1410 goto erret;
1411 pt->pt_func = ufunc;
1412 pt->pt_refcount = 1;
1413
1414 ufunc->uf_lines = newlines;
1415 newlines.ga_data = NULL;
1416 if (sandbox)
1417 ufunc->uf_flags |= FC_SANDBOX;
1418 if (!ASCII_ISUPPER(*ufunc->uf_name))
1419 ufunc->uf_flags |= FC_VIM9;
1420 ufunc->uf_script_ctx = current_sctx;
1421 ufunc->uf_script_ctx_version = current_sctx.sc_version;
1422 ufunc->uf_script_ctx.sc_lnum += sourcing_lnum_top;
1423 set_function_type(ufunc);
1424
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02001425 function_using_block_scopes(ufunc, evalarg->eval_cstack);
1426
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001427 rettv->vval.v_partial = pt;
1428 rettv->v_type = VAR_PARTIAL;
Bram Moolenaar79efa2e2021-03-27 15:40:11 +01001429 ufunc = NULL;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001430 ret = OK;
1431
1432erret:
1433 if (lnum_save >= 0)
1434 SOURCING_LNUM = lnum_save;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001435 ga_clear_strings(&newlines);
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001436 if (newargs != NULL)
1437 ga_clear_strings(newargs);
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001438 ga_clear_strings(default_args);
Bram Moolenaar79efa2e2021-03-27 15:40:11 +01001439 if (ufunc != NULL)
1440 {
1441 func_clear(ufunc, TRUE);
1442 func_free(ufunc, TRUE);
1443 }
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001444 return ret;
1445}
1446
1447/*
1448 * Parse a lambda expression and get a Funcref from "*arg" into "rettv".
Bram Moolenaar65c44152020-12-24 15:14:01 +01001449 * "arg" points to the { in "{arg -> expr}" or the ( in "(arg) => expr"
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001450 * When "types_optional" is TRUE optionally take argument types.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001451 * Return OK or FAIL. Returns NOTDONE for dict or {expr}.
1452 */
1453 int
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001454get_lambda_tv(
1455 char_u **arg,
1456 typval_T *rettv,
1457 int types_optional,
1458 evalarg_T *evalarg)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001459{
Bram Moolenaare40fbc22020-06-27 18:06:45 +02001460 int evaluate = evalarg != NULL
1461 && (evalarg->eval_flags & EVAL_EVALUATE);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001462 garray_T newargs;
1463 garray_T newlines;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001464 garray_T *pnewargs;
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001465 garray_T argtypes;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001466 garray_T default_args;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001467 ufunc_T *fp = NULL;
Bram Moolenaar445e71c2019-02-14 13:43:36 +01001468 partial_T *pt = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001469 int varargs;
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001470 char_u *ret_type = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001471 int ret;
Bram Moolenaar8e2730a2020-07-08 22:01:49 +02001472 char_u *s;
1473 char_u *start, *end;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001474 int *old_eval_lavars = eval_lavars_used;
1475 int eval_lavars = FALSE;
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01001476 char_u *tofree2 = NULL;
Bram Moolenaar65c44152020-12-24 15:14:01 +01001477 int equal_arrow = **arg == '(';
Bram Moolenaarc754b4c2020-12-25 15:24:23 +01001478 int white_error = FALSE;
Bram Moolenaar0346b792021-01-31 22:18:29 +01001479 int called_emsg_start = called_emsg;
Bram Moolenaar4525a572022-02-13 11:57:33 +00001480 int vim9script = in_vim9script();
Bram Moolenaar521bf322022-05-06 15:47:07 +01001481 long start_lnum = SOURCING_LNUM;
Bram Moolenaar65c44152020-12-24 15:14:01 +01001482
Bram Moolenaar4525a572022-02-13 11:57:33 +00001483 if (equal_arrow && !vim9script)
Bram Moolenaar65c44152020-12-24 15:14:01 +01001484 return NOTDONE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001485
1486 ga_init(&newargs);
1487 ga_init(&newlines);
1488
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001489 // First, check if this is really a lambda expression. "->" or "=>" must
1490 // be found after the arguments.
Bram Moolenaarcef12702021-01-04 14:09:43 +01001491 s = *arg + 1;
Bram Moolenaar65c44152020-12-24 15:14:01 +01001492 ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001493 types_optional ? &argtypes : NULL, types_optional, evalarg,
Bram Moolenaarffdaca92022-12-09 21:41:48 +00001494 NULL, &default_args, TRUE, NULL, FALSE, NULL, NULL);
Bram Moolenaarc754b4c2020-12-25 15:24:23 +01001495 if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type, NULL) == NULL)
Bram Moolenaar6dd41b12020-12-24 16:06:00 +01001496 {
1497 if (types_optional)
1498 ga_clear_strings(&argtypes);
Bram Moolenaar0346b792021-01-31 22:18:29 +01001499 return called_emsg == called_emsg_start ? NOTDONE : FAIL;
Bram Moolenaar6dd41b12020-12-24 16:06:00 +01001500 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001501
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001502 // Parse the arguments for real.
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001503 if (evaluate)
1504 pnewargs = &newargs;
1505 else
1506 pnewargs = NULL;
Bram Moolenaarcef12702021-01-04 14:09:43 +01001507 *arg += 1;
Bram Moolenaar65c44152020-12-24 15:14:01 +01001508 ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001509 types_optional ? &argtypes : NULL, types_optional, evalarg,
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001510 &varargs, &default_args,
Bram Moolenaarffdaca92022-12-09 21:41:48 +00001511 FALSE, NULL, FALSE, NULL, NULL);
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001512 if (ret == FAIL
Bram Moolenaarc754b4c2020-12-25 15:24:23 +01001513 || (s = skip_arrow(*arg, equal_arrow, &ret_type,
Bram Moolenaar4525a572022-02-13 11:57:33 +00001514 equal_arrow || vim9script ? &white_error : NULL)) == NULL)
Bram Moolenaar6dd41b12020-12-24 16:06:00 +01001515 {
1516 if (types_optional)
1517 ga_clear_strings(&argtypes);
Bram Moolenaare5730bd2020-12-25 22:30:16 +01001518 ga_clear_strings(&newargs);
Bram Moolenaarc754b4c2020-12-25 15:24:23 +01001519 return white_error ? FAIL : NOTDONE;
Bram Moolenaar6dd41b12020-12-24 16:06:00 +01001520 }
Bram Moolenaarc754b4c2020-12-25 15:24:23 +01001521 *arg = s;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001522
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01001523 // Skipping over linebreaks may make "ret_type" invalid, make a copy.
1524 if (ret_type != NULL)
1525 {
1526 ret_type = vim_strsave(ret_type);
1527 tofree2 = ret_type;
1528 }
1529
Bram Moolenaare38eab22019-12-05 21:50:01 +01001530 // Set up a flag for checking local variables and arguments.
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001531 if (evaluate)
1532 eval_lavars_used = &eval_lavars;
1533
Bram Moolenaar65c44152020-12-24 15:14:01 +01001534 *arg = skipwhite_and_linebreak(*arg, evalarg);
1535
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001536 // Recognize "{" as the start of a function body.
1537 if (equal_arrow && **arg == '{')
Bram Moolenaar65c44152020-12-24 15:14:01 +01001538 {
Bram Moolenaarfed9e832021-04-10 21:38:38 +02001539 if (evalarg == NULL)
1540 // cannot happen?
1541 goto theend;
Bram Moolenaar521bf322022-05-06 15:47:07 +01001542 SOURCING_LNUM = start_lnum; // used for where lambda is defined
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001543 if (lambda_function_body(arg, rettv, evalarg, pnewargs,
1544 types_optional ? &argtypes : NULL, varargs,
1545 &default_args, ret_type) == FAIL)
1546 goto errret;
1547 goto theend;
1548 }
1549 if (default_args.ga_len > 0)
1550 {
1551 emsg(_(e_cannot_use_default_values_in_lambda));
Bram Moolenaar65c44152020-12-24 15:14:01 +01001552 goto errret;
1553 }
1554
Bram Moolenaare38eab22019-12-05 21:50:01 +01001555 // Get the start and the end of the expression.
Bram Moolenaar8e2730a2020-07-08 22:01:49 +02001556 start = *arg;
1557 ret = skip_expr_concatenate(arg, &start, &end, evalarg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001558 if (ret == FAIL)
1559 goto errret;
Bram Moolenaare40fbc22020-06-27 18:06:45 +02001560
Bram Moolenaar65c44152020-12-24 15:14:01 +01001561 if (!equal_arrow)
Bram Moolenaaree619e52020-03-28 21:38:06 +01001562 {
Bram Moolenaar65c44152020-12-24 15:14:01 +01001563 *arg = skipwhite_and_linebreak(*arg, evalarg);
1564 if (**arg != '}')
1565 {
Bram Moolenaarb09feaa2022-01-02 20:20:45 +00001566 semsg(_(e_expected_right_curly_str), *arg);
Bram Moolenaar65c44152020-12-24 15:14:01 +01001567 goto errret;
1568 }
1569 ++*arg;
Bram Moolenaaree619e52020-03-28 21:38:06 +01001570 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001571
1572 if (evaluate)
1573 {
Bram Moolenaare40fbc22020-06-27 18:06:45 +02001574 int len;
Bram Moolenaar38453522021-11-28 22:00:12 +00001575 int flags = FC_LAMBDA;
Bram Moolenaar437bafe2016-08-01 15:40:54 +02001576 char_u *p;
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001577 char_u *line_end;
Bram Moolenaar04b12692020-05-04 23:24:44 +02001578 char_u *name = get_lambda_name();
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001579
Bram Moolenaare01e5212023-01-08 20:31:18 +00001580 fp = alloc_ufunc(name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001581 if (fp == NULL)
1582 goto errret;
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02001583 fp->uf_def_status = UF_NOT_COMPILED;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02001584 pt = ALLOC_CLEAR_ONE(partial_T);
Bram Moolenaar437bafe2016-08-01 15:40:54 +02001585 if (pt == NULL)
Bram Moolenaar437bafe2016-08-01 15:40:54 +02001586 goto errret;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001587
Bram Moolenaar04935fb2022-01-08 16:19:22 +00001588 ga_init2(&newlines, sizeof(char_u *), 1);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001589 if (ga_grow(&newlines, 1) == FAIL)
1590 goto errret;
1591
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001592 // If there are line breaks, we need to split up the string.
1593 line_end = vim_strchr(start, '\n');
Bram Moolenaar68686342021-07-28 15:54:54 +02001594 if (line_end == NULL || line_end > end)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001595 line_end = end;
1596
1597 // Add "return " before the expression (or the first line).
1598 len = 7 + (int)(line_end - start) + 1;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02001599 p = alloc(len);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001600 if (p == NULL)
1601 goto errret;
1602 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
1603 STRCPY(p, "return ");
Bram Moolenaar074f84c2021-05-18 11:47:44 +02001604 vim_strncpy(p + 7, start, line_end - start);
1605
1606 if (line_end != end)
1607 {
1608 // Add more lines, split by line breaks. Thus is used when a
1609 // lambda with { cmds } is encountered.
1610 while (*line_end == '\n')
1611 {
1612 if (ga_grow(&newlines, 1) == FAIL)
1613 goto errret;
1614 start = line_end + 1;
1615 line_end = vim_strchr(start, '\n');
1616 if (line_end == NULL)
1617 line_end = end;
1618 ((char_u **)(newlines.ga_data))[newlines.ga_len++] =
1619 vim_strnsave(start, line_end - start);
1620 }
1621 }
1622
Bram Moolenaarf10806b2020-04-02 18:34:35 +02001623 if (strstr((char *)p + 7, "a:") == NULL)
1624 // No a: variables are used for sure.
1625 flags |= FC_NOARGS;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001626
1627 fp->uf_refcount = 1;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01001628 set_ufunc_name(fp, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001629 fp->uf_args = newargs;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02001630 ga_init(&fp->uf_def_args);
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001631 if (types_optional)
1632 {
Bram Moolenaar2a389082021-04-09 20:24:31 +02001633 if (parse_argument_types(fp, &argtypes,
Bram Moolenaar4525a572022-02-13 11:57:33 +00001634 vim9script && varargs) == FAIL)
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001635 goto errret;
1636 if (ret_type != NULL)
1637 {
1638 fp->uf_ret_type = parse_type(&ret_type,
1639 &fp->uf_type_list, TRUE);
1640 if (fp->uf_ret_type == NULL)
1641 goto errret;
1642 }
Bram Moolenaarca2f7e72020-12-31 13:39:54 +01001643 else
Bram Moolenaara9931532021-06-12 15:58:16 +02001644 fp->uf_ret_type = &t_unknown;
Bram Moolenaar9e68c322020-12-25 12:38:04 +01001645 }
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001646
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001647 fp->uf_lines = newlines;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001648 if (current_funccal != NULL && eval_lavars)
1649 {
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02001650 flags |= FC_CLOSURE;
Bram Moolenaar58016442016-07-31 18:30:22 +02001651 if (register_closure(fp) == FAIL)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001652 goto errret;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001653 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001654
1655#ifdef FEAT_PROFILE
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001656 if (prof_def_func())
1657 func_do_profile(fp);
1658#endif
Bram Moolenaar93343722018-07-10 19:39:18 +02001659 if (sandbox)
1660 flags |= FC_SANDBOX;
Bram Moolenaar767034c2021-04-09 17:24:52 +02001661 // In legacy script a lambda can be called with more args than
Bram Moolenaar2a389082021-04-09 20:24:31 +02001662 // uf_args.ga_len. In Vim9 script "...name" has to be used.
Bram Moolenaar4525a572022-02-13 11:57:33 +00001663 fp->uf_varargs = !vim9script || varargs;
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02001664 fp->uf_flags = flags;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001665 fp->uf_calls = 0;
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001666 fp->uf_script_ctx = current_sctx;
Bram Moolenaar521bf322022-05-06 15:47:07 +01001667 // Use the line number of the arguments.
1668 fp->uf_script_ctx.sc_lnum += start_lnum;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001669
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02001670 function_using_block_scopes(fp, evalarg->eval_cstack);
1671
Bram Moolenaar437bafe2016-08-01 15:40:54 +02001672 pt->pt_func = fp;
1673 pt->pt_refcount = 1;
1674 rettv->vval.v_partial = pt;
1675 rettv->v_type = VAR_PARTIAL;
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001676
Bram Moolenaaref2c3252022-11-25 16:31:51 +00001677 hash_add(&func_hashtab, UF2HIKEY(fp), "add lambda");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001678 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001679
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001680theend:
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001681 eval_lavars_used = old_eval_lavars;
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01001682 vim_free(tofree2);
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001683 if (types_optional)
1684 ga_clear_strings(&argtypes);
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02001685
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001686 return OK;
1687
1688errret:
1689 ga_clear_strings(&newargs);
1690 ga_clear_strings(&newlines);
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01001691 ga_clear_strings(&default_args);
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001692 if (types_optional)
Bram Moolenaar15bbb8f2021-05-24 15:45:29 +02001693 {
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001694 ga_clear_strings(&argtypes);
Bram Moolenaar15bbb8f2021-05-24 15:45:29 +02001695 if (fp != NULL)
1696 vim_free(fp->uf_arg_types);
1697 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001698 vim_free(fp);
Bram Moolenaar445e71c2019-02-14 13:43:36 +01001699 vim_free(pt);
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01001700 vim_free(tofree2);
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02001701 eval_lavars_used = old_eval_lavars;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001702 return FAIL;
1703}
1704
1705/*
1706 * Check if "name" is a variable of type VAR_FUNC. If so, return the function
1707 * name it contains, otherwise return "name".
1708 * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set
1709 * "partialp".
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001710 * If "type" is not NULL and a Vim9 script-local variable is found look up the
1711 * type of the variable.
Bram Moolenaar937610b2022-01-19 17:21:29 +00001712 * If "new_function" is TRUE the name is for a new function.
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001713 * If "found_var" is not NULL and a variable was found set it to TRUE.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001714 */
1715 char_u *
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001716deref_func_name(
1717 char_u *name,
1718 int *lenp,
1719 partial_T **partialp,
1720 type_T **type,
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001721 int no_autoload,
Bram Moolenaar937610b2022-01-19 17:21:29 +00001722 int new_function,
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001723 int *found_var)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001724{
1725 dictitem_T *v;
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001726 typval_T *tv = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001727 int cc;
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001728 char_u *s = NULL;
1729 hashtab_T *ht;
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001730 int did_type = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001731
1732 if (partialp != NULL)
1733 *partialp = NULL;
1734
1735 cc = name[*lenp];
1736 name[*lenp] = NUL;
Bram Moolenaar20677332021-06-06 17:02:53 +02001737
Bram Moolenaar71f21932022-01-07 18:20:55 +00001738 v = find_var_also_in_script(name, &ht, no_autoload);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001739 name[*lenp] = cc;
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001740 if (v != NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001741 {
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001742 tv = &v->di_tv;
1743 }
1744 else if (in_vim9script() || STRNCMP(name, "s:", 2) == 0)
1745 {
1746 imported_T *import;
1747 char_u *p = name;
1748 int len = *lenp;
1749
1750 if (STRNCMP(name, "s:", 2) == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001751 {
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001752 p = name + 2;
1753 len -= 2;
1754 }
Bram Moolenaar4b1d9632022-02-13 21:51:08 +00001755 import = find_imported(p, len, FALSE);
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001756
Bram Moolenaard5f400c2022-01-06 21:10:28 +00001757 // imported function from another script
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001758 if (import != NULL)
1759 {
Bram Moolenaard5f400c2022-01-06 21:10:28 +00001760 name[len] = NUL;
Bram Moolenaar937610b2022-01-19 17:21:29 +00001761 if (new_function)
1762 semsg(_(e_redefining_imported_item_str), name);
1763 else
1764 semsg(_(e_cannot_use_str_itself_it_is_imported), name);
Bram Moolenaard5f400c2022-01-06 21:10:28 +00001765 name[len] = cc;
1766 *lenp = 0;
1767 return (char_u *)""; // just in case
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001768 }
1769 }
1770
1771 if (tv != NULL)
1772 {
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001773 if (found_var != NULL)
1774 *found_var = TRUE;
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001775 if (tv->v_type == VAR_FUNC)
1776 {
1777 if (tv->vval.v_string == NULL)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001778 {
1779 *lenp = 0;
1780 return (char_u *)""; // just in case
1781 }
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001782 s = tv->vval.v_string;
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001783 *lenp = (int)STRLEN(s);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001784 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001785
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001786 if (tv->v_type == VAR_PARTIAL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001787 {
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001788 partial_T *pt = tv->vval.v_partial;
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001789
1790 if (pt == NULL)
1791 {
1792 *lenp = 0;
1793 return (char_u *)""; // just in case
1794 }
1795 if (partialp != NULL)
1796 *partialp = pt;
1797 s = partial_name(pt);
1798 *lenp = (int)STRLEN(s);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001799 }
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001800
1801 if (s != NULL)
1802 {
Bram Moolenaar5fe07d22021-10-22 22:17:53 +01001803 if (!did_type && type != NULL && ht == get_script_local_ht())
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001804 {
Bram Moolenaar7a411a32022-04-04 14:58:06 +01001805 svar_T *sv = find_typval_in_script(tv, 0, TRUE);
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001806
1807 if (sv != NULL)
1808 *type = sv->sv_type;
1809 }
1810 return s;
1811 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001812 }
1813
1814 return name;
1815}
1816
1817/*
1818 * Give an error message with a function name. Handle <SNR> things.
1819 * "ermsg" is to be passed without translation, use N_() instead of _().
1820 */
Bram Moolenaar4c054e92019-11-10 00:13:50 +01001821 void
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001822emsg_funcname(char *ermsg, char_u *name)
1823{
Bram Moolenaar54598062022-01-13 12:05:09 +00001824 char_u *p = name;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001825
Bram Moolenaar54598062022-01-13 12:05:09 +00001826 if (name[0] == K_SPECIAL && name[1] != NUL && name[2] != NUL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001827 p = concat_str((char_u *)"<SNR>", name + 3);
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001828 semsg(_(ermsg), p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001829 if (p != name)
1830 vim_free(p);
1831}
1832
1833/*
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001834 * Get function arguments at "*arg" and advance it.
1835 * Return them in "*argvars[MAX_FUNC_ARGS + 1]" and the count in "argcount".
Bram Moolenaar806a2732022-09-04 15:40:36 +01001836 * On failure FAIL is returned but the "argvars[argcount]" are still set.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001837 */
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001838 int
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001839get_func_arguments(
1840 char_u **arg,
1841 evalarg_T *evalarg,
1842 int partial_argc,
1843 typval_T *argvars,
1844 int *argcount)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001845{
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001846 char_u *argp = *arg;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001847 int ret = OK;
Bram Moolenaar7cb6fc22020-08-21 22:36:47 +02001848 int vim9script = in_vim9script();
Bram Moolenaar5e6b9882022-01-10 18:50:52 +00001849 int evaluate = evalarg == NULL
1850 ? FALSE : (evalarg->eval_flags & EVAL_EVALUATE);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001851
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001852 while (*argcount < MAX_FUNC_ARGS - partial_argc)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001853 {
Bram Moolenaare6b53242020-07-01 17:28:33 +02001854 // skip the '(' or ',' and possibly line breaks
1855 argp = skipwhite_and_linebreak(argp + 1, evalarg);
1856
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001857 if (*argp == ')' || *argp == ',' || *argp == NUL)
1858 break;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001859 if (eval1(&argp, &argvars[*argcount], evalarg) == FAIL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001860 {
1861 ret = FAIL;
1862 break;
1863 }
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001864 ++*argcount;
Bram Moolenaar9d489562020-07-30 20:08:50 +02001865 // The comma should come right after the argument, but this wasn't
1866 // checked previously, thus only enforce it in Vim9 script.
Bram Moolenaar7cb6fc22020-08-21 22:36:47 +02001867 if (vim9script)
1868 {
1869 if (*argp != ',' && *skipwhite(argp) == ',')
1870 {
Bram Moolenaar5e6b9882022-01-10 18:50:52 +00001871 if (evaluate)
1872 semsg(_(e_no_white_space_allowed_before_str_str),
1873 ",", argp);
Bram Moolenaar7cb6fc22020-08-21 22:36:47 +02001874 ret = FAIL;
1875 break;
1876 }
1877 }
1878 else
Bram Moolenaar9d489562020-07-30 20:08:50 +02001879 argp = skipwhite(argp);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001880 if (*argp != ',')
1881 break;
Bram Moolenaar7cb6fc22020-08-21 22:36:47 +02001882 if (vim9script && !IS_WHITE_OR_NUL(argp[1]))
1883 {
Bram Moolenaar5e6b9882022-01-10 18:50:52 +00001884 if (evaluate)
1885 semsg(_(e_white_space_required_after_str_str), ",", argp);
Bram Moolenaar7cb6fc22020-08-21 22:36:47 +02001886 ret = FAIL;
1887 break;
1888 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001889 }
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001890
Bram Moolenaare6b53242020-07-01 17:28:33 +02001891 argp = skipwhite_and_linebreak(argp, evalarg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001892 if (*argp == ')')
1893 ++argp;
1894 else
1895 ret = FAIL;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001896 *arg = argp;
1897 return ret;
1898}
1899
1900/*
1901 * Call a function and put the result in "rettv".
1902 * Return OK or FAIL.
1903 */
1904 int
1905get_func_tv(
1906 char_u *name, // name of the function
1907 int len, // length of "name" or -1 to use strlen()
1908 typval_T *rettv,
1909 char_u **arg, // argument, pointing to the '('
1910 evalarg_T *evalarg, // for line continuation
1911 funcexe_T *funcexe) // various values
1912{
1913 char_u *argp;
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001914 int ret;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01001915 typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
1916 int argcount = 0; // number of arguments found
1917 int vim9script = in_vim9script();
1918 int evaluate = evalarg == NULL
1919 ? FALSE : (evalarg->eval_flags & EVAL_EVALUATE);
1920
1921 argp = *arg;
1922 ret = get_func_arguments(&argp, evalarg,
1923 (funcexe->fe_partial == NULL ? 0 : funcexe->fe_partial->pt_argc),
1924 argvars, &argcount);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001925
1926 if (ret == OK)
1927 {
Bram Moolenaar327d3ee2021-07-28 19:34:14 +02001928 int i = 0;
1929 int did_emsg_before = did_emsg;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001930
1931 if (get_vim_var_nr(VV_TESTING))
1932 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01001933 // Prepare for calling test_garbagecollect_now(), need to know
1934 // what variables are used on the call stack.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001935 if (funcargs.ga_itemsize == 0)
Bram Moolenaar04935fb2022-01-08 16:19:22 +00001936 ga_init2(&funcargs, sizeof(typval_T *), 50);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001937 for (i = 0; i < argcount; ++i)
1938 if (ga_grow(&funcargs, 1) == OK)
1939 ((typval_T **)funcargs.ga_data)[funcargs.ga_len++] =
1940 &argvars[i];
1941 }
1942
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02001943 ret = call_func(name, len, rettv, argcount, argvars, funcexe);
Bram Moolenaar4525a572022-02-13 11:57:33 +00001944 if (vim9script && did_emsg > did_emsg_before)
Bram Moolenaar6e850a62021-07-28 22:21:23 +02001945 {
Bram Moolenaar327d3ee2021-07-28 19:34:14 +02001946 // An error in a builtin function does not return FAIL, but we do
1947 // want to abort further processing if an error was given.
1948 ret = FAIL;
Bram Moolenaar6e850a62021-07-28 22:21:23 +02001949 clear_tv(rettv);
1950 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001951
1952 funcargs.ga_len -= i;
1953 }
Bram Moolenaar5e6b9882022-01-10 18:50:52 +00001954 else if (!aborting() && evaluate)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001955 {
1956 if (argcount == MAX_FUNC_ARGS)
Bram Moolenaara6f79292022-01-04 21:30:47 +00001957 emsg_funcname(e_too_many_arguments_for_function_str_2, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001958 else
Bram Moolenaarc553a212021-12-26 20:20:34 +00001959 emsg_funcname(e_invalid_arguments_for_function_str, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001960 }
1961
1962 while (--argcount >= 0)
1963 clear_tv(&argvars[argcount]);
1964
Bram Moolenaar4525a572022-02-13 11:57:33 +00001965 if (vim9script)
Bram Moolenaar8294d492020-08-10 22:40:56 +02001966 *arg = argp;
1967 else
1968 *arg = skipwhite(argp);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001969 return ret;
1970}
1971
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001972/*
1973 * Return TRUE if "p" starts with "<SID>" or "s:".
1974 * Only works if eval_fname_script() returned non-zero for "p"!
1975 */
1976 static int
1977eval_fname_sid(char_u *p)
1978{
1979 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I');
1980}
1981
1982/*
1983 * In a script change <SID>name() and s:name() to K_SNR 123_name().
1984 * Change <SNR>123_name() to K_SNR 123_name().
1985 * Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
Yegappan Lakshmanane9dcf132022-09-24 11:30:41 +01001986 * and set "tofree".
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001987 */
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001988 char_u *
Bram Moolenaar0917e862023-02-18 14:42:44 +00001989fname_trans_sid(
1990 char_u *name,
1991 char_u *fname_buf,
1992 char_u **tofree,
1993 funcerror_T *error)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001994{
1995 int llen;
1996 char_u *fname;
1997 int i;
1998
1999 llen = eval_fname_script(name);
Yegappan Lakshmanane9dcf132022-09-24 11:30:41 +01002000 if (llen == 0)
2001 return name; // no prefix
2002
2003 fname_buf[0] = K_SPECIAL;
2004 fname_buf[1] = KS_EXTRA;
2005 fname_buf[2] = (int)KE_SNR;
2006 i = 3;
2007 if (eval_fname_sid(name)) // "<SID>" or "s:"
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002008 {
Yegappan Lakshmanane9dcf132022-09-24 11:30:41 +01002009 if (current_sctx.sc_sid <= 0)
2010 *error = FCERR_SCRIPT;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002011 else
2012 {
Yegappan Lakshmanane9dcf132022-09-24 11:30:41 +01002013 sprintf((char *)fname_buf + 3, "%ld_",
2014 (long)current_sctx.sc_sid);
2015 i = (int)STRLEN(fname_buf);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002016 }
2017 }
Yegappan Lakshmanane9dcf132022-09-24 11:30:41 +01002018 if (i + STRLEN(name + llen) < FLEN_FIXED)
2019 {
2020 STRCPY(fname_buf + i, name + llen);
2021 fname = fname_buf;
2022 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002023 else
Yegappan Lakshmanane9dcf132022-09-24 11:30:41 +01002024 {
2025 fname = alloc(i + STRLEN(name + llen) + 1);
2026 if (fname == NULL)
2027 *error = FCERR_OTHER;
2028 else
2029 {
2030 *tofree = fname;
2031 mch_memmove(fname, fname_buf, (size_t)i);
2032 STRCPY(fname + i, name + llen);
2033 }
2034 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002035 return fname;
2036}
2037
2038/*
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +01002039 * Concatenate the script ID and function name into "<SNR>99_name".
2040 * "buffer" must have size MAX_FUNC_NAME_LEN.
2041 */
2042 void
2043func_name_with_sid(char_u *name, int sid, char_u *buffer)
2044{
2045 // A script-local function is stored as "<SNR>99_name".
2046 buffer[0] = K_SPECIAL;
2047 buffer[1] = KS_EXTRA;
2048 buffer[2] = (int)KE_SNR;
2049 vim_snprintf((char *)buffer + 3, MAX_FUNC_NAME_LEN - 3, "%ld_%s",
2050 (long)sid, name);
2051}
2052
2053/*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002054 * Find a function "name" in script "sid".
2055 */
2056 static ufunc_T *
2057find_func_with_sid(char_u *name, int sid)
2058{
Bram Moolenaarb8822442022-01-11 15:24:05 +00002059 hashitem_T *hi;
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +01002060 char_u buffer[MAX_FUNC_NAME_LEN];
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002061
Bram Moolenaarb8822442022-01-11 15:24:05 +00002062 if (!SCRIPT_ID_VALID(sid))
2063 return NULL; // not in a script
2064
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +01002065 func_name_with_sid(name, sid, buffer);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002066 hi = hash_find(&func_hashtab, buffer);
2067 if (!HASHITEM_EMPTY(hi))
2068 return HI2UF(hi);
Bram Moolenaarb8822442022-01-11 15:24:05 +00002069 return NULL;
2070}
2071
2072/*
2073 * Find a function "name" in script "sid" prefixing the autoload prefix.
2074 */
2075 static ufunc_T *
2076find_func_with_prefix(char_u *name, int sid)
2077{
2078 hashitem_T *hi;
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +01002079 char_u buffer[MAX_FUNC_NAME_LEN];
Bram Moolenaarb8822442022-01-11 15:24:05 +00002080 scriptitem_T *si;
2081
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002082 if (vim_strchr(name, AUTOLOAD_CHAR) != NULL)
Bram Moolenaarb8822442022-01-11 15:24:05 +00002083 return NULL; // already has the prefix
2084 if (!SCRIPT_ID_VALID(sid))
2085 return NULL; // not in a script
2086 si = SCRIPT_ITEM(sid);
2087 if (si->sn_autoload_prefix != NULL)
2088 {
2089 size_t len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1;
2090 char_u *auto_name;
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00002091 char_u *namep;
2092
2093 // skip a "<SNR>99_" prefix
2094 namep = untrans_function_name(name);
2095 if (namep == NULL)
2096 namep = name;
Bram Moolenaarb8822442022-01-11 15:24:05 +00002097
2098 // An exported function in an autoload script is stored as
2099 // "dir#path#name".
2100 if (len < sizeof(buffer))
2101 auto_name = buffer;
2102 else
2103 auto_name = alloc(len);
2104 if (auto_name != NULL)
2105 {
2106 vim_snprintf((char *)auto_name, len, "%s%s",
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00002107 si->sn_autoload_prefix, namep);
Bram Moolenaarb8822442022-01-11 15:24:05 +00002108 hi = hash_find(&func_hashtab, auto_name);
2109 if (auto_name != buffer)
2110 vim_free(auto_name);
2111 if (!HASHITEM_EMPTY(hi))
2112 return HI2UF(hi);
2113 }
2114 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002115
2116 return NULL;
2117}
2118
2119/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002120 * Find a function by name, return pointer to it in ufuncs.
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002121 * When "flags" has FFED_IS_GLOBAL don't find script-local or imported
2122 * functions.
2123 * When "flags" has "FFED_NO_GLOBAL" don't find global functions.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002124 * Return NULL for unknown function.
2125 */
Bram Moolenaarce658352020-07-31 23:47:12 +02002126 ufunc_T *
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002127find_func_even_dead(char_u *name, int flags)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002128{
2129 hashitem_T *hi;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002130 ufunc_T *func;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002131
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002132 if ((flags & FFED_IS_GLOBAL) == 0)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002133 {
Bram Moolenaarc2f17f72022-02-21 13:13:50 +00002134 // Find script-local function before global one.
2135 if (in_vim9script() && eval_isnamec1(*name)
2136 && (name[1] != ':' || *name == 's'))
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002137 {
Bram Moolenaar33b968d2021-12-13 11:31:04 +00002138 func = find_func_with_sid(name[0] == 's' && name[1] == ':'
2139 ? name + 2 : name, current_sctx.sc_sid);
Bram Moolenaar9721fb42020-06-11 23:10:46 +02002140 if (func != NULL)
2141 return func;
2142 }
Bram Moolenaarc2f17f72022-02-21 13:13:50 +00002143 if (in_vim9script() && STRNCMP(name, "<SNR>", 5) == 0)
2144 {
2145 char_u *p = name + 5;
2146 long sid;
2147
2148 // printable "<SNR>123_Name" form
2149 sid = getdigits(&p);
2150 if (*p == '_')
2151 {
2152 func = find_func_with_sid(p + 1, (int)sid);
2153 if (func != NULL)
2154 return func;
2155 }
2156 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002157 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002158
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002159 if ((flags & FFED_NO_GLOBAL) == 0)
2160 {
2161 hi = hash_find(&func_hashtab,
Bram Moolenaara26b9702020-04-18 19:53:28 +02002162 STRNCMP(name, "g:", 2) == 0 ? name + 2 : name);
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002163 if (!HASHITEM_EMPTY(hi))
2164 return HI2UF(hi);
2165 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002166
Bram Moolenaarb8822442022-01-11 15:24:05 +00002167 // Find autoload function if this is an autoload script.
2168 return find_func_with_prefix(name[0] == 's' && name[1] == ':'
2169 ? name + 2 : name, current_sctx.sc_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002170}
2171
2172/*
2173 * Find a function by name, return pointer to it in ufuncs.
2174 * "cctx" is passed in a :def function to find imported functions.
2175 * Return NULL for unknown or dead function.
2176 */
2177 ufunc_T *
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00002178find_func(char_u *name, int is_global)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002179{
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002180 ufunc_T *fp = find_func_even_dead(name, is_global ? FFED_IS_GLOBAL : 0);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002181
2182 if (fp != NULL && (fp->uf_flags & FC_DEAD) == 0)
2183 return fp;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002184 return NULL;
2185}
2186
2187/*
Bram Moolenaar0f769812020-09-12 18:32:34 +02002188 * Return TRUE if "ufunc" is a global function.
2189 */
2190 int
2191func_is_global(ufunc_T *ufunc)
2192{
2193 return ufunc->uf_name[0] != K_SPECIAL;
2194}
2195
2196/*
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002197 * Return TRUE if "ufunc" must be called with a g: prefix in Vim9 script.
2198 */
2199 int
2200func_requires_g_prefix(ufunc_T *ufunc)
2201{
2202 return ufunc->uf_name[0] != K_SPECIAL
2203 && (ufunc->uf_flags & FC_LAMBDA) == 0
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01002204 && vim_strchr(ufunc->uf_name, AUTOLOAD_CHAR) == NULL
2205 && !isdigit(ufunc->uf_name[0]);
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002206}
2207
2208/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002209 * Copy the function name of "fp" to buffer "buf".
2210 * "buf" must be able to hold the function name plus three bytes.
2211 * Takes care of script-local function names.
2212 */
2213 static void
2214cat_func_name(char_u *buf, ufunc_T *fp)
2215{
Bram Moolenaar0f769812020-09-12 18:32:34 +02002216 if (!func_is_global(fp))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002217 {
2218 STRCPY(buf, "<SNR>");
2219 STRCAT(buf, fp->uf_name + 3);
2220 }
2221 else
2222 STRCPY(buf, fp->uf_name);
2223}
2224
2225/*
2226 * Add a number variable "name" to dict "dp" with value "nr".
2227 */
2228 static void
2229add_nr_var(
2230 dict_T *dp,
2231 dictitem_T *v,
2232 char *name,
2233 varnumber_T nr)
2234{
2235 STRCPY(v->di_key, name);
2236 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002237 hash_add(&dp->dv_hashtab, DI2HIKEY(v), "add variable");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002238 v->di_tv.v_type = VAR_NUMBER;
2239 v->di_tv.v_lock = VAR_FIXED;
2240 v->di_tv.vval.v_number = nr;
2241}
2242
2243/*
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002244 * Free "fc".
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002245 */
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002246 static void
2247free_funccal(funccall_T *fc)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002248{
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002249 int i;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02002250
Bram Moolenaarca16c602022-09-06 18:57:08 +01002251 for (i = 0; i < fc->fc_ufuncs.ga_len; ++i)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02002252 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01002253 ufunc_T *fp = ((ufunc_T **)(fc->fc_ufuncs.ga_data))[i];
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02002254
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002255 // When garbage collecting a funccall_T may be freed before the
2256 // function that references it, clear its uf_scoped field.
2257 // The function may have been redefined and point to another
2258 // funccall_T, don't clear it then.
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02002259 if (fp != NULL && fp->uf_scoped == fc)
2260 fp->uf_scoped = NULL;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02002261 }
Bram Moolenaarca16c602022-09-06 18:57:08 +01002262 ga_clear(&fc->fc_ufuncs);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002263
Bram Moolenaarca16c602022-09-06 18:57:08 +01002264 func_ptr_unref(fc->fc_func);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002265 vim_free(fc);
2266}
2267
2268/*
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002269 * Free "fc" and what it contains.
2270 * Can be called only when "fc" is kept beyond the period of it called,
2271 * i.e. after cleanup_function_call(fc).
2272 */
2273 static void
2274free_funccal_contents(funccall_T *fc)
2275{
2276 listitem_T *li;
2277
2278 // Free all l: variables.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002279 vars_clear(&fc->fc_l_vars.dv_hashtab);
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002280
2281 // Free all a: variables.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002282 vars_clear(&fc->fc_l_avars.dv_hashtab);
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002283
2284 // Free the a:000 variables.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002285 FOR_ALL_LIST_ITEMS(&fc->fc_l_varlist, li)
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002286 clear_tv(&li->li_tv);
2287
2288 free_funccal(fc);
2289}
2290
2291/*
Bram Moolenaar6914c642017-04-01 21:21:30 +02002292 * Handle the last part of returning from a function: free the local hashtable.
2293 * Unless it is still in use by a closure.
2294 */
2295 static void
2296cleanup_function_call(funccall_T *fc)
2297{
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002298 int may_free_fc = fc->fc_refcount <= 0;
2299 int free_fc = TRUE;
2300
Bram Moolenaarca16c602022-09-06 18:57:08 +01002301 current_funccal = fc->fc_caller;
Bram Moolenaar6914c642017-04-01 21:21:30 +02002302
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002303 // Free all l: variables if not referred.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002304 if (may_free_fc && fc->fc_l_vars.dv_refcount == DO_NOT_FREE_CNT)
2305 vars_clear(&fc->fc_l_vars.dv_hashtab);
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002306 else
2307 free_fc = FALSE;
2308
2309 // If the a:000 list and the l: and a: dicts are not referenced and
2310 // there is no closure using it, we can free the funccall_T and what's
2311 // in it.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002312 if (may_free_fc && fc->fc_l_avars.dv_refcount == DO_NOT_FREE_CNT)
2313 vars_clear_ext(&fc->fc_l_avars.dv_hashtab, FALSE);
Bram Moolenaar6914c642017-04-01 21:21:30 +02002314 else
2315 {
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002316 int todo;
2317 hashitem_T *hi;
2318 dictitem_T *di;
Bram Moolenaar6914c642017-04-01 21:21:30 +02002319
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002320 free_fc = FALSE;
Bram Moolenaar6914c642017-04-01 21:21:30 +02002321
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002322 // Make a copy of the a: variables, since we didn't do that above.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002323 todo = (int)fc->fc_l_avars.dv_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +00002324 FOR_ALL_HASHTAB_ITEMS(&fc->fc_l_avars.dv_hashtab, hi, todo)
Bram Moolenaar6914c642017-04-01 21:21:30 +02002325 {
2326 if (!HASHITEM_EMPTY(hi))
2327 {
2328 --todo;
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002329 di = HI2DI(hi);
2330 copy_tv(&di->di_tv, &di->di_tv);
Bram Moolenaar6914c642017-04-01 21:21:30 +02002331 }
2332 }
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002333 }
Bram Moolenaar6914c642017-04-01 21:21:30 +02002334
Bram Moolenaarca16c602022-09-06 18:57:08 +01002335 if (may_free_fc && fc->fc_l_varlist.lv_refcount == DO_NOT_FREE_CNT)
2336 fc->fc_l_varlist.lv_first = NULL;
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002337 else
2338 {
2339 listitem_T *li;
2340
2341 free_fc = FALSE;
2342
2343 // Make a copy of the a:000 items, since we didn't do that above.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002344 FOR_ALL_LIST_ITEMS(&fc->fc_l_varlist, li)
Bram Moolenaar6914c642017-04-01 21:21:30 +02002345 copy_tv(&li->li_tv, &li->li_tv);
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002346 }
Bram Moolenaar4456ab52019-01-23 23:00:30 +01002347
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002348 if (free_fc)
2349 free_funccal(fc);
2350 else
2351 {
2352 static int made_copy = 0;
2353
2354 // "fc" is still in use. This can happen when returning "a:000",
2355 // assigning "l:" to a global variable or defining a closure.
2356 // Link "fc" in the list for garbage collection later.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002357 fc->fc_caller = previous_funccal;
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002358 previous_funccal = fc;
2359
2360 if (want_garbage_collect)
2361 // If garbage collector is ready, clear count.
2362 made_copy = 0;
2363 else if (++made_copy >= (int)((4096 * 1024) / sizeof(*fc)))
Bram Moolenaar4456ab52019-01-23 23:00:30 +01002364 {
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002365 // We have made a lot of copies, worth 4 Mbyte. This can happen
2366 // when repetitively calling a function that creates a reference to
Bram Moolenaar889da2f2019-02-02 14:02:30 +01002367 // itself somehow. Call the garbage collector soon to avoid using
Bram Moolenaar4456ab52019-01-23 23:00:30 +01002368 // too much memory.
2369 made_copy = 0;
Bram Moolenaar889da2f2019-02-02 14:02:30 +01002370 want_garbage_collect = TRUE;
Bram Moolenaar4456ab52019-01-23 23:00:30 +01002371 }
Bram Moolenaar6914c642017-04-01 21:21:30 +02002372 }
2373}
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002374
2375/*
Bram Moolenaar57bc2332021-12-15 12:06:43 +00002376 * Return TRUE if "name" is a numbered function, ignoring a "g:" prefix.
2377 */
2378 static int
2379numbered_function(char_u *name)
2380{
2381 return isdigit(*name)
2382 || (name[0] == 'g' && name[1] == ':' && isdigit(name[2]));
2383}
2384
2385/*
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002386 * There are two kinds of function names:
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00002387 * 1. ordinary names, function defined with :function or :def;
2388 * can start with "<SNR>123_" literally or with K_SPECIAL.
2389 * 2. Numbered functions and lambdas: "<lambda>123"
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002390 * For the first we only count the name stored in func_hashtab as a reference,
2391 * using function() does not count as a reference, because the function is
2392 * looked up by name.
2393 */
Bram Moolenaara05e5242020-09-19 18:19:19 +02002394 int
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002395func_name_refcount(char_u *name)
2396{
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00002397 return numbered_function(name) || (name[0] == '<' && name[1] == 'l');
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002398}
2399
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002400/*
2401 * Unreference "fc": decrement the reference count and free it when it
2402 * becomes zero. "fp" is detached from "fc".
2403 * When "force" is TRUE we are exiting.
2404 */
2405 static void
2406funccal_unref(funccall_T *fc, ufunc_T *fp, int force)
2407{
2408 funccall_T **pfc;
2409 int i;
2410
2411 if (fc == NULL)
2412 return;
2413
2414 if (--fc->fc_refcount <= 0 && (force || (
Bram Moolenaarca16c602022-09-06 18:57:08 +01002415 fc->fc_l_varlist.lv_refcount == DO_NOT_FREE_CNT
2416 && fc->fc_l_vars.dv_refcount == DO_NOT_FREE_CNT
2417 && fc->fc_l_avars.dv_refcount == DO_NOT_FREE_CNT)))
2418 for (pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->fc_caller)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002419 {
2420 if (fc == *pfc)
2421 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01002422 *pfc = fc->fc_caller;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002423 free_funccal_contents(fc);
2424 return;
2425 }
2426 }
Bram Moolenaarca16c602022-09-06 18:57:08 +01002427 for (i = 0; i < fc->fc_ufuncs.ga_len; ++i)
2428 if (((ufunc_T **)(fc->fc_ufuncs.ga_data))[i] == fp)
2429 ((ufunc_T **)(fc->fc_ufuncs.ga_data))[i] = NULL;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002430}
2431
2432/*
2433 * Remove the function from the function hashtable. If the function was
2434 * deleted while it still has references this was already done.
2435 * Return TRUE if the entry was deleted, FALSE if it wasn't found.
2436 */
2437 static int
2438func_remove(ufunc_T *fp)
2439{
2440 hashitem_T *hi;
2441
2442 // Return if it was already virtually deleted.
2443 if (fp->uf_flags & FC_DEAD)
2444 return FALSE;
2445
2446 hi = hash_find(&func_hashtab, UF2HIKEY(fp));
Yegappan Lakshmanan142ed772023-01-26 12:00:00 +00002447 if (HASHITEM_EMPTY(hi))
2448 return FALSE;
2449
2450 // When there is a def-function index do not actually remove the
2451 // function, so we can find the index when defining the function again.
2452 // Do remove it when it's a copy.
2453 if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002454 {
Yegappan Lakshmanan142ed772023-01-26 12:00:00 +00002455 fp->uf_flags |= FC_DEAD;
2456 return FALSE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002457 }
Yegappan Lakshmanan142ed772023-01-26 12:00:00 +00002458 hash_remove(&func_hashtab, hi, "remove function");
2459 fp->uf_flags |= FC_DELETED;
2460 return TRUE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002461}
2462
2463 static void
2464func_clear_items(ufunc_T *fp)
2465{
2466 ga_clear_strings(&(fp->uf_args));
2467 ga_clear_strings(&(fp->uf_def_args));
2468 ga_clear_strings(&(fp->uf_lines));
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002469 VIM_CLEAR(fp->uf_arg_types);
Bram Moolenaarfbbcd002020-10-15 12:46:44 +02002470 VIM_CLEAR(fp->uf_block_ids);
Bram Moolenaar292b90d2020-03-18 15:23:16 +01002471 VIM_CLEAR(fp->uf_va_name);
Bram Moolenaar6110e792020-07-08 19:35:21 +02002472 clear_type_list(&fp->uf_type_list);
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01002473
2474 // Increment the refcount of this function to avoid it being freed
2475 // recursively when the partial is freed.
2476 fp->uf_refcount += 3;
Bram Moolenaarf112f302020-12-20 17:47:52 +01002477 partial_unref(fp->uf_partial);
2478 fp->uf_partial = NULL;
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01002479 fp->uf_refcount -= 3;
Bram Moolenaar801ab062020-06-25 19:27:56 +02002480
2481#ifdef FEAT_LUA
2482 if (fp->uf_cb_free != NULL)
2483 {
2484 fp->uf_cb_free(fp->uf_cb_state);
2485 fp->uf_cb_free = NULL;
2486 }
2487
2488 fp->uf_cb_state = NULL;
2489 fp->uf_cb = NULL;
2490#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002491#ifdef FEAT_PROFILE
2492 VIM_CLEAR(fp->uf_tml_count);
2493 VIM_CLEAR(fp->uf_tml_total);
2494 VIM_CLEAR(fp->uf_tml_self);
2495#endif
2496}
2497
2498/*
2499 * Free all things that a function contains. Does not free the function
2500 * itself, use func_free() for that.
2501 * When "force" is TRUE we are exiting.
2502 */
2503 static void
2504func_clear(ufunc_T *fp, int force)
2505{
2506 if (fp->uf_cleared)
2507 return;
2508 fp->uf_cleared = TRUE;
2509
2510 // clear this function
2511 func_clear_items(fp);
2512 funccal_unref(fp->uf_scoped, fp, force);
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002513 unlink_def_function(fp);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002514}
2515
2516/*
2517 * Free a function and remove it from the list of functions. Does not free
2518 * what a function contains, call func_clear() first.
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002519 * When "force" is TRUE we are exiting.
Bram Moolenaara05e5242020-09-19 18:19:19 +02002520 * Returns OK when the function was actually freed.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002521 */
Bram Moolenaara05e5242020-09-19 18:19:19 +02002522 static int
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002523func_free(ufunc_T *fp, int force)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002524{
2525 // Only remove it when not done already, otherwise we would remove a newer
2526 // version of the function with the same name.
2527 if ((fp->uf_flags & (FC_DELETED | FC_REMOVED)) == 0)
2528 func_remove(fp);
2529
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002530 if ((fp->uf_flags & FC_DEAD) == 0 || force)
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02002531 {
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002532 if (fp->uf_dfunc_idx > 0)
2533 unlink_def_function(fp);
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02002534 VIM_CLEAR(fp->uf_name_exp);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002535 vim_free(fp);
Bram Moolenaara05e5242020-09-19 18:19:19 +02002536 return OK;
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02002537 }
Bram Moolenaara05e5242020-09-19 18:19:19 +02002538 return FAIL;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002539}
2540
2541/*
2542 * Free all things that a function contains and free the function itself.
2543 * When "force" is TRUE we are exiting.
2544 */
Bram Moolenaar2336c372021-12-06 15:06:54 +00002545 void
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002546func_clear_free(ufunc_T *fp, int force)
2547{
2548 func_clear(fp, force);
Bram Moolenaarfdeab652020-09-19 15:16:50 +02002549 if (force || fp->uf_dfunc_idx == 0 || func_name_refcount(fp->uf_name)
2550 || (fp->uf_flags & FC_COPY))
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02002551 func_free(fp, force);
Bram Moolenaar925e9fd2020-07-25 15:41:11 +02002552 else
2553 fp->uf_flags |= FC_DEAD;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002554}
2555
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002556/*
2557 * Copy already defined function "lambda" to a new function with name "global".
2558 * This is for when a compiled function defines a global function.
2559 */
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002560 int
Bram Moolenaar8fa745e2022-09-16 19:04:24 +01002561copy_lambda_to_global_func(
Bram Moolenaarcc341812022-09-19 15:54:34 +01002562 char_u *lambda,
2563 char_u *global,
2564 loopvarinfo_T *loopvarinfo,
2565 ectx_T *ectx)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002566{
Bram Moolenaaracc4b562022-01-24 13:54:45 +00002567 ufunc_T *ufunc = find_func_even_dead(lambda, FFED_IS_GLOBAL);
Bram Moolenaarf112f302020-12-20 17:47:52 +01002568 ufunc_T *fp = NULL;
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002569
2570 if (ufunc == NULL)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002571 {
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002572 semsg(_(e_lambda_function_not_found_str), lambda);
2573 return FAIL;
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002574 }
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002575
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00002576 fp = find_func(global, TRUE);
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002577 if (fp != NULL)
2578 {
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01002579 // TODO: handle ! to overwrite
Bram Moolenaar1a992222021-12-31 17:25:48 +00002580 semsg(_(e_function_str_already_exists_add_bang_to_replace), global);
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002581 return FAIL;
2582 }
2583
Bram Moolenaare01e5212023-01-08 20:31:18 +00002584 fp = alloc_ufunc(global);
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002585 if (fp == NULL)
2586 return FAIL;
2587
2588 fp->uf_varargs = ufunc->uf_varargs;
2589 fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY;
2590 fp->uf_def_status = ufunc->uf_def_status;
2591 fp->uf_dfunc_idx = ufunc->uf_dfunc_idx;
2592 if (ga_copy_strings(&ufunc->uf_args, &fp->uf_args) == FAIL
2593 || ga_copy_strings(&ufunc->uf_def_args, &fp->uf_def_args)
2594 == FAIL
2595 || ga_copy_strings(&ufunc->uf_lines, &fp->uf_lines) == FAIL)
2596 goto failed;
2597
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002598 if (ufunc->uf_arg_types != NULL)
2599 {
2600 fp->uf_arg_types = ALLOC_MULT(type_T *, fp->uf_args.ga_len);
2601 if (fp->uf_arg_types == NULL)
2602 goto failed;
2603 mch_memmove(fp->uf_arg_types, ufunc->uf_arg_types,
2604 sizeof(type_T *) * fp->uf_args.ga_len);
2605 }
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002606 if (ufunc->uf_va_name != NULL)
2607 {
2608 fp->uf_va_name = vim_strsave(ufunc->uf_va_name);
2609 if (fp->uf_va_name == NULL)
2610 goto failed;
2611 }
2612 fp->uf_ret_type = ufunc->uf_ret_type;
2613
2614 fp->uf_refcount = 1;
Bram Moolenaarc8ab30a2023-01-09 11:35:47 +00002615
2616 fp->uf_name_exp = NULL;
2617 set_ufunc_name(fp, global);
2618
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002619 hash_add(&func_hashtab, UF2HIKEY(fp), "copy lambda");
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002620
2621 // the referenced dfunc_T is now used one more time
2622 link_def_function(fp);
2623
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01002624 // Create a partial to store the context of the function where it was
2625 // instantiated. Only needs to be done once. Do this on the original
2626 // function, "dfunc->df_ufunc" will point to it.
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002627 if ((ufunc->uf_flags & FC_CLOSURE) && ufunc->uf_partial == NULL)
2628 {
2629 partial_T *pt = ALLOC_CLEAR_ONE(partial_T);
2630
2631 if (pt == NULL)
2632 goto failed;
Bram Moolenaarcc341812022-09-19 15:54:34 +01002633 if (fill_partial_and_closure(pt, ufunc, loopvarinfo, ectx) == FAIL)
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01002634 {
Bram Moolenaar6ed545e2022-05-09 20:09:23 +01002635 vim_free(pt);
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002636 goto failed;
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01002637 }
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002638 ufunc->uf_partial = pt;
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002639 }
2640
2641 return OK;
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002642
2643failed:
2644 func_clear_free(fp, TRUE);
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01002645 return FAIL;
Bram Moolenaar38ddf332020-07-31 22:05:04 +02002646}
2647
Bram Moolenaar0ba48e82020-11-17 18:23:19 +01002648static int funcdepth = 0;
2649
2650/*
2651 * Increment the function call depth count.
2652 * Return FAIL when going over 'maxfuncdepth'.
2653 * Otherwise return OK, must call funcdepth_decrement() later!
2654 */
2655 int
2656funcdepth_increment(void)
2657{
2658 if (funcdepth >= p_mfd)
2659 {
Bram Moolenaarc553a212021-12-26 20:20:34 +00002660 emsg(_(e_function_call_depth_is_higher_than_macfuncdepth));
Bram Moolenaar0ba48e82020-11-17 18:23:19 +01002661 return FAIL;
2662 }
2663 ++funcdepth;
2664 return OK;
2665}
2666
2667 void
2668funcdepth_decrement(void)
2669{
2670 --funcdepth;
2671}
2672
2673/*
2674 * Get the current function call depth.
2675 */
2676 int
2677funcdepth_get(void)
2678{
2679 return funcdepth;
2680}
2681
2682/*
2683 * Restore the function call depth. This is for cases where there is no
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01002684 * guarantee funcdepth_decrement() can be called exactly the same number of
Bram Moolenaar0ba48e82020-11-17 18:23:19 +01002685 * times as funcdepth_increment().
2686 */
2687 void
2688funcdepth_restore(int depth)
2689{
2690 funcdepth = depth;
2691}
Bram Moolenaar6914c642017-04-01 21:21:30 +02002692
2693/*
Bram Moolenaar9667b2c2022-09-07 17:28:09 +01002694 * Allocate a funccall_T, link it in current_funccal and fill in "fp" and
2695 * "rettv".
2696 * Must be followed by one call to remove_funccal() or cleanup_function_call().
2697 * Returns NULL when allocation fails.
2698 */
2699 funccall_T *
2700create_funccal(ufunc_T *fp, typval_T *rettv)
2701{
2702 funccall_T *fc = ALLOC_CLEAR_ONE(funccall_T);
2703
2704 if (fc == NULL)
2705 return NULL;
2706 fc->fc_caller = current_funccal;
2707 current_funccal = fc;
2708 fc->fc_func = fp;
2709 func_ptr_ref(fp);
2710 fc->fc_rettv = rettv;
2711 return fc;
2712}
2713
2714/*
2715 * To be called when returning from a compiled function; restores
2716 * current_funccal.
2717 */
2718 void
Yegappan Lakshmanana23a11b2023-02-21 14:27:41 +00002719remove_funccal(void)
Bram Moolenaar9667b2c2022-09-07 17:28:09 +01002720{
2721 funccall_T *fc = current_funccal;
2722
2723 current_funccal = fc->fc_caller;
2724 free_funccal(fc);
2725}
2726
2727/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002728 * Call a user function.
2729 */
Bram Moolenaar0917e862023-02-18 14:42:44 +00002730 static funcerror_T
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002731call_user_func(
Bram Moolenaare38eab22019-12-05 21:50:01 +01002732 ufunc_T *fp, // pointer to function
2733 int argcount, // nr of args
2734 typval_T *argvars, // arguments
2735 typval_T *rettv, // return value
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02002736 funcexe_T *funcexe, // context
Bram Moolenaare38eab22019-12-05 21:50:01 +01002737 dict_T *selfdict) // Dictionary for "self"
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002738{
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002739 sctx_T save_current_sctx;
Bram Moolenaar98aff652022-09-06 21:02:35 +01002740 ectx_T *save_current_ectx;
Bram Moolenaar93343722018-07-10 19:39:18 +02002741 int using_sandbox = FALSE;
Bram Moolenaarcdf04852022-02-12 22:13:06 +00002742 int save_sticky_cmdmod_flags = sticky_cmdmod_flags;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002743 funccall_T *fc;
2744 int save_did_emsg;
Bram Moolenaar0917e862023-02-18 14:42:44 +00002745 funcerror_T retval = FCERR_NONE;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002746 int default_arg_err = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002747 dictitem_T *v;
Bram Moolenaarca16c602022-09-06 18:57:08 +01002748 int fixvar_idx = 0; // index in fc_fixvar[]
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002749 int i;
2750 int ai;
2751 int islambda = FALSE;
2752 char_u numbuf[NUMBUFLEN];
2753 char_u *name;
Bram Moolenaarb47bed22021-04-14 17:06:43 +02002754 typval_T *tv_to_free[MAX_FUNC_ARGS];
2755 int tv_to_free_len = 0;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002756#ifdef FEAT_PROFILE
Bram Moolenaarb2049902021-01-24 12:53:53 +01002757 profinfo_T profile_info;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002758#endif
ichizok7e5fe382023-04-15 13:17:50 +01002759 ESTACK_CHECK_DECLARATION;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002760
Bram Moolenaarb2049902021-01-24 12:53:53 +01002761#ifdef FEAT_PROFILE
2762 CLEAR_FIELD(profile_info);
2763#endif
2764
Bram Moolenaar0ba48e82020-11-17 18:23:19 +01002765 // If depth of calling is getting too high, don't execute the function.
2766 if (funcdepth_increment() == FAIL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002767 {
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002768 rettv->v_type = VAR_NUMBER;
2769 rettv->vval.v_number = -1;
Bram Moolenaar0917e862023-02-18 14:42:44 +00002770 return FCERR_FAILED;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002771 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002772
Bram Moolenaare38eab22019-12-05 21:50:01 +01002773 line_breakcheck(); // check for CTRL-C hit
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002774
Bram Moolenaar9667b2c2022-09-07 17:28:09 +01002775 fc = create_funccal(fp, rettv);
Bram Moolenaar4456ab52019-01-23 23:00:30 +01002776 if (fc == NULL)
Bram Moolenaar0917e862023-02-18 14:42:44 +00002777 return FCERR_OTHER;
Bram Moolenaarca16c602022-09-06 18:57:08 +01002778 fc->fc_level = ex_nesting_level;
Bram Moolenaare38eab22019-12-05 21:50:01 +01002779 // Check if this function has a breakpoint.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002780 fc->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
2781 fc->fc_dbg_tick = debug_tick;
Bram Moolenaare38eab22019-12-05 21:50:01 +01002782 // Set up fields for closure.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002783 ga_init2(&fc->fc_ufuncs, sizeof(ufunc_T *), 1);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002784
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02002785 if (fp->uf_def_status != UF_NOT_COMPILED)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002786 {
Bram Moolenaar12d26532021-02-19 19:13:21 +01002787#ifdef FEAT_PROFILE
Bram Moolenaarca16c602022-09-06 18:57:08 +01002788 ufunc_T *caller = fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func;
Bram Moolenaar12d26532021-02-19 19:13:21 +01002789#endif
Bram Moolenaar25e0f582020-05-25 22:36:50 +02002790 // Execute the function, possibly compiling it first.
Bram Moolenaarb2049902021-01-24 12:53:53 +01002791#ifdef FEAT_PROFILE
Bram Moolenaar12d26532021-02-19 19:13:21 +01002792 if (do_profiling == PROF_YES)
2793 profile_may_start_func(&profile_info, fp, caller);
Bram Moolenaarb2049902021-01-24 12:53:53 +01002794#endif
Bram Moolenaarcdf04852022-02-12 22:13:06 +00002795 sticky_cmdmod_flags = 0;
Bram Moolenaar0917e862023-02-18 14:42:44 +00002796 if (call_def_function(fp, argcount, argvars, 0,
2797 funcexe->fe_partial, funcexe->fe_object, fc, rettv) == FAIL)
2798 retval = FCERR_FAILED;
Bram Moolenaar0ba48e82020-11-17 18:23:19 +01002799 funcdepth_decrement();
Bram Moolenaarb2049902021-01-24 12:53:53 +01002800#ifdef FEAT_PROFILE
2801 if (do_profiling == PROF_YES && (fp->uf_profiling
Bram Moolenaar12d26532021-02-19 19:13:21 +01002802 || (caller != NULL && caller->uf_profiling)))
2803 profile_may_end_func(&profile_info, fp, caller);
Bram Moolenaarb2049902021-01-24 12:53:53 +01002804#endif
Bram Moolenaar9667b2c2022-09-07 17:28:09 +01002805 remove_funccal();
Bram Moolenaarcdf04852022-02-12 22:13:06 +00002806 sticky_cmdmod_flags = save_sticky_cmdmod_flags;
Bram Moolenaar0917e862023-02-18 14:42:44 +00002807 return retval;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002808 }
2809
Bram Moolenaar38453522021-11-28 22:00:12 +00002810 islambda = fp->uf_flags & FC_LAMBDA;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002811
2812 /*
Bram Moolenaar98aff652022-09-06 21:02:35 +01002813 * Note about using fc->fc_fixvar[]: This is an array of FIXVAR_CNT
2814 * variables with names up to VAR_SHORT_LEN long. This avoids having to
2815 * alloc/free each argument variable and saves a lot of time.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002816 */
2817 /*
2818 * Init l: variables.
2819 */
Bram Moolenaarca16c602022-09-06 18:57:08 +01002820 init_var_dict(&fc->fc_l_vars, &fc->fc_l_vars_var, VAR_DEF_SCOPE);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002821 if (selfdict != NULL)
2822 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01002823 // Set l:self to "selfdict". Use "name" to avoid a warning from
2824 // some compiler that checks the destination size.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002825 v = &fc->fc_fixvar[fixvar_idx++].var;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002826 name = v->di_key;
2827 STRCPY(name, "self");
Bram Moolenaar31b81602019-02-10 22:14:27 +01002828 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002829 hash_add(&fc->fc_l_vars.dv_hashtab, DI2HIKEY(v), "set self dictionary");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002830 v->di_tv.v_type = VAR_DICT;
2831 v->di_tv.v_lock = 0;
2832 v->di_tv.vval.v_dict = selfdict;
2833 ++selfdict->dv_refcount;
2834 }
2835
2836 /*
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002837 * Init a: variables, unless none found (in lambda).
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002838 * Set a:0 to "argcount" less number of named arguments, if >= 0.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002839 * Set a:000 to a list with room for the "..." arguments.
2840 */
Bram Moolenaarca16c602022-09-06 18:57:08 +01002841 init_var_dict(&fc->fc_l_avars, &fc->fc_l_avars_var, VAR_SCOPE);
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002842 if ((fp->uf_flags & FC_NOARGS) == 0)
Bram Moolenaarca16c602022-09-06 18:57:08 +01002843 add_nr_var(&fc->fc_l_avars, &fc->fc_fixvar[fixvar_idx++].var, "0",
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002844 (varnumber_T)(argcount >= fp->uf_args.ga_len
2845 ? argcount - fp->uf_args.ga_len : 0));
Bram Moolenaarca16c602022-09-06 18:57:08 +01002846 fc->fc_l_avars.dv_lock = VAR_FIXED;
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002847 if ((fp->uf_flags & FC_NOARGS) == 0)
2848 {
2849 // Use "name" to avoid a warning from some compiler that checks the
2850 // destination size.
Bram Moolenaarca16c602022-09-06 18:57:08 +01002851 v = &fc->fc_fixvar[fixvar_idx++].var;
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002852 name = v->di_key;
2853 STRCPY(name, "000");
2854 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002855 hash_add(&fc->fc_l_avars.dv_hashtab, DI2HIKEY(v), "function argument");
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002856 v->di_tv.v_type = VAR_LIST;
2857 v->di_tv.v_lock = VAR_FIXED;
Bram Moolenaarca16c602022-09-06 18:57:08 +01002858 v->di_tv.vval.v_list = &fc->fc_l_varlist;
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002859 }
Bram Moolenaarca16c602022-09-06 18:57:08 +01002860 CLEAR_FIELD(fc->fc_l_varlist);
2861 fc->fc_l_varlist.lv_refcount = DO_NOT_FREE_CNT;
2862 fc->fc_l_varlist.lv_lock = VAR_FIXED;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002863
2864 /*
2865 * Set a:firstline to "firstline" and a:lastline to "lastline".
2866 * Set a:name to named arguments.
2867 * Set a:N to the "..." arguments.
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002868 * Skipped when no a: variables used (in lambda).
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002869 */
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002870 if ((fp->uf_flags & FC_NOARGS) == 0)
2871 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01002872 add_nr_var(&fc->fc_l_avars, &fc->fc_fixvar[fixvar_idx++].var,
2873 "firstline", (varnumber_T)funcexe->fe_firstline);
2874 add_nr_var(&fc->fc_l_avars, &fc->fc_fixvar[fixvar_idx++].var,
2875 "lastline", (varnumber_T)funcexe->fe_lastline);
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002876 }
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002877 for (i = 0; i < argcount || i < fp->uf_args.ga_len; ++i)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002878 {
2879 int addlocal = FALSE;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002880 typval_T def_rettv;
2881 int isdefault = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002882
2883 ai = i - fp->uf_args.ga_len;
2884 if (ai < 0)
2885 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01002886 // named argument a:name
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002887 name = FUNCARG(fp, i);
2888 if (islambda)
2889 addlocal = TRUE;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002890
2891 // evaluate named argument default expression
2892 isdefault = ai + fp->uf_def_args.ga_len >= 0
2893 && (i >= argcount || (argvars[i].v_type == VAR_SPECIAL
2894 && argvars[i].vval.v_number == VVAL_NONE));
2895 if (isdefault)
2896 {
2897 char_u *default_expr = NULL;
Bram Moolenaarb47bed22021-04-14 17:06:43 +02002898
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002899 def_rettv.v_type = VAR_NUMBER;
2900 def_rettv.vval.v_number = -1;
2901
2902 default_expr = ((char_u **)(fp->uf_def_args.ga_data))
2903 [ai + fp->uf_def_args.ga_len];
Bram Moolenaar5409f5d2020-06-24 18:37:35 +02002904 if (eval1(&default_expr, &def_rettv, &EVALARG_EVALUATE) == FAIL)
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02002905 {
2906 default_arg_err = 1;
2907 break;
2908 }
2909 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002910 }
2911 else
2912 {
Bram Moolenaarf10806b2020-04-02 18:34:35 +02002913 if ((fp->uf_flags & FC_NOARGS) != 0)
2914 // Bail out if no a: arguments used (in lambda).
2915 break;
2916
Bram Moolenaare38eab22019-12-05 21:50:01 +01002917 // "..." argument a:1, a:2, etc.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002918 sprintf((char *)numbuf, "%d", ai + 1);
2919 name = numbuf;
2920 }
2921 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
2922 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01002923 v = &fc->fc_fixvar[fixvar_idx++].var;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002924 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002925 STRCPY(v->di_key, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002926 }
2927 else
2928 {
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002929 v = dictitem_alloc(name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002930 if (v == NULL)
2931 break;
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002932 v->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002933 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002934
Bram Moolenaar6e5000d2019-06-17 21:18:41 +02002935 // Note: the values are copied directly to avoid alloc/free.
2936 // "argvars" must have VAR_FIXED for v_lock.
2937 v->di_tv = isdefault ? def_rettv : argvars[i];
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002938 v->di_tv.v_lock = VAR_FIXED;
2939
Bram Moolenaarb47bed22021-04-14 17:06:43 +02002940 if (isdefault)
2941 // Need to free this later, no matter where it's stored.
2942 tv_to_free[tv_to_free_len++] = &v->di_tv;
2943
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002944 if (addlocal)
2945 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01002946 // Named arguments should be accessed without the "a:" prefix in
2947 // lambda expressions. Add to the l: dict.
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02002948 copy_tv(&v->di_tv, &v->di_tv);
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002949 hash_add(&fc->fc_l_vars.dv_hashtab, DI2HIKEY(v), "local variable");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002950 }
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02002951 else
Bram Moolenaaref2c3252022-11-25 16:31:51 +00002952 hash_add(&fc->fc_l_avars.dv_hashtab, DI2HIKEY(v), "add variable");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002953
2954 if (ai >= 0 && ai < MAX_FUNC_ARGS)
2955 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01002956 listitem_T *li = &fc->fc_l_listitems[ai];
Bram Moolenaar209b8e32019-03-14 13:43:24 +01002957
2958 li->li_tv = argvars[i];
2959 li->li_tv.v_lock = VAR_FIXED;
Bram Moolenaarca16c602022-09-06 18:57:08 +01002960 list_append(&fc->fc_l_varlist, li);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002961 }
2962 }
2963
Bram Moolenaare38eab22019-12-05 21:50:01 +01002964 // Don't redraw while executing the function.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002965 ++RedrawingDisabled;
Bram Moolenaar93343722018-07-10 19:39:18 +02002966
2967 if (fp->uf_flags & FC_SANDBOX)
2968 {
2969 using_sandbox = TRUE;
2970 ++sandbox;
2971 }
2972
Bram Moolenaar25e0f582020-05-25 22:36:50 +02002973 estack_push_ufunc(fp, 1);
ichizok7e5fe382023-04-15 13:17:50 +01002974 ESTACK_CHECK_SETUP;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002975 if (p_verbose >= 12)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002976 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002977 ++no_wait_return;
2978 verbose_enter_scroll();
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002979
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002980 smsg(_("calling %s"), SOURCING_NAME);
2981 if (p_verbose >= 14)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002982 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002983 char_u buf[MSG_BUF_LEN];
2984 char_u numbuf2[NUMBUFLEN];
2985 char_u *tofree;
2986 char_u *s;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002987
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002988 msg_puts("(");
2989 for (i = 0; i < argcount; ++i)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002990 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002991 if (i > 0)
2992 msg_puts(", ");
2993 if (argvars[i].v_type == VAR_NUMBER)
2994 msg_outnum((long)argvars[i].vval.v_number);
2995 else
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002996 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002997 // Do not want errors such as E724 here.
2998 ++emsg_off;
2999 s = tv2string(&argvars[i], &tofree, numbuf2, 0);
3000 --emsg_off;
3001 if (s != NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003002 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003003 if (vim_strsize(s) > MSG_BUF_CLEN)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003004 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003005 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
3006 s = buf;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003007 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003008 msg_puts((char *)s);
3009 vim_free(tofree);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003010 }
3011 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003012 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003013 msg_puts(")");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003014 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003015 msg_puts("\n"); // don't overwrite this either
3016
3017 verbose_leave_scroll();
3018 --no_wait_return;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003019 }
3020#ifdef FEAT_PROFILE
Bram Moolenaar12d26532021-02-19 19:13:21 +01003021 if (do_profiling == PROF_YES)
3022 profile_may_start_func(&profile_info, fp,
Bram Moolenaarca16c602022-09-06 18:57:08 +01003023 fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003024#endif
3025
Bram Moolenaarcdf04852022-02-12 22:13:06 +00003026 // "legacy" does not apply to commands in the function
3027 sticky_cmdmod_flags = 0;
3028
Bram Moolenaar98aff652022-09-06 21:02:35 +01003029 // If called from a compiled :def function the execution context must be
3030 // hidden, any deferred functions need to be added to the function being
3031 // executed here.
dundargocc57b5bc2022-11-02 13:30:51 +00003032 save_current_ectx = clear_current_ectx();
Bram Moolenaar98aff652022-09-06 21:02:35 +01003033
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02003034 save_current_sctx = current_sctx;
3035 current_sctx = fp->uf_script_ctx;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003036 save_did_emsg = did_emsg;
3037 did_emsg = FALSE;
3038
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02003039 if (default_arg_err && (fp->uf_flags & FC_ABORT))
Bram Moolenaar0917e862023-02-18 14:42:44 +00003040 {
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02003041 did_emsg = TRUE;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003042 retval = FCERR_FAILED;
3043 }
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003044 else if (islambda)
3045 {
3046 char_u *p = *(char_u **)fp->uf_lines.ga_data + 7;
3047
3048 // A Lambda always has the command "return {expr}". It is much faster
3049 // to evaluate {expr} directly.
3050 ++ex_nesting_level;
Bram Moolenaar5409f5d2020-06-24 18:37:35 +02003051 (void)eval1(&p, rettv, &EVALARG_EVALUATE);
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003052 --ex_nesting_level;
3053 }
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02003054 else
3055 // call do_cmdline() to execute the lines
3056 do_cmdline(NULL, get_func_line, (void *)fc,
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003057 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
3058
Bram Moolenaar1d84f762022-09-03 21:35:53 +01003059 // Invoke functions added with ":defer".
Bram Moolenaar58779852022-09-06 18:31:14 +01003060 handle_defer_one(current_funccal);
Bram Moolenaar1d84f762022-09-03 21:35:53 +01003061
Bram Moolenaar79cdf022023-05-20 14:07:00 +01003062 if (RedrawingDisabled > 0)
3063 --RedrawingDisabled;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003064
Bram Moolenaare38eab22019-12-05 21:50:01 +01003065 // when the function was aborted because of an error, return -1
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003066 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN)
3067 {
3068 clear_tv(rettv);
3069 rettv->v_type = VAR_NUMBER;
3070 rettv->vval.v_number = -1;
Bram Moolenaard1149752023-02-18 15:31:53 +00003071
3072 // In corner cases returning a "failed" value is not backwards
3073 // compatible. Only do this for Vim9 script.
3074 if (in_vim9script())
3075 retval = FCERR_FAILED;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003076 }
3077
3078#ifdef FEAT_PROFILE
Bram Moolenaar12d26532021-02-19 19:13:21 +01003079 if (do_profiling == PROF_YES)
3080 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01003081 ufunc_T *caller = fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func;
Bram Moolenaar12d26532021-02-19 19:13:21 +01003082
3083 if (fp->uf_profiling || (caller != NULL && caller->uf_profiling))
3084 profile_may_end_func(&profile_info, fp, caller);
3085 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003086#endif
3087
Bram Moolenaare38eab22019-12-05 21:50:01 +01003088 // when being verbose, mention the return value
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003089 if (p_verbose >= 12)
3090 {
3091 ++no_wait_return;
3092 verbose_enter_scroll();
3093
3094 if (aborting())
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003095 smsg(_("%s aborted"), SOURCING_NAME);
Bram Moolenaarca16c602022-09-06 18:57:08 +01003096 else if (fc->fc_rettv->v_type == VAR_NUMBER)
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003097 smsg(_("%s returning #%ld"), SOURCING_NAME,
Bram Moolenaarca16c602022-09-06 18:57:08 +01003098 (long)fc->fc_rettv->vval.v_number);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003099 else
3100 {
3101 char_u buf[MSG_BUF_LEN];
3102 char_u numbuf2[NUMBUFLEN];
3103 char_u *tofree;
3104 char_u *s;
3105
Bram Moolenaare38eab22019-12-05 21:50:01 +01003106 // The value may be very long. Skip the middle part, so that we
3107 // have some idea how it starts and ends. smsg() would always
3108 // truncate it at the end. Don't want errors such as E724 here.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003109 ++emsg_off;
Bram Moolenaarca16c602022-09-06 18:57:08 +01003110 s = tv2string(fc->fc_rettv, &tofree, numbuf2, 0);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003111 --emsg_off;
3112 if (s != NULL)
3113 {
3114 if (vim_strsize(s) > MSG_BUF_CLEN)
3115 {
3116 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
3117 s = buf;
3118 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003119 smsg(_("%s returning %s"), SOURCING_NAME, s);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003120 vim_free(tofree);
3121 }
3122 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01003123 msg_puts("\n"); // don't overwrite this either
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003124
3125 verbose_leave_scroll();
3126 --no_wait_return;
3127 }
3128
ichizok7e5fe382023-04-15 13:17:50 +01003129 ESTACK_CHECK_NOW;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003130 estack_pop();
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02003131 current_sctx = save_current_sctx;
Bram Moolenaar98aff652022-09-06 21:02:35 +01003132 restore_current_ectx(save_current_ectx);
3133
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003134#ifdef FEAT_PROFILE
3135 if (do_profiling == PROF_YES)
Bram Moolenaarb2049902021-01-24 12:53:53 +01003136 script_prof_restore(&profile_info.pi_wait_start);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003137#endif
Bram Moolenaar93343722018-07-10 19:39:18 +02003138 if (using_sandbox)
3139 --sandbox;
Bram Moolenaarcdf04852022-02-12 22:13:06 +00003140 sticky_cmdmod_flags = save_sticky_cmdmod_flags;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003141
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003142 if (p_verbose >= 12 && SOURCING_NAME != NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003143 {
3144 ++no_wait_return;
3145 verbose_enter_scroll();
3146
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01003147 smsg(_("continuing in %s"), SOURCING_NAME);
Bram Moolenaare38eab22019-12-05 21:50:01 +01003148 msg_puts("\n"); // don't overwrite this either
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003149
3150 verbose_leave_scroll();
3151 --no_wait_return;
3152 }
3153
3154 did_emsg |= save_did_emsg;
Bram Moolenaar0ba48e82020-11-17 18:23:19 +01003155 funcdepth_decrement();
Bram Moolenaarb47bed22021-04-14 17:06:43 +02003156 for (i = 0; i < tv_to_free_len; ++i)
3157 clear_tv(tv_to_free[i]);
Bram Moolenaar6914c642017-04-01 21:21:30 +02003158 cleanup_function_call(fc);
Bram Moolenaar0917e862023-02-18 14:42:44 +00003159
3160 return retval;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003161}
3162
3163/*
Bram Moolenaar50824712020-12-20 21:10:17 +01003164 * Check the argument count for user function "fp".
3165 * Return FCERR_UNKNOWN if OK, FCERR_TOOFEW or FCERR_TOOMANY otherwise.
3166 */
Bram Moolenaar0917e862023-02-18 14:42:44 +00003167 funcerror_T
Bram Moolenaar50824712020-12-20 21:10:17 +01003168check_user_func_argcount(ufunc_T *fp, int argcount)
3169{
3170 int regular_args = fp->uf_args.ga_len;
3171
3172 if (argcount < regular_args - fp->uf_def_args.ga_len)
3173 return FCERR_TOOFEW;
3174 else if (!has_varargs(fp) && argcount > regular_args)
3175 return FCERR_TOOMANY;
3176 return FCERR_UNKNOWN;
3177}
3178
3179/*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003180 * Call a user function after checking the arguments.
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02003181 */
Bram Moolenaar0917e862023-02-18 14:42:44 +00003182 funcerror_T
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003183call_user_func_check(
3184 ufunc_T *fp,
3185 int argcount,
3186 typval_T *argvars,
3187 typval_T *rettv,
3188 funcexe_T *funcexe,
3189 dict_T *selfdict)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02003190{
Bram Moolenaar0917e862023-02-18 14:42:44 +00003191 funcerror_T error = FCERR_NONE;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02003192
Bram Moolenaar7d149f82022-06-17 19:23:34 +01003193#ifdef FEAT_LUA
3194 if (fp->uf_flags & FC_CFUNC)
3195 {
3196 cfunc_T cb = fp->uf_cb;
3197
3198 return (*cb)(argcount, argvars, rettv, fp->uf_cb_state);
3199 }
3200#endif
3201
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003202 if (fp->uf_flags & FC_RANGE && funcexe->fe_doesrange != NULL)
3203 *funcexe->fe_doesrange = TRUE;
Bram Moolenaar50824712020-12-20 21:10:17 +01003204 error = check_user_func_argcount(fp, argcount);
3205 if (error != FCERR_UNKNOWN)
3206 return error;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003207
Bram Moolenaar50824712020-12-20 21:10:17 +01003208 if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
Bram Moolenaar0917e862023-02-18 14:42:44 +00003209 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003210 error = FCERR_DICT;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003211 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003212 else
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02003213 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003214 int did_save_redo = FALSE;
3215 save_redo_T save_redo;
3216
3217 /*
3218 * Call the user function.
3219 * Save and restore search patterns, script variables and
3220 * redo buffer.
3221 */
3222 save_search_patterns();
3223 if (!ins_compl_active())
3224 {
3225 saveRedobuff(&save_redo);
3226 did_save_redo = TRUE;
3227 }
3228 ++fp->uf_calls;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003229 error = call_user_func(fp, argcount, argvars, rettv, funcexe,
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003230 (fp->uf_flags & FC_DICT) ? selfdict : NULL);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003231 if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0)
3232 // Function was unreferenced while being used, free it now.
3233 func_clear_free(fp, FALSE);
3234 if (did_save_redo)
3235 restoreRedobuff(&save_redo);
3236 restore_search_patterns();
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02003237 }
Bram Moolenaar0917e862023-02-18 14:42:44 +00003238
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003239 return error;
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003240}
3241
Bram Moolenaar27e80c82018-10-14 21:41:01 +02003242static funccal_entry_T *funccal_stack = NULL;
3243
3244/*
3245 * Save the current function call pointer, and set it to NULL.
3246 * Used when executing autocommands and for ":source".
3247 */
3248 void
3249save_funccal(funccal_entry_T *entry)
3250{
3251 entry->top_funccal = current_funccal;
3252 entry->next = funccal_stack;
3253 funccal_stack = entry;
3254 current_funccal = NULL;
3255}
3256
3257 void
3258restore_funccal(void)
3259{
3260 if (funccal_stack == NULL)
Bram Moolenaar097c5372023-05-24 21:02:24 +01003261 internal_error("restore_funccal()");
Bram Moolenaar27e80c82018-10-14 21:41:01 +02003262 else
3263 {
3264 current_funccal = funccal_stack->top_funccal;
3265 funccal_stack = funccal_stack->next;
3266 }
3267}
3268
Bram Moolenaarfa55cfc2019-07-13 22:59:32 +02003269 funccall_T *
3270get_current_funccal(void)
3271{
3272 return current_funccal;
3273}
3274
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003275/*
Bram Moolenaara749a422022-02-12 19:52:25 +00003276 * Return TRUE when currently at the script level:
3277 * - not in a function
3278 * - not executing an autocommand
3279 * Note that when an autocommand sources a script the result is FALSE;
3280 */
3281 int
3282at_script_level(void)
3283{
3284 return current_funccal == NULL && autocmd_match == NULL;
3285}
3286
3287/*
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003288 * Mark all functions of script "sid" as deleted.
3289 */
3290 void
3291delete_script_functions(int sid)
3292{
3293 hashitem_T *hi;
3294 ufunc_T *fp;
Bram Moolenaarce658352020-07-31 23:47:12 +02003295 long_u todo = 1;
Bram Moolenaar909ed7e2020-04-27 23:16:41 +02003296 char_u buf[30];
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003297 size_t len;
3298
3299 buf[0] = K_SPECIAL;
3300 buf[1] = KS_EXTRA;
3301 buf[2] = (int)KE_SNR;
Bram Moolenaar909ed7e2020-04-27 23:16:41 +02003302 sprintf((char *)buf + 3, "%d_", sid);
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003303 len = STRLEN(buf);
3304
Bram Moolenaarce658352020-07-31 23:47:12 +02003305 while (todo > 0)
3306 {
3307 todo = func_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +00003308 FOR_ALL_HASHTAB_ITEMS(&func_hashtab, hi, todo)
Bram Moolenaarce658352020-07-31 23:47:12 +02003309 if (!HASHITEM_EMPTY(hi))
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003310 {
Bram Moolenaarce658352020-07-31 23:47:12 +02003311 fp = HI2UF(hi);
3312 if (STRNCMP(fp->uf_name, buf, len) == 0)
3313 {
3314 int changed = func_hashtab.ht_changed;
3315
3316 fp->uf_flags |= FC_DEAD;
Bram Moolenaarc970e422021-03-17 15:03:04 +01003317
3318 if (fp->uf_calls > 0)
3319 {
3320 // Function is executing, don't free it but do remove
3321 // it from the hashtable.
3322 if (func_remove(fp))
3323 fp->uf_refcount--;
3324 }
3325 else
3326 {
3327 func_clear(fp, TRUE);
3328 // When clearing a function another function can be
3329 // cleared as a side effect. When that happens start
3330 // over.
3331 if (changed != func_hashtab.ht_changed)
3332 break;
3333 }
Bram Moolenaarce658352020-07-31 23:47:12 +02003334 }
3335 --todo;
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003336 }
Bram Moolenaarce658352020-07-31 23:47:12 +02003337 }
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003338}
3339
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003340#if defined(EXITFREE) || defined(PROTO)
3341 void
3342free_all_functions(void)
3343{
3344 hashitem_T *hi;
Bram Moolenaarc2574872016-08-11 22:51:05 +02003345 ufunc_T *fp;
3346 long_u skipped = 0;
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003347 long_u todo = 1;
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02003348 int changed;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003349
Bram Moolenaare38eab22019-12-05 21:50:01 +01003350 // Clean up the current_funccal chain and the funccal stack.
Bram Moolenaar6914c642017-04-01 21:21:30 +02003351 while (current_funccal != NULL)
3352 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01003353 clear_tv(current_funccal->fc_rettv);
Bram Moolenaar6914c642017-04-01 21:21:30 +02003354 cleanup_function_call(current_funccal);
Bram Moolenaar27e80c82018-10-14 21:41:01 +02003355 if (current_funccal == NULL && funccal_stack != NULL)
3356 restore_funccal();
Bram Moolenaar6914c642017-04-01 21:21:30 +02003357 }
3358
Bram Moolenaare38eab22019-12-05 21:50:01 +01003359 // First clear what the functions contain. Since this may lower the
3360 // reference count of a function, it may also free a function and change
3361 // the hash table. Restart if that happens.
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003362 while (todo > 0)
3363 {
3364 todo = func_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +00003365 FOR_ALL_HASHTAB_ITEMS(&func_hashtab, hi, todo)
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003366 if (!HASHITEM_EMPTY(hi))
3367 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003368 // clear the def function index now
3369 fp = HI2UF(hi);
3370 fp->uf_flags &= ~FC_DEAD;
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02003371 fp->uf_def_status = UF_NOT_COMPILED;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003372
Bram Moolenaare38eab22019-12-05 21:50:01 +01003373 // Only free functions that are not refcounted, those are
3374 // supposed to be freed when no longer referenced.
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003375 if (func_name_refcount(fp->uf_name))
3376 ++skipped;
3377 else
3378 {
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02003379 changed = func_hashtab.ht_changed;
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003380 func_clear(fp, TRUE);
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02003381 if (changed != func_hashtab.ht_changed)
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003382 {
3383 skipped = 0;
3384 break;
3385 }
3386 }
3387 --todo;
3388 }
3389 }
3390
Bram Moolenaare38eab22019-12-05 21:50:01 +01003391 // Now actually free the functions. Need to start all over every time,
3392 // because func_free() may change the hash table.
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01003393 skipped = 0;
Bram Moolenaarc2574872016-08-11 22:51:05 +02003394 while (func_hashtab.ht_used > skipped)
3395 {
3396 todo = func_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +00003397 FOR_ALL_HASHTAB_ITEMS(&func_hashtab, hi, todo)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003398 if (!HASHITEM_EMPTY(hi))
3399 {
Bram Moolenaarc2574872016-08-11 22:51:05 +02003400 --todo;
Bram Moolenaare38eab22019-12-05 21:50:01 +01003401 // Only free functions that are not refcounted, those are
3402 // supposed to be freed when no longer referenced.
Bram Moolenaarc2574872016-08-11 22:51:05 +02003403 fp = HI2UF(hi);
3404 if (func_name_refcount(fp->uf_name))
3405 ++skipped;
3406 else
3407 {
Bram Moolenaara05e5242020-09-19 18:19:19 +02003408 if (func_free(fp, FALSE) == OK)
3409 {
3410 skipped = 0;
3411 break;
3412 }
3413 // did not actually free it
3414 ++skipped;
Bram Moolenaarc2574872016-08-11 22:51:05 +02003415 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003416 }
Bram Moolenaarc2574872016-08-11 22:51:05 +02003417 }
3418 if (skipped == 0)
3419 hash_clear(&func_hashtab);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003420
3421 free_def_functions();
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003422}
3423#endif
3424
3425/*
3426 * Return TRUE if "name" looks like a builtin function name: starts with a
Bram Moolenaar15d16352022-01-17 20:09:08 +00003427 * lower case letter, doesn't contain AUTOLOAD_CHAR or ':', no "." after the
3428 * name.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003429 * "len" is the length of "name", or -1 for NUL terminated.
3430 */
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003431 int
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003432builtin_function(char_u *name, int len)
3433{
Bram Moolenaar15d16352022-01-17 20:09:08 +00003434 int i;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003435
Bram Moolenaara26b9702020-04-18 19:53:28 +02003436 if (!ASCII_ISLOWER(name[0]) || name[1] == ':')
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003437 return FALSE;
Bram Moolenaar15d16352022-01-17 20:09:08 +00003438 for (i = 0; name[i] != NUL && (len < 0 || i < len); ++i)
3439 {
3440 if (name[i] == AUTOLOAD_CHAR)
3441 return FALSE;
3442 if (!eval_isnamec(name[i]))
3443 {
3444 // "name.something" is not a builtin function
3445 if (name[i] == '.')
3446 return FALSE;
3447 break;
3448 }
3449 }
3450 return TRUE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003451}
3452
3453 int
3454func_call(
3455 char_u *name,
3456 typval_T *args,
3457 partial_T *partial,
3458 dict_T *selfdict,
3459 typval_T *rettv)
3460{
Bram Moolenaar50985eb2020-01-27 22:09:39 +01003461 list_T *l = args->vval.v_list;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003462 listitem_T *item;
3463 typval_T argv[MAX_FUNC_ARGS + 1];
3464 int argc = 0;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003465 int r = 0;
3466
Bram Moolenaar7e9f3512020-05-13 22:44:22 +02003467 CHECK_LIST_MATERIALIZE(l);
Bram Moolenaar00d253e2020-04-06 22:13:01 +02003468 FOR_ALL_LIST_ITEMS(l, item)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003469 {
3470 if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc))
3471 {
Bram Moolenaara6f79292022-01-04 21:30:47 +00003472 emsg(_(e_too_many_arguments));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003473 break;
3474 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01003475 // Make a copy of each argument. This is needed to be able to set
3476 // v_lock to VAR_FIXED in the copy without changing the original list.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003477 copy_tv(&item->li_tv, &argv[argc++]);
3478 }
3479
3480 if (item == NULL)
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003481 {
3482 funcexe_T funcexe;
3483
Bram Moolenaara80faa82020-04-12 19:37:17 +02003484 CLEAR_FIELD(funcexe);
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003485 funcexe.fe_firstline = curwin->w_cursor.lnum;
3486 funcexe.fe_lastline = curwin->w_cursor.lnum;
3487 funcexe.fe_evaluate = TRUE;
3488 funcexe.fe_partial = partial;
3489 funcexe.fe_selfdict = selfdict;
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003490 r = call_func(name, -1, rettv, argc, argv, &funcexe);
3491 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003492
Bram Moolenaare38eab22019-12-05 21:50:01 +01003493 // Free the arguments.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003494 while (argc > 0)
3495 clear_tv(&argv[--argc]);
3496
3497 return r;
3498}
3499
Bram Moolenaar0e57dd82019-09-16 22:56:03 +02003500static int callback_depth = 0;
3501
3502 int
3503get_callback_depth(void)
3504{
3505 return callback_depth;
3506}
3507
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003508/*
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02003509 * Invoke call_func() with a callback.
Yegappan Lakshmanan4dc24eb2021-12-07 12:23:57 +00003510 * Returns FAIL if the callback could not be called.
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02003511 */
3512 int
3513call_callback(
3514 callback_T *callback,
3515 int len, // length of "name" or -1 to use strlen()
3516 typval_T *rettv, // return value goes here
3517 int argcount, // number of "argvars"
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003518 typval_T *argvars) // vars for arguments, must have "argcount"
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02003519 // PLUS ONE elements!
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02003520{
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003521 funcexe_T funcexe;
Bram Moolenaar0e57dd82019-09-16 22:56:03 +02003522 int ret;
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003523
Yegappan Lakshmanan4dc24eb2021-12-07 12:23:57 +00003524 if (callback->cb_name == NULL || *callback->cb_name == NUL)
3525 return FAIL;
Bram Moolenaara80faa82020-04-12 19:37:17 +02003526 CLEAR_FIELD(funcexe);
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003527 funcexe.fe_evaluate = TRUE;
3528 funcexe.fe_partial = callback->cb_partial;
Bram Moolenaar0e57dd82019-09-16 22:56:03 +02003529 ++callback_depth;
3530 ret = call_func(callback->cb_name, len, rettv, argcount, argvars, &funcexe);
3531 --callback_depth;
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003532
3533 // When a :def function was called that uses :try an error would be turned
3534 // into an exception. Need to give the error here.
Bram Moolenaar80d60912021-12-13 19:14:52 +00003535 if (need_rethrow && current_exception != NULL && trylevel == 0)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003536 {
3537 need_rethrow = FALSE;
3538 handle_did_throw();
3539 }
3540
Bram Moolenaar0e57dd82019-09-16 22:56:03 +02003541 return ret;
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02003542}
3543
3544/*
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00003545 * call the 'callback' function and return the result as a number.
Yegappan Lakshmanan4dc24eb2021-12-07 12:23:57 +00003546 * Returns -2 when calling the function fails. Uses argv[0] to argv[argc - 1]
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00003547 * for the function arguments. argv[argc] should have type VAR_UNKNOWN.
3548 */
3549 varnumber_T
3550call_callback_retnr(
3551 callback_T *callback,
3552 int argcount, // number of "argvars"
3553 typval_T *argvars) // vars for arguments, must have "argcount"
3554 // PLUS ONE elements!
3555{
3556 typval_T rettv;
3557 varnumber_T retval;
3558
Bram Moolenaarf0e7e632022-01-21 13:29:56 +00003559 if (call_callback(callback, -1, &rettv, argcount, argvars) == FAIL)
Yegappan Lakshmanan4dc24eb2021-12-07 12:23:57 +00003560 return -2;
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00003561
3562 retval = tv_get_number_chk(&rettv, NULL);
3563 clear_tv(&rettv);
3564 return retval;
3565}
3566
3567/*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003568 * Give an error message for the result of a function.
3569 * Nothing if "error" is FCERR_NONE.
3570 */
3571 void
Bram Moolenaar0917e862023-02-18 14:42:44 +00003572user_func_error(funcerror_T error, char_u *name, int found_var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003573{
3574 switch (error)
3575 {
3576 case FCERR_UNKNOWN:
Bram Moolenaar87b4e5c2022-10-01 15:32:46 +01003577 if (found_var)
Bram Moolenaara6c18d32022-03-31 20:02:56 +01003578 emsg_funcname(e_not_callable_type_str, name);
Bram Moolenaar2ef91562021-12-11 16:14:07 +00003579 else
Bram Moolenaare1242042021-12-16 20:56:57 +00003580 emsg_funcname(e_unknown_function_str, name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003581 break;
3582 case FCERR_NOTMETHOD:
Bram Moolenaara6c18d32022-03-31 20:02:56 +01003583 emsg_funcname(e_cannot_use_function_as_method_str, name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003584 break;
3585 case FCERR_DELETED:
Bram Moolenaar460ae5d2022-01-01 14:19:49 +00003586 emsg_funcname(e_function_was_deleted_str, name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003587 break;
3588 case FCERR_TOOMANY:
Bram Moolenaara6f79292022-01-04 21:30:47 +00003589 emsg_funcname(e_too_many_arguments_for_function_str, name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003590 break;
3591 case FCERR_TOOFEW:
Bram Moolenaara6f79292022-01-04 21:30:47 +00003592 emsg_funcname(e_not_enough_arguments_for_function_str, name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003593 break;
3594 case FCERR_SCRIPT:
Bram Moolenaara6c18d32022-03-31 20:02:56 +01003595 emsg_funcname(e_using_sid_not_in_script_context_str, name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003596 break;
3597 case FCERR_DICT:
Bram Moolenaara6f79292022-01-04 21:30:47 +00003598 emsg_funcname(e_calling_dict_function_without_dictionary_str,
3599 name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003600 break;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003601 case FCERR_OTHER:
3602 case FCERR_FAILED:
3603 // assume the error message was already given
3604 break;
3605 case FCERR_NONE:
3606 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003607 }
3608}
3609
3610/*
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003611 * Check the argument types "argvars[argcount]" for "name" using the
3612 * information in "funcexe". When "base_included" then "funcexe->fe_basetv"
3613 * is already included in "argvars[]".
3614 * Will do nothing if "funcexe->fe_check_type" is NULL or
3615 * "funcexe->fe_evaluate" is FALSE;
3616 * Returns an FCERR_ value.
3617 */
3618 static funcerror_T
3619may_check_argument_types(
3620 funcexe_T *funcexe,
3621 typval_T *argvars,
3622 int argcount,
3623 int base_included,
3624 char_u *name)
3625{
3626 if (funcexe->fe_check_type != NULL && funcexe->fe_evaluate)
3627 {
3628 // Check that the argument types are OK for the types of the funcref.
3629 if (check_argument_types(funcexe->fe_check_type,
3630 argvars, argcount,
3631 base_included ? NULL : funcexe->fe_basetv,
3632 name) == FAIL)
3633 return FCERR_OTHER;
3634 }
3635 return FCERR_NONE;
3636}
3637
3638/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003639 * Call a function with its resolved parameters
Bram Moolenaardf48fb42016-07-22 21:50:18 +02003640 *
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003641 * Return FAIL when the function can't be called, OK otherwise.
3642 * Also returns OK when an error was encountered while executing the function.
3643 */
3644 int
3645call_func(
Bram Moolenaar6ed88192019-05-11 18:37:44 +02003646 char_u *funcname, // name of the function
3647 int len, // length of "name" or -1 to use strlen()
3648 typval_T *rettv, // return value goes here
3649 int argcount_in, // number of "argvars"
3650 typval_T *argvars_in, // vars for arguments, must have "argcount"
3651 // PLUS ONE elements!
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003652 funcexe_T *funcexe) // more arguments
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003653{
3654 int ret = FAIL;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003655 funcerror_T error = FCERR_NONE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003656 int i;
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003657 ufunc_T *fp = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003658 char_u fname_buf[FLEN_FIXED + 1];
3659 char_u *tofree = NULL;
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003660 char_u *fname = NULL;
3661 char_u *name = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003662 int argcount = argcount_in;
3663 typval_T *argvars = argvars_in;
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003664 dict_T *selfdict = funcexe->fe_selfdict;
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003665 typval_T argv[MAX_FUNC_ARGS + 1]; // used when "partial" or
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003666 // "funcexe->fe_basetv" is not NULL
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003667 int argv_clear = 0;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003668 int argv_base = 0;
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003669 partial_T *partial = funcexe->fe_partial;
Bram Moolenaar97f227d2021-07-04 20:20:52 +02003670 type_T check_type;
Bram Moolenaar13789bf2021-12-30 13:29:00 +00003671 type_T *check_type_args[MAX_FUNC_ARGS];
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003672
Bram Moolenaarc507a2d2019-08-29 21:32:55 +02003673 // Initialize rettv so that it is safe for caller to invoke clear_tv(rettv)
3674 // even when call_func() returns FAIL.
3675 rettv->v_type = VAR_UNKNOWN;
3676
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003677 if (partial != NULL)
3678 fp = partial->pt_func;
3679 if (fp == NULL)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003680 fp = funcexe->fe_ufunc;
3681
3682 if (fp == NULL)
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003683 {
3684 // Make a copy of the name, if it comes from a funcref variable it
3685 // could be changed or deleted in the called function.
3686 name = len > 0 ? vim_strnsave(funcname, len) : vim_strsave(funcname);
3687 if (name == NULL)
3688 return ret;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003689
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003690 fname = fname_trans_sid(name, fname_buf, &tofree, &error);
3691 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003692
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003693 if (funcexe->fe_doesrange != NULL)
3694 *funcexe->fe_doesrange = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003695
3696 if (partial != NULL)
3697 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01003698 // When the function has a partial with a dict and there is a dict
3699 // argument, use the dict argument. That is backwards compatible.
3700 // When the dict was bound explicitly use the one from the partial.
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02003701 if (partial->pt_dict != NULL && (selfdict == NULL || !partial->pt_auto))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003702 selfdict = partial->pt_dict;
Bram Moolenaaref140542019-12-31 21:27:13 +01003703 if (error == FCERR_NONE && partial->pt_argc > 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003704 {
3705 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
Bram Moolenaar4c054e92019-11-10 00:13:50 +01003706 {
3707 if (argv_clear + argcount_in >= MAX_FUNC_ARGS)
3708 {
Bram Moolenaaref140542019-12-31 21:27:13 +01003709 error = FCERR_TOOMANY;
Bram Moolenaar4c054e92019-11-10 00:13:50 +01003710 goto theend;
3711 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003712 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]);
Bram Moolenaar4c054e92019-11-10 00:13:50 +01003713 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003714 for (i = 0; i < argcount_in; ++i)
3715 argv[i + argv_clear] = argvars_in[i];
3716 argvars = argv;
3717 argcount = partial->pt_argc + argcount_in;
Bram Moolenaar97f227d2021-07-04 20:20:52 +02003718
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003719 if (funcexe->fe_check_type != NULL
3720 && funcexe->fe_check_type->tt_argcount != -1)
Bram Moolenaar97f227d2021-07-04 20:20:52 +02003721 {
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003722 // Now funcexe->fe_check_type is missing the added arguments,
3723 // make a copy of the type with the correction.
3724 check_type = *funcexe->fe_check_type;
3725 funcexe->fe_check_type = &check_type;
Bram Moolenaar13789bf2021-12-30 13:29:00 +00003726 check_type.tt_args = check_type_args;
3727 CLEAR_FIELD(check_type_args);
3728 for (i = 0; i < check_type.tt_argcount; ++i)
3729 check_type_args[i + partial->pt_argc] =
3730 check_type.tt_args[i];
Bram Moolenaar97f227d2021-07-04 20:20:52 +02003731 check_type.tt_argcount += partial->pt_argc;
3732 check_type.tt_min_argcount += partial->pt_argc;
3733 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003734 }
3735 }
3736
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003737 if (error == FCERR_NONE)
3738 // check the argument types if possible
3739 error = may_check_argument_types(funcexe, argvars, argcount, FALSE,
3740 (name != NULL) ? name : funcname);
Bram Moolenaar32b3f822021-01-06 21:59:39 +01003741
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003742 if (error == FCERR_NONE && funcexe->fe_evaluate)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003743 {
3744 char_u *rfname = fname;
Bram Moolenaar333894b2020-08-01 18:53:07 +02003745 int is_global = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003746
Bram Moolenaar333894b2020-08-01 18:53:07 +02003747 // Skip "g:" before a function name.
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003748 if (fp == NULL && fname[0] == 'g' && fname[1] == ':')
Bram Moolenaar333894b2020-08-01 18:53:07 +02003749 {
3750 is_global = TRUE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003751 rfname = fname + 2;
Bram Moolenaar333894b2020-08-01 18:53:07 +02003752 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003753
Bram Moolenaare38eab22019-12-05 21:50:01 +01003754 rettv->v_type = VAR_NUMBER; // default rettv is number zero
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003755 rettv->vval.v_number = 0;
Bram Moolenaaref140542019-12-31 21:27:13 +01003756 error = FCERR_UNKNOWN;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003757
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003758 if (fp != NULL || !builtin_function(rfname, -1))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003759 {
3760 /*
3761 * User defined function.
3762 */
Bram Moolenaarf10806b2020-04-02 18:34:35 +02003763 if (fp == NULL)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003764 {
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00003765 fp = find_func(rfname, is_global);
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003766 if (fp != NULL && !is_global && in_vim9script()
3767 && func_requires_g_prefix(fp))
3768 // In Vim9 script g: is required to find a global
3769 // non-autoload function.
3770 fp = NULL;
3771 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003772
Bram Moolenaare38eab22019-12-05 21:50:01 +01003773 // Trigger FuncUndefined event, may load the function.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003774 if (fp == NULL
3775 && apply_autocmds(EVENT_FUNCUNDEFINED,
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003776 rfname, rfname, TRUE, NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003777 && !aborting())
3778 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01003779 // executed an autocommand, search for the function again
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00003780 fp = find_func(rfname, is_global);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003781 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01003782 // Try loading a package.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003783 if (fp == NULL && script_autoload(rfname, TRUE) && !aborting())
3784 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01003785 // loaded a package, search for the function again
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00003786 fp = find_func(rfname, is_global);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003787 }
Bram Moolenaara26b9702020-04-18 19:53:28 +02003788 if (fp == NULL)
3789 {
3790 char_u *p = untrans_function_name(rfname);
3791
3792 // If using Vim9 script try not local to the script.
Bram Moolenaar035d6e92020-08-11 22:30:42 +02003793 // Don't do this if the name starts with "s:".
3794 if (p != NULL && (funcname[0] != 's' || funcname[1] != ':'))
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00003795 fp = find_func(p, is_global);
Bram Moolenaara26b9702020-04-18 19:53:28 +02003796 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003797
Bram Moolenaar437bafe2016-08-01 15:40:54 +02003798 if (fp != NULL && (fp->uf_flags & FC_DELETED))
Bram Moolenaaref140542019-12-31 21:27:13 +01003799 error = FCERR_DELETED;
Bram Moolenaar437bafe2016-08-01 15:40:54 +02003800 else if (fp != NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003801 {
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003802 int need_arg_check = FALSE;
3803 if (funcexe->fe_check_type == NULL)
3804 {
3805 funcexe->fe_check_type = fp->uf_func_type;
3806 need_arg_check = TRUE;
3807 }
3808
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003809 if (funcexe->fe_argv_func != NULL)
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003810 {
Bram Moolenaarb0745b22019-11-09 22:28:11 +01003811 // postponed filling in the arguments, do it now
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003812 argcount = funcexe->fe_argv_func(argcount, argvars,
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003813 argv_clear, fp);
3814 need_arg_check = TRUE;
3815 }
Bram Moolenaardf48fb42016-07-22 21:50:18 +02003816
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003817 if (funcexe->fe_basetv != NULL)
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003818 {
3819 // Method call: base->Method()
3820 mch_memmove(&argv[1], argvars, sizeof(typval_T) * argcount);
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003821 argv[0] = *funcexe->fe_basetv;
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003822 argcount++;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003823 argvars = argv;
3824 argv_base = 1;
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003825 need_arg_check = TRUE;
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003826 }
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003827
Bram Moolenaar2ba51232023-05-15 16:22:38 +01003828 // Check the argument types now that the function type and all
3829 // argument values are known, if not done above.
3830 if (need_arg_check)
3831 error = may_check_argument_types(funcexe, argvars, argcount,
3832 TRUE, (name != NULL) ? name : funcname);
3833 if (error == FCERR_NONE || error == FCERR_UNKNOWN)
3834 error = call_user_func_check(fp, argcount, argvars, rettv,
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003835 funcexe, selfdict);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003836 }
3837 }
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003838 else if (funcexe->fe_basetv != NULL)
Bram Moolenaarac92e252019-08-03 21:58:38 +02003839 {
3840 /*
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003841 * expr->method(): Find the method name in the table, call its
3842 * implementation with the base as one of the arguments.
Bram Moolenaarac92e252019-08-03 21:58:38 +02003843 */
3844 error = call_internal_method(fname, argcount, argvars, rettv,
Bram Moolenaar851f86b2021-12-13 14:26:44 +00003845 funcexe->fe_basetv);
Bram Moolenaarac92e252019-08-03 21:58:38 +02003846 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003847 else
3848 {
3849 /*
3850 * Find the function name in the table, call its implementation.
3851 */
3852 error = call_internal_func(fname, argcount, argvars, rettv);
3853 }
Bram Moolenaar333894b2020-08-01 18:53:07 +02003854
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003855 /*
3856 * The function call (or "FuncUndefined" autocommand sequence) might
3857 * have been aborted by an error, an interrupt, or an explicitly thrown
3858 * exception that has not been caught so far. This situation can be
3859 * tested for by calling aborting(). For an error in an internal
3860 * function or for the "E132" error in call_user_func(), however, the
3861 * throw point at which the "force_abort" flag (temporarily reset by
3862 * emsg()) is normally updated has not been reached yet. We need to
3863 * update that flag first to make aborting() reliable.
3864 */
3865 update_force_abort();
3866 }
Bram Moolenaaref140542019-12-31 21:27:13 +01003867 if (error == FCERR_NONE)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003868 ret = OK;
3869
Bram Moolenaar4c054e92019-11-10 00:13:50 +01003870theend:
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003871 /*
3872 * Report an error unless the argument evaluation or function call has been
3873 * cancelled due to an aborting error, an interrupt, or an exception.
3874 */
3875 if (!aborting())
Bram Moolenaar87b4e5c2022-10-01 15:32:46 +01003876 user_func_error(error, (name != NULL) ? name : funcname,
3877 funcexe->fe_found_var);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003878
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003879 // clear the copies made from the partial
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003880 while (argv_clear > 0)
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003881 clear_tv(&argv[--argv_clear + argv_base]);
3882
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003883 vim_free(tofree);
3884 vim_free(name);
3885
3886 return ret;
3887}
3888
Bram Moolenaar87b4e5c2022-10-01 15:32:46 +01003889/*
3890 * Call a function without arguments, partial or dict.
3891 * This is like call_func() when the call is only "FuncName()".
3892 * To be used by "expr" options.
3893 * Returns NOTDONE when the function could not be found.
3894 */
3895 int
3896call_simple_func(
3897 char_u *funcname, // name of the function
3898 int len, // length of "name" or -1 to use strlen()
3899 typval_T *rettv) // return value goes here
3900{
3901 int ret = FAIL;
Bram Moolenaar0917e862023-02-18 14:42:44 +00003902 funcerror_T error = FCERR_NONE;
Bram Moolenaar87b4e5c2022-10-01 15:32:46 +01003903 char_u fname_buf[FLEN_FIXED + 1];
3904 char_u *tofree = NULL;
3905 char_u *name;
3906 char_u *fname;
3907 char_u *rfname;
3908 int is_global = FALSE;
3909 ufunc_T *fp;
3910
3911 rettv->v_type = VAR_NUMBER; // default rettv is number zero
3912 rettv->vval.v_number = 0;
3913
3914 // Make a copy of the name, an option can be changed in the function.
3915 name = vim_strnsave(funcname, len);
3916 if (name == NULL)
3917 return ret;
3918
3919 fname = fname_trans_sid(name, fname_buf, &tofree, &error);
3920
3921 // Skip "g:" before a function name.
3922 if (fname[0] == 'g' && fname[1] == ':')
3923 {
3924 is_global = TRUE;
3925 rfname = fname + 2;
3926 }
3927 else
3928 rfname = fname;
3929 fp = find_func(rfname, is_global);
3930 if (fp != NULL && !is_global && in_vim9script()
3931 && func_requires_g_prefix(fp))
3932 // In Vim9 script g: is required to find a global non-autoload
3933 // function.
3934 fp = NULL;
3935 if (fp == NULL)
3936 ret = NOTDONE;
3937 else if (fp != NULL && (fp->uf_flags & FC_DELETED))
3938 error = FCERR_DELETED;
3939 else if (fp != NULL)
3940 {
3941 typval_T argvars[1];
3942 funcexe_T funcexe;
3943
3944 argvars[0].v_type = VAR_UNKNOWN;
3945 CLEAR_FIELD(funcexe);
3946 funcexe.fe_evaluate = TRUE;
3947
3948 error = call_user_func_check(fp, 0, argvars, rettv, &funcexe, NULL);
3949 if (error == FCERR_NONE)
3950 ret = OK;
3951 }
3952
3953 user_func_error(error, name, FALSE);
3954 vim_free(tofree);
3955 vim_free(name);
3956
3957 return ret;
3958}
3959
Bram Moolenaar682d0a12020-07-19 20:48:59 +02003960 char_u *
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01003961printable_func_name(ufunc_T *fp)
3962{
3963 return fp->uf_name_exp != NULL ? fp->uf_name_exp : fp->uf_name;
3964}
3965
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003966/*
Bram Moolenaar398a26f2022-11-13 22:13:33 +00003967 * When "prev_ht_changed" does not equal "ht_changed" give an error and return
3968 * TRUE. Otherwise return FALSE.
3969 */
3970 static int
3971function_list_modified(int prev_ht_changed)
3972{
3973 if (prev_ht_changed != func_hashtab.ht_changed)
3974 {
3975 emsg(_(e_function_list_was_modified));
3976 return TRUE;
3977 }
3978 return FALSE;
3979}
3980
3981/*
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01003982 * List the head of the function: "function name(arg1, arg2)".
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003983 */
Bram Moolenaar398a26f2022-11-13 22:13:33 +00003984 static int
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003985list_func_head(ufunc_T *fp, int indent)
3986{
Bram Moolenaar398a26f2022-11-13 22:13:33 +00003987 int prev_ht_changed = func_hashtab.ht_changed;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003988 int j;
3989
3990 msg_start();
Bram Moolenaar398a26f2022-11-13 22:13:33 +00003991
3992 // a timer at the more prompt may have deleted the function
3993 if (function_list_modified(prev_ht_changed))
3994 return FAIL;
3995
Bram Moolenaara9b579f2016-07-17 18:29:19 +02003996 if (indent)
Bram Moolenaar32526b32019-01-19 17:43:09 +01003997 msg_puts(" ");
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02003998 if (fp->uf_def_status != UF_NOT_COMPILED)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01003999 msg_puts("def ");
4000 else
4001 msg_puts("function ");
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004002 msg_puts((char *)printable_func_name(fp));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004003 msg_putchar('(');
4004 for (j = 0; j < fp->uf_args.ga_len; ++j)
4005 {
4006 if (j)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004007 msg_puts(", ");
4008 msg_puts((char *)FUNCARG(fp, j));
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004009 if (fp->uf_arg_types != NULL)
4010 {
4011 char *tofree;
4012
4013 msg_puts(": ");
4014 msg_puts(type_name(fp->uf_arg_types[j], &tofree));
4015 vim_free(tofree);
4016 }
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02004017 if (j >= fp->uf_args.ga_len - fp->uf_def_args.ga_len)
4018 {
4019 msg_puts(" = ");
4020 msg_puts(((char **)(fp->uf_def_args.ga_data))
4021 [j - fp->uf_args.ga_len + fp->uf_def_args.ga_len]);
4022 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004023 }
4024 if (fp->uf_varargs)
4025 {
4026 if (j)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004027 msg_puts(", ");
4028 msg_puts("...");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004029 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004030 if (fp->uf_va_name != NULL)
4031 {
Bram Moolenaar521bf322022-05-06 15:47:07 +01004032 if (!fp->uf_varargs)
4033 {
4034 if (j)
4035 msg_puts(", ");
4036 msg_puts("...");
4037 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004038 msg_puts((char *)fp->uf_va_name);
Bram Moolenaar2a389082021-04-09 20:24:31 +02004039 if (fp->uf_va_type != NULL)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004040 {
4041 char *tofree;
4042
4043 msg_puts(": ");
4044 msg_puts(type_name(fp->uf_va_type, &tofree));
4045 vim_free(tofree);
4046 }
4047 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004048 msg_putchar(')');
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01004049
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02004050 if (fp->uf_def_status != UF_NOT_COMPILED)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01004051 {
4052 if (fp->uf_ret_type != &t_void)
4053 {
4054 char *tofree;
4055
4056 msg_puts(": ");
4057 msg_puts(type_name(fp->uf_ret_type, &tofree));
4058 vim_free(tofree);
4059 }
4060 }
4061 else if (fp->uf_flags & FC_ABORT)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004062 msg_puts(" abort");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004063 if (fp->uf_flags & FC_RANGE)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004064 msg_puts(" range");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004065 if (fp->uf_flags & FC_DICT)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004066 msg_puts(" dict");
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02004067 if (fp->uf_flags & FC_CLOSURE)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004068 msg_puts(" closure");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004069 msg_clr_eos();
4070 if (p_verbose > 0)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02004071 last_set_msg(fp->uf_script_ctx);
Bram Moolenaar398a26f2022-11-13 22:13:33 +00004072
4073 return OK;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004074}
4075
4076/*
4077 * Get a function name, translating "<SID>" and "<SNR>".
4078 * Also handles a Funcref in a List or Dictionary.
4079 * Returns the function name in allocated memory, or NULL for failure.
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02004080 * Set "*is_global" to TRUE when the function must be global, unless
4081 * "is_global" is NULL.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004082 * flags:
4083 * TFN_INT: internal function name OK
Bram Moolenaarffdaca92022-12-09 21:41:48 +00004084 * TFN_IN_CLASS: function in a class
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004085 * TFN_QUIET: be quiet
4086 * TFN_NO_AUTOLOAD: do not use script autoloading
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02004087 * TFN_NO_DEREF: do not dereference a Funcref
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004088 * Advances "pp" to just after the function name (if no error).
4089 */
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004090 char_u *
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004091trans_function_name(
4092 char_u **pp,
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02004093 int *is_global,
Bram Moolenaare38eab22019-12-05 21:50:01 +01004094 int skip, // only find the end, don't evaluate
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004095 int flags)
4096{
4097 return trans_function_name_ext(pp, is_global, skip, flags,
4098 NULL, NULL, NULL, NULL);
4099}
4100
4101/*
4102 * trans_function_name() with extra arguments.
4103 * "fdp", "partial", "type" and "ufunc" can be NULL.
4104 */
4105 char_u *
4106trans_function_name_ext(
4107 char_u **pp,
4108 int *is_global,
4109 int skip, // only find the end, don't evaluate
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004110 int flags,
Bram Moolenaare38eab22019-12-05 21:50:01 +01004111 funcdict_T *fdp, // return: info about dictionary used
Bram Moolenaar32b3f822021-01-06 21:59:39 +01004112 partial_T **partial, // return: partial of a FuncRef
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004113 type_T **type, // return: type of funcref
4114 ufunc_T **ufunc) // return: function
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004115{
4116 char_u *name = NULL;
4117 char_u *start;
4118 char_u *end;
4119 int lead;
4120 char_u sid_buf[20];
4121 int len;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004122 int extra = 0;
Bram Moolenaar848fadd2022-01-30 15:28:30 +00004123 int prefix_g = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004124 lval_T lv;
Bram Moolenaar4525a572022-02-13 11:57:33 +00004125 int vim9script = in_vim9script();
4126 int vim9_local;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004127
4128 if (fdp != NULL)
Bram Moolenaara80faa82020-04-12 19:37:17 +02004129 CLEAR_POINTER(fdp);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004130 start = *pp;
4131
Bram Moolenaare38eab22019-12-05 21:50:01 +01004132 // Check for hard coded <SNR>: already translated function ID (from a user
4133 // command).
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004134 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
4135 && (*pp)[2] == (int)KE_SNR)
4136 {
4137 *pp += 3;
4138 len = get_id_len(pp) + 3;
4139 return vim_strnsave(start, len);
4140 }
4141
Bram Moolenaare38eab22019-12-05 21:50:01 +01004142 // A name starting with "<SID>" or "<SNR>" is local to a script. But
4143 // don't skip over "s:", get_lval() needs it for "s:dict.func".
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004144 lead = eval_fname_script(start);
4145 if (lead > 2)
4146 start += lead;
4147
Bram Moolenaare38eab22019-12-05 21:50:01 +01004148 // Note that TFN_ flags use the same values as GLV_ flags.
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004149 end = get_lval(start, NULL, &lv, FALSE, skip,
4150 flags | GLV_READ_ONLY | GLV_PREFER_FUNC,
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004151 lead > 2 ? 0 : FNE_CHECK_START);
Bram Moolenaar4525a572022-02-13 11:57:33 +00004152 if (end == start || (vim9script && end != NULL
Bram Moolenaare6a42002022-01-21 10:32:58 +00004153 && end[-1] == AUTOLOAD_CHAR && *end == '('))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004154 {
4155 if (!skip)
Bram Moolenaarc553a212021-12-26 20:20:34 +00004156 emsg(_(e_function_name_required));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004157 goto theend;
4158 }
4159 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range)))
4160 {
4161 /*
4162 * Report an invalid expression in braces, unless the expression
4163 * evaluation has been cancelled due to an aborting error, an
4164 * interrupt, or an exception.
4165 */
4166 if (!aborting())
4167 {
4168 if (end != NULL)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +00004169 semsg(_(e_invalid_argument_str), start);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004170 }
4171 else
4172 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
4173 goto theend;
4174 }
4175
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004176 if (lv.ll_ufunc != NULL)
4177 {
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01004178 if (ufunc != NULL)
4179 *ufunc = lv.ll_ufunc;
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004180 name = vim_strsave(lv.ll_ufunc->uf_name);
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01004181 *pp = end;
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004182 goto theend;
4183 }
4184
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004185 if (lv.ll_tv != NULL)
4186 {
4187 if (fdp != NULL)
4188 {
4189 fdp->fd_dict = lv.ll_dict;
4190 fdp->fd_newkey = lv.ll_newkey;
4191 lv.ll_newkey = NULL;
4192 fdp->fd_di = lv.ll_di;
4193 }
4194 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL)
4195 {
4196 name = vim_strsave(lv.ll_tv->vval.v_string);
4197 *pp = end;
4198 }
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +00004199 else if (lv.ll_tv->v_type == VAR_CLASS
4200 && lv.ll_tv->vval.v_class != NULL)
4201 {
4202 name = vim_strsave(lv.ll_tv->vval.v_class->class_name);
4203 *pp = end;
4204 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004205 else if (lv.ll_tv->v_type == VAR_PARTIAL
4206 && lv.ll_tv->vval.v_partial != NULL)
4207 {
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004208 name = vim_strsave(partial_name(lv.ll_tv->vval.v_partial));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004209 *pp = end;
4210 if (partial != NULL)
4211 *partial = lv.ll_tv->vval.v_partial;
4212 }
4213 else
4214 {
4215 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
4216 || lv.ll_dict == NULL || fdp->fd_newkey == NULL))
Bram Moolenaara6f79292022-01-04 21:30:47 +00004217 emsg(_(e_funcref_required));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004218 else
4219 *pp = end;
4220 name = NULL;
4221 }
4222 goto theend;
4223 }
4224
4225 if (lv.ll_name == NULL)
4226 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01004227 // Error found, but continue after the function name.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004228 *pp = end;
4229 goto theend;
4230 }
4231
Bram Moolenaare38eab22019-12-05 21:50:01 +01004232 // Check if the name is a Funcref. If so, use the value.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004233 if (lv.ll_exp_name != NULL)
4234 {
4235 len = (int)STRLEN(lv.ll_exp_name);
Bram Moolenaar32b3f822021-01-06 21:59:39 +01004236 name = deref_func_name(lv.ll_exp_name, &len, partial, type,
Bram Moolenaar937610b2022-01-19 17:21:29 +00004237 flags & TFN_NO_AUTOLOAD, flags & TFN_NEW_FUNC, NULL);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004238 if (name == lv.ll_exp_name)
4239 name = NULL;
4240 }
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00004241 else if (lv.ll_sid > 0)
4242 {
4243 scriptitem_T *si = SCRIPT_ITEM(lv.ll_sid);
4244 int cc = *lv.ll_name_end;
4245
4246 // function in another script. Prefix <SNR>99_ or the autoload prefix.
4247 *lv.ll_name_end = NUL;
4248 if (si->sn_autoload_prefix != NULL)
4249 {
4250 name = concat_str(si->sn_autoload_prefix, lv.ll_name);
4251 }
4252 else
4253 {
4254 sid_buf[0] = K_SPECIAL;
4255 sid_buf[1] = KS_EXTRA;
4256 sid_buf[2] = (int)KE_SNR;
4257 vim_snprintf((char *)sid_buf + 3, sizeof(sid_buf) - 3,
Bram Moolenaar62aec932022-01-29 21:45:34 +00004258 "%ld_", (long)lv.ll_sid);
Bram Moolenaarf111cdf2022-01-12 12:48:17 +00004259 name = concat_str(sid_buf, lv.ll_name);
4260 }
4261 *lv.ll_name_end = cc;
4262 *pp = end;
4263 goto theend;
4264 }
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02004265 else if (!(flags & TFN_NO_DEREF))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004266 {
4267 len = (int)(end - *pp);
Bram Moolenaar32b3f822021-01-06 21:59:39 +01004268 name = deref_func_name(*pp, &len, partial, type,
Bram Moolenaar937610b2022-01-19 17:21:29 +00004269 flags & TFN_NO_AUTOLOAD, flags & TFN_NEW_FUNC, NULL);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004270 if (name == *pp)
4271 name = NULL;
4272 }
4273 if (name != NULL)
4274 {
4275 name = vim_strsave(name);
4276 *pp = end;
4277 if (STRNCMP(name, "<SNR>", 5) == 0)
4278 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01004279 // Change "<SNR>" to the byte sequence.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004280 name[0] = K_SPECIAL;
4281 name[1] = KS_EXTRA;
4282 name[2] = (int)KE_SNR;
4283 mch_memmove(name + 3, name + 5, STRLEN(name + 5) + 1);
4284 }
4285 goto theend;
4286 }
4287
4288 if (lv.ll_exp_name != NULL)
4289 {
4290 len = (int)STRLEN(lv.ll_exp_name);
4291 if (lead <= 2 && lv.ll_name == lv.ll_exp_name
4292 && STRNCMP(lv.ll_name, "s:", 2) == 0)
4293 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01004294 // When there was "s:" already or the name expanded to get a
4295 // leading "s:" then remove it.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004296 lv.ll_name += 2;
4297 len -= 2;
4298 lead = 2;
4299 }
4300 }
4301 else
4302 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01004303 // skip over "s:" and "g:"
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004304 if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':'))
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02004305 {
Bram Moolenaar848fadd2022-01-30 15:28:30 +00004306 if (lv.ll_name[0] == 'g')
4307 {
4308 if (is_global != NULL)
4309 {
4310 *is_global = TRUE;
4311 }
4312 else
4313 {
4314 // dropping "g:" without setting "is_global" won't work in
4315 // Vim9script, put it back later
4316 prefix_g = TRUE;
4317 extra = 2;
4318 }
4319 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004320 lv.ll_name += 2;
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02004321 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004322 len = (int)(end - lv.ll_name);
4323 }
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02004324 if (len <= 0)
4325 {
4326 if (!skip)
Bram Moolenaarc553a212021-12-26 20:20:34 +00004327 emsg(_(e_function_name_required));
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02004328 goto theend;
4329 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004330
Bram Moolenaar17f700a2020-12-19 21:23:42 +01004331 // In Vim9 script a user function is script-local by default, unless it
Bram Moolenaarffdaca92022-12-09 21:41:48 +00004332 // starts with a lower case character: dict.func(). Or when in a class.
4333 vim9_local = ASCII_ISUPPER(*start) && vim9script
4334 && (flags & TFN_IN_CLASS) == 0;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004335
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004336 /*
4337 * Copy the function name to allocated memory.
4338 * Accept <SID>name() inside a script, translate into <SNR>123_name().
4339 * Accept <SNR>123_name() outside a script.
4340 */
4341 if (skip)
Bram Moolenaare38eab22019-12-05 21:50:01 +01004342 lead = 0; // do nothing
Bram Moolenaar4525a572022-02-13 11:57:33 +00004343 else if (lead > 0 || vim9_local)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004344 {
Bram Moolenaar4525a572022-02-13 11:57:33 +00004345 if (!vim9_local)
Bram Moolenaar3787f262022-02-07 21:54:01 +00004346 {
Kota Kato948a3892022-08-16 16:09:59 +01004347 if (vim9script && lead == 2 && !ASCII_ISUPPER(*lv.ll_name)
4348 && current_script_is_vim9())
Bram Moolenaar3787f262022-02-07 21:54:01 +00004349 {
Bram Moolenaar72981ac2022-07-29 19:50:41 +01004350 semsg(_(e_function_name_must_start_with_capital_str), start);
Bram Moolenaar3787f262022-02-07 21:54:01 +00004351 goto theend;
4352 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004353 lead = 3;
Bram Moolenaar3787f262022-02-07 21:54:01 +00004354 }
Bram Moolenaar4525a572022-02-13 11:57:33 +00004355 if (vim9_local || (lv.ll_exp_name != NULL
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004356 && eval_fname_sid(lv.ll_exp_name))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004357 || eval_fname_sid(*pp))
4358 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004359 // It's script-local, "s:" or "<SID>"
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02004360 if (current_sctx.sc_sid <= 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004361 {
Bram Moolenaar40bcec12021-12-05 22:19:27 +00004362 emsg(_(e_using_sid_not_in_script_context));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004363 goto theend;
4364 }
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02004365 sprintf((char *)sid_buf, "%ld_", (long)current_sctx.sc_sid);
Bram Moolenaar4525a572022-02-13 11:57:33 +00004366 if (vim9_local)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004367 extra = 3 + (int)STRLEN(sid_buf);
4368 else
4369 lead += (int)STRLEN(sid_buf);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004370 }
4371 }
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004372 // The function name must start with an upper case letter (unless it is a
4373 // Vim9 class new() function or a Vim9 class private method)
Bram Moolenaarffdaca92022-12-09 21:41:48 +00004374 else if (!(flags & TFN_INT)
4375 && (builtin_function(lv.ll_name, len)
4376 || (vim9script && *lv.ll_name == '_'))
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004377 && !((flags & TFN_IN_CLASS)
4378 && (STRNCMP(lv.ll_name, "new", 3) == 0
4379 || (*lv.ll_name == '_'))))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004380 {
Bram Moolenaar4525a572022-02-13 11:57:33 +00004381 semsg(_(vim9script ? e_function_name_must_start_with_capital_str
Bram Moolenaar3787f262022-02-07 21:54:01 +00004382 : e_function_name_must_start_with_capital_or_s_str),
4383 start);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004384 goto theend;
4385 }
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02004386 if (!skip && !(flags & TFN_QUIET) && !(flags & TFN_NO_DEREF))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004387 {
4388 char_u *cp = vim_strchr(lv.ll_name, ':');
4389
4390 if (cp != NULL && cp < end)
4391 {
Bram Moolenaard82a47d2022-01-05 20:24:39 +00004392 semsg(_(e_function_name_cannot_contain_colon_str), start);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004393 goto theend;
4394 }
4395 }
4396
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004397 name = alloc(len + lead + extra + 1);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004398 if (name != NULL)
4399 {
Bram Moolenaar4525a572022-02-13 11:57:33 +00004400 if (!skip && (lead > 0 || vim9_local))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004401 {
4402 name[0] = K_SPECIAL;
4403 name[1] = KS_EXTRA;
4404 name[2] = (int)KE_SNR;
Bram Moolenaar4525a572022-02-13 11:57:33 +00004405 if (vim9_local || lead > 3) // If it's "<SID>"
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004406 STRCPY(name + 3, sid_buf);
4407 }
Bram Moolenaar848fadd2022-01-30 15:28:30 +00004408 else if (prefix_g)
4409 {
4410 name[0] = 'g';
4411 name[1] = ':';
4412 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004413 mch_memmove(name + lead + extra, lv.ll_name, (size_t)len);
4414 name[lead + extra + len] = NUL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004415 }
4416 *pp = end;
4417
4418theend:
4419 clear_lval(&lv);
4420 return name;
4421}
4422
4423/*
Bram Moolenaara26b9702020-04-18 19:53:28 +02004424 * Assuming "name" is the result of trans_function_name() and it was prefixed
4425 * to use the script-local name, return the unmodified name (points into
4426 * "name"). Otherwise return NULL.
4427 * This can be used to first search for a script-local function and fall back
4428 * to the global function if not found.
4429 */
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01004430 static char_u *
Bram Moolenaara26b9702020-04-18 19:53:28 +02004431untrans_function_name(char_u *name)
4432{
4433 char_u *p;
4434
Bram Moolenaareb6880b2020-07-12 17:07:05 +02004435 if (*name == K_SPECIAL && in_vim9script())
Bram Moolenaara26b9702020-04-18 19:53:28 +02004436 {
4437 p = vim_strchr(name, '_');
4438 if (p != NULL)
4439 return p + 1;
4440 }
4441 return NULL;
4442}
4443
4444/*
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +00004445 * If the 'funcname' starts with "s:" or "<SID>", then expands it to the
4446 * current script ID and returns the expanded function name. The caller should
4447 * free the returned name. If not called from a script context or the function
4448 * name doesn't start with these prefixes, then returns NULL.
4449 * This doesn't check whether the script-local function exists or not.
4450 */
4451 char_u *
4452get_scriptlocal_funcname(char_u *funcname)
4453{
4454 char sid_buf[25];
Bram Moolenaare89bfd22022-02-18 18:34:45 +00004455 int off;
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +00004456 char_u *newname;
Bram Moolenaar1fca5f32022-02-18 17:50:47 +00004457 char_u *p = funcname;
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +00004458
4459 if (funcname == NULL)
4460 return NULL;
4461
4462 if (STRNCMP(funcname, "s:", 2) != 0
4463 && STRNCMP(funcname, "<SID>", 5) != 0)
Bram Moolenaar1fca5f32022-02-18 17:50:47 +00004464 {
4465 ufunc_T *ufunc;
4466
4467 // The function name does not have a script-local prefix. Try finding
4468 // it when in a Vim9 script and there is no "g:" prefix.
4469 if (!in_vim9script() || STRNCMP(funcname, "g:", 2) == 0)
4470 return NULL;
4471 ufunc = find_func(funcname, FALSE);
4472 if (ufunc == NULL || func_is_global(ufunc)
4473 || (p = vim_strchr(ufunc->uf_name, '_')) == NULL)
4474 return NULL;
4475 ++p;
4476 off = 0;
4477 }
Bram Moolenaare89bfd22022-02-18 18:34:45 +00004478 else
4479 off = *funcname == 's' ? 2 : 5;
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +00004480
4481 if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
4482 {
4483 emsg(_(e_using_sid_not_in_script_context));
4484 return NULL;
4485 }
4486 // Expand s: prefix into <SNR>nr_<name>
4487 vim_snprintf(sid_buf, sizeof(sid_buf), "<SNR>%ld_",
4488 (long)current_sctx.sc_sid);
Bram Moolenaar1fca5f32022-02-18 17:50:47 +00004489 newname = alloc(STRLEN(sid_buf) + STRLEN(p + off) + 1);
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +00004490 if (newname == NULL)
4491 return NULL;
4492 STRCPY(newname, sid_buf);
Bram Moolenaar1fca5f32022-02-18 17:50:47 +00004493 STRCAT(newname, p + off);
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +00004494
4495 return newname;
4496}
4497
4498/*
Bram Moolenaarc2f17f72022-02-21 13:13:50 +00004499 * Return script-local "fname" with the 3-byte sequence replaced by
4500 * printable <SNR> in allocated memory.
4501 */
4502 char_u *
4503alloc_printable_func_name(char_u *fname)
4504{
4505 char_u *n = alloc(STRLEN(fname + 3) + 6);
4506
4507 if (n != NULL)
4508 {
4509 STRCPY(n, "<SNR>");
4510 STRCPY(n + 5, fname + 3);
4511 }
4512 return n;
4513}
4514
4515/*
Bram Moolenaareba3b7f2021-11-30 18:25:08 +00004516 * Call trans_function_name(), except that a lambda is returned as-is.
4517 * Returns the name in allocated memory.
4518 */
4519 char_u *
4520save_function_name(
4521 char_u **name,
4522 int *is_global,
4523 int skip,
4524 int flags,
4525 funcdict_T *fudi)
4526{
4527 char_u *p = *name;
4528 char_u *saved;
4529
4530 if (STRNCMP(p, "<lambda>", 8) == 0)
4531 {
4532 p += 8;
4533 (void)getdigits(&p);
4534 saved = vim_strnsave(*name, p - *name);
4535 if (fudi != NULL)
4536 CLEAR_POINTER(fudi);
4537 }
4538 else
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00004539 saved = trans_function_name_ext(&p, is_global, skip,
4540 flags, fudi, NULL, NULL, NULL);
Bram Moolenaareba3b7f2021-11-30 18:25:08 +00004541 *name = p;
4542 return saved;
4543}
4544
4545/*
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004546 * List functions. When "regmatch" is NULL all of then.
4547 * Otherwise functions matching "regmatch".
4548 */
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01004549 void
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004550list_functions(regmatch_T *regmatch)
4551{
Bram Moolenaar398a26f2022-11-13 22:13:33 +00004552 int prev_ht_changed = func_hashtab.ht_changed;
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02004553 long_u todo = func_hashtab.ht_used;
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004554 hashitem_T *hi;
4555
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02004556 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004557 {
4558 if (!HASHITEM_EMPTY(hi))
4559 {
4560 ufunc_T *fp = HI2UF(hi);
4561
4562 --todo;
4563 if ((fp->uf_flags & FC_DEAD) == 0
4564 && (regmatch == NULL
4565 ? !message_filtered(fp->uf_name)
4566 && !func_name_refcount(fp->uf_name)
4567 : !isdigit(*fp->uf_name)
4568 && vim_regexec(regmatch, fp->uf_name, 0)))
4569 {
Bram Moolenaar398a26f2022-11-13 22:13:33 +00004570 if (list_func_head(fp, FALSE) == FAIL)
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004571 return;
Bram Moolenaar398a26f2022-11-13 22:13:33 +00004572 if (function_list_modified(prev_ht_changed))
4573 return;
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004574 }
4575 }
4576 }
4577}
4578
4579/*
Bram Moolenaar04b12692020-05-04 23:24:44 +02004580 * ":function" also supporting nested ":def".
Bram Moolenaar38ddf332020-07-31 22:05:04 +02004581 * When "name_arg" is not NULL this is a nested function, using "name_arg" for
4582 * the function name.
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00004583 * "lines_to_free" is a list of strings to be freed later.
Bram Moolenaar554d0312023-01-05 19:59:18 +00004584 * If "class_flags" has CF_CLASS then the function is defined inside a class.
4585 * With CF_INTERFACE the function is define inside an interface, only the
4586 * ":def"/":function" line is expected, no function body.
Bram Moolenaar04b12692020-05-04 23:24:44 +02004587 * Returns a pointer to the function or NULL if no function defined.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004588 */
Bram Moolenaar04b12692020-05-04 23:24:44 +02004589 ufunc_T *
Bram Moolenaar00b28d62022-12-08 15:32:33 +00004590define_function(
4591 exarg_T *eap,
4592 char_u *name_arg,
4593 garray_T *lines_to_free,
Bram Moolenaar554d0312023-01-05 19:59:18 +00004594 int class_flags)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004595{
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004596 int j;
4597 int c;
Bram Moolenaar57033102022-01-30 19:37:52 +00004598 int saved_did_emsg = FALSE;
Bram Moolenaar04b12692020-05-04 23:24:44 +02004599 char_u *name = name_arg;
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02004600 int is_global = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004601 char_u *p;
4602 char_u *arg;
Bram Moolenaarcef12702021-01-04 14:09:43 +01004603 char_u *whitep;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004604 char_u *line_arg = NULL;
4605 garray_T newargs;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004606 garray_T argtypes;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02004607 garray_T default_args;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004608 garray_T newlines;
4609 int varargs = FALSE;
4610 int flags = 0;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004611 char_u *ret_type = NULL;
Bram Moolenaar04b12692020-05-04 23:24:44 +02004612 ufunc_T *fp = NULL;
Bram Moolenaar57bc2332021-12-15 12:06:43 +00004613 int fp_allocated = FALSE;
4614 int free_fp = FALSE;
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004615 int overwrite = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004616 dictitem_T *v;
4617 funcdict_T fudi;
Bram Moolenaare38eab22019-12-05 21:50:01 +01004618 static int func_nr = 0; // number for nameless function
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004619 int paren;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004620 hashitem_T *hi;
Bram Moolenaarbc2cfe42019-07-04 14:57:12 +02004621 linenr_T sourcing_lnum_top;
Bram Moolenaare7e48382020-07-22 18:17:08 +02004622 int vim9script = in_vim9script();
Bram Moolenaareef21022020-08-01 22:16:43 +02004623 imported_T *import = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004624
4625 /*
4626 * ":function" without argument: list functions.
4627 */
Bram Moolenaara72cfb82020-04-23 17:07:30 +02004628 if (ends_excmd2(eap->cmd, eap->arg))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004629 {
4630 if (!eap->skip)
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004631 list_functions(NULL);
Bram Moolenaar63b91732021-08-05 20:40:03 +02004632 set_nextcmd(eap, eap->arg);
Bram Moolenaar04b12692020-05-04 23:24:44 +02004633 return NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004634 }
4635
4636 /*
4637 * ":function /pat": list functions matching pattern.
4638 */
4639 if (*eap->arg == '/')
4640 {
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02004641 p = skip_regexp(eap->arg + 1, '/', TRUE);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004642 if (!eap->skip)
4643 {
4644 regmatch_T regmatch;
4645
4646 c = *p;
4647 *p = NUL;
4648 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
4649 *p = c;
4650 if (regmatch.regprog != NULL)
4651 {
4652 regmatch.rm_ic = p_ic;
Bram Moolenaar3fffa972020-06-05 21:06:10 +02004653 list_functions(&regmatch);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004654 vim_regfree(regmatch.regprog);
4655 }
4656 }
4657 if (*p == '/')
4658 ++p;
Bram Moolenaar63b91732021-08-05 20:40:03 +02004659 set_nextcmd(eap, p);
Bram Moolenaar04b12692020-05-04 23:24:44 +02004660 return NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004661 }
4662
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004663 ga_init(&newargs);
4664 ga_init(&argtypes);
4665 ga_init(&default_args);
4666
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004667 /*
4668 * Get the function name. There are these situations:
Bram Moolenaar554d0312023-01-05 19:59:18 +00004669 * func normal function name, also when "class_flags" is non-zero
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004670 * "name" == func, "fudi.fd_dict" == NULL
4671 * dict.func new dictionary entry
4672 * "name" == NULL, "fudi.fd_dict" set,
4673 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
4674 * dict.func existing dict entry with a Funcref
4675 * "name" == func, "fudi.fd_dict" set,
4676 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL
4677 * dict.func existing dict entry that's not a Funcref
4678 * "name" == NULL, "fudi.fd_dict" set,
4679 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL
4680 * s:func script-local function name
4681 * g:func global function name, same as "func"
4682 */
4683 p = eap->arg;
Bram Moolenaar04b12692020-05-04 23:24:44 +02004684 if (name_arg != NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004685 {
Bram Moolenaar04b12692020-05-04 23:24:44 +02004686 // nested function, argument is (args).
4687 paren = TRUE;
4688 CLEAR_FIELD(fudi);
4689 }
4690 else
4691 {
Bram Moolenaardea5ab02022-02-23 22:12:02 +00004692 if (vim9script)
Bram Moolenaara749a422022-02-12 19:52:25 +00004693 {
Bram Moolenaardea5ab02022-02-23 22:12:02 +00004694 if (p[0] == 's' && p[1] == ':')
4695 {
4696 semsg(_(e_cannot_use_s_colon_in_vim9_script_str), p);
4697 return NULL;
4698 }
4699 p = to_name_end(p, TRUE);
4700 if (*skipwhite(p) == '.' && vim_strchr(p, '(') != NULL)
4701 {
4702 semsg(_(e_cannot_define_dict_func_in_vim9_script_str),
4703 eap->arg);
4704 return NULL;
4705 }
4706 p = eap->arg;
Bram Moolenaara749a422022-02-12 19:52:25 +00004707 }
4708
Bram Moolenaar00b28d62022-12-08 15:32:33 +00004709 int tfn_flags = TFN_NO_AUTOLOAD | TFN_NEW_FUNC
Bram Moolenaar554d0312023-01-05 19:59:18 +00004710 | (class_flags != 0 ? TFN_IN_CLASS : 0);
Bram Moolenaar00b28d62022-12-08 15:32:33 +00004711 name = save_function_name(&p, &is_global, eap->skip, tfn_flags, &fudi);
Bram Moolenaar04b12692020-05-04 23:24:44 +02004712 paren = (vim_strchr(p, '(') != NULL);
4713 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004714 {
Bram Moolenaar04b12692020-05-04 23:24:44 +02004715 /*
4716 * Return on an invalid expression in braces, unless the expression
4717 * evaluation has been cancelled due to an aborting error, an
4718 * interrupt, or an exception.
4719 */
4720 if (!aborting())
4721 {
4722 if (!eap->skip && fudi.fd_newkey != NULL)
Bram Moolenaara9fa8c52023-01-02 18:10:04 +00004723 semsg(_(e_key_not_present_in_dictionary_str),
4724 fudi.fd_newkey);
Bram Moolenaar04b12692020-05-04 23:24:44 +02004725 vim_free(fudi.fd_newkey);
4726 return NULL;
4727 }
4728 else
4729 eap->skip = TRUE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004730 }
Bram Moolenaardc4451d2022-01-09 21:36:37 +00004731
Bram Moolenaarfe2ef0b2022-01-10 18:08:00 +00004732 // For "export def FuncName()" in an autoload script the function name
4733 // is stored with the legacy autoload name "dir#script#FuncName" so
4734 // that it can also be found in legacy script.
Bram Moolenaar78a70532022-01-13 13:24:34 +00004735 if (is_export && name != NULL)
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00004736 {
4737 char_u *prefixed = may_prefix_autoload(name);
4738
4739 if (prefixed != NULL && prefixed != name)
4740 {
4741 vim_free(name);
4742 name = prefixed;
4743 }
4744 }
Bram Moolenaar8164f6e2022-02-06 13:08:41 +00004745 else if (paren && vim9script && name != NULL
Bram Moolenaar48a60482022-01-31 11:44:48 +00004746 && vim_strchr(name, AUTOLOAD_CHAR) != NULL)
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00004747 {
4748 emsg(_(e_cannot_use_name_with_hash_in_vim9_script_use_export_instead));
4749 goto ret_free;
4750 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004751 }
4752
Bram Moolenaare38eab22019-12-05 21:50:01 +01004753 // An error in a function call during evaluation of an expression in magic
4754 // braces should not cause the function not to be defined.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004755 saved_did_emsg = did_emsg;
4756 did_emsg = FALSE;
4757
4758 /*
4759 * ":function func" with only function name: list function.
4760 */
4761 if (!paren)
4762 {
4763 if (!ends_excmd(*skipwhite(p)))
4764 {
Bram Moolenaar74409f62022-01-01 15:58:22 +00004765 semsg(_(e_trailing_characters_str), p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004766 goto ret_free;
4767 }
Bram Moolenaar63b91732021-08-05 20:40:03 +02004768 set_nextcmd(eap, p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004769 if (eap->nextcmd != NULL)
4770 *p = NUL;
4771 if (!eap->skip && !got_int)
4772 {
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00004773 fp = find_func(name, is_global);
Bram Moolenaara26b9702020-04-18 19:53:28 +02004774 if (fp == NULL && ASCII_ISUPPER(*eap->arg))
4775 {
4776 char_u *up = untrans_function_name(name);
4777
4778 // With Vim9 script the name was made script-local, if not
4779 // found try again with the original name.
Bram Moolenaarec9749f2020-04-18 20:51:40 +02004780 if (up != NULL)
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00004781 fp = find_func(up, FALSE);
Bram Moolenaara26b9702020-04-18 19:53:28 +02004782 }
4783
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004784 if (fp != NULL)
4785 {
Bram Moolenaar398a26f2022-11-13 22:13:33 +00004786 // Check no function was added or removed from a timer, e.g. at
4787 // the more prompt. "fp" may then be invalid.
4788 int prev_ht_changed = func_hashtab.ht_changed;
4789
4790 if (list_func_head(fp, TRUE) == OK)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004791 {
Bram Moolenaar398a26f2022-11-13 22:13:33 +00004792 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j)
4793 {
4794 if (FUNCLINE(fp, j) == NULL)
4795 continue;
4796 msg_putchar('\n');
4797 msg_outnum((long)(j + 1));
4798 if (j < 9)
4799 msg_putchar(' ');
4800 if (j < 99)
4801 msg_putchar(' ');
4802 if (function_list_modified(prev_ht_changed))
4803 break;
4804 msg_prt_line(FUNCLINE(fp, j), FALSE);
4805 out_flush(); // show a line at a time
4806 ui_breakcheck();
4807 }
4808 if (!got_int)
4809 {
4810 msg_putchar('\n');
4811 if (!function_list_modified(prev_ht_changed))
4812 {
4813 if (fp->uf_def_status != UF_NOT_COMPILED)
4814 msg_puts(" enddef");
4815 else
4816 msg_puts(" endfunction");
4817 }
4818 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004819 }
4820 }
4821 else
Bram Moolenaarc553a212021-12-26 20:20:34 +00004822 emsg_funcname(e_undefined_function_str, eap->arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004823 }
4824 goto ret_free;
4825 }
4826
4827 /*
4828 * ":function name(arg1, arg2)" Define function.
4829 */
4830 p = skipwhite(p);
4831 if (*p != '(')
4832 {
4833 if (!eap->skip)
4834 {
Bram Moolenaarc553a212021-12-26 20:20:34 +00004835 semsg(_(e_missing_paren_str), eap->arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004836 goto ret_free;
4837 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01004838 // attempt to continue by skipping some text
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004839 if (vim_strchr(p, '(') != NULL)
4840 p = vim_strchr(p, '(');
4841 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004842
Bram Moolenaar4efd9942021-01-24 21:14:20 +01004843 if ((vim9script || eap->cmdidx == CMD_def) && VIM_ISWHITE(p[-1]))
4844 {
Bram Moolenaarba98fb52021-02-07 18:06:29 +01004845 semsg(_(e_no_white_space_allowed_before_str_str), "(", p - 1);
Bram Moolenaar4efd9942021-01-24 21:14:20 +01004846 goto ret_free;
4847 }
4848
Bram Moolenaar925e9fd2020-07-25 15:41:11 +02004849 // In Vim9 script only global functions can be redefined.
4850 if (vim9script && eap->forceit && !is_global)
4851 {
Bram Moolenaar460ae5d2022-01-01 14:19:49 +00004852 emsg(_(e_no_bang_allowed));
Bram Moolenaar925e9fd2020-07-25 15:41:11 +02004853 goto ret_free;
4854 }
4855
Bram Moolenaar04935fb2022-01-08 16:19:22 +00004856 ga_init2(&newlines, sizeof(char_u *), 10);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004857
Bram Moolenaar04b12692020-05-04 23:24:44 +02004858 if (!eap->skip && name_arg == NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004859 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01004860 // Check the name of the function. Unless it's a dictionary function
4861 // (that we are overwriting).
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004862 if (name != NULL)
4863 arg = name;
4864 else
4865 arg = fudi.fd_newkey;
4866 if (arg != NULL && (fudi.fd_di == NULL
4867 || (fudi.fd_di->di_tv.v_type != VAR_FUNC
4868 && fudi.fd_di->di_tv.v_type != VAR_PARTIAL)))
4869 {
Bram Moolenaar052ff292021-12-11 13:54:46 +00004870 char_u *name_base = arg;
4871 int i;
4872
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004873 if (*arg == K_SPECIAL)
Bram Moolenaar052ff292021-12-11 13:54:46 +00004874 {
4875 name_base = vim_strchr(arg, '_');
4876 if (name_base == NULL)
4877 name_base = arg + 3;
4878 else
4879 ++name_base;
4880 }
4881 for (i = 0; name_base[i] != NUL && (i == 0
4882 ? eval_isnamec1(name_base[i])
4883 : eval_isnamec(name_base[i])); ++i)
4884 ;
4885 if (name_base[i] != NUL)
Bram Moolenaara6f79292022-01-04 21:30:47 +00004886 emsg_funcname(e_invalid_argument_str, arg);
Bram Moolenaar052ff292021-12-11 13:54:46 +00004887
4888 // In Vim9 script a function cannot have the same name as a
4889 // variable.
4890 if (vim9script && *arg == K_SPECIAL
Bram Moolenaard5f400c2022-01-06 21:10:28 +00004891 && eval_variable(name_base, (int)STRLEN(name_base), 0, NULL,
4892 NULL, EVAL_VAR_NOAUTOLOAD + EVAL_VAR_IMPORT
Bram Moolenaar052ff292021-12-11 13:54:46 +00004893 + EVAL_VAR_NO_FUNC) == OK)
4894 {
4895 semsg(_(e_redefining_script_item_str), name_base);
4896 goto ret_free;
4897 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004898 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01004899 // Disallow using the g: dict.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004900 if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
Bram Moolenaar052ff292021-12-11 13:54:46 +00004901 {
Bram Moolenaar9d00e4a2022-01-05 17:49:15 +00004902 emsg(_(e_cannot_use_g_here));
Bram Moolenaar052ff292021-12-11 13:54:46 +00004903 goto ret_free;
4904 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004905 }
4906
Bram Moolenaar5e774c72020-04-12 21:53:00 +02004907 // This may get more lines and make the pointers into the first line
4908 // invalid.
Bram Moolenaarcef12702021-01-04 14:09:43 +01004909 ++p;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004910 if (get_function_args(&p, ')', &newargs,
Bram Moolenaarf0571712023-01-04 13:16:20 +00004911 eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE,
Bram Moolenaar057e84a2021-02-28 16:55:11 +01004912 NULL, &varargs, &default_args, eap->skip,
Bram Moolenaar554d0312023-01-05 19:59:18 +00004913 eap, class_flags, &newlines, lines_to_free) == FAIL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004914 goto errret_2;
Bram Moolenaarcef12702021-01-04 14:09:43 +01004915 whitep = p;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004916
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004917 if (eap->cmdidx == CMD_def)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004918 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004919 // find the return type: :def Func(): type
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02004920 if (*skipwhite(p) == ':')
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004921 {
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02004922 if (*p != ':')
4923 {
4924 semsg(_(e_no_white_space_allowed_before_colon_str), p);
4925 p = skipwhite(p);
4926 }
4927 else if (!IS_WHITE_OR_NUL(p[1]))
4928 semsg(_(e_white_space_required_after_str_str), ":", p);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004929 ret_type = skipwhite(p + 1);
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02004930 p = skip_type(ret_type, FALSE);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004931 if (p > ret_type)
Bram Moolenaar5e774c72020-04-12 21:53:00 +02004932 {
Bram Moolenaar71ccd032020-06-12 22:59:11 +02004933 ret_type = vim_strnsave(ret_type, p - ret_type);
Bram Moolenaarcef12702021-01-04 14:09:43 +01004934 whitep = p;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004935 p = skipwhite(p);
Bram Moolenaar5e774c72020-04-12 21:53:00 +02004936 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004937 else
Bram Moolenaar5e774c72020-04-12 21:53:00 +02004938 {
Bram Moolenaar451c2e32020-08-15 16:33:28 +02004939 semsg(_(e_expected_type_str), ret_type);
Bram Moolenaarb8ce6b02020-04-23 22:23:14 +02004940 ret_type = NULL;
Bram Moolenaar5e774c72020-04-12 21:53:00 +02004941 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004942 }
Bram Moolenaare7e48382020-07-22 18:17:08 +02004943 p = skipwhite(p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004944 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004945 else
4946 // find extra arguments "range", "dict", "abort" and "closure"
4947 for (;;)
4948 {
Bram Moolenaarcef12702021-01-04 14:09:43 +01004949 whitep = p;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004950 p = skipwhite(p);
4951 if (STRNCMP(p, "range", 5) == 0)
4952 {
4953 flags |= FC_RANGE;
4954 p += 5;
4955 }
4956 else if (STRNCMP(p, "dict", 4) == 0)
4957 {
4958 flags |= FC_DICT;
4959 p += 4;
4960 }
4961 else if (STRNCMP(p, "abort", 5) == 0)
4962 {
4963 flags |= FC_ABORT;
4964 p += 5;
4965 }
4966 else if (STRNCMP(p, "closure", 7) == 0)
4967 {
4968 flags |= FC_CLOSURE;
4969 p += 7;
4970 if (current_funccal == NULL)
4971 {
Bram Moolenaara9fa8c52023-01-02 18:10:04 +00004972 emsg_funcname(e_closure_function_should_not_be_at_top_level_str,
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004973 name == NULL ? (char_u *)"" : name);
4974 goto erret;
4975 }
4976 }
4977 else
4978 break;
4979 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004980
Bram Moolenaare38eab22019-12-05 21:50:01 +01004981 // When there is a line break use what follows for the function body.
4982 // Makes 'exe "func Test()\n...\nendfunc"' work.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004983 if (*p == '\n')
4984 line_arg = p + 1;
Bram Moolenaare7e48382020-07-22 18:17:08 +02004985 else if (*p != NUL
Bram Moolenaar98981072020-07-29 14:40:25 +02004986 && !(*p == '"' && (!vim9script || eap->cmdidx == CMD_function)
4987 && eap->cmdidx != CMD_def)
Bram Moolenaarcef12702021-01-04 14:09:43 +01004988 && !(VIM_ISWHITE(*whitep) && *p == '#'
4989 && (vim9script || eap->cmdidx == CMD_def))
Bram Moolenaare7e48382020-07-22 18:17:08 +02004990 && !eap->skip
4991 && !did_emsg)
Bram Moolenaar74409f62022-01-01 15:58:22 +00004992 semsg(_(e_trailing_characters_str), p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004993
4994 /*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01004995 * Read the body of the function, until "}", ":endfunction" or ":enddef" is
4996 * found.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004997 */
4998 if (KeyTyped)
4999 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005000 // Check if the function already exists, don't let the user type the
5001 // whole function before telling him it doesn't work! For a script we
5002 // need to skip the body to be able to find what follows.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005003 if (!eap->skip && !eap->forceit)
5004 {
5005 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
Bram Moolenaara6f79292022-01-04 21:30:47 +00005006 emsg(_(e_dictionary_entry_already_exists));
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00005007 else if (name != NULL && find_func(name, is_global) != NULL)
Bram Moolenaar1a992222021-12-31 17:25:48 +00005008 emsg_funcname(e_function_str_already_exists_add_bang_to_replace, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005009 }
5010
5011 if (!eap->skip && did_emsg)
5012 goto erret;
5013
Bram Moolenaare38eab22019-12-05 21:50:01 +01005014 msg_putchar('\n'); // don't overwrite the function name
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005015 cmdline_row = msg_row;
5016 }
5017
Bram Moolenaarbc2cfe42019-07-04 14:57:12 +02005018 // Save the starting line number.
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01005019 sourcing_lnum_top = SOURCING_LNUM;
Bram Moolenaarbc2cfe42019-07-04 14:57:12 +02005020
Bram Moolenaard87c21a2021-05-18 13:40:33 +02005021 // Do not define the function when getting the body fails and when
5022 // skipping.
Bram Moolenaar554d0312023-01-05 19:59:18 +00005023 if (((class_flags & CF_INTERFACE) == 0
5024 && get_function_body(eap, &newlines, line_arg, lines_to_free)
5025 == FAIL)
Bram Moolenaard87c21a2021-05-18 13:40:33 +02005026 || eap->skip)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005027 goto erret;
5028
5029 /*
5030 * If there are no errors, add the function
5031 */
Bram Moolenaarffdaca92022-12-09 21:41:48 +00005032 if (fudi.fd_dict != NULL)
5033 {
5034 char numbuf[20];
5035
5036 fp = NULL;
5037 if (fudi.fd_newkey == NULL && !eap->forceit)
5038 {
5039 emsg(_(e_dictionary_entry_already_exists));
5040 goto erret;
5041 }
5042 if (fudi.fd_di == NULL)
5043 {
5044 // Can't add a function to a locked dictionary
5045 if (value_check_lock(fudi.fd_dict->dv_lock, eap->arg, FALSE))
5046 goto erret;
5047 }
5048 // Can't change an existing function if it is locked
5049 else if (value_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, FALSE))
5050 goto erret;
5051
5052 // Give the function a sequential number. Can only be used with a
5053 // Funcref!
5054 vim_free(name);
5055 sprintf(numbuf, "%d", ++func_nr);
5056 name = vim_strsave((char_u *)numbuf);
5057 if (name == NULL)
5058 goto erret;
5059 }
Bram Moolenaar554d0312023-01-05 19:59:18 +00005060 else if (class_flags == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005061 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005062 hashtab_T *ht;
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00005063 char_u *find_name = name;
5064 int var_conflict = FALSE;
Bram Moolenaaracc4b562022-01-24 13:54:45 +00005065 int ffed_flags = is_global ? FFED_IS_GLOBAL : 0;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005066
Bram Moolenaar32b3f822021-01-06 21:59:39 +01005067 v = find_var(name, &ht, TRUE);
Bram Moolenaar4525a572022-02-13 11:57:33 +00005068 if (v != NULL && (vim9script || v->di_tv.v_type == VAR_FUNC))
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00005069 var_conflict = TRUE;
5070
5071 if (SCRIPT_ID_VALID(current_sctx.sc_sid))
5072 {
5073 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
5074
5075 if (si->sn_autoload_prefix != NULL)
5076 {
5077 if (is_export)
5078 {
5079 find_name = name + STRLEN(si->sn_autoload_prefix);
5080 v = find_var(find_name, &ht, TRUE);
5081 if (v != NULL)
5082 var_conflict = TRUE;
Bram Moolenaaracc4b562022-01-24 13:54:45 +00005083 // Only check if the function already exists in the script,
5084 // global functions can be shadowed.
5085 ffed_flags |= FFED_NO_GLOBAL;
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00005086 }
5087 else
5088 {
5089 char_u *prefixed = may_prefix_autoload(name);
5090
Bram Moolenaar9383a3a2022-02-25 21:35:17 +00005091 if (prefixed != NULL && prefixed != name)
Bram Moolenaar9c7cae62022-01-20 19:10:25 +00005092 {
5093 v = find_var(prefixed, &ht, TRUE);
5094 if (v != NULL)
5095 var_conflict = TRUE;
5096 vim_free(prefixed);
5097 }
5098 }
5099 }
5100 }
5101 if (var_conflict)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005102 {
Bram Moolenaara6f79292022-01-04 21:30:47 +00005103 emsg_funcname(e_function_name_conflicts_with_variable_str, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005104 goto erret;
5105 }
5106
Bram Moolenaaracc4b562022-01-24 13:54:45 +00005107 fp = find_func_even_dead(find_name, ffed_flags);
Bram Moolenaareef21022020-08-01 22:16:43 +02005108 if (vim9script)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005109 {
Bram Moolenaareef21022020-08-01 22:16:43 +02005110 char_u *uname = untrans_function_name(name);
5111
Bram Moolenaar4b1d9632022-02-13 21:51:08 +00005112 import = find_imported(uname == NULL ? name : uname, 0, FALSE);
Bram Moolenaareef21022020-08-01 22:16:43 +02005113 }
5114
5115 if (fp != NULL || import != NULL)
5116 {
5117 int dead = fp != NULL && (fp->uf_flags & FC_DEAD);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005118
Bram Moolenaarded5f1b2018-11-10 17:33:29 +01005119 // Function can be replaced with "function!" and when sourcing the
5120 // same script again, but only once.
Bram Moolenaareef21022020-08-01 22:16:43 +02005121 // A name that is used by an import can not be overruled.
5122 if (import != NULL
5123 || (!dead && !eap->forceit
Bram Moolenaarded5f1b2018-11-10 17:33:29 +01005124 && (fp->uf_script_ctx.sc_sid != current_sctx.sc_sid
Bram Moolenaareef21022020-08-01 22:16:43 +02005125 || fp->uf_script_ctx.sc_seq == current_sctx.sc_seq)))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005126 {
Bram Moolenaard604d782021-11-20 21:46:20 +00005127 SOURCING_LNUM = sourcing_lnum_top;
Bram Moolenaareef21022020-08-01 22:16:43 +02005128 if (vim9script)
Bram Moolenaar7cb6fc22020-08-21 22:36:47 +02005129 emsg_funcname(e_name_already_defined_str, name);
Bram Moolenaareef21022020-08-01 22:16:43 +02005130 else
Bram Moolenaar1a992222021-12-31 17:25:48 +00005131 emsg_funcname(e_function_str_already_exists_add_bang_to_replace, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005132 goto erret;
5133 }
5134 if (fp->uf_calls > 0)
5135 {
Bram Moolenaarded5f1b2018-11-10 17:33:29 +01005136 emsg_funcname(
Bram Moolenaarc553a212021-12-26 20:20:34 +00005137 e_cannot_redefine_function_str_it_is_in_use, name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005138 goto erret;
5139 }
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005140 if (fp->uf_refcount > 1)
5141 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005142 // This function is referenced somewhere, don't redefine it but
5143 // create a new one.
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005144 --fp->uf_refcount;
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02005145 fp->uf_flags |= FC_REMOVED;
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005146 fp = NULL;
5147 overwrite = TRUE;
5148 }
5149 else
5150 {
Bram Moolenaarb9adef72020-01-02 14:31:22 +01005151 char_u *exp_name = fp->uf_name_exp;
5152
5153 // redefine existing function, keep the expanded name
Bram Moolenaard23a8232018-02-10 18:45:26 +01005154 VIM_CLEAR(name);
Bram Moolenaarb9adef72020-01-02 14:31:22 +01005155 fp->uf_name_exp = NULL;
Bram Moolenaar79c2ad52018-07-29 17:40:43 +02005156 func_clear_items(fp);
Bram Moolenaarb9adef72020-01-02 14:31:22 +01005157 fp->uf_name_exp = exp_name;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005158 fp->uf_flags &= ~FC_DEAD;
Bram Moolenaar79c2ad52018-07-29 17:40:43 +02005159#ifdef FEAT_PROFILE
5160 fp->uf_profiling = FALSE;
5161 fp->uf_prof_initialized = FALSE;
5162#endif
Bram Moolenaarcdc40c42020-12-26 17:43:08 +01005163 fp->uf_def_status = UF_NOT_COMPILED;
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005164 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005165 }
5166 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005167
5168 if (fp == NULL)
5169 {
5170 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL)
5171 {
5172 int slen, plen;
5173 char_u *scriptname;
5174
Bram Moolenaare38eab22019-12-05 21:50:01 +01005175 // Check that the autoload name matches the script name.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005176 j = FAIL;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01005177 if (SOURCING_NAME != NULL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005178 {
5179 scriptname = autoload_name(name);
5180 if (scriptname != NULL)
5181 {
5182 p = vim_strchr(scriptname, '/');
5183 plen = (int)STRLEN(p);
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01005184 slen = (int)STRLEN(SOURCING_NAME);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005185 if (slen > plen && fnamecmp(p,
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01005186 SOURCING_NAME + slen - plen) == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005187 j = OK;
5188 vim_free(scriptname);
5189 }
5190 }
5191 if (j == FAIL)
5192 {
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +02005193 linenr_T save_lnum = SOURCING_LNUM;
5194
5195 SOURCING_LNUM = sourcing_lnum_top;
Bram Moolenaar677658a2022-01-05 16:09:06 +00005196 semsg(_(e_function_name_does_not_match_script_file_name_str),
5197 name);
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +02005198 SOURCING_LNUM = save_lnum;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005199 goto erret;
5200 }
5201 }
5202
Bram Moolenaare01e5212023-01-08 20:31:18 +00005203 fp = alloc_ufunc(name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005204 if (fp == NULL)
5205 goto erret;
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005206 fp_allocated = TRUE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005207
5208 if (fudi.fd_dict != NULL)
5209 {
5210 if (fudi.fd_di == NULL)
5211 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005212 // add new dict entry
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005213 fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
5214 if (fudi.fd_di == NULL)
5215 {
Yegappan Lakshmanan960dcbd2023-03-07 17:45:11 +00005216 VIM_CLEAR(fp);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005217 goto erret;
5218 }
5219 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL)
5220 {
5221 vim_free(fudi.fd_di);
Yegappan Lakshmanan960dcbd2023-03-07 17:45:11 +00005222 VIM_CLEAR(fp);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005223 goto erret;
5224 }
5225 }
5226 else
Bram Moolenaare38eab22019-12-05 21:50:01 +01005227 // overwrite existing dict entry
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005228 clear_tv(&fudi.fd_di->di_tv);
5229 fudi.fd_di->di_tv.v_type = VAR_FUNC;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005230 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005231
Bram Moolenaare38eab22019-12-05 21:50:01 +01005232 // behave like "dict" was used
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005233 flags |= FC_DICT;
5234 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005235 }
5236 fp->uf_args = newargs;
Bram Moolenaar42ae78c2019-05-09 21:08:58 +02005237 fp->uf_def_args = default_args;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005238 fp->uf_ret_type = &t_any;
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02005239 fp->uf_func_type = &t_func_any;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005240
5241 if (eap->cmdidx == CMD_def)
5242 {
Bram Moolenaar39ca4122020-10-20 14:25:07 +02005243 int lnum_save = SOURCING_LNUM;
5244 cstack_T *cstack = eap->cstack;
Bram Moolenaarbfe12042020-02-04 21:54:07 +01005245
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02005246 fp->uf_def_status = UF_TO_BE_COMPILED;
Bram Moolenaar822ba242020-05-24 23:00:18 +02005247
Bram Moolenaarbfe12042020-02-04 21:54:07 +01005248 // error messages are for the first function line
5249 SOURCING_LNUM = sourcing_lnum_top;
5250
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02005251 // The function may use script variables from the context.
5252 function_using_block_scopes(fp, cstack);
Bram Moolenaarfbbcd002020-10-15 12:46:44 +02005253
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01005254 if (parse_argument_types(fp, &argtypes, varargs) == FAIL)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005255 {
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01005256 SOURCING_LNUM = lnum_save;
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005257 free_fp = fp_allocated;
5258 goto erret;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005259 }
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01005260 varargs = FALSE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005261
5262 // parse the return type, if any
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01005263 if (parse_return_type(fp, ret_type) == FAIL)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005264 {
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01005265 SOURCING_LNUM = lnum_save;
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005266 free_fp = fp_allocated;
Bram Moolenaar7a6eaa02021-03-21 20:53:29 +01005267 goto erret;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005268 }
Bram Moolenaar09689a02020-05-09 22:50:08 +02005269 SOURCING_LNUM = lnum_save;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005270 }
Bram Moolenaar822ba242020-05-24 23:00:18 +02005271 else
Bram Moolenaar0cb5bcf2020-06-20 18:19:09 +02005272 fp->uf_def_status = UF_NOT_COMPILED;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005273
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005274 if (fp_allocated)
5275 {
5276 // insert the new function in the function list
5277 set_ufunc_name(fp, name);
5278 if (overwrite)
5279 {
5280 hi = hash_find(&func_hashtab, name);
5281 hi->hi_key = UF2HIKEY(fp);
5282 }
Bram Moolenaar554d0312023-01-05 19:59:18 +00005283 else if (class_flags == 0 && hash_add(&func_hashtab,
Bram Moolenaarffdaca92022-12-09 21:41:48 +00005284 UF2HIKEY(fp), "add function") == FAIL)
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005285 {
5286 free_fp = TRUE;
5287 goto erret;
5288 }
5289 fp->uf_refcount = 1;
5290 }
5291
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005292 fp->uf_lines = newlines;
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005293 newlines.ga_data = NULL;
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02005294 if ((flags & FC_CLOSURE) != 0)
5295 {
Bram Moolenaar58016442016-07-31 18:30:22 +02005296 if (register_closure(fp) == FAIL)
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02005297 goto erret;
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02005298 }
5299 else
5300 fp->uf_scoped = NULL;
5301
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005302#ifdef FEAT_PROFILE
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005303 if (prof_def_func())
5304 func_do_profile(fp);
5305#endif
5306 fp->uf_varargs = varargs;
Bram Moolenaar93343722018-07-10 19:39:18 +02005307 if (sandbox)
5308 flags |= FC_SANDBOX;
Bram Moolenaare7e48382020-07-22 18:17:08 +02005309 if (vim9script && !ASCII_ISUPPER(*fp->uf_name))
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005310 flags |= FC_VIM9;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005311 fp->uf_flags = flags;
5312 fp->uf_calls = 0;
Bram Moolenaar63ce4842020-02-19 15:46:48 +01005313 fp->uf_cleared = FALSE;
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02005314 fp->uf_script_ctx = current_sctx;
Bram Moolenaarf9b2b492020-08-05 14:34:14 +02005315 fp->uf_script_ctx_version = current_sctx.sc_version;
Bram Moolenaarbc2cfe42019-07-04 14:57:12 +02005316 fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005317 if (is_export)
5318 {
5319 fp->uf_flags |= FC_EXPORT;
dundargocc57b5bc2022-11-02 13:30:51 +00005320 // let do_one_cmd() know the export worked.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005321 is_export = FALSE;
5322 }
5323
Bram Moolenaar6ff71d82020-05-24 23:45:24 +02005324 if (eap->cmdidx == CMD_def)
5325 set_function_type(fp);
Bram Moolenaar67979662020-06-20 22:50:47 +02005326 else if (fp->uf_script_ctx.sc_version == SCRIPT_VERSION_VIM9)
5327 // :func does not use Vim9 script syntax, even in a Vim9 script file
5328 fp->uf_script_ctx.sc_version = SCRIPT_VERSION_MAX;
Bram Moolenaar6ff71d82020-05-24 23:45:24 +02005329
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005330 goto ret_free;
5331
5332erret:
Bram Moolenaar31842cd2021-02-12 22:10:21 +01005333 if (fp != NULL)
5334 {
Bram Moolenaarf0571712023-01-04 13:16:20 +00005335 // these were set to "newargs" and "default_args", which are cleared
5336 // below
Bram Moolenaar31842cd2021-02-12 22:10:21 +01005337 ga_init(&fp->uf_args);
5338 ga_init(&fp->uf_def_args);
5339 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005340errret_2:
Bram Moolenaarf0571712023-01-04 13:16:20 +00005341 ga_clear_strings(&newargs);
5342 ga_clear_strings(&default_args);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005343 ga_clear_strings(&newlines);
Bram Moolenaar31842cd2021-02-12 22:10:21 +01005344 if (fp != NULL)
Bram Moolenaarf0571712023-01-04 13:16:20 +00005345 {
Bram Moolenaar31842cd2021-02-12 22:10:21 +01005346 VIM_CLEAR(fp->uf_arg_types);
Bram Moolenaarf0571712023-01-04 13:16:20 +00005347 VIM_CLEAR(fp->uf_va_name);
5348 clear_type_list(&fp->uf_type_list);
5349 }
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005350 if (free_fp)
Yegappan Lakshmanan960dcbd2023-03-07 17:45:11 +00005351 VIM_CLEAR(fp);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005352ret_free:
Bram Moolenaar292b90d2020-03-18 15:23:16 +01005353 ga_clear_strings(&argtypes);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005354 vim_free(fudi.fd_newkey);
Bram Moolenaar04b12692020-05-04 23:24:44 +02005355 if (name != name_arg)
5356 vim_free(name);
Bram Moolenaar5e774c72020-04-12 21:53:00 +02005357 vim_free(ret_type);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005358 did_emsg |= saved_did_emsg;
Bram Moolenaar04b12692020-05-04 23:24:44 +02005359
5360 return fp;
5361}
5362
5363/*
5364 * ":function"
5365 */
5366 void
5367ex_function(exarg_T *eap)
5368{
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00005369 garray_T lines_to_free;
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00005370
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00005371 ga_init2(&lines_to_free, sizeof(char_u *), 50);
Bram Moolenaar554d0312023-01-05 19:59:18 +00005372 (void)define_function(eap, NULL, &lines_to_free, 0);
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00005373 ga_clear_strings(&lines_to_free);
Bram Moolenaar822ba242020-05-24 23:00:18 +02005374}
5375
5376/*
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005377 * Find a function by name, including "<lambda>123".
5378 * Check for "profile" and "debug" arguments and set"compile_type".
Bram Moolenaar5a01caa2022-05-21 18:56:58 +01005379 * Caller should initialize "compile_type" to CT_NONE.
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005380 * Return NULL if not found.
5381 */
5382 ufunc_T *
5383find_func_by_name(char_u *name, compiletype_T *compile_type)
5384{
5385 char_u *arg = name;
5386 char_u *fname;
5387 ufunc_T *ufunc;
5388 int is_global = FALSE;
5389
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005390 if (STRNCMP(arg, "profile", 7) == 0 && VIM_ISWHITE(arg[7]))
5391 {
5392 *compile_type = CT_PROFILE;
5393 arg = skipwhite(arg + 7);
5394 }
5395 else if (STRNCMP(arg, "debug", 5) == 0 && VIM_ISWHITE(arg[5]))
5396 {
5397 *compile_type = CT_DEBUG;
5398 arg = skipwhite(arg + 5);
5399 }
5400
5401 if (STRNCMP(arg, "<lambda>", 8) == 0)
5402 {
5403 arg += 8;
5404 (void)getdigits(&arg);
5405 fname = vim_strnsave(name, arg - name);
5406 }
5407 else
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +00005408 {
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005409 // First try finding a method in a class, trans_function_name() will
5410 // give an error if the function is not found.
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +00005411 ufunc = find_class_func(&arg);
5412 if (ufunc != NULL)
5413 return ufunc;
5414
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005415 fname = trans_function_name_ext(&arg, &is_global, FALSE,
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +00005416 TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DECL,
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005417 NULL, NULL, NULL, &ufunc);
5418 if (ufunc != NULL)
5419 {
5420 vim_free(fname);
5421 return ufunc;
5422 }
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +00005423 }
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005424 if (fname == NULL)
5425 {
5426 semsg(_(e_invalid_argument_str), name);
5427 return NULL;
5428 }
5429 if (!ends_excmd2(name, arg))
5430 {
Bram Moolenaar1a56ea82022-05-21 16:28:42 +01005431 vim_free(fname);
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005432 emsg(ex_errmsg(e_trailing_characters_str, arg));
5433 return NULL;
5434 }
5435
5436 ufunc = find_func(fname, is_global);
5437 if (ufunc == NULL)
5438 {
5439 char_u *p = untrans_function_name(fname);
5440
5441 if (p != NULL)
5442 // Try again without making it script-local.
5443 ufunc = find_func(p, FALSE);
5444 }
5445 vim_free(fname);
5446 if (ufunc == NULL)
5447 semsg(_(e_cannot_find_function_str), name);
5448 return ufunc;
5449}
5450
5451/*
Bram Moolenaar96f8f492020-09-09 17:08:51 +02005452 * :defcompile - compile all :def functions in the current script that need to
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005453 * be compiled or the one specified by the argument.
5454 * Skips dead functions. Doesn't do profiling.
Bram Moolenaar822ba242020-05-24 23:00:18 +02005455 */
5456 void
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005457ex_defcompile(exarg_T *eap)
Bram Moolenaar822ba242020-05-24 23:00:18 +02005458{
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005459 if (*eap->arg != NUL)
Bram Moolenaar822ba242020-05-24 23:00:18 +02005460 {
Bram Moolenaar5a01caa2022-05-21 18:56:58 +01005461 compiletype_T compile_type = CT_NONE;
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005462 ufunc_T *ufunc = find_func_by_name(eap->arg, &compile_type);
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005463 if (ufunc != NULL)
5464 {
5465 if (func_needs_compiling(ufunc, compile_type))
5466 (void)compile_def_function(ufunc, FALSE, compile_type, NULL);
5467 else
5468 smsg(_("Function %s does not need compiling"), eap->arg);
5469 }
5470 }
5471 else
5472 {
5473 long todo = (long)func_hashtab.ht_used;
5474 int changed = func_hashtab.ht_changed;
5475 hashitem_T *hi;
5476
5477 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
5478 {
5479 if (!HASHITEM_EMPTY(hi))
5480 {
5481 --todo;
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005482 ufunc_T *ufunc = HI2UF(hi);
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005483 if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
5484 && ufunc->uf_def_status == UF_TO_BE_COMPILED
5485 && (ufunc->uf_flags & FC_DEAD) == 0)
Bram Moolenaarebc3de62020-05-26 11:08:28 +02005486 {
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +01005487 (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL);
5488
5489 if (func_hashtab.ht_changed != changed)
5490 {
5491 // a function has been added or removed, need to start
5492 // over
5493 todo = (long)func_hashtab.ht_used;
5494 changed = func_hashtab.ht_changed;
5495 hi = func_hashtab.ht_array;
5496 --hi;
5497 }
Bram Moolenaarebc3de62020-05-26 11:08:28 +02005498 }
5499 }
Bram Moolenaar822ba242020-05-24 23:00:18 +02005500 }
5501 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005502}
5503
5504/*
5505 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
5506 * Return 2 if "p" starts with "s:".
5507 * Return 0 otherwise.
5508 */
5509 int
5510eval_fname_script(char_u *p)
5511{
Bram Moolenaare38eab22019-12-05 21:50:01 +01005512 // Use MB_STRICMP() because in Turkish comparing the "I" may not work with
5513 // the standard library function.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005514 if (p[0] == '<' && (MB_STRNICMP(p + 1, "SID>", 4) == 0
5515 || MB_STRNICMP(p + 1, "SNR>", 4) == 0))
5516 return 5;
5517 if (p[0] == 's' && p[1] == ':')
5518 return 2;
5519 return 0;
5520}
5521
5522 int
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005523translated_function_exists(char_u *name, int is_global)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005524{
5525 if (builtin_function(name, -1))
Bram Moolenaarac92e252019-08-03 21:58:38 +02005526 return has_internal_func(name);
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00005527 return find_func(name, is_global) != NULL;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005528}
5529
5530/*
5531 * Return TRUE when "ufunc" has old-style "..." varargs
5532 * or named varargs "...name: type".
5533 */
5534 int
5535has_varargs(ufunc_T *ufunc)
5536{
5537 return ufunc->uf_varargs || ufunc->uf_va_name != NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005538}
5539
5540/*
5541 * Return TRUE if a function "name" exists.
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02005542 * If "no_defef" is TRUE, do not dereference a Funcref.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005543 */
5544 int
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02005545function_exists(char_u *name, int no_deref)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005546{
5547 char_u *nm = name;
5548 char_u *p;
5549 int n = FALSE;
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02005550 int flag;
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005551 int is_global = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005552
Bram Moolenaarb54c3ff2016-07-31 14:11:58 +02005553 flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD;
5554 if (no_deref)
5555 flag |= TFN_NO_DEREF;
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005556 p = trans_function_name(&nm, &is_global, FALSE, flag);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005557 nm = skipwhite(nm);
5558
Bram Moolenaare38eab22019-12-05 21:50:01 +01005559 // Only accept "funcname", "funcname ", "funcname (..." and
5560 // "funcname(...", not "funcname!...".
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005561 if (p != NULL && (*nm == NUL || *nm == '('))
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005562 n = translated_function_exists(p, is_global);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005563 vim_free(p);
5564 return n;
5565}
5566
Bram Moolenaar113e1072019-01-20 15:30:40 +01005567#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005568 char_u *
5569get_expanded_name(char_u *name, int check)
5570{
5571 char_u *nm = name;
5572 char_u *p;
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005573 int is_global = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005574
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005575 p = trans_function_name(&nm, &is_global, FALSE, TFN_INT|TFN_QUIET);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005576
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005577 if (p != NULL && *nm == NUL
5578 && (!check || translated_function_exists(p, is_global)))
5579 return p;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005580
5581 vim_free(p);
5582 return NULL;
5583}
Bram Moolenaar113e1072019-01-20 15:30:40 +01005584#endif
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005585
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005586/*
5587 * Function given to ExpandGeneric() to obtain the list of user defined
5588 * function names.
5589 */
5590 char_u *
5591get_user_func_name(expand_T *xp, int idx)
5592{
5593 static long_u done;
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02005594 static int changed;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005595 static hashitem_T *hi;
5596 ufunc_T *fp;
5597
5598 if (idx == 0)
5599 {
5600 done = 0;
5601 hi = func_hashtab.ht_array;
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02005602 changed = func_hashtab.ht_changed;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005603 }
Bram Moolenaar1f22cc52020-07-14 21:08:49 +02005604 if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005605 {
5606 if (done++ > 0)
5607 ++hi;
5608 while (HASHITEM_EMPTY(hi))
5609 ++hi;
5610 fp = HI2UF(hi);
5611
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005612 // don't show dead, dict and lambda functions
5613 if ((fp->uf_flags & FC_DEAD) || (fp->uf_flags & FC_DICT)
Bram Moolenaarb49edc12016-07-23 15:47:34 +02005614 || STRNCMP(fp->uf_name, "<lambda>", 8) == 0)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005615 return (char_u *)"";
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005616
5617 if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
Bram Moolenaare38eab22019-12-05 21:50:01 +01005618 return fp->uf_name; // prevents overflow
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005619
5620 cat_func_name(IObuff, fp);
naohiro ono9aecf792021-08-28 15:56:06 +02005621 if (xp->xp_context != EXPAND_USER_FUNC
5622 && xp->xp_context != EXPAND_DISASSEMBLE)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005623 {
5624 STRCAT(IObuff, "(");
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005625 if (!has_varargs(fp) && fp->uf_args.ga_len == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005626 STRCAT(IObuff, ")");
5627 }
5628 return IObuff;
5629 }
5630 return NULL;
5631}
5632
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005633/*
Bram Moolenaar83677162023-01-08 19:54:10 +00005634 * Make a copy of a function.
5635 * Intended to be used for a function defined on a base class that has a copy
5636 * on the child class.
5637 * The copy has uf_refcount set to one.
5638 * Returns NULL when out of memory.
5639 */
5640 ufunc_T *
5641copy_function(ufunc_T *fp)
5642{
Bram Moolenaare01e5212023-01-08 20:31:18 +00005643 ufunc_T *ufunc = alloc_ufunc(fp->uf_name);
Bram Moolenaar83677162023-01-08 19:54:10 +00005644 if (ufunc == NULL)
5645 return NULL;
5646
5647 // Most things can just be copied.
5648 *ufunc = *fp;
5649
5650 ufunc->uf_def_status = UF_TO_BE_COMPILED;
5651 ufunc->uf_dfunc_idx = 0;
5652 ufunc->uf_class = NULL;
5653
5654 ga_copy_strings(&fp->uf_args, &ufunc->uf_args);
5655 ga_copy_strings(&fp->uf_def_args, &ufunc->uf_def_args);
5656
5657 if (ufunc->uf_arg_types != NULL)
5658 {
5659 // "uf_arg_types" is an allocated array, make a copy.
5660 type_T **at = ALLOC_CLEAR_MULT(type_T *, ufunc->uf_args.ga_len);
5661 if (at != NULL)
5662 {
5663 mch_memmove(at, ufunc->uf_arg_types,
5664 sizeof(type_T *) * ufunc->uf_args.ga_len);
5665 ufunc->uf_arg_types = at;
5666 }
5667 }
5668
5669 // TODO: how about the types themselves? they can be freed when the
5670 // original function is freed:
5671 // type_T **uf_arg_types;
5672 // type_T *uf_ret_type;
5673
Ernie Rael114ec812023-06-04 18:11:35 +01005674 // make uf_type_list empty
5675 ga_init(&ufunc->uf_type_list);
Bram Moolenaar83677162023-01-08 19:54:10 +00005676
5677 // TODO: partial_T *uf_partial;
5678
5679 if (ufunc->uf_va_name != NULL)
5680 ufunc->uf_va_name = vim_strsave(ufunc->uf_va_name);
5681
5682 // TODO:
5683 // type_T *uf_va_type;
5684 // type_T *uf_func_type;
5685
5686 ufunc->uf_block_depth = 0;
5687 ufunc->uf_block_ids = NULL;
5688
5689 ga_copy_strings(&fp->uf_lines, &ufunc->uf_lines);
5690
5691 ufunc->uf_refcount = 1;
5692 ufunc->uf_name_exp = NULL;
5693 STRCPY(ufunc->uf_name, fp->uf_name);
5694
5695 return ufunc;
5696}
5697
5698/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005699 * ":delfunction {name}"
5700 */
5701 void
5702ex_delfunction(exarg_T *eap)
5703{
5704 ufunc_T *fp = NULL;
5705 char_u *p;
5706 char_u *name;
5707 funcdict_T fudi;
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005708 int is_global = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005709
5710 p = eap->arg;
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00005711 name = trans_function_name_ext(&p, &is_global, eap->skip, 0, &fudi,
5712 NULL, NULL, NULL);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005713 vim_free(fudi.fd_newkey);
5714 if (name == NULL)
5715 {
5716 if (fudi.fd_dict != NULL && !eap->skip)
Bram Moolenaara6f79292022-01-04 21:30:47 +00005717 emsg(_(e_funcref_required));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005718 return;
5719 }
5720 if (!ends_excmd(*skipwhite(p)))
5721 {
5722 vim_free(name);
Bram Moolenaar74409f62022-01-01 15:58:22 +00005723 semsg(_(e_trailing_characters_str), p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005724 return;
5725 }
Bram Moolenaar63b91732021-08-05 20:40:03 +02005726 set_nextcmd(eap, p);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005727 if (eap->nextcmd != NULL)
5728 *p = NUL;
5729
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005730 if (numbered_function(name) && fudi.fd_dict == NULL)
Bram Moolenaarddfc0512021-09-06 20:56:56 +02005731 {
5732 if (!eap->skip)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +00005733 semsg(_(e_invalid_argument_str), eap->arg);
Bram Moolenaarddfc0512021-09-06 20:56:56 +02005734 vim_free(name);
5735 return;
5736 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005737 if (!eap->skip)
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00005738 fp = find_func(name, is_global);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005739 vim_free(name);
5740
5741 if (!eap->skip)
5742 {
5743 if (fp == NULL)
5744 {
Bram Moolenaard6abcd12017-06-22 19:15:24 +02005745 if (!eap->forceit)
Bram Moolenaarc553a212021-12-26 20:20:34 +00005746 semsg(_(e_unknown_function_str), eap->arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005747 return;
5748 }
5749 if (fp->uf_calls > 0)
5750 {
Bram Moolenaarc553a212021-12-26 20:20:34 +00005751 semsg(_(e_cannot_delete_function_str_it_is_in_use), eap->arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005752 return;
5753 }
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005754 if (fp->uf_flags & FC_VIM9)
5755 {
Bram Moolenaar451c2e32020-08-15 16:33:28 +02005756 semsg(_(e_cannot_delete_vim9_script_function_str), eap->arg);
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02005757 return;
5758 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005759
5760 if (fudi.fd_dict != NULL)
5761 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005762 // Delete the dict item that refers to the function, it will
5763 // invoke func_unref() and possibly delete the function.
Bram Moolenaaref2c3252022-11-25 16:31:51 +00005764 dictitem_remove(fudi.fd_dict, fudi.fd_di, "delfunction");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005765 }
5766 else
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005767 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005768 // A normal function (not a numbered function or lambda) has a
5769 // refcount of 1 for the entry in the hashtable. When deleting
5770 // it and the refcount is more than one, it should be kept.
5771 // A numbered function and lambda should be kept if the refcount is
5772 // one or more.
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02005773 if (fp->uf_refcount > (func_name_refcount(fp->uf_name) ? 0 : 1))
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005774 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005775 // Function is still referenced somewhere. Don't free it but
5776 // do remove it from the hashtable.
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02005777 if (func_remove(fp))
5778 fp->uf_refcount--;
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005779 }
5780 else
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01005781 func_clear_free(fp, FALSE);
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005782 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005783 }
5784}
5785
5786/*
5787 * Unreference a Function: decrement the reference count and free it when it
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005788 * becomes zero.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005789 */
5790 void
5791func_unref(char_u *name)
5792{
Bram Moolenaar97baee82016-07-26 20:46:08 +02005793 ufunc_T *fp = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005794
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02005795 if (name == NULL || !func_name_refcount(name))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005796 return;
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00005797 fp = find_func(name, FALSE);
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005798 if (fp == NULL && numbered_function(name))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005799 {
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005800#ifdef EXITFREE
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005801 if (!entered_free_all_mem)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005802#endif
Bram Moolenaar95f09602016-11-10 20:01:45 +01005803 internal_error("func_unref()");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005804 }
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01005805 func_ptr_unref(fp);
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005806}
5807
5808/*
5809 * Unreference a Function: decrement the reference count and free it when it
5810 * becomes zero.
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01005811 * Also when it becomes one and uf_partial points to the function.
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005812 */
5813 void
5814func_ptr_unref(ufunc_T *fp)
5815{
Bram Moolenaar0d3de8c2021-01-22 20:46:27 +01005816 if (fp != NULL && (--fp->uf_refcount <= 0
5817 || (fp->uf_refcount == 1 && fp->uf_partial != NULL
5818 && fp->uf_partial->pt_refcount <= 1
5819 && fp->uf_partial->pt_func == fp)))
Bram Moolenaar97baee82016-07-26 20:46:08 +02005820 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005821 // Only delete it when it's not being used. Otherwise it's done
5822 // when "uf_calls" becomes zero.
Bram Moolenaar97baee82016-07-26 20:46:08 +02005823 if (fp->uf_calls == 0)
Bram Moolenaar03ff9bc2017-02-02 22:59:27 +01005824 func_clear_free(fp, FALSE);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005825 }
5826}
5827
5828/*
5829 * Count a reference to a Function.
5830 */
5831 void
5832func_ref(char_u *name)
5833{
5834 ufunc_T *fp;
5835
Bram Moolenaar8dd3a432016-08-01 20:46:25 +02005836 if (name == NULL || !func_name_refcount(name))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005837 return;
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00005838 fp = find_func(name, FALSE);
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005839 if (fp != NULL)
5840 ++fp->uf_refcount;
Bram Moolenaar57bc2332021-12-15 12:06:43 +00005841 else if (numbered_function(name))
Bram Moolenaare38eab22019-12-05 21:50:01 +01005842 // Only give an error for a numbered function.
5843 // Fail silently, when named or lambda function isn't found.
Bram Moolenaar95f09602016-11-10 20:01:45 +01005844 internal_error("func_ref()");
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005845}
5846
5847/*
5848 * Count a reference to a Function.
5849 */
5850 void
5851func_ptr_ref(ufunc_T *fp)
5852{
5853 if (fp != NULL)
5854 ++fp->uf_refcount;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005855}
5856
5857/*
5858 * Return TRUE if items in "fc" do not have "copyID". That means they are not
5859 * referenced from anywhere that is in use.
5860 */
5861 static int
5862can_free_funccal(funccall_T *fc, int copyID)
5863{
Bram Moolenaarca16c602022-09-06 18:57:08 +01005864 return (fc->fc_l_varlist.lv_copyID != copyID
5865 && fc->fc_l_vars.dv_copyID != copyID
5866 && fc->fc_l_avars.dv_copyID != copyID
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02005867 && fc->fc_copyID != copyID);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005868}
5869
5870/*
5871 * ":return [expr]"
5872 */
5873 void
5874ex_return(exarg_T *eap)
5875{
5876 char_u *arg = eap->arg;
5877 typval_T rettv;
5878 int returning = FALSE;
Bram Moolenaar5409f5d2020-06-24 18:37:35 +02005879 evalarg_T evalarg;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005880
5881 if (current_funccal == NULL)
5882 {
Bram Moolenaarc553a212021-12-26 20:20:34 +00005883 emsg(_(e_return_not_inside_function));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005884 return;
5885 }
5886
Bram Moolenaar844fb642021-10-23 13:32:30 +01005887 init_evalarg(&evalarg);
Bram Moolenaar5409f5d2020-06-24 18:37:35 +02005888 evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
5889
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005890 if (eap->skip)
5891 ++emsg_skip;
5892
5893 eap->nextcmd = NULL;
5894 if ((*arg != NUL && *arg != '|' && *arg != '\n')
Bram Moolenaarb171fb12020-06-24 20:34:03 +02005895 && eval0(arg, &rettv, eap, &evalarg) != FAIL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005896 {
5897 if (!eap->skip)
5898 returning = do_return(eap, FALSE, TRUE, &rettv);
5899 else
5900 clear_tv(&rettv);
5901 }
Bram Moolenaare38eab22019-12-05 21:50:01 +01005902 // It's safer to return also on error.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005903 else if (!eap->skip)
5904 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01005905 // In return statement, cause_abort should be force_abort.
Bram Moolenaarfabaf752017-12-23 17:26:11 +01005906 update_force_abort();
5907
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005908 /*
5909 * Return unless the expression evaluation has been cancelled due to an
5910 * aborting error, an interrupt, or an exception.
5911 */
5912 if (!aborting())
5913 returning = do_return(eap, FALSE, TRUE, NULL);
5914 }
5915
Bram Moolenaare38eab22019-12-05 21:50:01 +01005916 // When skipping or the return gets pending, advance to the next command
5917 // in this line (!returning). Otherwise, ignore the rest of the line.
5918 // Following lines will be ignored by get_func_line().
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005919 if (returning)
5920 eap->nextcmd = NULL;
Bram Moolenaare38eab22019-12-05 21:50:01 +01005921 else if (eap->nextcmd == NULL) // no argument
Bram Moolenaar63b91732021-08-05 20:40:03 +02005922 set_nextcmd(eap, arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005923
5924 if (eap->skip)
5925 --emsg_skip;
Bram Moolenaarb7a78f72020-06-28 18:43:40 +02005926 clear_evalarg(&evalarg, eap);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005927}
5928
zeertzjq5299c092023-04-12 20:48:16 +01005929/*
5930 * Lower level implementation of "call". Only called when not skipping.
5931 */
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005932 static int
5933ex_call_inner(
5934 exarg_T *eap,
5935 char_u *name,
5936 char_u **arg,
5937 char_u *startarg,
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01005938 funcexe_T *funcexe_init,
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005939 evalarg_T *evalarg)
5940{
5941 linenr_T lnum;
5942 int doesrange;
5943 typval_T rettv;
5944 int failed = FALSE;
5945
zeertzjq5299c092023-04-12 20:48:16 +01005946 lnum = eap->line1;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005947 for ( ; lnum <= eap->line2; ++lnum)
5948 {
5949 funcexe_T funcexe;
5950
zeertzjq5299c092023-04-12 20:48:16 +01005951 if (eap->addr_count > 0)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005952 {
5953 if (lnum > curbuf->b_ml.ml_line_count)
5954 {
5955 // If the function deleted lines or switched to another buffer
5956 // the line number may become invalid.
5957 emsg(_(e_invalid_range));
5958 break;
5959 }
5960 curwin->w_cursor.lnum = lnum;
5961 curwin->w_cursor.col = 0;
5962 curwin->w_cursor.coladd = 0;
5963 }
5964 *arg = startarg;
5965
5966 funcexe = *funcexe_init;
5967 funcexe.fe_doesrange = &doesrange;
5968 rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
5969 if (get_func_tv(name, -1, &rettv, arg, evalarg, &funcexe) == FAIL)
5970 {
5971 failed = TRUE;
5972 break;
5973 }
5974 if (has_watchexpr())
5975 dbg_check_breakpoint(eap);
5976
5977 // Handle a function returning a Funcref, Dictionary or List.
5978 if (handle_subscript(arg, NULL, &rettv,
zeertzjq5299c092023-04-12 20:48:16 +01005979 &EVALARG_EVALUATE, TRUE) == FAIL)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005980 {
5981 failed = TRUE;
5982 break;
5983 }
5984
5985 clear_tv(&rettv);
zeertzjq5299c092023-04-12 20:48:16 +01005986 if (doesrange)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005987 break;
5988
5989 // Stop when immediately aborting on error, or when an interrupt
5990 // occurred or an exception was thrown but not caught.
5991 // get_func_tv() returned OK, so that the check for trailing
5992 // characters below is executed.
5993 if (aborting())
5994 break;
5995 }
Bram Moolenaar1d84f762022-09-03 21:35:53 +01005996 return failed;
5997}
5998
5999/*
6000 * Core part of ":defer func(arg)". "arg" points to the "(" and is advanced.
6001 * Returns FAIL or OK.
6002 */
6003 static int
Bram Moolenaar86d87252022-09-05 21:21:25 +01006004ex_defer_inner(
6005 char_u *name,
6006 char_u **arg,
Bram Moolenaar16900322022-09-08 19:51:45 +01006007 type_T *type,
Bram Moolenaar86d87252022-09-05 21:21:25 +01006008 partial_T *partial,
6009 evalarg_T *evalarg)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006010{
6011 typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
Bram Moolenaar86d87252022-09-05 21:21:25 +01006012 int partial_argc = 0; // number of partial arguments
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006013 int argcount = 0; // number of arguments found
Bram Moolenaar86d87252022-09-05 21:21:25 +01006014 int r;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006015
6016 if (current_funccal == NULL)
6017 {
6018 semsg(_(e_str_not_inside_function), "defer");
6019 return FAIL;
6020 }
Bram Moolenaar86d87252022-09-05 21:21:25 +01006021 if (partial != NULL)
6022 {
6023 if (partial->pt_dict != NULL)
6024 {
6025 emsg(_(e_cannot_use_partial_with_dictionary_for_defer));
6026 return FAIL;
6027 }
6028 if (partial->pt_argc > 0)
6029 {
6030 int i;
6031
6032 partial_argc = partial->pt_argc;
6033 for (i = 0; i < partial_argc; ++i)
6034 copy_tv(&partial->pt_argv[i], &argvars[i]);
6035 }
6036 }
6037 r = get_func_arguments(arg, evalarg, FALSE,
6038 argvars + partial_argc, &argcount);
6039 argcount += partial_argc;
Bram Moolenaar16900322022-09-08 19:51:45 +01006040
6041 if (r == OK)
6042 {
6043 if (type != NULL)
6044 {
6045 // Check that the arguments are OK for the types of the funcref.
6046 r = check_argument_types(type, argvars, argcount, NULL, name);
6047 }
6048 else if (builtin_function(name, -1))
6049 {
6050 int idx = find_internal_func(name);
6051
6052 if (idx < 0)
6053 {
6054 emsg_funcname(e_unknown_function_str, name);
6055 r = FAIL;
6056 }
6057 else if (check_internal_func(idx, argcount) == -1)
6058 r = FAIL;
6059 }
6060 else
6061 {
6062 ufunc_T *ufunc = find_func(name, FALSE);
6063
6064 // we tolerate an unknown function here, it might be defined later
6065 if (ufunc != NULL)
6066 {
Bram Moolenaar0917e862023-02-18 14:42:44 +00006067 funcerror_T error = check_user_func_argcount(ufunc, argcount);
Bram Moolenaar16900322022-09-08 19:51:45 +01006068 if (error != FCERR_UNKNOWN)
6069 {
Bram Moolenaar87b4e5c2022-10-01 15:32:46 +01006070 user_func_error(error, name, FALSE);
Bram Moolenaar16900322022-09-08 19:51:45 +01006071 r = FAIL;
6072 }
6073 }
6074 }
6075 }
6076
Bram Moolenaar86d87252022-09-05 21:21:25 +01006077 if (r == FAIL)
Bram Moolenaar806a2732022-09-04 15:40:36 +01006078 {
6079 while (--argcount >= 0)
6080 clear_tv(&argvars[argcount]);
6081 return FAIL;
6082 }
6083 return add_defer(name, argcount, argvars);
6084}
6085
6086/*
Bram Moolenaar6f14da12022-09-07 21:30:44 +01006087 * Return TRUE if currently inside a function call.
6088 * Give an error message and return FALSE when not.
6089 */
6090 int
6091can_add_defer(void)
6092{
6093 if (!in_def_function() && get_current_funccal() == NULL)
6094 {
6095 semsg(_(e_str_not_inside_function), "defer");
6096 return FALSE;
6097 }
6098 return TRUE;
6099}
6100
6101/*
Bram Moolenaar806a2732022-09-04 15:40:36 +01006102 * Add a deferred call for "name" with arguments "argvars[argcount]".
6103 * Consumes "argvars[]".
6104 * Caller must check that in_def_function() returns TRUE or current_funccal is
6105 * not NULL.
6106 * Returns OK or FAIL.
6107 */
6108 int
6109add_defer(char_u *name, int argcount_arg, typval_T *argvars)
6110{
6111 char_u *saved_name = vim_strsave(name);
6112 int argcount = argcount_arg;
6113 defer_T *dr;
6114 int ret = FAIL;
6115
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006116 if (saved_name == NULL)
6117 goto theend;
Bram Moolenaar806a2732022-09-04 15:40:36 +01006118 if (in_def_function())
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006119 {
Bram Moolenaar806a2732022-09-04 15:40:36 +01006120 if (add_defer_function(saved_name, argcount, argvars) == OK)
6121 argcount = 0;
6122 }
6123 else
6124 {
6125 if (current_funccal->fc_defer.ga_itemsize == 0)
6126 ga_init2(&current_funccal->fc_defer, sizeof(defer_T), 10);
6127 if (ga_grow(&current_funccal->fc_defer, 1) == FAIL)
6128 goto theend;
6129 dr = ((defer_T *)current_funccal->fc_defer.ga_data)
6130 + current_funccal->fc_defer.ga_len++;
6131 dr->dr_name = saved_name;
6132 dr->dr_argcount = argcount;
6133 while (argcount > 0)
6134 {
6135 --argcount;
6136 dr->dr_argvars[argcount] = argvars[argcount];
6137 }
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006138 }
6139 ret = OK;
6140
6141theend:
6142 while (--argcount >= 0)
6143 clear_tv(&argvars[argcount]);
6144 return ret;
6145}
6146
6147/*
6148 * Invoked after a functions has finished: invoke ":defer" functions.
6149 */
Bram Moolenaar58779852022-09-06 18:31:14 +01006150 static void
6151handle_defer_one(funccall_T *funccal)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006152{
6153 int idx;
6154
Bram Moolenaar58779852022-09-06 18:31:14 +01006155 for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006156 {
Bram Moolenaar58779852022-09-06 18:31:14 +01006157 defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006158
Bram Moolenaar42994bf2023-04-17 19:23:45 +01006159 if (dr->dr_name == NULL)
6160 // already being called, can happen if function does ":qa"
6161 continue;
6162
6163 funcexe_T funcexe;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006164 CLEAR_FIELD(funcexe);
6165 funcexe.fe_evaluate = TRUE;
6166
Bram Moolenaar42994bf2023-04-17 19:23:45 +01006167 typval_T rettv;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006168 rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
Bram Moolenaar42994bf2023-04-17 19:23:45 +01006169
6170 char_u *name = dr->dr_name;
6171 dr->dr_name = NULL;
6172
6173 call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
6174
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006175 clear_tv(&rettv);
Bram Moolenaar42994bf2023-04-17 19:23:45 +01006176 vim_free(name);
6177 for (int i = dr->dr_argcount - 1; i >= 0; --i)
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006178 clear_tv(&dr->dr_argvars[i]);
6179 }
Bram Moolenaar58779852022-09-06 18:31:14 +01006180 ga_clear(&funccal->fc_defer);
6181}
6182
zeertzjq960cf912023-04-18 21:52:54 +01006183 static void
6184invoke_funccall_defer(funccall_T *fc)
6185{
6186 if (fc->fc_ectx != NULL)
6187 {
6188 // :def function
6189 unwind_def_callstack(fc->fc_ectx);
6190 may_invoke_defer_funcs(fc->fc_ectx);
6191 }
6192 else
6193 {
6194 // legacy function
6195 handle_defer_one(fc);
6196 }
6197}
6198
Bram Moolenaar58779852022-09-06 18:31:14 +01006199/*
6200 * Called when exiting: call all defer functions.
6201 */
6202 void
6203invoke_all_defer(void)
6204{
zeertzjq1be4b812023-04-19 14:21:24 +01006205 for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->fc_caller)
6206 invoke_funccall_defer(fc);
6207
zeertzjq960cf912023-04-18 21:52:54 +01006208 for (funccal_entry_T *fce = funccal_stack; fce != NULL; fce = fce->next)
6209 for (funccall_T *fc = fce->top_funccal; fc != NULL; fc = fc->fc_caller)
6210 invoke_funccall_defer(fc);
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006211}
6212
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006213/*
6214 * ":1,25call func(arg1, arg2)" function call.
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006215 * ":defer func(arg1, arg2)" deferred function call.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006216 */
6217 void
6218ex_call(exarg_T *eap)
6219{
6220 char_u *arg = eap->arg;
6221 char_u *startarg;
6222 char_u *name;
6223 char_u *tofree;
6224 int len;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006225 int failed = FALSE;
6226 funcdict_T fudi;
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01006227 ufunc_T *ufunc = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006228 partial_T *partial = NULL;
Bram Moolenaare6b53242020-07-01 17:28:33 +02006229 evalarg_T evalarg;
Bram Moolenaar32b3f822021-01-06 21:59:39 +01006230 type_T *type = NULL;
Bram Moolenaar2ef91562021-12-11 16:14:07 +00006231 int found_var = FALSE;
Bram Moolenaar4525a572022-02-13 11:57:33 +00006232 int vim9script = in_vim9script();
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006233
Bram Moolenaare6b53242020-07-01 17:28:33 +02006234 fill_evalarg_from_eap(&evalarg, eap, eap->skip);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006235 if (eap->skip)
6236 {
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006237 typval_T rettv;
6238
Bram Moolenaare38eab22019-12-05 21:50:01 +01006239 // trans_function_name() doesn't work well when skipping, use eval0()
6240 // instead to skip to any following command, e.g. for:
6241 // :if 0 | call dict.foo().bar() | endif
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006242 ++emsg_skip;
Bram Moolenaare6b53242020-07-01 17:28:33 +02006243 if (eval0(eap->arg, &rettv, eap, &evalarg) != FAIL)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006244 clear_tv(&rettv);
6245 --emsg_skip;
Bram Moolenaare6b53242020-07-01 17:28:33 +02006246 clear_evalarg(&evalarg, eap);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006247 return;
6248 }
6249
zeertzjq5299c092023-04-12 20:48:16 +01006250 tofree = trans_function_name_ext(&arg, NULL, FALSE, TFN_INT,
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01006251 &fudi, &partial, vim9script ? &type : NULL, &ufunc);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006252 if (fudi.fd_newkey != NULL)
6253 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006254 // Still need to give an error message for missing key.
Bram Moolenaara9fa8c52023-01-02 18:10:04 +00006255 semsg(_(e_key_not_present_in_dictionary_str), fudi.fd_newkey);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006256 vim_free(fudi.fd_newkey);
6257 }
6258 if (tofree == NULL)
6259 return;
6260
Bram Moolenaare38eab22019-12-05 21:50:01 +01006261 // Increase refcount on dictionary, it could get deleted when evaluating
6262 // the arguments.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006263 if (fudi.fd_dict != NULL)
6264 ++fudi.fd_dict->dv_refcount;
6265
Bram Moolenaare38eab22019-12-05 21:50:01 +01006266 // If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
6267 // contents. For VAR_PARTIAL get its partial, unless we already have one
6268 // from trans_function_name().
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006269 len = (int)STRLEN(tofree);
Bram Moolenaar32b3f822021-01-06 21:59:39 +01006270 name = deref_func_name(tofree, &len, partial != NULL ? NULL : &partial,
Bram Moolenaar4525a572022-02-13 11:57:33 +00006271 vim9script && type == NULL ? &type : NULL,
Bram Moolenaar937610b2022-01-19 17:21:29 +00006272 FALSE, FALSE, &found_var);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006273
Bram Moolenaare38eab22019-12-05 21:50:01 +01006274 // Skip white space to allow ":call func ()". Not good, but required for
6275 // backward compatibility.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006276 startarg = skipwhite(arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006277 if (*startarg != '(')
6278 {
Bram Moolenaare1242042021-12-16 20:56:57 +00006279 semsg(_(e_missing_parenthesis_str), eap->arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006280 goto end;
6281 }
Bram Moolenaar4525a572022-02-13 11:57:33 +00006282 if (vim9script && startarg > arg)
Bram Moolenaar01dd6c32021-09-05 16:36:23 +02006283 {
6284 semsg(_(e_no_white_space_allowed_before_str_str), "(", eap->arg);
6285 goto end;
6286 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006287
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006288 if (eap->cmdidx == CMD_defer)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006289 {
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006290 arg = startarg;
Bram Moolenaar16900322022-09-08 19:51:45 +01006291 failed = ex_defer_inner(name, &arg, type, partial, &evalarg) == FAIL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006292 }
6293 else
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006294 {
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02006295 funcexe_T funcexe;
6296
Bram Moolenaara80faa82020-04-12 19:37:17 +02006297 CLEAR_FIELD(funcexe);
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006298 funcexe.fe_check_type = type;
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01006299 funcexe.fe_ufunc = ufunc;
Bram Moolenaar851f86b2021-12-13 14:26:44 +00006300 funcexe.fe_partial = partial;
6301 funcexe.fe_selfdict = fudi.fd_dict;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006302 funcexe.fe_firstline = eap->line1;
6303 funcexe.fe_lastline = eap->line2;
Bram Moolenaar2ef91562021-12-11 16:14:07 +00006304 funcexe.fe_found_var = found_var;
zeertzjq5299c092023-04-12 20:48:16 +01006305 funcexe.fe_evaluate = TRUE;
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006306 failed = ex_call_inner(eap, name, &arg, startarg, &funcexe, &evalarg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006307 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006308
Bram Moolenaar1d341892021-09-18 15:25:52 +02006309 // When inside :try we need to check for following "| catch" or "| endtry".
6310 // Not when there was an error, but do check if an exception was thrown.
Bram Moolenaar1d84f762022-09-03 21:35:53 +01006311 if ((!aborting() || did_throw) && (!failed || eap->cstack->cs_trylevel > 0))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006312 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006313 // Check for trailing illegal characters and a following command.
Bram Moolenaar8294d492020-08-10 22:40:56 +02006314 arg = skipwhite(arg);
Bram Moolenaara72cfb82020-04-23 17:07:30 +02006315 if (!ends_excmd2(eap->arg, arg))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006316 {
Bram Moolenaar1d341892021-09-18 15:25:52 +02006317 if (!failed && !aborting())
Bram Moolenaar40d9da22020-02-17 10:01:24 +01006318 {
6319 emsg_severe = TRUE;
Bram Moolenaar74409f62022-01-01 15:58:22 +00006320 semsg(_(e_trailing_characters_str), arg);
Bram Moolenaar40d9da22020-02-17 10:01:24 +01006321 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006322 }
6323 else
Bram Moolenaar63b91732021-08-05 20:40:03 +02006324 set_nextcmd(eap, arg);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006325 }
Bram Moolenaara929c922022-04-18 15:21:17 +01006326 // Must be after using "arg", it may point into memory cleared here.
6327 clear_evalarg(&evalarg, eap);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006328
6329end:
6330 dict_unref(fudi.fd_dict);
6331 vim_free(tofree);
6332}
6333
6334/*
6335 * Return from a function. Possibly makes the return pending. Also called
6336 * for a pending return at the ":endtry" or after returning from an extra
6337 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set
6338 * when called due to a ":return" command. "rettv" may point to a typval_T
6339 * with the return rettv. Returns TRUE when the return can be carried out,
6340 * FALSE when the return gets pending.
6341 */
6342 int
6343do_return(
6344 exarg_T *eap,
6345 int reanimate,
6346 int is_cmd,
6347 void *rettv)
6348{
6349 int idx;
Bram Moolenaarddef1292019-12-16 17:10:33 +01006350 cstack_T *cstack = eap->cstack;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006351
6352 if (reanimate)
Bram Moolenaare38eab22019-12-05 21:50:01 +01006353 // Undo the return.
Bram Moolenaarca16c602022-09-06 18:57:08 +01006354 current_funccal->fc_returned = FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006355
6356 /*
6357 * Cleanup (and inactivate) conditionals, but stop when a try conditional
6358 * not in its finally clause (which then is to be executed next) is found.
6359 * In this case, make the ":return" pending for execution at the ":endtry".
6360 * Otherwise, return normally.
6361 */
6362 idx = cleanup_conditionals(eap->cstack, 0, TRUE);
6363 if (idx >= 0)
6364 {
6365 cstack->cs_pending[idx] = CSTP_RETURN;
6366
6367 if (!is_cmd && !reanimate)
Bram Moolenaare38eab22019-12-05 21:50:01 +01006368 // A pending return again gets pending. "rettv" points to an
6369 // allocated variable with the rettv of the original ":return"'s
6370 // argument if present or is NULL else.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006371 cstack->cs_rettv[idx] = rettv;
6372 else
6373 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006374 // When undoing a return in order to make it pending, get the stored
6375 // return rettv.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006376 if (reanimate)
Bram Moolenaarca16c602022-09-06 18:57:08 +01006377 rettv = current_funccal->fc_rettv;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006378
6379 if (rettv != NULL)
6380 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006381 // Store the value of the pending return.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006382 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL)
6383 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
6384 else
Bram Moolenaare29a27f2021-07-20 21:07:36 +02006385 emsg(_(e_out_of_memory));
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006386 }
6387 else
6388 cstack->cs_rettv[idx] = NULL;
6389
6390 if (reanimate)
6391 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006392 // The pending return value could be overwritten by a ":return"
6393 // without argument in a finally clause; reset the default
6394 // return value.
Bram Moolenaarca16c602022-09-06 18:57:08 +01006395 current_funccal->fc_rettv->v_type = VAR_NUMBER;
6396 current_funccal->fc_rettv->vval.v_number = 0;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006397 }
6398 }
6399 report_make_pending(CSTP_RETURN, rettv);
6400 }
6401 else
6402 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01006403 current_funccal->fc_returned = TRUE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006404
Bram Moolenaare38eab22019-12-05 21:50:01 +01006405 // If the return is carried out now, store the return value. For
6406 // a return immediately after reanimation, the value is already
6407 // there.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006408 if (!reanimate && rettv != NULL)
6409 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01006410 clear_tv(current_funccal->fc_rettv);
6411 *current_funccal->fc_rettv = *(typval_T *)rettv;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006412 if (!is_cmd)
6413 vim_free(rettv);
6414 }
6415 }
6416
6417 return idx < 0;
6418}
6419
6420/*
6421 * Free the variable with a pending return value.
6422 */
6423 void
6424discard_pending_return(void *rettv)
6425{
6426 free_tv((typval_T *)rettv);
6427}
6428
6429/*
6430 * Generate a return command for producing the value of "rettv". The result
6431 * is an allocated string. Used by report_pending() for verbose messages.
6432 */
6433 char_u *
6434get_return_cmd(void *rettv)
6435{
6436 char_u *s = NULL;
6437 char_u *tofree = NULL;
6438 char_u numbuf[NUMBUFLEN];
6439
6440 if (rettv != NULL)
6441 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0);
6442 if (s == NULL)
6443 s = (char_u *)"";
6444
6445 STRCPY(IObuff, ":return ");
6446 STRNCPY(IObuff + 8, s, IOSIZE - 8);
6447 if (STRLEN(s) + 8 >= IOSIZE)
6448 STRCPY(IObuff + IOSIZE - 4, "...");
6449 vim_free(tofree);
6450 return vim_strsave(IObuff);
6451}
6452
6453/*
6454 * Get next function line.
6455 * Called by do_cmdline() to get the next line.
6456 * Returns allocated string, or NULL for end of function.
6457 */
6458 char_u *
6459get_func_line(
6460 int c UNUSED,
6461 void *cookie,
Bram Moolenaare96a2492019-06-25 04:12:16 +02006462 int indent UNUSED,
Bram Moolenaar66250c92020-08-20 15:02:42 +02006463 getline_opt_T options UNUSED)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006464{
6465 funccall_T *fcp = (funccall_T *)cookie;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006466 ufunc_T *fp = fcp->fc_func;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006467 char_u *retval;
Bram Moolenaare38eab22019-12-05 21:50:01 +01006468 garray_T *gap; // growarray with function lines
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006469
Bram Moolenaare38eab22019-12-05 21:50:01 +01006470 // If breakpoints have been added/deleted need to check for it.
Bram Moolenaarca16c602022-09-06 18:57:08 +01006471 if (fcp->fc_dbg_tick != debug_tick)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006472 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01006473 fcp->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01006474 SOURCING_LNUM);
Bram Moolenaarca16c602022-09-06 18:57:08 +01006475 fcp->fc_dbg_tick = debug_tick;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006476 }
6477#ifdef FEAT_PROFILE
6478 if (do_profiling == PROF_YES)
6479 func_line_end(cookie);
6480#endif
6481
6482 gap = &fp->uf_lines;
6483 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
Bram Moolenaarca16c602022-09-06 18:57:08 +01006484 || fcp->fc_returned)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006485 retval = NULL;
6486 else
6487 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006488 // Skip NULL lines (continuation lines).
Bram Moolenaarca16c602022-09-06 18:57:08 +01006489 while (fcp->fc_linenr < gap->ga_len
6490 && ((char_u **)(gap->ga_data))[fcp->fc_linenr] == NULL)
6491 ++fcp->fc_linenr;
6492 if (fcp->fc_linenr >= gap->ga_len)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006493 retval = NULL;
6494 else
6495 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01006496 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->fc_linenr++]);
6497 SOURCING_LNUM = fcp->fc_linenr;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006498#ifdef FEAT_PROFILE
6499 if (do_profiling == PROF_YES)
Bram Moolenaarb2049902021-01-24 12:53:53 +01006500 func_line_start(cookie, SOURCING_LNUM);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006501#endif
6502 }
6503 }
6504
Bram Moolenaare38eab22019-12-05 21:50:01 +01006505 // Did we encounter a breakpoint?
Bram Moolenaarca16c602022-09-06 18:57:08 +01006506 if (fcp->fc_breakpoint != 0 && fcp->fc_breakpoint <= SOURCING_LNUM)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006507 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01006508 dbg_breakpoint(fp->uf_name, SOURCING_LNUM);
Bram Moolenaare38eab22019-12-05 21:50:01 +01006509 // Find next breakpoint.
Bram Moolenaarca16c602022-09-06 18:57:08 +01006510 fcp->fc_breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01006511 SOURCING_LNUM);
Bram Moolenaarca16c602022-09-06 18:57:08 +01006512 fcp->fc_dbg_tick = debug_tick;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006513 }
6514
6515 return retval;
6516}
6517
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006518/*
6519 * Return TRUE if the currently active function should be ended, because a
6520 * return was encountered or an error occurred. Used inside a ":while".
6521 */
6522 int
6523func_has_ended(void *cookie)
6524{
6525 funccall_T *fcp = (funccall_T *)cookie;
6526
Bram Moolenaare38eab22019-12-05 21:50:01 +01006527 // Ignore the "abort" flag if the abortion behavior has been changed due to
6528 // an error inside a try conditional.
Bram Moolenaarca16c602022-09-06 18:57:08 +01006529 return (((fcp->fc_func->uf_flags & FC_ABORT)
6530 && did_emsg && !aborted_in_try())
6531 || fcp->fc_returned);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006532}
6533
6534/*
6535 * return TRUE if cookie indicates a function which "abort"s on errors.
6536 */
6537 int
6538func_has_abort(
6539 void *cookie)
6540{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006541 return ((funccall_T *)cookie)->fc_func->uf_flags & FC_ABORT;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006542}
6543
6544
6545/*
6546 * Turn "dict.Func" into a partial for "Func" bound to "dict".
6547 * Don't do this when "Func" is already a partial that was bound
6548 * explicitly (pt_auto is FALSE).
6549 * Changes "rettv" in-place.
6550 * Returns the updated "selfdict_in".
6551 */
6552 dict_T *
6553make_partial(dict_T *selfdict_in, typval_T *rettv)
6554{
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006555 char_u *fname;
Bram Moolenaared0c62e2022-03-08 19:43:55 +00006556 ufunc_T *fp = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006557 char_u fname_buf[FLEN_FIXED + 1];
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006558 dict_T *selfdict = selfdict_in;
6559
Bram Moolenaared0c62e2022-03-08 19:43:55 +00006560 if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial != NULL
6561 && rettv->vval.v_partial->pt_func != NULL)
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006562 fp = rettv->vval.v_partial->pt_func;
6563 else
6564 {
6565 fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
Bram Moolenaared0c62e2022-03-08 19:43:55 +00006566 : rettv->vval.v_partial == NULL ? NULL
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006567 : rettv->vval.v_partial->pt_name;
Bram Moolenaared0c62e2022-03-08 19:43:55 +00006568 if (fname == NULL)
6569 {
6570 // There is no point binding a dict to a NULL function, just create
6571 // a function reference.
6572 rettv->v_type = VAR_FUNC;
6573 rettv->vval.v_string = NULL;
6574 }
6575 else
Bram Moolenaar673bcb12022-03-08 16:52:24 +00006576 {
6577 char_u *tofree = NULL;
Bram Moolenaar0917e862023-02-18 14:42:44 +00006578 funcerror_T error;
Bram Moolenaar673bcb12022-03-08 16:52:24 +00006579
6580 // Translate "s:func" to the stored function name.
6581 fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
6582 fp = find_func(fname, FALSE);
6583 vim_free(tofree);
6584 }
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006585 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006586
Bram Moolenaared0c62e2022-03-08 19:43:55 +00006587 if (fp != NULL && (fp->uf_flags & FC_DICT))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006588 {
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006589 partial_T *pt = ALLOC_CLEAR_ONE(partial_T);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006590
6591 if (pt != NULL)
6592 {
6593 pt->pt_refcount = 1;
6594 pt->pt_dict = selfdict;
6595 pt->pt_auto = TRUE;
6596 selfdict = NULL;
6597 if (rettv->v_type == VAR_FUNC)
6598 {
Bram Moolenaare38eab22019-12-05 21:50:01 +01006599 // Just a function: Take over the function name and use
6600 // selfdict.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006601 pt->pt_name = rettv->vval.v_string;
6602 }
6603 else
6604 {
6605 partial_T *ret_pt = rettv->vval.v_partial;
6606 int i;
6607
Bram Moolenaare38eab22019-12-05 21:50:01 +01006608 // Partial: copy the function name, use selfdict and copy
6609 // args. Can't take over name or args, the partial might
6610 // be referenced elsewhere.
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006611 if (ret_pt->pt_name != NULL)
6612 {
6613 pt->pt_name = vim_strsave(ret_pt->pt_name);
6614 func_ref(pt->pt_name);
6615 }
6616 else
6617 {
6618 pt->pt_func = ret_pt->pt_func;
6619 func_ptr_ref(pt->pt_func);
6620 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006621 if (ret_pt->pt_argc > 0)
6622 {
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006623 pt->pt_argv = ALLOC_MULT(typval_T, ret_pt->pt_argc);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006624 if (pt->pt_argv == NULL)
Bram Moolenaare38eab22019-12-05 21:50:01 +01006625 // out of memory: drop the arguments
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006626 pt->pt_argc = 0;
6627 else
6628 {
6629 pt->pt_argc = ret_pt->pt_argc;
6630 for (i = 0; i < pt->pt_argc; i++)
6631 copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
6632 }
6633 }
6634 partial_unref(ret_pt);
6635 }
6636 rettv->v_type = VAR_PARTIAL;
6637 rettv->vval.v_partial = pt;
6638 }
6639 }
6640 return selfdict;
6641}
6642
6643/*
6644 * Return the name of the executed function.
6645 */
6646 char_u *
6647func_name(void *cookie)
6648{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006649 return ((funccall_T *)cookie)->fc_func->uf_name;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006650}
6651
6652/*
6653 * Return the address holding the next breakpoint line for a funccall cookie.
6654 */
6655 linenr_T *
6656func_breakpoint(void *cookie)
6657{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006658 return &((funccall_T *)cookie)->fc_breakpoint;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006659}
6660
6661/*
6662 * Return the address holding the debug tick for a funccall cookie.
6663 */
6664 int *
6665func_dbg_tick(void *cookie)
6666{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006667 return &((funccall_T *)cookie)->fc_dbg_tick;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006668}
6669
6670/*
6671 * Return the nesting level for a funccall cookie.
6672 */
6673 int
6674func_level(void *cookie)
6675{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006676 return ((funccall_T *)cookie)->fc_level;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006677}
6678
6679/*
6680 * Return TRUE when a function was ended by a ":return" command.
6681 */
6682 int
6683current_func_returned(void)
6684{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006685 return current_funccal->fc_returned;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006686}
6687
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006688 int
6689free_unref_funccal(int copyID, int testing)
6690{
6691 int did_free = FALSE;
6692 int did_free_funccal = FALSE;
6693 funccall_T *fc, **pfc;
6694
6695 for (pfc = &previous_funccal; *pfc != NULL; )
6696 {
6697 if (can_free_funccal(*pfc, copyID))
6698 {
6699 fc = *pfc;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006700 *pfc = fc->fc_caller;
Bram Moolenaar209b8e32019-03-14 13:43:24 +01006701 free_funccal_contents(fc);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006702 did_free = TRUE;
6703 did_free_funccal = TRUE;
6704 }
6705 else
Bram Moolenaarca16c602022-09-06 18:57:08 +01006706 pfc = &(*pfc)->fc_caller;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006707 }
6708 if (did_free_funccal)
Bram Moolenaare38eab22019-12-05 21:50:01 +01006709 // When a funccal was freed some more items might be garbage
6710 // collected, so run again.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006711 (void)garbage_collect(testing);
6712
6713 return did_free;
6714}
6715
6716/*
Bram Moolenaarba209902016-08-24 22:06:38 +02006717 * Get function call environment based on backtrace debug level
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006718 */
6719 static funccall_T *
6720get_funccal(void)
6721{
6722 int i;
6723 funccall_T *funccal;
6724 funccall_T *temp_funccal;
6725
6726 funccal = current_funccal;
6727 if (debug_backtrace_level > 0)
6728 {
6729 for (i = 0; i < debug_backtrace_level; i++)
6730 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01006731 temp_funccal = funccal->fc_caller;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006732 if (temp_funccal)
6733 funccal = temp_funccal;
6734 else
Bram Moolenaare38eab22019-12-05 21:50:01 +01006735 // backtrace level overflow. reset to max
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006736 debug_backtrace_level = i;
6737 }
6738 }
6739 return funccal;
6740}
6741
6742/*
6743 * Return the hashtable used for local variables in the current funccal.
6744 * Return NULL if there is no current funccal.
6745 */
6746 hashtab_T *
Yegappan Lakshmanana23a11b2023-02-21 14:27:41 +00006747get_funccal_local_ht(void)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006748{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006749 if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006750 return NULL;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006751 return &get_funccal()->fc_l_vars.dv_hashtab;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006752}
6753
6754/*
6755 * Return the l: scope variable.
6756 * Return NULL if there is no current funccal.
6757 */
6758 dictitem_T *
Yegappan Lakshmanana23a11b2023-02-21 14:27:41 +00006759get_funccal_local_var(void)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006760{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006761 if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006762 return NULL;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006763 return &get_funccal()->fc_l_vars_var;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006764}
6765
6766/*
6767 * Return the hashtable used for argument in the current funccal.
6768 * Return NULL if there is no current funccal.
6769 */
6770 hashtab_T *
Yegappan Lakshmanana23a11b2023-02-21 14:27:41 +00006771get_funccal_args_ht(void)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006772{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006773 if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006774 return NULL;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006775 return &get_funccal()->fc_l_avars.dv_hashtab;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006776}
6777
6778/*
6779 * Return the a: scope variable.
6780 * Return NULL if there is no current funccal.
6781 */
6782 dictitem_T *
Yegappan Lakshmanana23a11b2023-02-21 14:27:41 +00006783get_funccal_args_var(void)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006784{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006785 if (current_funccal == NULL || current_funccal->fc_l_vars.dv_refcount == 0)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006786 return NULL;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006787 return &get_funccal()->fc_l_avars_var;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006788}
6789
6790/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006791 * List function variables, if there is a function.
6792 */
6793 void
6794list_func_vars(int *first)
6795{
Bram Moolenaarca16c602022-09-06 18:57:08 +01006796 if (current_funccal != NULL && current_funccal->fc_l_vars.dv_refcount > 0)
6797 list_hashtable_vars(&current_funccal->fc_l_vars.dv_hashtab,
Bram Moolenaar32526b32019-01-19 17:43:09 +01006798 "l:", FALSE, first);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006799}
6800
6801/*
6802 * If "ht" is the hashtable for local variables in the current funccal, return
6803 * the dict that contains it.
6804 * Otherwise return NULL.
6805 */
6806 dict_T *
6807get_current_funccal_dict(hashtab_T *ht)
6808{
6809 if (current_funccal != NULL
Bram Moolenaarca16c602022-09-06 18:57:08 +01006810 && ht == &current_funccal->fc_l_vars.dv_hashtab)
6811 return &current_funccal->fc_l_vars;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006812 return NULL;
6813}
6814
6815/*
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02006816 * Search hashitem in parent scope.
6817 */
6818 hashitem_T *
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006819find_hi_in_scoped_ht(char_u *name, hashtab_T **pht)
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02006820{
6821 funccall_T *old_current_funccal = current_funccal;
6822 hashtab_T *ht;
6823 hashitem_T *hi = NULL;
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006824 char_u *varname;
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02006825
Bram Moolenaarca16c602022-09-06 18:57:08 +01006826 if (current_funccal == NULL || current_funccal->fc_func->uf_scoped == NULL)
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02006827 return NULL;
6828
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02006829 // Search in parent scope, which can be referenced from a lambda.
Bram Moolenaarca16c602022-09-06 18:57:08 +01006830 current_funccal = current_funccal->fc_func->uf_scoped;
Bram Moolenaar58016442016-07-31 18:30:22 +02006831 while (current_funccal != NULL)
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02006832 {
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006833 ht = find_var_ht(name, &varname);
6834 if (ht != NULL && *varname != NUL)
Bram Moolenaar58016442016-07-31 18:30:22 +02006835 {
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006836 hi = hash_find(ht, varname);
Bram Moolenaar58016442016-07-31 18:30:22 +02006837 if (!HASHITEM_EMPTY(hi))
6838 {
6839 *pht = ht;
6840 break;
6841 }
6842 }
Bram Moolenaarca16c602022-09-06 18:57:08 +01006843 if (current_funccal == current_funccal->fc_func->uf_scoped)
Bram Moolenaar58016442016-07-31 18:30:22 +02006844 break;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006845 current_funccal = current_funccal->fc_func->uf_scoped;
Bram Moolenaar10ce39a2016-07-29 22:37:06 +02006846 }
6847 current_funccal = old_current_funccal;
6848
6849 return hi;
6850}
6851
6852/*
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006853 * Search variable in parent scope.
6854 */
6855 dictitem_T *
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006856find_var_in_scoped_ht(char_u *name, int no_autoload)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006857{
6858 dictitem_T *v = NULL;
6859 funccall_T *old_current_funccal = current_funccal;
6860 hashtab_T *ht;
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006861 char_u *varname;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006862
Bram Moolenaarca16c602022-09-06 18:57:08 +01006863 if (current_funccal == NULL || current_funccal->fc_func->uf_scoped == NULL)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006864 return NULL;
6865
Bram Moolenaare38eab22019-12-05 21:50:01 +01006866 // Search in parent scope which is possible to reference from lambda
Bram Moolenaarca16c602022-09-06 18:57:08 +01006867 current_funccal = current_funccal->fc_func->uf_scoped;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006868 while (current_funccal)
6869 {
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006870 ht = find_var_ht(name, &varname);
6871 if (ht != NULL && *varname != NUL)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006872 {
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006873 v = find_var_in_ht(ht, *name, varname, no_autoload);
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006874 if (v != NULL)
6875 break;
6876 }
Bram Moolenaarca16c602022-09-06 18:57:08 +01006877 if (current_funccal == current_funccal->fc_func->uf_scoped)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006878 break;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006879 current_funccal = current_funccal->fc_func->uf_scoped;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006880 }
6881 current_funccal = old_current_funccal;
6882
6883 return v;
6884}
6885
6886/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006887 * Set "copyID + 1" in previous_funccal and callers.
6888 */
6889 int
6890set_ref_in_previous_funccal(int copyID)
6891{
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006892 funccall_T *fc;
6893
Bram Moolenaarca16c602022-09-06 18:57:08 +01006894 for (fc = previous_funccal; fc != NULL; fc = fc->fc_caller)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006895 {
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006896 fc->fc_copyID = copyID + 1;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006897 if (set_ref_in_ht(&fc->fc_l_vars.dv_hashtab, copyID + 1, NULL)
6898 || set_ref_in_ht(&fc->fc_l_avars.dv_hashtab, copyID + 1, NULL)
6899 || set_ref_in_list_items(&fc->fc_l_varlist, copyID + 1, NULL))
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006900 return TRUE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006901 }
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006902 return FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006903}
6904
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006905 static int
6906set_ref_in_funccal(funccall_T *fc, int copyID)
6907{
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006908 if (fc->fc_copyID != copyID)
6909 {
6910 fc->fc_copyID = copyID;
Bram Moolenaarca16c602022-09-06 18:57:08 +01006911 if (set_ref_in_ht(&fc->fc_l_vars.dv_hashtab, copyID, NULL)
6912 || set_ref_in_ht(&fc->fc_l_avars.dv_hashtab, copyID, NULL)
6913 || set_ref_in_list_items(&fc->fc_l_varlist, copyID, NULL)
6914 || set_ref_in_func(NULL, fc->fc_func, copyID))
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006915 return TRUE;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006916 }
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006917 return FALSE;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006918}
6919
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006920/*
6921 * Set "copyID" in all local vars and arguments in the call stack.
6922 */
6923 int
6924set_ref_in_call_stack(int copyID)
6925{
Bram Moolenaarc07f67a2019-06-06 19:03:17 +02006926 funccall_T *fc;
6927 funccal_entry_T *entry;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006928
Bram Moolenaarca16c602022-09-06 18:57:08 +01006929 for (fc = current_funccal; fc != NULL; fc = fc->fc_caller)
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006930 if (set_ref_in_funccal(fc, copyID))
6931 return TRUE;
Bram Moolenaarc07f67a2019-06-06 19:03:17 +02006932
6933 // Also go through the funccal_stack.
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006934 for (entry = funccal_stack; entry != NULL; entry = entry->next)
Bram Moolenaarca16c602022-09-06 18:57:08 +01006935 for (fc = entry->top_funccal; fc != NULL; fc = fc->fc_caller)
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006936 if (set_ref_in_funccal(fc, copyID))
6937 return TRUE;
6938 return FALSE;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006939}
6940
6941/*
6942 * Set "copyID" in all functions available by name.
6943 */
6944 int
6945set_ref_in_functions(int copyID)
6946{
6947 int todo;
6948 hashitem_T *hi = NULL;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006949 ufunc_T *fp;
6950
6951 todo = (int)func_hashtab.ht_used;
6952 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006953 {
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006954 if (!HASHITEM_EMPTY(hi))
6955 {
6956 --todo;
6957 fp = HI2UF(hi);
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006958 if (!func_name_refcount(fp->uf_name)
6959 && set_ref_in_func(NULL, fp, copyID))
6960 return TRUE;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006961 }
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006962 }
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006963 return FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006964}
6965
6966/*
6967 * Set "copyID" in all function arguments.
6968 */
6969 int
6970set_ref_in_func_args(int copyID)
6971{
6972 int i;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006973
6974 for (i = 0; i < funcargs.ga_len; ++i)
Bram Moolenaar20cc5282021-07-03 16:33:16 +02006975 if (set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
6976 copyID, NULL, NULL))
6977 return TRUE;
6978 return FALSE;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006979}
6980
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006981/*
6982 * Mark all lists and dicts referenced through function "name" with "copyID".
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006983 * Returns TRUE if setting references failed somehow.
6984 */
6985 int
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006986set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006987{
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006988 ufunc_T *fp = fp_in;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006989 funccall_T *fc;
Bram Moolenaar0917e862023-02-18 14:42:44 +00006990 funcerror_T error = FCERR_NONE;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006991 char_u fname_buf[FLEN_FIXED + 1];
6992 char_u *tofree = NULL;
6993 char_u *fname;
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02006994 int abort = FALSE;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006995
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006996 if (name == NULL && fp_in == NULL)
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006997 return FALSE;
6998
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006999 if (fp_in == NULL)
7000 {
7001 fname = fname_trans_sid(name, fname_buf, &tofree, &error);
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00007002 fp = find_func(fname, FALSE);
Bram Moolenaar437bafe2016-08-01 15:40:54 +02007003 }
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02007004 if (fp != NULL)
7005 {
Bram Moolenaarca16c602022-09-06 18:57:08 +01007006 for (fc = fp->uf_scoped; fc != NULL; fc = fc->fc_func->uf_scoped)
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02007007 abort = abort || set_ref_in_funccal(fc, copyID);
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02007008 }
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02007009
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02007010 vim_free(tofree);
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02007011 return abort;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02007012}
7013
Bram Moolenaare38eab22019-12-05 21:50:01 +01007014#endif // FEAT_EVAL