1 /* vi:set ts=8 sts=4 sw=4 noet:
2 *
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 /*
11 * eval.c: Expression evaluation.
12 */
13 #define USING_FLOAT_STUFF
14
15 #include "vim.h"
16
17 #if defined(FEAT_EVAL) || defined(PROTO)
18
19 #ifdef VMS
20 # include <float.h>
21 #endif
22
23 #define NAMESPACE_CHAR (char_u *)"abglstvw"
24
25 /*
26 * When recursively copying lists and dicts we need to remember which ones we
27 * have done to avoid endless recursiveness. This unique ID is used for that.
28 * The last bit is used for previous_funccal, ignored when comparing.
29 */
30 static int current_copyID = 0;
31
32 /*
33 * Info used by a ":for" loop.
34 */
35 typedef struct
36 {
37 int fi_semicolon; // TRUE if ending in '; var]'
38 int fi_varcount; // nr of variables in the list
39 int fi_break_count; // nr of line breaks encountered
40 listwatch_T fi_lw; // keep an eye on the item used.
41 list_T *fi_list; // list being used
42 int fi_bi; // index of blob
43 blob_T *fi_blob; // blob being used
44 char_u *fi_string; // copy of string being used
45 int fi_byte_idx; // byte index in fi_string
46 } forinfo_T;
47
48 static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
49 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
50 static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
51 static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
52 static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
53 static int eval7t(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
54 static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
55 static int eval7_leader(typval_T *rettv, int numeric_only, char_u *start_leader, char_u **end_leaderp);
56
57 static int free_unref_items(int copyID);
58 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
59 static char_u *eval_next_line(evalarg_T *evalarg);
60
61 /*
62 * Return "n1" divided by "n2", taking care of dividing by zero.
63 * If "failed" is not NULL set it to TRUE when dividing by zero fails.
64 */
65 varnumber_T
num_divide(varnumber_T n1,varnumber_T n2,int * failed)66 num_divide(varnumber_T n1, varnumber_T n2, int *failed)
67 {
68 varnumber_T result;
69
70 if (n2 == 0)
71 {
72 if (in_vim9script())
73 {
74 emsg(_(e_divide_by_zero));
75 if (failed != NULL)
76 *failed = TRUE;
77 }
78 if (n1 == 0)
79 result = VARNUM_MIN; // similar to NaN
80 else if (n1 < 0)
81 result = -VARNUM_MAX;
82 else
83 result = VARNUM_MAX;
84 }
85 else
86 result = n1 / n2;
87
88 return result;
89 }
90
91 /*
92 * Return "n1" modulus "n2", taking care of dividing by zero.
93 * If "failed" is not NULL set it to TRUE when dividing by zero fails.
94 */
95 varnumber_T
num_modulus(varnumber_T n1,varnumber_T n2,int * failed)96 num_modulus(varnumber_T n1, varnumber_T n2, int *failed)
97 {
98 if (n2 == 0 && in_vim9script())
99 {
100 emsg(_(e_divide_by_zero));
101 if (failed != NULL)
102 *failed = TRUE;
103 }
104 return (n2 == 0) ? 0 : (n1 % n2);
105 }
106
107 /*
108 * Initialize the global and v: variables.
109 */
110 void
eval_init(void)111 eval_init(void)
112 {
113 evalvars_init();
114 func_init();
115
116 #ifdef EBCDIC
117 /*
118 * Sort the function table, to enable binary search.
119 */
120 sortFunctions();
121 #endif
122 }
123
124 #if defined(EXITFREE) || defined(PROTO)
125 void
eval_clear(void)126 eval_clear(void)
127 {
128 evalvars_clear();
129 free_scriptnames(); // must come after evalvars_clear().
130 free_locales();
131
132 // autoloaded script names
133 free_autoload_scriptnames();
134
135 // unreferenced lists and dicts
136 (void)garbage_collect(FALSE);
137
138 // functions not garbage collected
139 free_all_functions();
140 }
141 #endif
142
143 void
fill_evalarg_from_eap(evalarg_T * evalarg,exarg_T * eap,int skip)144 fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip)
145 {
146 init_evalarg(evalarg);
147 evalarg->eval_flags = skip ? 0 : EVAL_EVALUATE;
148 if (eap != NULL)
149 {
150 evalarg->eval_cstack = eap->cstack;
151 if (getline_equal(eap->getline, eap->cookie, getsourceline))
152 {
153 evalarg->eval_getline = eap->getline;
154 evalarg->eval_cookie = eap->cookie;
155 }
156 }
157 }
158
159 /*
160 * Top level evaluation function, returning a boolean.
161 * Sets "error" to TRUE if there was an error.
162 * Return TRUE or FALSE.
163 */
164 int
eval_to_bool(char_u * arg,int * error,exarg_T * eap,int skip)165 eval_to_bool(
166 char_u *arg,
167 int *error,
168 exarg_T *eap,
169 int skip) // only parse, don't execute
170 {
171 typval_T tv;
172 varnumber_T retval = FALSE;
173 evalarg_T evalarg;
174
175 fill_evalarg_from_eap(&evalarg, eap, skip);
176
177 if (skip)
178 ++emsg_skip;
179 if (eval0(arg, &tv, eap, &evalarg) == FAIL)
180 *error = TRUE;
181 else
182 {
183 *error = FALSE;
184 if (!skip)
185 {
186 if (in_vim9script())
187 retval = tv_get_bool_chk(&tv, error);
188 else
189 retval = (tv_get_number_chk(&tv, error) != 0);
190 clear_tv(&tv);
191 }
192 }
193 if (skip)
194 --emsg_skip;
195 clear_evalarg(&evalarg, eap);
196
197 return (int)retval;
198 }
199
200 /*
201 * Call eval1() and give an error message if not done at a lower level.
202 */
203 static int
eval1_emsg(char_u ** arg,typval_T * rettv,exarg_T * eap)204 eval1_emsg(char_u **arg, typval_T *rettv, exarg_T *eap)
205 {
206 char_u *start = *arg;
207 int ret;
208 int did_emsg_before = did_emsg;
209 int called_emsg_before = called_emsg;
210 evalarg_T evalarg;
211
212 fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
213
214 ret = eval1(arg, rettv, &evalarg);
215 if (ret == FAIL)
216 {
217 // Report the invalid expression unless the expression evaluation has
218 // been cancelled due to an aborting error, an interrupt, or an
219 // exception, or we already gave a more specific error.
220 // Also check called_emsg for when using assert_fails().
221 if (!aborting() && did_emsg == did_emsg_before
222 && called_emsg == called_emsg_before)
223 semsg(_(e_invalid_expression_str), start);
224 }
225 clear_evalarg(&evalarg, eap);
226 return ret;
227 }
228
229 /*
230 * Return whether a typval is a valid expression to pass to eval_expr_typval()
231 * or eval_expr_to_bool(). An empty string returns FALSE;
232 */
233 int
eval_expr_valid_arg(typval_T * tv)234 eval_expr_valid_arg(typval_T *tv)
235 {
236 return tv->v_type != VAR_UNKNOWN
237 && (tv->v_type != VAR_STRING
238 || (tv->vval.v_string != NULL && *tv->vval.v_string != NUL));
239 }
240
241 /*
242 * Evaluate an expression, which can be a function, partial or string.
243 * Pass arguments "argv[argc]".
244 * Return the result in "rettv" and OK or FAIL.
245 */
246 int
eval_expr_typval(typval_T * expr,typval_T * argv,int argc,typval_T * rettv)247 eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
248 {
249 char_u *s;
250 char_u buf[NUMBUFLEN];
251 funcexe_T funcexe;
252
253 if (expr->v_type == VAR_FUNC)
254 {
255 s = expr->vval.v_string;
256 if (s == NULL || *s == NUL)
257 return FAIL;
258 CLEAR_FIELD(funcexe);
259 funcexe.evaluate = TRUE;
260 if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
261 return FAIL;
262 }
263 else if (expr->v_type == VAR_PARTIAL)
264 {
265 partial_T *partial = expr->vval.v_partial;
266
267 if (partial == NULL)
268 return FAIL;
269
270 if (partial->pt_func != NULL
271 && partial->pt_func->uf_def_status != UF_NOT_COMPILED)
272 {
273 if (call_def_function(partial->pt_func, argc, argv,
274 partial, rettv) == FAIL)
275 return FAIL;
276 }
277 else
278 {
279 s = partial_name(partial);
280 if (s == NULL || *s == NUL)
281 return FAIL;
282 CLEAR_FIELD(funcexe);
283 funcexe.evaluate = TRUE;
284 funcexe.partial = partial;
285 if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
286 return FAIL;
287 }
288 }
289 else if (expr->v_type == VAR_INSTR)
290 {
291 return exe_typval_instr(expr, rettv);
292 }
293 else
294 {
295 s = tv_get_string_buf_chk(expr, buf);
296 if (s == NULL)
297 return FAIL;
298 s = skipwhite(s);
299 if (eval1_emsg(&s, rettv, NULL) == FAIL)
300 return FAIL;
301 if (*skipwhite(s) != NUL) // check for trailing chars after expr
302 {
303 clear_tv(rettv);
304 semsg(_(e_invalid_expression_str), s);
305 return FAIL;
306 }
307 }
308 return OK;
309 }
310
311 /*
312 * Like eval_to_bool() but using a typval_T instead of a string.
313 * Works for string, funcref and partial.
314 */
315 int
eval_expr_to_bool(typval_T * expr,int * error)316 eval_expr_to_bool(typval_T *expr, int *error)
317 {
318 typval_T rettv;
319 int res;
320
321 if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL)
322 {
323 *error = TRUE;
324 return FALSE;
325 }
326 res = (tv_get_bool_chk(&rettv, error) != 0);
327 clear_tv(&rettv);
328 return res;
329 }
330
331 /*
332 * Top level evaluation function, returning a string. If "skip" is TRUE,
333 * only parsing to "nextcmd" is done, without reporting errors. Return
334 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
335 */
336 char_u *
eval_to_string_skip(char_u * arg,exarg_T * eap,int skip)337 eval_to_string_skip(
338 char_u *arg,
339 exarg_T *eap,
340 int skip) // only parse, don't execute
341 {
342 typval_T tv;
343 char_u *retval;
344 evalarg_T evalarg;
345
346 fill_evalarg_from_eap(&evalarg, eap, skip);
347 if (skip)
348 ++emsg_skip;
349 if (eval0(arg, &tv, eap, &evalarg) == FAIL || skip)
350 retval = NULL;
351 else
352 {
353 retval = vim_strsave(tv_get_string(&tv));
354 clear_tv(&tv);
355 }
356 if (skip)
357 --emsg_skip;
358 clear_evalarg(&evalarg, eap);
359
360 return retval;
361 }
362
363 /*
364 * Skip over an expression at "*pp".
365 * Return FAIL for an error, OK otherwise.
366 */
367 int
skip_expr(char_u ** pp,evalarg_T * evalarg)368 skip_expr(char_u **pp, evalarg_T *evalarg)
369 {
370 typval_T rettv;
371
372 *pp = skipwhite(*pp);
373 return eval1(pp, &rettv, evalarg);
374 }
375
376 /*
377 * Skip over an expression at "*arg".
378 * If in Vim9 script and line breaks are encountered, the lines are
379 * concatenated. "evalarg->eval_tofree" will be set accordingly.
380 * "arg" is advanced to just after the expression.
381 * "start" is set to the start of the expression, "end" to just after the end.
382 * Also when the expression is copied to allocated memory.
383 * Return FAIL for an error, OK otherwise.
384 */
385 int
skip_expr_concatenate(char_u ** arg,char_u ** start,char_u ** end,evalarg_T * evalarg)386 skip_expr_concatenate(
387 char_u **arg,
388 char_u **start,
389 char_u **end,
390 evalarg_T *evalarg)
391 {
392 typval_T rettv;
393 int res;
394 int vim9script = in_vim9script();
395 garray_T *gap = evalarg == NULL ? NULL : &evalarg->eval_ga;
396 garray_T *freegap = evalarg == NULL ? NULL : &evalarg->eval_freega;
397 int save_flags = evalarg == NULL ? 0 : evalarg->eval_flags;
398 int evaluate = evalarg == NULL
399 ? FALSE : (evalarg->eval_flags & EVAL_EVALUATE);
400
401 if (vim9script && evaluate
402 && (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL))
403 {
404 ga_init2(gap, sizeof(char_u *), 10);
405 // leave room for "start"
406 if (ga_grow(gap, 1) == OK)
407 ++gap->ga_len;
408 ga_init2(freegap, sizeof(char_u *), 10);
409 }
410 *start = *arg;
411
412 // Don't evaluate the expression.
413 if (evalarg != NULL)
414 evalarg->eval_flags &= ~EVAL_EVALUATE;
415 *arg = skipwhite(*arg);
416 res = eval1(arg, &rettv, evalarg);
417 *end = *arg;
418 if (evalarg != NULL)
419 evalarg->eval_flags = save_flags;
420
421 if (vim9script && evaluate
422 && (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL))
423 {
424 if (evalarg->eval_ga.ga_len == 1)
425 {
426 // just the one line, no need to concatenate
427 ga_clear(gap);
428 gap->ga_itemsize = 0;
429 }
430 else
431 {
432 char_u *p;
433 size_t endoff = STRLEN(*arg);
434
435 // Line breaks encountered, concatenate all the lines.
436 *((char_u **)gap->ga_data) = *start;
437 p = ga_concat_strings(gap, " ");
438
439 // free the lines only when using getsourceline()
440 if (evalarg->eval_cookie != NULL)
441 {
442 // Do not free the first line, the caller can still use it.
443 *((char_u **)gap->ga_data) = NULL;
444 // Do not free the last line, "arg" points into it, free it
445 // later.
446 vim_free(evalarg->eval_tofree);
447 evalarg->eval_tofree =
448 ((char_u **)gap->ga_data)[gap->ga_len - 1];
449 ((char_u **)gap->ga_data)[gap->ga_len - 1] = NULL;
450 ga_clear_strings(gap);
451 }
452 else
453 {
454 ga_clear(gap);
455
456 // free lines that were explicitly marked for freeing
457 ga_clear_strings(freegap);
458 }
459
460 gap->ga_itemsize = 0;
461 if (p == NULL)
462 return FAIL;
463 *start = p;
464 vim_free(evalarg->eval_tofree_lambda);
465 evalarg->eval_tofree_lambda = p;
466 // Compute "end" relative to the end.
467 *end = *start + STRLEN(*start) - endoff;
468 }
469 }
470
471 return res;
472 }
473
474 /*
475 * Convert "tv" to a string.
476 * When "convert" is TRUE convert a List into a sequence of lines and convert
477 * a Float to a String.
478 * Returns an allocated string (NULL when out of memory).
479 */
480 char_u *
typval2string(typval_T * tv,int convert)481 typval2string(typval_T *tv, int convert)
482 {
483 garray_T ga;
484 char_u *retval;
485 #ifdef FEAT_FLOAT
486 char_u numbuf[NUMBUFLEN];
487 #endif
488
489 if (convert && tv->v_type == VAR_LIST)
490 {
491 ga_init2(&ga, (int)sizeof(char), 80);
492 if (tv->vval.v_list != NULL)
493 {
494 list_join(&ga, tv->vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
495 if (tv->vval.v_list->lv_len > 0)
496 ga_append(&ga, NL);
497 }
498 ga_append(&ga, NUL);
499 retval = (char_u *)ga.ga_data;
500 }
501 #ifdef FEAT_FLOAT
502 else if (convert && tv->v_type == VAR_FLOAT)
503 {
504 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
505 retval = vim_strsave(numbuf);
506 }
507 #endif
508 else
509 retval = vim_strsave(tv_get_string(tv));
510 return retval;
511 }
512
513 /*
514 * Top level evaluation function, returning a string. Does not handle line
515 * breaks.
516 * When "convert" is TRUE convert a List into a sequence of lines and convert
517 * a Float to a String.
518 * Return pointer to allocated memory, or NULL for failure.
519 */
520 char_u *
eval_to_string_eap(char_u * arg,int convert,exarg_T * eap)521 eval_to_string_eap(
522 char_u *arg,
523 int convert,
524 exarg_T *eap)
525 {
526 typval_T tv;
527 char_u *retval;
528 evalarg_T evalarg;
529
530 fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
531 if (eval0(arg, &tv, NULL, &evalarg) == FAIL)
532 retval = NULL;
533 else
534 {
535 retval = typval2string(&tv, convert);
536 clear_tv(&tv);
537 }
538 clear_evalarg(&evalarg, NULL);
539
540 return retval;
541 }
542
543 char_u *
eval_to_string(char_u * arg,int convert)544 eval_to_string(
545 char_u *arg,
546 int convert)
547 {
548 return eval_to_string_eap(arg, convert, NULL);
549 }
550
551 /*
552 * Call eval_to_string() without using current local variables and using
553 * textwinlock. When "use_sandbox" is TRUE use the sandbox.
554 * Use legacy Vim script syntax.
555 */
556 char_u *
eval_to_string_safe(char_u * arg,int use_sandbox)557 eval_to_string_safe(
558 char_u *arg,
559 int use_sandbox)
560 {
561 char_u *retval;
562 funccal_entry_T funccal_entry;
563 int save_sc_version = current_sctx.sc_version;
564 int save_garbage = may_garbage_collect;
565
566 current_sctx.sc_version = 1;
567 save_funccal(&funccal_entry);
568 if (use_sandbox)
569 ++sandbox;
570 ++textwinlock;
571 may_garbage_collect = FALSE;
572 retval = eval_to_string(arg, FALSE);
573 if (use_sandbox)
574 --sandbox;
575 --textwinlock;
576 may_garbage_collect = save_garbage;
577 restore_funccal();
578 current_sctx.sc_version = save_sc_version;
579 return retval;
580 }
581
582 /*
583 * Top level evaluation function, returning a number.
584 * Evaluates "expr" silently.
585 * Returns -1 for an error.
586 */
587 varnumber_T
eval_to_number(char_u * expr)588 eval_to_number(char_u *expr)
589 {
590 typval_T rettv;
591 varnumber_T retval;
592 char_u *p = skipwhite(expr);
593
594 ++emsg_off;
595
596 if (eval1(&p, &rettv, &EVALARG_EVALUATE) == FAIL)
597 retval = -1;
598 else
599 {
600 retval = tv_get_number_chk(&rettv, NULL);
601 clear_tv(&rettv);
602 }
603 --emsg_off;
604
605 return retval;
606 }
607
608 /*
609 * Top level evaluation function.
610 * Returns an allocated typval_T with the result.
611 * Returns NULL when there is an error.
612 */
613 typval_T *
eval_expr(char_u * arg,exarg_T * eap)614 eval_expr(char_u *arg, exarg_T *eap)
615 {
616 typval_T *tv;
617 evalarg_T evalarg;
618
619 fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
620
621 tv = ALLOC_ONE(typval_T);
622 if (tv != NULL && eval0(arg, tv, eap, &evalarg) == FAIL)
623 VIM_CLEAR(tv);
624
625 clear_evalarg(&evalarg, eap);
626 return tv;
627 }
628
629 /*
630 * Call some Vim script function and return the result in "*rettv".
631 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc]
632 * should have type VAR_UNKNOWN.
633 * Returns OK or FAIL.
634 */
635 int
call_vim_function(char_u * func,int argc,typval_T * argv,typval_T * rettv)636 call_vim_function(
637 char_u *func,
638 int argc,
639 typval_T *argv,
640 typval_T *rettv)
641 {
642 int ret;
643 funcexe_T funcexe;
644
645 rettv->v_type = VAR_UNKNOWN; // clear_tv() uses this
646 CLEAR_FIELD(funcexe);
647 funcexe.firstline = curwin->w_cursor.lnum;
648 funcexe.lastline = curwin->w_cursor.lnum;
649 funcexe.evaluate = TRUE;
650 ret = call_func(func, -1, rettv, argc, argv, &funcexe);
651 if (ret == FAIL)
652 clear_tv(rettv);
653
654 return ret;
655 }
656
657 /*
658 * Call Vim script function "func" and return the result as a number.
659 * Returns -1 when calling the function fails.
660 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
661 * have type VAR_UNKNOWN.
662 */
663 varnumber_T
call_func_retnr(char_u * func,int argc,typval_T * argv)664 call_func_retnr(
665 char_u *func,
666 int argc,
667 typval_T *argv)
668 {
669 typval_T rettv;
670 varnumber_T retval;
671
672 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
673 return -1;
674
675 retval = tv_get_number_chk(&rettv, NULL);
676 clear_tv(&rettv);
677 return retval;
678 }
679
680 /*
681 * Call Vim script function like call_func_retnr() and drop the result.
682 * Returns FAIL when calling the function fails.
683 */
684 int
call_func_noret(char_u * func,int argc,typval_T * argv)685 call_func_noret(
686 char_u *func,
687 int argc,
688 typval_T *argv)
689 {
690 typval_T rettv;
691
692 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
693 return FAIL;
694 clear_tv(&rettv);
695 return OK;
696 }
697
698 /*
699 * Call Vim script function "func" and return the result as a string.
700 * Uses "argv" and "argc" as call_func_retnr().
701 * Returns NULL when calling the function fails.
702 */
703 void *
call_func_retstr(char_u * func,int argc,typval_T * argv)704 call_func_retstr(
705 char_u *func,
706 int argc,
707 typval_T *argv)
708 {
709 typval_T rettv;
710 char_u *retval;
711
712 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
713 return NULL;
714
715 retval = vim_strsave(tv_get_string(&rettv));
716 clear_tv(&rettv);
717 return retval;
718 }
719
720 /*
721 * Call Vim script function "func" and return the result as a List.
722 * Uses "argv" and "argc" as call_func_retnr().
723 * Returns NULL when there is something wrong.
724 */
725 void *
call_func_retlist(char_u * func,int argc,typval_T * argv)726 call_func_retlist(
727 char_u *func,
728 int argc,
729 typval_T *argv)
730 {
731 typval_T rettv;
732
733 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
734 return NULL;
735
736 if (rettv.v_type != VAR_LIST)
737 {
738 clear_tv(&rettv);
739 return NULL;
740 }
741
742 return rettv.vval.v_list;
743 }
744
745 #ifdef FEAT_FOLDING
746 /*
747 * Evaluate "arg", which is 'foldexpr'.
748 * Note: caller must set "curwin" to match "arg".
749 * Returns the foldlevel, and any character preceding it in "*cp". Doesn't
750 * give error messages.
751 */
752 int
eval_foldexpr(char_u * arg,int * cp)753 eval_foldexpr(char_u *arg, int *cp)
754 {
755 typval_T tv;
756 varnumber_T retval;
757 char_u *s;
758 int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
759 OPT_LOCAL);
760
761 ++emsg_off;
762 if (use_sandbox)
763 ++sandbox;
764 ++textwinlock;
765 *cp = NUL;
766 if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
767 retval = 0;
768 else
769 {
770 // If the result is a number, just return the number.
771 if (tv.v_type == VAR_NUMBER)
772 retval = tv.vval.v_number;
773 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
774 retval = 0;
775 else
776 {
777 // If the result is a string, check if there is a non-digit before
778 // the number.
779 s = tv.vval.v_string;
780 if (!VIM_ISDIGIT(*s) && *s != '-')
781 *cp = *s++;
782 retval = atol((char *)s);
783 }
784 clear_tv(&tv);
785 }
786 --emsg_off;
787 if (use_sandbox)
788 --sandbox;
789 --textwinlock;
790 clear_evalarg(&EVALARG_EVALUATE, NULL);
791
792 return (int)retval;
793 }
794 #endif
795
796 /*
797 * Get an lval: variable, Dict item or List item that can be assigned a value
798 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
799 * "name.key", "name.key[expr]" etc.
800 * Indexing only works if "name" is an existing List or Dictionary.
801 * "name" points to the start of the name.
802 * If "rettv" is not NULL it points to the value to be assigned.
803 * "unlet" is TRUE for ":unlet": slightly different behavior when something is
804 * wrong; must end in space or cmd separator.
805 *
806 * flags:
807 * GLV_QUIET: do not give error messages
808 * GLV_READ_ONLY: will not change the variable
809 * GLV_NO_AUTOLOAD: do not use script autoloading
810 *
811 * Returns a pointer to just after the name, including indexes.
812 * When an evaluation error occurs "lp->ll_name" is NULL;
813 * Returns NULL for a parsing error. Still need to free items in "lp"!
814 */
815 char_u *
get_lval(char_u * name,typval_T * rettv,lval_T * lp,int unlet,int skip,int flags,int fne_flags)816 get_lval(
817 char_u *name,
818 typval_T *rettv,
819 lval_T *lp,
820 int unlet,
821 int skip,
822 int flags, // GLV_ values
823 int fne_flags) // flags for find_name_end()
824 {
825 char_u *p;
826 char_u *expr_start, *expr_end;
827 int cc;
828 dictitem_T *v;
829 typval_T var1;
830 typval_T var2;
831 int empty1 = FALSE;
832 char_u *key = NULL;
833 int len;
834 hashtab_T *ht = NULL;
835 int quiet = flags & GLV_QUIET;
836 int writing;
837
838 // Clear everything in "lp".
839 CLEAR_POINTER(lp);
840
841 if (skip || (flags & GLV_COMPILING))
842 {
843 // When skipping or compiling just find the end of the name.
844 lp->ll_name = name;
845 lp->ll_name_end = find_name_end(name, NULL, NULL,
846 FNE_INCL_BR | fne_flags);
847 return lp->ll_name_end;
848 }
849
850 // Find the end of the name.
851 p = find_name_end(name, &expr_start, &expr_end, fne_flags);
852 lp->ll_name_end = p;
853 if (expr_start != NULL)
854 {
855 // Don't expand the name when we already know there is an error.
856 if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p)
857 && *p != '[' && *p != '.')
858 {
859 semsg(_(e_trailing_arg), p);
860 return NULL;
861 }
862
863 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
864 if (lp->ll_exp_name == NULL)
865 {
866 // Report an invalid expression in braces, unless the
867 // expression evaluation has been cancelled due to an
868 // aborting error, an interrupt, or an exception.
869 if (!aborting() && !quiet)
870 {
871 emsg_severe = TRUE;
872 semsg(_(e_invarg2), name);
873 return NULL;
874 }
875 }
876 lp->ll_name = lp->ll_exp_name;
877 }
878 else
879 {
880 lp->ll_name = name;
881
882 if (in_vim9script())
883 {
884 // "a: type" is declaring variable "a" with a type, not "a:".
885 if (p == name + 2 && p[-1] == ':')
886 {
887 --p;
888 lp->ll_name_end = p;
889 }
890 if (*p == ':')
891 {
892 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
893 char_u *tp = skipwhite(p + 1);
894
895 if (tp == p + 1 && !quiet)
896 {
897 semsg(_(e_white_space_required_after_str_str), ":", p);
898 return NULL;
899 }
900
901 // parse the type after the name
902 lp->ll_type = parse_type(&tp, &si->sn_type_list, !quiet);
903 if (lp->ll_type == NULL && !quiet)
904 return NULL;
905 lp->ll_name_end = tp;
906 }
907 }
908 }
909
910 // Without [idx] or .key we are done.
911 if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
912 return p;
913
914 if (in_vim9script() && lval_root != NULL)
915 {
916 // using local variable
917 lp->ll_tv = lval_root;
918 v = NULL;
919 }
920 else
921 {
922 cc = *p;
923 *p = NUL;
924 // When we would write to the variable pass &ht and prevent autoload.
925 writing = !(flags & GLV_READ_ONLY);
926 v = find_var(lp->ll_name, writing ? &ht : NULL,
927 (flags & GLV_NO_AUTOLOAD) || writing);
928 if (v == NULL && !quiet)
929 semsg(_(e_undefined_variable_str), lp->ll_name);
930 *p = cc;
931 if (v == NULL)
932 return NULL;
933 lp->ll_tv = &v->di_tv;
934 }
935
936 if (in_vim9script() && (flags & GLV_NO_DECL) == 0)
937 {
938 if (!quiet)
939 semsg(_(e_variable_already_declared), lp->ll_name);
940 return NULL;
941 }
942
943 /*
944 * Loop until no more [idx] or .key is following.
945 */
946 var1.v_type = VAR_UNKNOWN;
947 var2.v_type = VAR_UNKNOWN;
948 while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.'))
949 {
950 if (*p == '.' && lp->ll_tv->v_type != VAR_DICT)
951 {
952 if (!quiet)
953 semsg(_(e_dot_can_only_be_used_on_dictionary_str), name);
954 return NULL;
955 }
956 if (lp->ll_tv->v_type != VAR_LIST
957 && lp->ll_tv->v_type != VAR_DICT
958 && lp->ll_tv->v_type != VAR_BLOB)
959 {
960 if (!quiet)
961 emsg(_("E689: Can only index a List, Dictionary or Blob"));
962 return NULL;
963 }
964
965 // a NULL list/blob works like an empty list/blob, allocate one now.
966 if (lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL)
967 rettv_list_alloc(lp->ll_tv);
968 else if (lp->ll_tv->v_type == VAR_BLOB
969 && lp->ll_tv->vval.v_blob == NULL)
970 rettv_blob_alloc(lp->ll_tv);
971
972 if (lp->ll_range)
973 {
974 if (!quiet)
975 emsg(_("E708: [:] must come last"));
976 return NULL;
977 }
978
979 if (in_vim9script() && lp->ll_valtype == NULL
980 && v != NULL
981 && lp->ll_tv == &v->di_tv
982 && ht != NULL && ht == get_script_local_ht())
983 {
984 svar_T *sv = find_typval_in_script(lp->ll_tv);
985
986 // Vim9 script local variable: get the type
987 if (sv != NULL)
988 lp->ll_valtype = sv->sv_type;
989 }
990
991 len = -1;
992 if (*p == '.')
993 {
994 key = p + 1;
995 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
996 ;
997 if (len == 0)
998 {
999 if (!quiet)
1000 emsg(_(e_emptykey));
1001 return NULL;
1002 }
1003 p = key + len;
1004 }
1005 else
1006 {
1007 // Get the index [expr] or the first index [expr: ].
1008 p = skipwhite(p + 1);
1009 if (*p == ':')
1010 empty1 = TRUE;
1011 else
1012 {
1013 empty1 = FALSE;
1014 if (eval1(&p, &var1, &EVALARG_EVALUATE) == FAIL) // recursive!
1015 return NULL;
1016 if (tv_get_string_chk(&var1) == NULL)
1017 {
1018 // not a number or string
1019 clear_tv(&var1);
1020 return NULL;
1021 }
1022 p = skipwhite(p);
1023 }
1024
1025 // Optionally get the second index [ :expr].
1026 if (*p == ':')
1027 {
1028 if (lp->ll_tv->v_type == VAR_DICT)
1029 {
1030 if (!quiet)
1031 emsg(_(e_cannot_slice_dictionary));
1032 clear_tv(&var1);
1033 return NULL;
1034 }
1035 if (rettv != NULL
1036 && !(rettv->v_type == VAR_LIST
1037 && rettv->vval.v_list != NULL)
1038 && !(rettv->v_type == VAR_BLOB
1039 && rettv->vval.v_blob != NULL))
1040 {
1041 if (!quiet)
1042 emsg(_("E709: [:] requires a List or Blob value"));
1043 clear_tv(&var1);
1044 return NULL;
1045 }
1046 p = skipwhite(p + 1);
1047 if (*p == ']')
1048 lp->ll_empty2 = TRUE;
1049 else
1050 {
1051 lp->ll_empty2 = FALSE;
1052 // recursive!
1053 if (eval1(&p, &var2, &EVALARG_EVALUATE) == FAIL)
1054 {
1055 clear_tv(&var1);
1056 return NULL;
1057 }
1058 if (tv_get_string_chk(&var2) == NULL)
1059 {
1060 // not a number or string
1061 clear_tv(&var1);
1062 clear_tv(&var2);
1063 return NULL;
1064 }
1065 }
1066 lp->ll_range = TRUE;
1067 }
1068 else
1069 lp->ll_range = FALSE;
1070
1071 if (*p != ']')
1072 {
1073 if (!quiet)
1074 emsg(_(e_missbrac));
1075 clear_tv(&var1);
1076 clear_tv(&var2);
1077 return NULL;
1078 }
1079
1080 // Skip to past ']'.
1081 ++p;
1082 }
1083
1084 if (lp->ll_tv->v_type == VAR_DICT)
1085 {
1086 if (len == -1)
1087 {
1088 // "[key]": get key from "var1"
1089 key = tv_get_string_chk(&var1); // is number or string
1090 if (key == NULL)
1091 {
1092 clear_tv(&var1);
1093 return NULL;
1094 }
1095 }
1096 lp->ll_list = NULL;
1097
1098 // a NULL dict is equivalent with an empty dict
1099 if (lp->ll_tv->vval.v_dict == NULL)
1100 {
1101 lp->ll_tv->vval.v_dict = dict_alloc();
1102 if (lp->ll_tv->vval.v_dict == NULL)
1103 {
1104 clear_tv(&var1);
1105 return NULL;
1106 }
1107 ++lp->ll_tv->vval.v_dict->dv_refcount;
1108 }
1109 lp->ll_dict = lp->ll_tv->vval.v_dict;
1110
1111 lp->ll_di = dict_find(lp->ll_dict, key, len);
1112
1113 // When assigning to a scope dictionary check that a function and
1114 // variable name is valid (only variable name unless it is l: or
1115 // g: dictionary). Disallow overwriting a builtin function.
1116 if (rettv != NULL && lp->ll_dict->dv_scope != 0)
1117 {
1118 int prevval;
1119 int wrong;
1120
1121 if (len != -1)
1122 {
1123 prevval = key[len];
1124 key[len] = NUL;
1125 }
1126 else
1127 prevval = 0; // avoid compiler warning
1128 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
1129 && rettv->v_type == VAR_FUNC
1130 && var_wrong_func_name(key, lp->ll_di == NULL))
1131 || !valid_varname(key, -1, TRUE);
1132 if (len != -1)
1133 key[len] = prevval;
1134 if (wrong)
1135 {
1136 clear_tv(&var1);
1137 return NULL;
1138 }
1139 }
1140
1141 if (lp->ll_valtype != NULL)
1142 // use the type of the member
1143 lp->ll_valtype = lp->ll_valtype->tt_member;
1144
1145 if (lp->ll_di == NULL)
1146 {
1147 // Can't add "v:" or "a:" variable.
1148 if (lp->ll_dict == get_vimvar_dict()
1149 || &lp->ll_dict->dv_hashtab == get_funccal_args_ht())
1150 {
1151 semsg(_(e_illvar), name);
1152 clear_tv(&var1);
1153 return NULL;
1154 }
1155
1156 // Key does not exist in dict: may need to add it.
1157 if (*p == '[' || *p == '.' || unlet)
1158 {
1159 if (!quiet)
1160 semsg(_(e_dictkey), key);
1161 clear_tv(&var1);
1162 return NULL;
1163 }
1164 if (len == -1)
1165 lp->ll_newkey = vim_strsave(key);
1166 else
1167 lp->ll_newkey = vim_strnsave(key, len);
1168 clear_tv(&var1);
1169 if (lp->ll_newkey == NULL)
1170 p = NULL;
1171 break;
1172 }
1173 // existing variable, need to check if it can be changed
1174 else if ((flags & GLV_READ_ONLY) == 0
1175 && (var_check_ro(lp->ll_di->di_flags, name, FALSE)
1176 || var_check_lock(lp->ll_di->di_flags, name, FALSE)))
1177 {
1178 clear_tv(&var1);
1179 return NULL;
1180 }
1181
1182 clear_tv(&var1);
1183 lp->ll_tv = &lp->ll_di->di_tv;
1184 }
1185 else if (lp->ll_tv->v_type == VAR_BLOB)
1186 {
1187 long bloblen = blob_len(lp->ll_tv->vval.v_blob);
1188
1189 /*
1190 * Get the number and item for the only or first index of the List.
1191 */
1192 if (empty1)
1193 lp->ll_n1 = 0;
1194 else
1195 // is number or string
1196 lp->ll_n1 = (long)tv_get_number(&var1);
1197 clear_tv(&var1);
1198
1199 if (check_blob_index(bloblen, lp->ll_n1, quiet) == FAIL)
1200 {
1201 clear_tv(&var2);
1202 return NULL;
1203 }
1204 if (lp->ll_range && !lp->ll_empty2)
1205 {
1206 lp->ll_n2 = (long)tv_get_number(&var2);
1207 clear_tv(&var2);
1208 if (check_blob_range(bloblen, lp->ll_n1, lp->ll_n2, quiet)
1209 == FAIL)
1210 return NULL;
1211 }
1212 lp->ll_blob = lp->ll_tv->vval.v_blob;
1213 lp->ll_tv = NULL;
1214 break;
1215 }
1216 else
1217 {
1218 /*
1219 * Get the number and item for the only or first index of the List.
1220 */
1221 if (empty1)
1222 lp->ll_n1 = 0;
1223 else
1224 // is number or string
1225 lp->ll_n1 = (long)tv_get_number(&var1);
1226 clear_tv(&var1);
1227
1228 lp->ll_dict = NULL;
1229 lp->ll_list = lp->ll_tv->vval.v_list;
1230 lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1, quiet);
1231 if (lp->ll_li == NULL)
1232 {
1233 clear_tv(&var2);
1234 return NULL;
1235 }
1236
1237 if (lp->ll_valtype != NULL)
1238 // use the type of the member
1239 lp->ll_valtype = lp->ll_valtype->tt_member;
1240
1241 /*
1242 * May need to find the item or absolute index for the second
1243 * index of a range.
1244 * When no index given: "lp->ll_empty2" is TRUE.
1245 * Otherwise "lp->ll_n2" is set to the second index.
1246 */
1247 if (lp->ll_range && !lp->ll_empty2)
1248 {
1249 lp->ll_n2 = (long)tv_get_number(&var2);
1250 // is number or string
1251 clear_tv(&var2);
1252 if (check_range_index_two(lp->ll_list,
1253 &lp->ll_n1, lp->ll_li,
1254 &lp->ll_n2, quiet) == FAIL)
1255 return NULL;
1256 }
1257
1258 lp->ll_tv = &lp->ll_li->li_tv;
1259 }
1260 }
1261
1262 clear_tv(&var1);
1263 lp->ll_name_end = p;
1264 return p;
1265 }
1266
1267 /*
1268 * Clear lval "lp" that was filled by get_lval().
1269 */
1270 void
clear_lval(lval_T * lp)1271 clear_lval(lval_T *lp)
1272 {
1273 vim_free(lp->ll_exp_name);
1274 vim_free(lp->ll_newkey);
1275 }
1276
1277 /*
1278 * Set a variable that was parsed by get_lval() to "rettv".
1279 * "endp" points to just after the parsed name.
1280 * "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=",
1281 * "%" for "%=", "." for ".=" or "=" for "=".
1282 */
1283 void
set_var_lval(lval_T * lp,char_u * endp,typval_T * rettv,int copy,int flags,char_u * op,int var_idx)1284 set_var_lval(
1285 lval_T *lp,
1286 char_u *endp,
1287 typval_T *rettv,
1288 int copy,
1289 int flags, // ASSIGN_CONST, ASSIGN_NO_DECL
1290 char_u *op,
1291 int var_idx) // index for "let [a, b] = list"
1292 {
1293 int cc;
1294 dictitem_T *di;
1295
1296 if (lp->ll_tv == NULL)
1297 {
1298 cc = *endp;
1299 *endp = NUL;
1300 if (in_vim9script() && check_reserved_name(lp->ll_name) == FAIL)
1301 return;
1302
1303 if (lp->ll_blob != NULL)
1304 {
1305 int error = FALSE, val;
1306
1307 if (op != NULL && *op != '=')
1308 {
1309 semsg(_(e_letwrong), op);
1310 return;
1311 }
1312 if (value_check_lock(lp->ll_blob->bv_lock, lp->ll_name, FALSE))
1313 return;
1314
1315 if (lp->ll_range && rettv->v_type == VAR_BLOB)
1316 {
1317 if (lp->ll_empty2)
1318 lp->ll_n2 = blob_len(lp->ll_blob) - 1;
1319
1320 if (blob_set_range(lp->ll_blob, lp->ll_n1, lp->ll_n2,
1321 rettv) == FAIL)
1322 return;
1323 }
1324 else
1325 {
1326 val = (int)tv_get_number_chk(rettv, &error);
1327 if (!error)
1328 blob_set_append(lp->ll_blob, lp->ll_n1, val);
1329 }
1330 }
1331 else if (op != NULL && *op != '=')
1332 {
1333 typval_T tv;
1334
1335 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1336 && (flags & ASSIGN_FOR_LOOP) == 0)
1337 {
1338 emsg(_(e_cannot_mod));
1339 *endp = cc;
1340 return;
1341 }
1342
1343 // handle +=, -=, *=, /=, %= and .=
1344 di = NULL;
1345 if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
1346 &tv, &di, EVAL_VAR_VERBOSE) == OK)
1347 {
1348 if ((di == NULL
1349 || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
1350 && !tv_check_lock(&di->di_tv, lp->ll_name, FALSE)))
1351 && tv_op(&tv, rettv, op) == OK)
1352 set_var_const(lp->ll_name, NULL, &tv, FALSE,
1353 ASSIGN_NO_DECL, 0);
1354 clear_tv(&tv);
1355 }
1356 }
1357 else
1358 {
1359 if (lp->ll_type != NULL && check_typval_arg_type(lp->ll_type, rettv,
1360 NULL, 0) == FAIL)
1361 return;
1362 set_var_const(lp->ll_name, lp->ll_type, rettv, copy,
1363 flags, var_idx);
1364 }
1365 *endp = cc;
1366 }
1367 else if (value_check_lock(lp->ll_newkey == NULL
1368 ? lp->ll_tv->v_lock
1369 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE))
1370 ;
1371 else if (lp->ll_range)
1372 {
1373 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1374 && (flags & ASSIGN_FOR_LOOP) == 0)
1375 {
1376 emsg(_("E996: Cannot lock a range"));
1377 return;
1378 }
1379
1380 (void)list_assign_range(lp->ll_list, rettv->vval.v_list,
1381 lp->ll_n1, lp->ll_n2, lp->ll_empty2, op, lp->ll_name);
1382 }
1383 else
1384 {
1385 /*
1386 * Assign to a List or Dictionary item.
1387 */
1388 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1389 && (flags & ASSIGN_FOR_LOOP) == 0)
1390 {
1391 emsg(_("E996: Cannot lock a list or dict"));
1392 return;
1393 }
1394
1395 if (lp->ll_valtype != NULL
1396 && check_typval_arg_type(lp->ll_valtype, rettv,
1397 NULL, 0) == FAIL)
1398 return;
1399
1400 if (lp->ll_newkey != NULL)
1401 {
1402 if (op != NULL && *op != '=')
1403 {
1404 semsg(_(e_dictkey), lp->ll_newkey);
1405 return;
1406 }
1407 if (dict_wrong_func_name(lp->ll_tv->vval.v_dict, rettv,
1408 lp->ll_newkey))
1409 return;
1410
1411 // Need to add an item to the Dictionary.
1412 di = dictitem_alloc(lp->ll_newkey);
1413 if (di == NULL)
1414 return;
1415 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL)
1416 {
1417 vim_free(di);
1418 return;
1419 }
1420 lp->ll_tv = &di->di_tv;
1421 }
1422 else if (op != NULL && *op != '=')
1423 {
1424 tv_op(lp->ll_tv, rettv, op);
1425 return;
1426 }
1427 else
1428 clear_tv(lp->ll_tv);
1429
1430 /*
1431 * Assign the value to the variable or list item.
1432 */
1433 if (copy)
1434 copy_tv(rettv, lp->ll_tv);
1435 else
1436 {
1437 *lp->ll_tv = *rettv;
1438 lp->ll_tv->v_lock = 0;
1439 init_tv(rettv);
1440 }
1441 }
1442 }
1443
1444 /*
1445 * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
1446 * and "tv1 .= tv2"
1447 * Returns OK or FAIL.
1448 */
1449 int
tv_op(typval_T * tv1,typval_T * tv2,char_u * op)1450 tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
1451 {
1452 varnumber_T n;
1453 char_u numbuf[NUMBUFLEN];
1454 char_u *s;
1455 int failed = FALSE;
1456
1457 // Can't do anything with a Funcref or Dict on the right.
1458 // v:true and friends only work with "..=".
1459 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
1460 && ((tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)
1461 || *op == '.'))
1462 {
1463 switch (tv1->v_type)
1464 {
1465 case VAR_UNKNOWN:
1466 case VAR_ANY:
1467 case VAR_VOID:
1468 case VAR_DICT:
1469 case VAR_FUNC:
1470 case VAR_PARTIAL:
1471 case VAR_BOOL:
1472 case VAR_SPECIAL:
1473 case VAR_JOB:
1474 case VAR_CHANNEL:
1475 case VAR_INSTR:
1476 break;
1477
1478 case VAR_BLOB:
1479 if (*op != '+' || tv2->v_type != VAR_BLOB)
1480 break;
1481 // BLOB += BLOB
1482 if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL)
1483 {
1484 blob_T *b1 = tv1->vval.v_blob;
1485 blob_T *b2 = tv2->vval.v_blob;
1486 int i, len = blob_len(b2);
1487 for (i = 0; i < len; i++)
1488 ga_append(&b1->bv_ga, blob_get(b2, i));
1489 }
1490 return OK;
1491
1492 case VAR_LIST:
1493 if (*op != '+' || tv2->v_type != VAR_LIST)
1494 break;
1495 // List += List
1496 if (tv2->vval.v_list != NULL)
1497 {
1498 if (tv1->vval.v_list == NULL)
1499 {
1500 tv1->vval.v_list = tv2->vval.v_list;
1501 ++tv1->vval.v_list->lv_refcount;
1502 }
1503 else
1504 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
1505 }
1506 return OK;
1507
1508 case VAR_NUMBER:
1509 case VAR_STRING:
1510 if (tv2->v_type == VAR_LIST)
1511 break;
1512 if (vim_strchr((char_u *)"+-*/%", *op) != NULL)
1513 {
1514 // nr += nr , nr -= nr , nr *=nr , nr /= nr , nr %= nr
1515 n = tv_get_number(tv1);
1516 #ifdef FEAT_FLOAT
1517 if (tv2->v_type == VAR_FLOAT)
1518 {
1519 float_T f = n;
1520
1521 if (*op == '%')
1522 break;
1523 switch (*op)
1524 {
1525 case '+': f += tv2->vval.v_float; break;
1526 case '-': f -= tv2->vval.v_float; break;
1527 case '*': f *= tv2->vval.v_float; break;
1528 case '/': f /= tv2->vval.v_float; break;
1529 }
1530 clear_tv(tv1);
1531 tv1->v_type = VAR_FLOAT;
1532 tv1->vval.v_float = f;
1533 }
1534 else
1535 #endif
1536 {
1537 switch (*op)
1538 {
1539 case '+': n += tv_get_number(tv2); break;
1540 case '-': n -= tv_get_number(tv2); break;
1541 case '*': n *= tv_get_number(tv2); break;
1542 case '/': n = num_divide(n, tv_get_number(tv2),
1543 &failed); break;
1544 case '%': n = num_modulus(n, tv_get_number(tv2),
1545 &failed); break;
1546 }
1547 clear_tv(tv1);
1548 tv1->v_type = VAR_NUMBER;
1549 tv1->vval.v_number = n;
1550 }
1551 }
1552 else
1553 {
1554 if (tv2->v_type == VAR_FLOAT)
1555 break;
1556
1557 // str .= str
1558 s = tv_get_string(tv1);
1559 s = concat_str(s, tv_get_string_buf(tv2, numbuf));
1560 clear_tv(tv1);
1561 tv1->v_type = VAR_STRING;
1562 tv1->vval.v_string = s;
1563 }
1564 return failed ? FAIL : OK;
1565
1566 case VAR_FLOAT:
1567 #ifdef FEAT_FLOAT
1568 {
1569 float_T f;
1570
1571 if (*op == '%' || *op == '.'
1572 || (tv2->v_type != VAR_FLOAT
1573 && tv2->v_type != VAR_NUMBER
1574 && tv2->v_type != VAR_STRING))
1575 break;
1576 if (tv2->v_type == VAR_FLOAT)
1577 f = tv2->vval.v_float;
1578 else
1579 f = tv_get_number(tv2);
1580 switch (*op)
1581 {
1582 case '+': tv1->vval.v_float += f; break;
1583 case '-': tv1->vval.v_float -= f; break;
1584 case '*': tv1->vval.v_float *= f; break;
1585 case '/': tv1->vval.v_float /= f; break;
1586 }
1587 }
1588 #endif
1589 return OK;
1590 }
1591 }
1592
1593 semsg(_(e_letwrong), op);
1594 return FAIL;
1595 }
1596
1597 /*
1598 * Evaluate the expression used in a ":for var in expr" command.
1599 * "arg" points to "var".
1600 * Set "*errp" to TRUE for an error, FALSE otherwise;
1601 * Return a pointer that holds the info. Null when there is an error.
1602 */
1603 void *
eval_for_line(char_u * arg,int * errp,exarg_T * eap,evalarg_T * evalarg)1604 eval_for_line(
1605 char_u *arg,
1606 int *errp,
1607 exarg_T *eap,
1608 evalarg_T *evalarg)
1609 {
1610 forinfo_T *fi;
1611 char_u *var_list_end;
1612 char_u *expr;
1613 typval_T tv;
1614 list_T *l;
1615 int skip = !(evalarg->eval_flags & EVAL_EVALUATE);
1616
1617 *errp = TRUE; // default: there is an error
1618
1619 fi = ALLOC_CLEAR_ONE(forinfo_T);
1620 if (fi == NULL)
1621 return NULL;
1622
1623 var_list_end = skip_var_list(arg, TRUE, &fi->fi_varcount,
1624 &fi->fi_semicolon, FALSE);
1625 if (var_list_end == NULL)
1626 return fi;
1627
1628 expr = skipwhite_and_linebreak(var_list_end, evalarg);
1629 if (expr[0] != 'i' || expr[1] != 'n'
1630 || !(expr[2] == NUL || VIM_ISWHITE(expr[2])))
1631 {
1632 if (in_vim9script() && *expr == ':' && expr != var_list_end)
1633 semsg(_(e_no_white_space_allowed_before_colon_str), expr);
1634 else
1635 emsg(_(e_missing_in));
1636 return fi;
1637 }
1638
1639 if (skip)
1640 ++emsg_skip;
1641 expr = skipwhite_and_linebreak(expr + 2, evalarg);
1642 if (eval0(expr, &tv, eap, evalarg) == OK)
1643 {
1644 *errp = FALSE;
1645 if (!skip)
1646 {
1647 if (tv.v_type == VAR_LIST)
1648 {
1649 l = tv.vval.v_list;
1650 if (l == NULL)
1651 {
1652 // a null list is like an empty list: do nothing
1653 clear_tv(&tv);
1654 }
1655 else
1656 {
1657 // Need a real list here.
1658 CHECK_LIST_MATERIALIZE(l);
1659
1660 // No need to increment the refcount, it's already set for
1661 // the list being used in "tv".
1662 fi->fi_list = l;
1663 list_add_watch(l, &fi->fi_lw);
1664 fi->fi_lw.lw_item = l->lv_first;
1665 }
1666 }
1667 else if (tv.v_type == VAR_BLOB)
1668 {
1669 fi->fi_bi = 0;
1670 if (tv.vval.v_blob != NULL)
1671 {
1672 typval_T btv;
1673
1674 // Make a copy, so that the iteration still works when the
1675 // blob is changed.
1676 blob_copy(tv.vval.v_blob, &btv);
1677 fi->fi_blob = btv.vval.v_blob;
1678 }
1679 clear_tv(&tv);
1680 }
1681 else if (tv.v_type == VAR_STRING)
1682 {
1683 fi->fi_byte_idx = 0;
1684 fi->fi_string = tv.vval.v_string;
1685 tv.vval.v_string = NULL;
1686 if (fi->fi_string == NULL)
1687 fi->fi_string = vim_strsave((char_u *)"");
1688 }
1689 else
1690 {
1691 emsg(_(e_string_list_or_blob_required));
1692 clear_tv(&tv);
1693 }
1694 }
1695 }
1696 if (skip)
1697 --emsg_skip;
1698 fi->fi_break_count = evalarg->eval_break_count;
1699
1700 return fi;
1701 }
1702
1703 /*
1704 * Used when looping over a :for line, skip the "in expr" part.
1705 */
1706 void
skip_for_lines(void * fi_void,evalarg_T * evalarg)1707 skip_for_lines(void *fi_void, evalarg_T *evalarg)
1708 {
1709 forinfo_T *fi = (forinfo_T *)fi_void;
1710 int i;
1711
1712 for (i = 0; i < fi->fi_break_count; ++i)
1713 eval_next_line(evalarg);
1714 }
1715
1716 /*
1717 * Use the first item in a ":for" list. Advance to the next.
1718 * Assign the values to the variable (list). "arg" points to the first one.
1719 * Return TRUE when a valid item was found, FALSE when at end of list or
1720 * something wrong.
1721 */
1722 int
next_for_item(void * fi_void,char_u * arg)1723 next_for_item(void *fi_void, char_u *arg)
1724 {
1725 forinfo_T *fi = (forinfo_T *)fi_void;
1726 int result;
1727 int flag = ASSIGN_FOR_LOOP | (in_vim9script()
1728 ? (ASSIGN_FINAL
1729 // first round: error if variable exists
1730 | (fi->fi_bi == 0 ? 0 : ASSIGN_DECL)
1731 | ASSIGN_NO_MEMBER_TYPE)
1732 : 0);
1733 listitem_T *item;
1734 int skip_assign = in_vim9script() && arg[0] == '_'
1735 && !eval_isnamec(arg[1]);
1736
1737 if (fi->fi_blob != NULL)
1738 {
1739 typval_T tv;
1740
1741 if (fi->fi_bi >= blob_len(fi->fi_blob))
1742 return FALSE;
1743 tv.v_type = VAR_NUMBER;
1744 tv.v_lock = VAR_FIXED;
1745 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi);
1746 ++fi->fi_bi;
1747 if (skip_assign)
1748 return TRUE;
1749 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon,
1750 fi->fi_varcount, flag, NULL) == OK;
1751 }
1752
1753 if (fi->fi_string != NULL)
1754 {
1755 typval_T tv;
1756 int len;
1757
1758 len = mb_ptr2len(fi->fi_string + fi->fi_byte_idx);
1759 if (len == 0)
1760 return FALSE;
1761 tv.v_type = VAR_STRING;
1762 tv.v_lock = VAR_FIXED;
1763 tv.vval.v_string = vim_strnsave(fi->fi_string + fi->fi_byte_idx, len);
1764 fi->fi_byte_idx += len;
1765 ++fi->fi_bi;
1766 if (skip_assign)
1767 result = TRUE;
1768 else
1769 result = ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon,
1770 fi->fi_varcount, flag, NULL) == OK;
1771 vim_free(tv.vval.v_string);
1772 return result;
1773 }
1774
1775 item = fi->fi_lw.lw_item;
1776 if (item == NULL)
1777 result = FALSE;
1778 else
1779 {
1780 fi->fi_lw.lw_item = item->li_next;
1781 ++fi->fi_bi;
1782 if (skip_assign)
1783 result = TRUE;
1784 else
1785 result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon,
1786 fi->fi_varcount, flag, NULL) == OK);
1787 }
1788 return result;
1789 }
1790
1791 /*
1792 * Free the structure used to store info used by ":for".
1793 */
1794 void
free_for_info(void * fi_void)1795 free_for_info(void *fi_void)
1796 {
1797 forinfo_T *fi = (forinfo_T *)fi_void;
1798
1799 if (fi == NULL)
1800 return;
1801 if (fi->fi_list != NULL)
1802 {
1803 list_rem_watch(fi->fi_list, &fi->fi_lw);
1804 list_unref(fi->fi_list);
1805 }
1806 else if (fi->fi_blob != NULL)
1807 blob_unref(fi->fi_blob);
1808 else
1809 vim_free(fi->fi_string);
1810 vim_free(fi);
1811 }
1812
1813 void
set_context_for_expression(expand_T * xp,char_u * arg,cmdidx_T cmdidx)1814 set_context_for_expression(
1815 expand_T *xp,
1816 char_u *arg,
1817 cmdidx_T cmdidx)
1818 {
1819 int has_expr = cmdidx != CMD_let && cmdidx != CMD_var;
1820 int c;
1821 char_u *p;
1822
1823 if (cmdidx == CMD_let || cmdidx == CMD_var
1824 || cmdidx == CMD_const || cmdidx == CMD_final)
1825 {
1826 xp->xp_context = EXPAND_USER_VARS;
1827 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL)
1828 {
1829 // ":let var1 var2 ...": find last space.
1830 for (p = arg + STRLEN(arg); p >= arg; )
1831 {
1832 xp->xp_pattern = p;
1833 MB_PTR_BACK(arg, p);
1834 if (VIM_ISWHITE(*p))
1835 break;
1836 }
1837 return;
1838 }
1839 }
1840 else
1841 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
1842 : EXPAND_EXPRESSION;
1843 while ((xp->xp_pattern = vim_strpbrk(arg,
1844 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
1845 {
1846 c = *xp->xp_pattern;
1847 if (c == '&')
1848 {
1849 c = xp->xp_pattern[1];
1850 if (c == '&')
1851 {
1852 ++xp->xp_pattern;
1853 xp->xp_context = has_expr ? EXPAND_EXPRESSION : EXPAND_NOTHING;
1854 }
1855 else if (c != ' ')
1856 {
1857 xp->xp_context = EXPAND_SETTINGS;
1858 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
1859 xp->xp_pattern += 2;
1860
1861 }
1862 }
1863 else if (c == '$')
1864 {
1865 // environment variable
1866 xp->xp_context = EXPAND_ENV_VARS;
1867 }
1868 else if (c == '=')
1869 {
1870 has_expr = TRUE;
1871 xp->xp_context = EXPAND_EXPRESSION;
1872 }
1873 else if (c == '#'
1874 && xp->xp_context == EXPAND_EXPRESSION)
1875 {
1876 // Autoload function/variable contains '#'.
1877 break;
1878 }
1879 else if ((c == '<' || c == '#')
1880 && xp->xp_context == EXPAND_FUNCTIONS
1881 && vim_strchr(xp->xp_pattern, '(') == NULL)
1882 {
1883 // Function name can start with "<SNR>" and contain '#'.
1884 break;
1885 }
1886 else if (has_expr)
1887 {
1888 if (c == '"') // string
1889 {
1890 while ((c = *++xp->xp_pattern) != NUL && c != '"')
1891 if (c == '\\' && xp->xp_pattern[1] != NUL)
1892 ++xp->xp_pattern;
1893 xp->xp_context = EXPAND_NOTHING;
1894 }
1895 else if (c == '\'') // literal string
1896 {
1897 // Trick: '' is like stopping and starting a literal string.
1898 while ((c = *++xp->xp_pattern) != NUL && c != '\'')
1899 /* skip */ ;
1900 xp->xp_context = EXPAND_NOTHING;
1901 }
1902 else if (c == '|')
1903 {
1904 if (xp->xp_pattern[1] == '|')
1905 {
1906 ++xp->xp_pattern;
1907 xp->xp_context = EXPAND_EXPRESSION;
1908 }
1909 else
1910 xp->xp_context = EXPAND_COMMANDS;
1911 }
1912 else
1913 xp->xp_context = EXPAND_EXPRESSION;
1914 }
1915 else
1916 // Doesn't look like something valid, expand as an expression
1917 // anyway.
1918 xp->xp_context = EXPAND_EXPRESSION;
1919 arg = xp->xp_pattern;
1920 if (*arg != NUL)
1921 while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
1922 /* skip */ ;
1923 }
1924
1925 // ":exe one two" completes "two"
1926 if ((cmdidx == CMD_execute
1927 || cmdidx == CMD_echo
1928 || cmdidx == CMD_echon
1929 || cmdidx == CMD_echomsg)
1930 && xp->xp_context == EXPAND_EXPRESSION)
1931 {
1932 for (;;)
1933 {
1934 char_u *n = skiptowhite(arg);
1935
1936 if (n == arg || IS_WHITE_OR_NUL(*skipwhite(n)))
1937 break;
1938 arg = skipwhite(n);
1939 }
1940 }
1941
1942 xp->xp_pattern = arg;
1943 }
1944
1945 /*
1946 * Return TRUE if "pat" matches "text".
1947 * Does not use 'cpo' and always uses 'magic'.
1948 */
1949 int
pattern_match(char_u * pat,char_u * text,int ic)1950 pattern_match(char_u *pat, char_u *text, int ic)
1951 {
1952 int matches = FALSE;
1953 char_u *save_cpo;
1954 regmatch_T regmatch;
1955
1956 // avoid 'l' flag in 'cpoptions'
1957 save_cpo = p_cpo;
1958 p_cpo = empty_option;
1959 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
1960 if (regmatch.regprog != NULL)
1961 {
1962 regmatch.rm_ic = ic;
1963 matches = vim_regexec_nl(®match, text, (colnr_T)0);
1964 vim_regfree(regmatch.regprog);
1965 }
1966 p_cpo = save_cpo;
1967 return matches;
1968 }
1969
1970 /*
1971 * Handle a name followed by "(". Both for just "name(arg)" and for
1972 * "expr->name(arg)".
1973 * Returns OK or FAIL.
1974 */
1975 static int
eval_func(char_u ** arg,evalarg_T * evalarg,char_u * name,int name_len,typval_T * rettv,int flags,typval_T * basetv)1976 eval_func(
1977 char_u **arg, // points to "(", will be advanced
1978 evalarg_T *evalarg,
1979 char_u *name,
1980 int name_len,
1981 typval_T *rettv,
1982 int flags,
1983 typval_T *basetv) // "expr" for "expr->name(arg)"
1984 {
1985 int evaluate = flags & EVAL_EVALUATE;
1986 char_u *s = name;
1987 int len = name_len;
1988 partial_T *partial;
1989 int ret = OK;
1990 type_T *type = NULL;
1991
1992 if (!evaluate)
1993 check_vars(s, len);
1994
1995 // If "s" is the name of a variable of type VAR_FUNC
1996 // use its contents.
1997 s = deref_func_name(s, &len, &partial,
1998 in_vim9script() ? &type : NULL, !evaluate);
1999
2000 // Need to make a copy, in case evaluating the arguments makes
2001 // the name invalid.
2002 s = vim_strsave(s);
2003 if (s == NULL || (flags & EVAL_CONSTANT))
2004 ret = FAIL;
2005 else
2006 {
2007 funcexe_T funcexe;
2008
2009 // Invoke the function.
2010 CLEAR_FIELD(funcexe);
2011 funcexe.firstline = curwin->w_cursor.lnum;
2012 funcexe.lastline = curwin->w_cursor.lnum;
2013 funcexe.evaluate = evaluate;
2014 funcexe.partial = partial;
2015 funcexe.basetv = basetv;
2016 funcexe.check_type = type;
2017 ret = get_func_tv(s, len, rettv, arg, evalarg, &funcexe);
2018 }
2019 vim_free(s);
2020
2021 // If evaluate is FALSE rettv->v_type was not set in
2022 // get_func_tv, but it's needed in handle_subscript() to parse
2023 // what follows. So set it here.
2024 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(')
2025 {
2026 rettv->vval.v_string = NULL;
2027 rettv->v_type = VAR_FUNC;
2028 }
2029
2030 // Stop the expression evaluation when immediately
2031 // aborting on error, or when an interrupt occurred or
2032 // an exception was thrown but not caught.
2033 if (evaluate && aborting())
2034 {
2035 if (ret == OK)
2036 clear_tv(rettv);
2037 ret = FAIL;
2038 }
2039 return ret;
2040 }
2041
2042 /*
2043 * Get the next line source line without advancing. But do skip over comment
2044 * lines.
2045 * Only called for Vim9 script.
2046 */
2047 static char_u *
getline_peek_skip_comments(evalarg_T * evalarg)2048 getline_peek_skip_comments(evalarg_T *evalarg)
2049 {
2050 for (;;)
2051 {
2052 char_u *next = getline_peek(evalarg->eval_getline,
2053 evalarg->eval_cookie);
2054 char_u *p;
2055
2056 if (next == NULL)
2057 break;
2058 p = skipwhite(next);
2059 if (*p != NUL && !vim9_comment_start(p))
2060 return next;
2061 (void)eval_next_line(evalarg);
2062 }
2063 return NULL;
2064 }
2065
2066 /*
2067 * If inside Vim9 script, "arg" points to the end of a line (ignoring a #
2068 * comment) and there is a next line, return the next line (skipping blanks)
2069 * and set "getnext".
2070 * Otherwise return the next non-white at or after "arg" and set "getnext" to
2071 * FALSE.
2072 * "arg" must point somewhere inside a line, not at the start.
2073 */
2074 static char_u *
eval_next_non_blank(char_u * arg,evalarg_T * evalarg,int * getnext)2075 eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
2076 {
2077 char_u *p = skipwhite(arg);
2078
2079 *getnext = FALSE;
2080 if (in_vim9script()
2081 && evalarg != NULL
2082 && (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL)
2083 && (*p == NUL || (vim9_comment_start(p) && VIM_ISWHITE(p[-1]))))
2084 {
2085 char_u *next;
2086
2087 if (evalarg->eval_cookie != NULL)
2088 next = getline_peek_skip_comments(evalarg);
2089 else
2090 next = peek_next_line_from_context(evalarg->eval_cctx);
2091
2092 if (next != NULL)
2093 {
2094 *getnext = TRUE;
2095 return skipwhite(next);
2096 }
2097 }
2098 return p;
2099 }
2100
2101 /*
2102 * To be called after eval_next_non_blank() sets "getnext" to TRUE.
2103 * Only called for Vim9 script.
2104 */
2105 static char_u *
eval_next_line(evalarg_T * evalarg)2106 eval_next_line(evalarg_T *evalarg)
2107 {
2108 garray_T *gap = &evalarg->eval_ga;
2109 char_u *line;
2110
2111 if (evalarg->eval_cookie != NULL)
2112 line = evalarg->eval_getline(0, evalarg->eval_cookie, 0,
2113 GETLINE_CONCAT_ALL);
2114 else
2115 line = next_line_from_context(evalarg->eval_cctx, TRUE);
2116 ++evalarg->eval_break_count;
2117 if (gap->ga_itemsize > 0 && ga_grow(gap, 1) == OK)
2118 {
2119 char_u *p = skipwhite(line);
2120
2121 // Going to concatenate the lines after parsing. For an empty or
2122 // comment line use an empty string.
2123 if (*p == NUL || vim9_comment_start(p))
2124 {
2125 vim_free(line);
2126 line = vim_strsave((char_u *)"");
2127 }
2128
2129 ((char_u **)gap->ga_data)[gap->ga_len] = line;
2130 ++gap->ga_len;
2131 }
2132 else if (evalarg->eval_cookie != NULL)
2133 {
2134 vim_free(evalarg->eval_tofree);
2135 evalarg->eval_tofree = line;
2136 }
2137
2138 // Advanced to the next line, "arg" no longer points into the previous
2139 // line.
2140 evalarg->eval_using_cmdline = FALSE;
2141 return skipwhite(line);
2142 }
2143
2144 /*
2145 * Call eval_next_non_blank() and get the next line if needed.
2146 */
2147 char_u *
skipwhite_and_linebreak(char_u * arg,evalarg_T * evalarg)2148 skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg)
2149 {
2150 int getnext;
2151 char_u *p = skipwhite(arg);
2152
2153 if (evalarg == NULL)
2154 return skipwhite(arg);
2155 eval_next_non_blank(p, evalarg, &getnext);
2156 if (getnext)
2157 return eval_next_line(evalarg);
2158 return p;
2159 }
2160
2161 /*
2162 * Initialize "evalarg" for use.
2163 */
2164 void
init_evalarg(evalarg_T * evalarg)2165 init_evalarg(evalarg_T *evalarg)
2166 {
2167 CLEAR_POINTER(evalarg);
2168 ga_init2(&evalarg->eval_tofree_ga, sizeof(char_u *), 20);
2169 }
2170
2171 /*
2172 * After using "evalarg" filled from "eap": free the memory.
2173 */
2174 void
clear_evalarg(evalarg_T * evalarg,exarg_T * eap)2175 clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
2176 {
2177 if (evalarg != NULL)
2178 {
2179 if (evalarg->eval_tofree != NULL)
2180 {
2181 if (eap != NULL)
2182 {
2183 // We may need to keep the original command line, e.g. for
2184 // ":let" it has the variable names. But we may also need the
2185 // new one, "nextcmd" points into it. Keep both.
2186 vim_free(eap->cmdline_tofree);
2187 eap->cmdline_tofree = *eap->cmdlinep;
2188 *eap->cmdlinep = evalarg->eval_tofree;
2189 }
2190 else
2191 vim_free(evalarg->eval_tofree);
2192 evalarg->eval_tofree = NULL;
2193 }
2194
2195 ga_clear_strings(&evalarg->eval_tofree_ga);
2196 VIM_CLEAR(evalarg->eval_tofree_lambda);
2197 }
2198 }
2199
2200 /*
2201 * The "evaluate" argument: When FALSE, the argument is only parsed but not
2202 * executed. The function may return OK, but the rettv will be of type
2203 * VAR_UNKNOWN. The function still returns FAIL for a syntax error.
2204 */
2205
2206 /*
2207 * Handle zero level expression.
2208 * This calls eval1() and handles error message and nextcmd.
2209 * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
2210 * Note: "rettv.v_lock" is not set.
2211 * "evalarg" can be NULL, EVALARG_EVALUATE or a pointer.
2212 * Return OK or FAIL.
2213 */
2214 int
eval0(char_u * arg,typval_T * rettv,exarg_T * eap,evalarg_T * evalarg)2215 eval0(
2216 char_u *arg,
2217 typval_T *rettv,
2218 exarg_T *eap,
2219 evalarg_T *evalarg)
2220 {
2221 int ret;
2222 char_u *p;
2223 int did_emsg_before = did_emsg;
2224 int called_emsg_before = called_emsg;
2225 int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
2226 int end_error = FALSE;
2227
2228 p = skipwhite(arg);
2229 ret = eval1(&p, rettv, evalarg);
2230 p = skipwhite(p);
2231
2232 if (ret != FAIL)
2233 end_error = !ends_excmd2(arg, p);
2234 if (ret == FAIL || end_error)
2235 {
2236 if (ret != FAIL)
2237 clear_tv(rettv);
2238 /*
2239 * Report the invalid expression unless the expression evaluation has
2240 * been cancelled due to an aborting error, an interrupt, or an
2241 * exception, or we already gave a more specific error.
2242 * Also check called_emsg for when using assert_fails().
2243 */
2244 if (!aborting()
2245 && did_emsg == did_emsg_before
2246 && called_emsg == called_emsg_before
2247 && (flags & EVAL_CONSTANT) == 0
2248 && (!in_vim9script() || !vim9_bad_comment(p)))
2249 {
2250 if (end_error)
2251 semsg(_(e_trailing_arg), p);
2252 else
2253 semsg(_(e_invalid_expression_str), arg);
2254 }
2255
2256 // Some of the expression may not have been consumed. Do not check for
2257 // a next command to avoid more errors, unless "|" is following, which
2258 // could only be a command separator.
2259 if (eap != NULL && skipwhite(p)[0] == '|' && skipwhite(p)[1] != '|')
2260 eap->nextcmd = check_nextcmd(p);
2261 return FAIL;
2262 }
2263
2264 if (eap != NULL)
2265 set_nextcmd(eap, p);
2266
2267 return ret;
2268 }
2269
2270 /*
2271 * Handle top level expression:
2272 * expr2 ? expr1 : expr1
2273 * expr2 ?? expr1
2274 *
2275 * "arg" must point to the first non-white of the expression.
2276 * "arg" is advanced to just after the recognized expression.
2277 *
2278 * Note: "rettv.v_lock" is not set.
2279 *
2280 * Return OK or FAIL.
2281 */
2282 int
eval1(char_u ** arg,typval_T * rettv,evalarg_T * evalarg)2283 eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2284 {
2285 char_u *p;
2286 int getnext;
2287
2288 CLEAR_POINTER(rettv);
2289
2290 /*
2291 * Get the first variable.
2292 */
2293 if (eval2(arg, rettv, evalarg) == FAIL)
2294 return FAIL;
2295
2296 p = eval_next_non_blank(*arg, evalarg, &getnext);
2297 if (*p == '?')
2298 {
2299 int op_falsy = p[1] == '?';
2300 int result;
2301 typval_T var2;
2302 evalarg_T *evalarg_used = evalarg;
2303 evalarg_T local_evalarg;
2304 int orig_flags;
2305 int evaluate;
2306 int vim9script = in_vim9script();
2307
2308 if (evalarg == NULL)
2309 {
2310 init_evalarg(&local_evalarg);
2311 evalarg_used = &local_evalarg;
2312 }
2313 orig_flags = evalarg_used->eval_flags;
2314 evaluate = evalarg_used->eval_flags & EVAL_EVALUATE;
2315
2316 if (getnext)
2317 *arg = eval_next_line(evalarg_used);
2318 else
2319 {
2320 if (evaluate && vim9script && !VIM_ISWHITE(p[-1]))
2321 {
2322 error_white_both(p, op_falsy ? 2 : 1);
2323 clear_tv(rettv);
2324 return FAIL;
2325 }
2326 *arg = p;
2327 }
2328
2329 result = FALSE;
2330 if (evaluate)
2331 {
2332 int error = FALSE;
2333
2334 if (op_falsy)
2335 result = tv2bool(rettv);
2336 else if (vim9script)
2337 result = tv_get_bool_chk(rettv, &error);
2338 else if (tv_get_number_chk(rettv, &error) != 0)
2339 result = TRUE;
2340 if (error || !op_falsy || !result)
2341 clear_tv(rettv);
2342 if (error)
2343 return FAIL;
2344 }
2345
2346 /*
2347 * Get the second variable. Recursive!
2348 */
2349 if (op_falsy)
2350 ++*arg;
2351 if (evaluate && vim9script && !IS_WHITE_OR_NUL((*arg)[1]))
2352 {
2353 error_white_both(*arg - (op_falsy ? 1 : 0), op_falsy ? 2 : 1);
2354 clear_tv(rettv);
2355 return FAIL;
2356 }
2357 *arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
2358 evalarg_used->eval_flags = (op_falsy ? !result : result)
2359 ? orig_flags : orig_flags & ~EVAL_EVALUATE;
2360 if (eval1(arg, &var2, evalarg_used) == FAIL)
2361 {
2362 evalarg_used->eval_flags = orig_flags;
2363 return FAIL;
2364 }
2365 if (!op_falsy || !result)
2366 *rettv = var2;
2367
2368 if (!op_falsy)
2369 {
2370 /*
2371 * Check for the ":".
2372 */
2373 p = eval_next_non_blank(*arg, evalarg_used, &getnext);
2374 if (*p != ':')
2375 {
2376 emsg(_(e_missing_colon));
2377 if (evaluate && result)
2378 clear_tv(rettv);
2379 evalarg_used->eval_flags = orig_flags;
2380 return FAIL;
2381 }
2382 if (getnext)
2383 *arg = eval_next_line(evalarg_used);
2384 else
2385 {
2386 if (evaluate && vim9script && !VIM_ISWHITE(p[-1]))
2387 {
2388 error_white_both(p, 1);
2389 clear_tv(rettv);
2390 evalarg_used->eval_flags = orig_flags;
2391 return FAIL;
2392 }
2393 *arg = p;
2394 }
2395
2396 /*
2397 * Get the third variable. Recursive!
2398 */
2399 if (evaluate && vim9script && !IS_WHITE_OR_NUL((*arg)[1]))
2400 {
2401 error_white_both(*arg, 1);
2402 clear_tv(rettv);
2403 evalarg_used->eval_flags = orig_flags;
2404 return FAIL;
2405 }
2406 *arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
2407 evalarg_used->eval_flags = !result ? orig_flags
2408 : orig_flags & ~EVAL_EVALUATE;
2409 if (eval1(arg, &var2, evalarg_used) == FAIL)
2410 {
2411 if (evaluate && result)
2412 clear_tv(rettv);
2413 evalarg_used->eval_flags = orig_flags;
2414 return FAIL;
2415 }
2416 if (evaluate && !result)
2417 *rettv = var2;
2418 }
2419
2420 if (evalarg == NULL)
2421 clear_evalarg(&local_evalarg, NULL);
2422 else
2423 evalarg->eval_flags = orig_flags;
2424 }
2425
2426 return OK;
2427 }
2428
2429 /*
2430 * Handle first level expression:
2431 * expr2 || expr2 || expr2 logical OR
2432 *
2433 * "arg" must point to the first non-white of the expression.
2434 * "arg" is advanced to just after the recognized expression.
2435 *
2436 * Return OK or FAIL.
2437 */
2438 static int
eval2(char_u ** arg,typval_T * rettv,evalarg_T * evalarg)2439 eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2440 {
2441 char_u *p;
2442 int getnext;
2443
2444 /*
2445 * Get the first variable.
2446 */
2447 if (eval3(arg, rettv, evalarg) == FAIL)
2448 return FAIL;
2449
2450 /*
2451 * Handle the "||" operator.
2452 */
2453 p = eval_next_non_blank(*arg, evalarg, &getnext);
2454 if (p[0] == '|' && p[1] == '|')
2455 {
2456 evalarg_T *evalarg_used = evalarg;
2457 evalarg_T local_evalarg;
2458 int evaluate;
2459 int orig_flags;
2460 long result = FALSE;
2461 typval_T var2;
2462 int error = FALSE;
2463 int vim9script = in_vim9script();
2464
2465 if (evalarg == NULL)
2466 {
2467 init_evalarg(&local_evalarg);
2468 evalarg_used = &local_evalarg;
2469 }
2470 orig_flags = evalarg_used->eval_flags;
2471 evaluate = orig_flags & EVAL_EVALUATE;
2472 if (evaluate)
2473 {
2474 if (vim9script)
2475 result = tv_get_bool_chk(rettv, &error);
2476 else if (tv_get_number_chk(rettv, &error) != 0)
2477 result = TRUE;
2478 clear_tv(rettv);
2479 if (error)
2480 return FAIL;
2481 }
2482
2483 /*
2484 * Repeat until there is no following "||".
2485 */
2486 while (p[0] == '|' && p[1] == '|')
2487 {
2488 if (getnext)
2489 *arg = eval_next_line(evalarg_used);
2490 else
2491 {
2492 if (evaluate && in_vim9script() && !VIM_ISWHITE(p[-1]))
2493 {
2494 error_white_both(p, 2);
2495 clear_tv(rettv);
2496 return FAIL;
2497 }
2498 *arg = p;
2499 }
2500
2501 /*
2502 * Get the second variable.
2503 */
2504 if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[2]))
2505 {
2506 error_white_both(*arg, 2);
2507 clear_tv(rettv);
2508 return FAIL;
2509 }
2510 *arg = skipwhite_and_linebreak(*arg + 2, evalarg_used);
2511 evalarg_used->eval_flags = !result ? orig_flags
2512 : orig_flags & ~EVAL_EVALUATE;
2513 if (eval3(arg, &var2, evalarg_used) == FAIL)
2514 return FAIL;
2515
2516 /*
2517 * Compute the result.
2518 */
2519 if (evaluate && !result)
2520 {
2521 if (vim9script)
2522 result = tv_get_bool_chk(&var2, &error);
2523 else if (tv_get_number_chk(&var2, &error) != 0)
2524 result = TRUE;
2525 clear_tv(&var2);
2526 if (error)
2527 return FAIL;
2528 }
2529 if (evaluate)
2530 {
2531 if (vim9script)
2532 {
2533 rettv->v_type = VAR_BOOL;
2534 rettv->vval.v_number = result ? VVAL_TRUE : VVAL_FALSE;
2535 }
2536 else
2537 {
2538 rettv->v_type = VAR_NUMBER;
2539 rettv->vval.v_number = result;
2540 }
2541 }
2542
2543 p = eval_next_non_blank(*arg, evalarg_used, &getnext);
2544 }
2545
2546 if (evalarg == NULL)
2547 clear_evalarg(&local_evalarg, NULL);
2548 else
2549 evalarg->eval_flags = orig_flags;
2550 }
2551
2552 return OK;
2553 }
2554
2555 /*
2556 * Handle second level expression:
2557 * expr3 && expr3 && expr3 logical AND
2558 *
2559 * "arg" must point to the first non-white of the expression.
2560 * "arg" is advanced to just after the recognized expression.
2561 *
2562 * Return OK or FAIL.
2563 */
2564 static int
eval3(char_u ** arg,typval_T * rettv,evalarg_T * evalarg)2565 eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2566 {
2567 char_u *p;
2568 int getnext;
2569
2570 /*
2571 * Get the first variable.
2572 */
2573 if (eval4(arg, rettv, evalarg) == FAIL)
2574 return FAIL;
2575
2576 /*
2577 * Handle the "&&" operator.
2578 */
2579 p = eval_next_non_blank(*arg, evalarg, &getnext);
2580 if (p[0] == '&' && p[1] == '&')
2581 {
2582 evalarg_T *evalarg_used = evalarg;
2583 evalarg_T local_evalarg;
2584 int orig_flags;
2585 int evaluate;
2586 long result = TRUE;
2587 typval_T var2;
2588 int error = FALSE;
2589 int vim9script = in_vim9script();
2590
2591 if (evalarg == NULL)
2592 {
2593 init_evalarg(&local_evalarg);
2594 evalarg_used = &local_evalarg;
2595 }
2596 orig_flags = evalarg_used->eval_flags;
2597 evaluate = orig_flags & EVAL_EVALUATE;
2598 if (evaluate)
2599 {
2600 if (vim9script)
2601 result = tv_get_bool_chk(rettv, &error);
2602 else if (tv_get_number_chk(rettv, &error) == 0)
2603 result = FALSE;
2604 clear_tv(rettv);
2605 if (error)
2606 return FAIL;
2607 }
2608
2609 /*
2610 * Repeat until there is no following "&&".
2611 */
2612 while (p[0] == '&' && p[1] == '&')
2613 {
2614 if (getnext)
2615 *arg = eval_next_line(evalarg_used);
2616 else
2617 {
2618 if (evaluate && vim9script && !VIM_ISWHITE(p[-1]))
2619 {
2620 error_white_both(p, 2);
2621 clear_tv(rettv);
2622 return FAIL;
2623 }
2624 *arg = p;
2625 }
2626
2627 /*
2628 * Get the second variable.
2629 */
2630 if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[2]))
2631 {
2632 error_white_both(*arg, 2);
2633 clear_tv(rettv);
2634 return FAIL;
2635 }
2636 *arg = skipwhite_and_linebreak(*arg + 2, evalarg_used);
2637 evalarg_used->eval_flags = result ? orig_flags
2638 : orig_flags & ~EVAL_EVALUATE;
2639 CLEAR_FIELD(var2);
2640 if (eval4(arg, &var2, evalarg_used) == FAIL)
2641 return FAIL;
2642
2643 /*
2644 * Compute the result.
2645 */
2646 if (evaluate && result)
2647 {
2648 if (vim9script)
2649 result = tv_get_bool_chk(&var2, &error);
2650 else if (tv_get_number_chk(&var2, &error) == 0)
2651 result = FALSE;
2652 clear_tv(&var2);
2653 if (error)
2654 return FAIL;
2655 }
2656 if (evaluate)
2657 {
2658 if (vim9script)
2659 {
2660 rettv->v_type = VAR_BOOL;
2661 rettv->vval.v_number = result ? VVAL_TRUE : VVAL_FALSE;
2662 }
2663 else
2664 {
2665 rettv->v_type = VAR_NUMBER;
2666 rettv->vval.v_number = result;
2667 }
2668 }
2669
2670 p = eval_next_non_blank(*arg, evalarg_used, &getnext);
2671 }
2672
2673 if (evalarg == NULL)
2674 clear_evalarg(&local_evalarg, NULL);
2675 else
2676 evalarg->eval_flags = orig_flags;
2677 }
2678
2679 return OK;
2680 }
2681
2682 /*
2683 * Handle third level expression:
2684 * var1 == var2
2685 * var1 =~ var2
2686 * var1 != var2
2687 * var1 !~ var2
2688 * var1 > var2
2689 * var1 >= var2
2690 * var1 < var2
2691 * var1 <= var2
2692 * var1 is var2
2693 * var1 isnot var2
2694 *
2695 * "arg" must point to the first non-white of the expression.
2696 * "arg" is advanced to just after the recognized expression.
2697 *
2698 * Return OK or FAIL.
2699 */
2700 static int
eval4(char_u ** arg,typval_T * rettv,evalarg_T * evalarg)2701 eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2702 {
2703 char_u *p;
2704 int getnext;
2705 exprtype_T type = EXPR_UNKNOWN;
2706 int len = 2;
2707 int type_is = FALSE;
2708
2709 /*
2710 * Get the first variable.
2711 */
2712 if (eval5(arg, rettv, evalarg) == FAIL)
2713 return FAIL;
2714
2715 p = eval_next_non_blank(*arg, evalarg, &getnext);
2716 type = get_compare_type(p, &len, &type_is);
2717
2718 /*
2719 * If there is a comparative operator, use it.
2720 */
2721 if (type != EXPR_UNKNOWN)
2722 {
2723 typval_T var2;
2724 int ic;
2725 int vim9script = in_vim9script();
2726 int evaluate = evalarg == NULL
2727 ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
2728
2729 if (getnext)
2730 {
2731 *arg = eval_next_line(evalarg);
2732 p = *arg;
2733 }
2734 else if (evaluate && vim9script && !VIM_ISWHITE(**arg))
2735 {
2736 error_white_both(*arg, len);
2737 clear_tv(rettv);
2738 return FAIL;
2739 }
2740
2741 if (vim9script && type_is && (p[len] == '?' || p[len] == '#'))
2742 {
2743 semsg(_(e_invalid_expression_str), p);
2744 clear_tv(rettv);
2745 return FAIL;
2746 }
2747
2748 // extra question mark appended: ignore case
2749 if (p[len] == '?')
2750 {
2751 ic = TRUE;
2752 ++len;
2753 }
2754 // extra '#' appended: match case
2755 else if (p[len] == '#')
2756 {
2757 ic = FALSE;
2758 ++len;
2759 }
2760 // nothing appended: use 'ignorecase' if not in Vim script
2761 else
2762 ic = vim9script ? FALSE : p_ic;
2763
2764 /*
2765 * Get the second variable.
2766 */
2767 if (evaluate && vim9script && !IS_WHITE_OR_NUL(p[len]))
2768 {
2769 error_white_both(p, len);
2770 clear_tv(rettv);
2771 return FAIL;
2772 }
2773 *arg = skipwhite_and_linebreak(p + len, evalarg);
2774 if (eval5(arg, &var2, evalarg) == FAIL)
2775 {
2776 clear_tv(rettv);
2777 return FAIL;
2778 }
2779 if (evaluate)
2780 {
2781 int ret;
2782
2783 if (vim9script && check_compare_types(type, rettv, &var2) == FAIL)
2784 {
2785 ret = FAIL;
2786 clear_tv(rettv);
2787 }
2788 else
2789 ret = typval_compare(rettv, &var2, type, ic);
2790 clear_tv(&var2);
2791 return ret;
2792 }
2793 }
2794
2795 return OK;
2796 }
2797
2798 /*
2799 * Make a copy of blob "tv1" and append blob "tv2".
2800 */
2801 void
eval_addblob(typval_T * tv1,typval_T * tv2)2802 eval_addblob(typval_T *tv1, typval_T *tv2)
2803 {
2804 blob_T *b1 = tv1->vval.v_blob;
2805 blob_T *b2 = tv2->vval.v_blob;
2806 blob_T *b = blob_alloc();
2807 int i;
2808
2809 if (b != NULL)
2810 {
2811 for (i = 0; i < blob_len(b1); i++)
2812 ga_append(&b->bv_ga, blob_get(b1, i));
2813 for (i = 0; i < blob_len(b2); i++)
2814 ga_append(&b->bv_ga, blob_get(b2, i));
2815
2816 clear_tv(tv1);
2817 rettv_blob_set(tv1, b);
2818 }
2819 }
2820
2821 /*
2822 * Make a copy of list "tv1" and append list "tv2".
2823 */
2824 int
eval_addlist(typval_T * tv1,typval_T * tv2)2825 eval_addlist(typval_T *tv1, typval_T *tv2)
2826 {
2827 typval_T var3;
2828
2829 // concatenate Lists
2830 if (list_concat(tv1->vval.v_list, tv2->vval.v_list, &var3) == FAIL)
2831 {
2832 clear_tv(tv1);
2833 clear_tv(tv2);
2834 return FAIL;
2835 }
2836 clear_tv(tv1);
2837 *tv1 = var3;
2838 return OK;
2839 }
2840
2841 /*
2842 * Handle fourth level expression:
2843 * + number addition
2844 * - number subtraction
2845 * . string concatenation (if script version is 1)
2846 * .. string concatenation
2847 *
2848 * "arg" must point to the first non-white of the expression.
2849 * "arg" is advanced to just after the recognized expression.
2850 *
2851 * Return OK or FAIL.
2852 */
2853 static int
eval5(char_u ** arg,typval_T * rettv,evalarg_T * evalarg)2854 eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2855 {
2856 /*
2857 * Get the first variable.
2858 */
2859 if (eval6(arg, rettv, evalarg, FALSE) == FAIL)
2860 return FAIL;
2861
2862 /*
2863 * Repeat computing, until no '+', '-' or '.' is following.
2864 */
2865 for (;;)
2866 {
2867 int evaluate;
2868 int getnext;
2869 char_u *p;
2870 int op;
2871 int oplen;
2872 int concat;
2873 typval_T var2;
2874 int vim9script = in_vim9script();
2875
2876 // "." is only string concatenation when scriptversion is 1
2877 // "+=", "-=" and "..=" are assignments
2878 // "++" and "--" on the next line are a separate command.
2879 p = eval_next_non_blank(*arg, evalarg, &getnext);
2880 op = *p;
2881 concat = op == '.' && (*(p + 1) == '.' || in_old_script(2));
2882 if ((op != '+' && op != '-' && !concat) || p[1] == '='
2883 || (p[1] == '.' && p[2] == '='))
2884 break;
2885 if (getnext && (op == '+' || op == '-') && p[0] == p[1])
2886 break;
2887
2888 evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
2889 oplen = (concat && p[1] == '.') ? 2 : 1;
2890 if (getnext)
2891 *arg = eval_next_line(evalarg);
2892 else
2893 {
2894 if (evaluate && vim9script && !VIM_ISWHITE(**arg))
2895 {
2896 error_white_both(*arg, oplen);
2897 clear_tv(rettv);
2898 return FAIL;
2899 }
2900 *arg = p;
2901 }
2902 if ((op != '+' || (rettv->v_type != VAR_LIST
2903 && rettv->v_type != VAR_BLOB))
2904 #ifdef FEAT_FLOAT
2905 && (op == '.' || rettv->v_type != VAR_FLOAT)
2906 #endif
2907 && evaluate)
2908 {
2909 int error = FALSE;
2910
2911 // For "list + ...", an illegal use of the first operand as
2912 // a number cannot be determined before evaluating the 2nd
2913 // operand: if this is also a list, all is ok.
2914 // For "something . ...", "something - ..." or "non-list + ...",
2915 // we know that the first operand needs to be a string or number
2916 // without evaluating the 2nd operand. So check before to avoid
2917 // side effects after an error.
2918 if (op != '.')
2919 tv_get_number_chk(rettv, &error);
2920 if ((op == '.' && tv_get_string_chk(rettv) == NULL) || error)
2921 {
2922 clear_tv(rettv);
2923 return FAIL;
2924 }
2925 }
2926
2927 /*
2928 * Get the second variable.
2929 */
2930 if (evaluate && vim9script && !IS_WHITE_OR_NUL((*arg)[oplen]))
2931 {
2932 error_white_both(*arg, oplen);
2933 clear_tv(rettv);
2934 return FAIL;
2935 }
2936 *arg = skipwhite_and_linebreak(*arg + oplen, evalarg);
2937 if (eval6(arg, &var2, evalarg, !vim9script && op == '.') == FAIL)
2938 {
2939 clear_tv(rettv);
2940 return FAIL;
2941 }
2942
2943 if (evaluate)
2944 {
2945 /*
2946 * Compute the result.
2947 */
2948 if (op == '.')
2949 {
2950 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
2951 char_u *s1 = tv_get_string_buf(rettv, buf1);
2952 char_u *s2 = NULL;
2953
2954 if (vim9script && (var2.v_type == VAR_VOID
2955 || var2.v_type == VAR_CHANNEL
2956 || var2.v_type == VAR_JOB))
2957 semsg(_(e_using_invalid_value_as_string_str),
2958 vartype_name(var2.v_type));
2959 #ifdef FEAT_FLOAT
2960 else if (vim9script && var2.v_type == VAR_FLOAT)
2961 {
2962 vim_snprintf((char *)buf2, NUMBUFLEN, "%g",
2963 var2.vval.v_float);
2964 s2 = buf2;
2965 }
2966 #endif
2967 else
2968 s2 = tv_get_string_buf_chk(&var2, buf2);
2969 if (s2 == NULL) // type error ?
2970 {
2971 clear_tv(rettv);
2972 clear_tv(&var2);
2973 return FAIL;
2974 }
2975 p = concat_str(s1, s2);
2976 clear_tv(rettv);
2977 rettv->v_type = VAR_STRING;
2978 rettv->vval.v_string = p;
2979 }
2980 else if (op == '+' && rettv->v_type == VAR_BLOB
2981 && var2.v_type == VAR_BLOB)
2982 eval_addblob(rettv, &var2);
2983 else if (op == '+' && rettv->v_type == VAR_LIST
2984 && var2.v_type == VAR_LIST)
2985 {
2986 if (eval_addlist(rettv, &var2) == FAIL)
2987 return FAIL;
2988 }
2989 else
2990 {
2991 int error = FALSE;
2992 varnumber_T n1, n2;
2993 #ifdef FEAT_FLOAT
2994 float_T f1 = 0, f2 = 0;
2995
2996 if (rettv->v_type == VAR_FLOAT)
2997 {
2998 f1 = rettv->vval.v_float;
2999 n1 = 0;
3000 }
3001 else
3002 #endif
3003 {
3004 n1 = tv_get_number_chk(rettv, &error);
3005 if (error)
3006 {
3007 // This can only happen for "list + non-list" or
3008 // "blob + non-blob". For "non-list + ..." or
3009 // "something - ...", we returned before evaluating the
3010 // 2nd operand.
3011 clear_tv(rettv);
3012 clear_tv(&var2);
3013 return FAIL;
3014 }
3015 #ifdef FEAT_FLOAT
3016 if (var2.v_type == VAR_FLOAT)
3017 f1 = n1;
3018 #endif
3019 }
3020 #ifdef FEAT_FLOAT
3021 if (var2.v_type == VAR_FLOAT)
3022 {
3023 f2 = var2.vval.v_float;
3024 n2 = 0;
3025 }
3026 else
3027 #endif
3028 {
3029 n2 = tv_get_number_chk(&var2, &error);
3030 if (error)
3031 {
3032 clear_tv(rettv);
3033 clear_tv(&var2);
3034 return FAIL;
3035 }
3036 #ifdef FEAT_FLOAT
3037 if (rettv->v_type == VAR_FLOAT)
3038 f2 = n2;
3039 #endif
3040 }
3041 clear_tv(rettv);
3042
3043 #ifdef FEAT_FLOAT
3044 // If there is a float on either side the result is a float.
3045 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
3046 {
3047 if (op == '+')
3048 f1 = f1 + f2;
3049 else
3050 f1 = f1 - f2;
3051 rettv->v_type = VAR_FLOAT;
3052 rettv->vval.v_float = f1;
3053 }
3054 else
3055 #endif
3056 {
3057 if (op == '+')
3058 n1 = n1 + n2;
3059 else
3060 n1 = n1 - n2;
3061 rettv->v_type = VAR_NUMBER;
3062 rettv->vval.v_number = n1;
3063 }
3064 }
3065 clear_tv(&var2);
3066 }
3067 }
3068 return OK;
3069 }
3070
3071 /*
3072 * Handle fifth level expression:
3073 * * number multiplication
3074 * / number division
3075 * % number modulo
3076 *
3077 * "arg" must point to the first non-white of the expression.
3078 * "arg" is advanced to just after the recognized expression.
3079 *
3080 * Return OK or FAIL.
3081 */
3082 static int
eval6(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int want_string)3083 eval6(
3084 char_u **arg,
3085 typval_T *rettv,
3086 evalarg_T *evalarg,
3087 int want_string) // after "." operator
3088 {
3089 #ifdef FEAT_FLOAT
3090 int use_float = FALSE;
3091 #endif
3092
3093 /*
3094 * Get the first variable.
3095 */
3096 if (eval7t(arg, rettv, evalarg, want_string) == FAIL)
3097 return FAIL;
3098
3099 /*
3100 * Repeat computing, until no '*', '/' or '%' is following.
3101 */
3102 for (;;)
3103 {
3104 int evaluate;
3105 int getnext;
3106 typval_T var2;
3107 char_u *p;
3108 int op;
3109 varnumber_T n1, n2;
3110 #ifdef FEAT_FLOAT
3111 float_T f1, f2;
3112 #endif
3113 int error;
3114
3115 // "*=", "/=" and "%=" are assignments
3116 p = eval_next_non_blank(*arg, evalarg, &getnext);
3117 op = *p;
3118 if ((op != '*' && op != '/' && op != '%') || p[1] == '=')
3119 break;
3120
3121 evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
3122 if (getnext)
3123 *arg = eval_next_line(evalarg);
3124 else
3125 {
3126 if (evaluate && in_vim9script() && !VIM_ISWHITE(**arg))
3127 {
3128 error_white_both(*arg, 1);
3129 clear_tv(rettv);
3130 return FAIL;
3131 }
3132 *arg = p;
3133 }
3134
3135 #ifdef FEAT_FLOAT
3136 f1 = 0;
3137 f2 = 0;
3138 #endif
3139 error = FALSE;
3140 if (evaluate)
3141 {
3142 #ifdef FEAT_FLOAT
3143 if (rettv->v_type == VAR_FLOAT)
3144 {
3145 f1 = rettv->vval.v_float;
3146 use_float = TRUE;
3147 n1 = 0;
3148 }
3149 else
3150 #endif
3151 n1 = tv_get_number_chk(rettv, &error);
3152 clear_tv(rettv);
3153 if (error)
3154 return FAIL;
3155 }
3156 else
3157 n1 = 0;
3158
3159 /*
3160 * Get the second variable.
3161 */
3162 if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[1]))
3163 {
3164 error_white_both(*arg, 1);
3165 clear_tv(rettv);
3166 return FAIL;
3167 }
3168 *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
3169 if (eval7t(arg, &var2, evalarg, FALSE) == FAIL)
3170 return FAIL;
3171
3172 if (evaluate)
3173 {
3174 #ifdef FEAT_FLOAT
3175 if (var2.v_type == VAR_FLOAT)
3176 {
3177 if (!use_float)
3178 {
3179 f1 = n1;
3180 use_float = TRUE;
3181 }
3182 f2 = var2.vval.v_float;
3183 n2 = 0;
3184 }
3185 else
3186 #endif
3187 {
3188 n2 = tv_get_number_chk(&var2, &error);
3189 clear_tv(&var2);
3190 if (error)
3191 return FAIL;
3192 #ifdef FEAT_FLOAT
3193 if (use_float)
3194 f2 = n2;
3195 #endif
3196 }
3197
3198 /*
3199 * Compute the result.
3200 * When either side is a float the result is a float.
3201 */
3202 #ifdef FEAT_FLOAT
3203 if (use_float)
3204 {
3205 if (op == '*')
3206 f1 = f1 * f2;
3207 else if (op == '/')
3208 {
3209 # ifdef VMS
3210 // VMS crashes on divide by zero, work around it
3211 if (f2 == 0.0)
3212 {
3213 if (f1 == 0)
3214 f1 = -1 * __F_FLT_MAX - 1L; // similar to NaN
3215 else if (f1 < 0)
3216 f1 = -1 * __F_FLT_MAX;
3217 else
3218 f1 = __F_FLT_MAX;
3219 }
3220 else
3221 f1 = f1 / f2;
3222 # else
3223 // We rely on the floating point library to handle divide
3224 // by zero to result in "inf" and not a crash.
3225 f1 = f1 / f2;
3226 # endif
3227 }
3228 else
3229 {
3230 emsg(_(e_modulus));
3231 return FAIL;
3232 }
3233 rettv->v_type = VAR_FLOAT;
3234 rettv->vval.v_float = f1;
3235 }
3236 else
3237 #endif
3238 {
3239 int failed = FALSE;
3240
3241 if (op == '*')
3242 n1 = n1 * n2;
3243 else if (op == '/')
3244 n1 = num_divide(n1, n2, &failed);
3245 else
3246 n1 = num_modulus(n1, n2, &failed);
3247 if (failed)
3248 return FAIL;
3249
3250 rettv->v_type = VAR_NUMBER;
3251 rettv->vval.v_number = n1;
3252 }
3253 }
3254 }
3255
3256 return OK;
3257 }
3258
3259 /*
3260 * Handle a type cast before a base level expression.
3261 * "arg" must point to the first non-white of the expression.
3262 * "arg" is advanced to just after the recognized expression.
3263 * Return OK or FAIL.
3264 */
3265 static int
eval7t(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int want_string)3266 eval7t(
3267 char_u **arg,
3268 typval_T *rettv,
3269 evalarg_T *evalarg,
3270 int want_string) // after "." operator
3271 {
3272 type_T *want_type = NULL;
3273 garray_T type_list; // list of pointers to allocated types
3274 int res;
3275 int evaluate = evalarg == NULL ? 0
3276 : (evalarg->eval_flags & EVAL_EVALUATE);
3277
3278 // Recognize <type> in Vim9 script only.
3279 if (in_vim9script() && **arg == '<' && eval_isnamec1((*arg)[1])
3280 && STRNCMP(*arg, "<SNR>", 5) != 0)
3281 {
3282 ++*arg;
3283 ga_init2(&type_list, sizeof(type_T *), 10);
3284 want_type = parse_type(arg, &type_list, TRUE);
3285 if (want_type == NULL && (evaluate || **arg != '>'))
3286 {
3287 clear_type_list(&type_list);
3288 return FAIL;
3289 }
3290
3291 if (**arg != '>')
3292 {
3293 if (*skipwhite(*arg) == '>')
3294 semsg(_(e_no_white_space_allowed_before_str_str), ">", *arg);
3295 else
3296 emsg(_(e_missing_gt));
3297 clear_type_list(&type_list);
3298 return FAIL;
3299 }
3300 ++*arg;
3301 *arg = skipwhite_and_linebreak(*arg, evalarg);
3302 }
3303
3304 res = eval7(arg, rettv, evalarg, want_string);
3305
3306 if (want_type != NULL && evaluate)
3307 {
3308 if (res == OK)
3309 {
3310 type_T *actual = typval2type(rettv, get_copyID(), &type_list, TRUE);
3311
3312 if (!equal_type(want_type, actual, 0))
3313 {
3314 if (want_type == &t_bool && actual != &t_bool
3315 && (actual->tt_flags & TTFLAG_BOOL_OK))
3316 {
3317 int n = tv2bool(rettv);
3318
3319 // can use "0" and "1" for boolean in some places
3320 clear_tv(rettv);
3321 rettv->v_type = VAR_BOOL;
3322 rettv->vval.v_number = n ? VVAL_TRUE : VVAL_FALSE;
3323 }
3324 else
3325 {
3326 where_T where = WHERE_INIT;
3327
3328 where.wt_variable = TRUE;
3329 res = check_type(want_type, actual, TRUE, where);
3330 }
3331 }
3332 }
3333 clear_type_list(&type_list);
3334 }
3335
3336 return res;
3337 }
3338
3339 int
eval_leader(char_u ** arg,int vim9)3340 eval_leader(char_u **arg, int vim9)
3341 {
3342 char_u *s = *arg;
3343 char_u *p = *arg;
3344
3345 while (*p == '!' || *p == '-' || *p == '+')
3346 {
3347 char_u *n = skipwhite(p + 1);
3348
3349 // ++, --, -+ and +- are not accepted in Vim9 script
3350 if (vim9 && (*p == '-' || *p == '+') && (*n == '-' || *n == '+'))
3351 {
3352 semsg(_(e_invalid_expression_str), s);
3353 return FAIL;
3354 }
3355 p = n;
3356 }
3357 *arg = p;
3358 return OK;
3359 }
3360
3361 /*
3362 * Handle sixth level expression:
3363 * number number constant
3364 * 0zFFFFFFFF Blob constant
3365 * "string" string constant
3366 * 'string' literal string constant
3367 * &option-name option value
3368 * @r register contents
3369 * identifier variable value
3370 * function() function call
3371 * $VAR environment variable
3372 * (expression) nested expression
3373 * [expr, expr] List
3374 * {arg, arg -> expr} Lambda
3375 * {key: val, key: val} Dictionary
3376 * #{key: val, key: val} Dictionary with literal keys
3377 *
3378 * Also handle:
3379 * ! in front logical NOT
3380 * - in front unary minus
3381 * + in front unary plus (ignored)
3382 * trailing [] subscript in String or List
3383 * trailing .name entry in Dictionary
3384 * trailing ->name() method call
3385 *
3386 * "arg" must point to the first non-white of the expression.
3387 * "arg" is advanced to just after the recognized expression.
3388 *
3389 * Return OK or FAIL.
3390 */
3391 static int
eval7(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int want_string)3392 eval7(
3393 char_u **arg,
3394 typval_T *rettv,
3395 evalarg_T *evalarg,
3396 int want_string) // after "." operator
3397 {
3398 int evaluate = evalarg != NULL
3399 && (evalarg->eval_flags & EVAL_EVALUATE);
3400 int len;
3401 char_u *s;
3402 char_u *start_leader, *end_leader;
3403 int ret = OK;
3404 char_u *alias;
3405
3406 /*
3407 * Initialise variable so that clear_tv() can't mistake this for a
3408 * string and free a string that isn't there.
3409 */
3410 rettv->v_type = VAR_UNKNOWN;
3411
3412 /*
3413 * Skip '!', '-' and '+' characters. They are handled later.
3414 */
3415 start_leader = *arg;
3416 if (eval_leader(arg, in_vim9script()) == FAIL)
3417 return FAIL;
3418 end_leader = *arg;
3419
3420 if (**arg == '.' && (!isdigit(*(*arg + 1))
3421 #ifdef FEAT_FLOAT
3422 || in_old_script(2)
3423 #endif
3424 ))
3425 {
3426 semsg(_(e_invalid_expression_str), *arg);
3427 ++*arg;
3428 return FAIL;
3429 }
3430
3431 switch (**arg)
3432 {
3433 /*
3434 * Number constant.
3435 */
3436 case '0':
3437 case '1':
3438 case '2':
3439 case '3':
3440 case '4':
3441 case '5':
3442 case '6':
3443 case '7':
3444 case '8':
3445 case '9':
3446 case '.': ret = eval_number(arg, rettv, evaluate, want_string);
3447
3448 // Apply prefixed "-" and "+" now. Matters especially when
3449 // "->" follows.
3450 if (ret == OK && evaluate && end_leader > start_leader
3451 && rettv->v_type != VAR_BLOB)
3452 ret = eval7_leader(rettv, TRUE, start_leader, &end_leader);
3453 break;
3454
3455 /*
3456 * String constant: "string".
3457 */
3458 case '"': ret = eval_string(arg, rettv, evaluate);
3459 break;
3460
3461 /*
3462 * Literal string constant: 'str''ing'.
3463 */
3464 case '\'': ret = eval_lit_string(arg, rettv, evaluate);
3465 break;
3466
3467 /*
3468 * List: [expr, expr]
3469 */
3470 case '[': ret = eval_list(arg, rettv, evalarg, TRUE);
3471 break;
3472
3473 /*
3474 * Dictionary: #{key: val, key: val}
3475 */
3476 case '#': if (in_vim9script())
3477 {
3478 ret = vim9_bad_comment(*arg) ? FAIL : NOTDONE;
3479 }
3480 else if ((*arg)[1] == '{')
3481 {
3482 ++*arg;
3483 ret = eval_dict(arg, rettv, evalarg, TRUE);
3484 }
3485 else
3486 ret = NOTDONE;
3487 break;
3488
3489 /*
3490 * Lambda: {arg, arg -> expr}
3491 * Dictionary: {'key': val, 'key': val}
3492 */
3493 case '{': if (in_vim9script())
3494 ret = NOTDONE;
3495 else
3496 ret = get_lambda_tv(arg, rettv, in_vim9script(), evalarg);
3497 if (ret == NOTDONE)
3498 ret = eval_dict(arg, rettv, evalarg, FALSE);
3499 break;
3500
3501 /*
3502 * Option value: &name
3503 */
3504 case '&': ret = eval_option(arg, rettv, evaluate);
3505 break;
3506
3507 /*
3508 * Environment variable: $VAR.
3509 */
3510 case '$': ret = eval_env_var(arg, rettv, evaluate);
3511 break;
3512
3513 /*
3514 * Register contents: @r.
3515 */
3516 case '@': ++*arg;
3517 if (evaluate)
3518 {
3519 if (in_vim9script() && IS_WHITE_OR_NUL(**arg))
3520 semsg(_(e_syntax_error_at_str), *arg);
3521 else if (in_vim9script() && !valid_yank_reg(**arg, FALSE))
3522 emsg_invreg(**arg);
3523 else
3524 {
3525 rettv->v_type = VAR_STRING;
3526 rettv->vval.v_string = get_reg_contents(**arg,
3527 GREG_EXPR_SRC);
3528 }
3529 }
3530 if (**arg != NUL)
3531 ++*arg;
3532 break;
3533
3534 /*
3535 * nested expression: (expression).
3536 * or lambda: (arg) => expr
3537 */
3538 case '(': ret = NOTDONE;
3539 if (in_vim9script())
3540 {
3541 ret = get_lambda_tv(arg, rettv, TRUE, evalarg);
3542 if (ret == OK && evaluate)
3543 {
3544 ufunc_T *ufunc = rettv->vval.v_partial->pt_func;
3545
3546 // Compile it here to get the return type. The return
3547 // type is optional, when it's missing use t_unknown.
3548 // This is recognized in compile_return().
3549 if (ufunc->uf_ret_type->tt_type == VAR_VOID)
3550 ufunc->uf_ret_type = &t_unknown;
3551 if (compile_def_function(ufunc,
3552 FALSE, COMPILE_TYPE(ufunc), NULL) == FAIL)
3553 {
3554 clear_tv(rettv);
3555 ret = FAIL;
3556 }
3557 }
3558 }
3559 if (ret == NOTDONE)
3560 {
3561 *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
3562 ret = eval1(arg, rettv, evalarg); // recursive!
3563
3564 *arg = skipwhite_and_linebreak(*arg, evalarg);
3565 if (**arg == ')')
3566 ++*arg;
3567 else if (ret == OK)
3568 {
3569 emsg(_(e_missing_close));
3570 clear_tv(rettv);
3571 ret = FAIL;
3572 }
3573 }
3574 break;
3575
3576 default: ret = NOTDONE;
3577 break;
3578 }
3579
3580 if (ret == NOTDONE)
3581 {
3582 /*
3583 * Must be a variable or function name.
3584 * Can also be a curly-braces kind of name: {expr}.
3585 */
3586 s = *arg;
3587 len = get_name_len(arg, &alias, evaluate, TRUE);
3588 if (alias != NULL)
3589 s = alias;
3590
3591 if (len <= 0)
3592 ret = FAIL;
3593 else
3594 {
3595 int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
3596
3597 if (evaluate && in_vim9script() && len == 1 && *s == '_')
3598 {
3599 emsg(_(e_cannot_use_underscore_here));
3600 ret = FAIL;
3601 }
3602 else if ((in_vim9script() ? **arg : *skipwhite(*arg)) == '(')
3603 {
3604 // "name(..." recursive!
3605 *arg = skipwhite(*arg);
3606 ret = eval_func(arg, evalarg, s, len, rettv, flags, NULL);
3607 }
3608 else if (flags & EVAL_CONSTANT)
3609 ret = FAIL;
3610 else if (evaluate)
3611 {
3612 // get the value of "true", "false" or a variable
3613 if (len == 4 && in_vim9script() && STRNCMP(s, "true", 4) == 0)
3614 {
3615 rettv->v_type = VAR_BOOL;
3616 rettv->vval.v_number = VVAL_TRUE;
3617 ret = OK;
3618 }
3619 else if (len == 5 && in_vim9script()
3620 && STRNCMP(s, "false", 5) == 0)
3621 {
3622 rettv->v_type = VAR_BOOL;
3623 rettv->vval.v_number = VVAL_FALSE;
3624 ret = OK;
3625 }
3626 else if (len == 4 && in_vim9script()
3627 && STRNCMP(s, "null", 4) == 0)
3628 {
3629 rettv->v_type = VAR_SPECIAL;
3630 rettv->vval.v_number = VVAL_NULL;
3631 ret = OK;
3632 }
3633 else
3634 ret = eval_variable(s, len, rettv, NULL,
3635 EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT);
3636 }
3637 else
3638 {
3639 // skip the name
3640 check_vars(s, len);
3641 ret = OK;
3642 }
3643 }
3644 vim_free(alias);
3645 }
3646
3647 // Handle following '[', '(' and '.' for expr[expr], expr.name,
3648 // expr(expr), expr->name(expr)
3649 if (ret == OK)
3650 ret = handle_subscript(arg, rettv, evalarg, TRUE);
3651
3652 /*
3653 * Apply logical NOT and unary '-', from right to left, ignore '+'.
3654 */
3655 if (ret == OK && evaluate && end_leader > start_leader)
3656 ret = eval7_leader(rettv, FALSE, start_leader, &end_leader);
3657 return ret;
3658 }
3659
3660 /*
3661 * Apply the leading "!" and "-" before an eval7 expression to "rettv".
3662 * When "numeric_only" is TRUE only handle "+" and "-".
3663 * Adjusts "end_leaderp" until it is at "start_leader".
3664 */
3665 static int
eval7_leader(typval_T * rettv,int numeric_only,char_u * start_leader,char_u ** end_leaderp)3666 eval7_leader(
3667 typval_T *rettv,
3668 int numeric_only,
3669 char_u *start_leader,
3670 char_u **end_leaderp)
3671 {
3672 char_u *end_leader = *end_leaderp;
3673 int ret = OK;
3674 int error = FALSE;
3675 varnumber_T val = 0;
3676 vartype_T type = rettv->v_type;
3677 #ifdef FEAT_FLOAT
3678 float_T f = 0.0;
3679
3680 if (rettv->v_type == VAR_FLOAT)
3681 f = rettv->vval.v_float;
3682 else
3683 #endif
3684 {
3685 while (VIM_ISWHITE(end_leader[-1]))
3686 --end_leader;
3687 if (in_vim9script() && end_leader[-1] == '!')
3688 val = tv2bool(rettv);
3689 else
3690 val = tv_get_number_chk(rettv, &error);
3691 }
3692 if (error)
3693 {
3694 clear_tv(rettv);
3695 ret = FAIL;
3696 }
3697 else
3698 {
3699 while (end_leader > start_leader)
3700 {
3701 --end_leader;
3702 if (*end_leader == '!')
3703 {
3704 if (numeric_only)
3705 {
3706 ++end_leader;
3707 break;
3708 }
3709 #ifdef FEAT_FLOAT
3710 if (rettv->v_type == VAR_FLOAT)
3711 {
3712 if (in_vim9script())
3713 {
3714 rettv->v_type = VAR_BOOL;
3715 val = f == 0.0 ? VVAL_TRUE : VVAL_FALSE;
3716 }
3717 else
3718 f = !f;
3719 }
3720 else
3721 #endif
3722 {
3723 val = !val;
3724 type = VAR_BOOL;
3725 }
3726 }
3727 else if (*end_leader == '-')
3728 {
3729 #ifdef FEAT_FLOAT
3730 if (rettv->v_type == VAR_FLOAT)
3731 f = -f;
3732 else
3733 #endif
3734 {
3735 val = -val;
3736 type = VAR_NUMBER;
3737 }
3738 }
3739 }
3740 #ifdef FEAT_FLOAT
3741 if (rettv->v_type == VAR_FLOAT)
3742 {
3743 clear_tv(rettv);
3744 rettv->vval.v_float = f;
3745 }
3746 else
3747 #endif
3748 {
3749 clear_tv(rettv);
3750 if (in_vim9script())
3751 rettv->v_type = type;
3752 else
3753 rettv->v_type = VAR_NUMBER;
3754 rettv->vval.v_number = val;
3755 }
3756 }
3757 *end_leaderp = end_leader;
3758 return ret;
3759 }
3760
3761 /*
3762 * Call the function referred to in "rettv".
3763 */
3764 static int
call_func_rettv(char_u ** arg,evalarg_T * evalarg,typval_T * rettv,int evaluate,dict_T * selfdict,typval_T * basetv)3765 call_func_rettv(
3766 char_u **arg,
3767 evalarg_T *evalarg,
3768 typval_T *rettv,
3769 int evaluate,
3770 dict_T *selfdict,
3771 typval_T *basetv)
3772 {
3773 partial_T *pt = NULL;
3774 funcexe_T funcexe;
3775 typval_T functv;
3776 char_u *s;
3777 int ret;
3778
3779 // need to copy the funcref so that we can clear rettv
3780 if (evaluate)
3781 {
3782 functv = *rettv;
3783 rettv->v_type = VAR_UNKNOWN;
3784
3785 // Invoke the function. Recursive!
3786 if (functv.v_type == VAR_PARTIAL)
3787 {
3788 pt = functv.vval.v_partial;
3789 s = partial_name(pt);
3790 }
3791 else
3792 {
3793 s = functv.vval.v_string;
3794 if (s == NULL || *s == NUL)
3795 {
3796 emsg(_(e_empty_function_name));
3797 ret = FAIL;
3798 goto theend;
3799 }
3800 }
3801 }
3802 else
3803 s = (char_u *)"";
3804
3805 CLEAR_FIELD(funcexe);
3806 funcexe.firstline = curwin->w_cursor.lnum;
3807 funcexe.lastline = curwin->w_cursor.lnum;
3808 funcexe.evaluate = evaluate;
3809 funcexe.partial = pt;
3810 funcexe.selfdict = selfdict;
3811 funcexe.basetv = basetv;
3812 ret = get_func_tv(s, -1, rettv, arg, evalarg, &funcexe);
3813
3814 theend:
3815 // Clear the funcref afterwards, so that deleting it while
3816 // evaluating the arguments is possible (see test55).
3817 if (evaluate)
3818 clear_tv(&functv);
3819
3820 return ret;
3821 }
3822
3823 /*
3824 * Evaluate "->method()".
3825 * "*arg" points to "method".
3826 * Returns FAIL or OK. "*arg" is advanced to after the ')'.
3827 */
3828 static int
eval_lambda(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int verbose)3829 eval_lambda(
3830 char_u **arg,
3831 typval_T *rettv,
3832 evalarg_T *evalarg,
3833 int verbose) // give error messages
3834 {
3835 int evaluate = evalarg != NULL
3836 && (evalarg->eval_flags & EVAL_EVALUATE);
3837 typval_T base = *rettv;
3838 int ret;
3839
3840 rettv->v_type = VAR_UNKNOWN;
3841
3842 if (**arg == '{')
3843 {
3844 // ->{lambda}()
3845 ret = get_lambda_tv(arg, rettv, FALSE, evalarg);
3846 }
3847 else
3848 {
3849 // ->(lambda)()
3850 ++*arg;
3851 ret = eval1(arg, rettv, evalarg);
3852 *arg = skipwhite_and_linebreak(*arg, evalarg);
3853 if (**arg != ')')
3854 {
3855 emsg(_(e_missing_close));
3856 ret = FAIL;
3857 }
3858 ++*arg;
3859 }
3860 if (ret != OK)
3861 return FAIL;
3862 else if (**arg != '(')
3863 {
3864 if (verbose)
3865 {
3866 if (*skipwhite(*arg) == '(')
3867 emsg(_(e_nowhitespace));
3868 else
3869 semsg(_(e_missing_paren), "lambda");
3870 }
3871 clear_tv(rettv);
3872 ret = FAIL;
3873 }
3874 else
3875 ret = call_func_rettv(arg, evalarg, rettv, evaluate, NULL, &base);
3876
3877 // Clear the funcref afterwards, so that deleting it while
3878 // evaluating the arguments is possible (see test55).
3879 if (evaluate)
3880 clear_tv(&base);
3881
3882 return ret;
3883 }
3884
3885 /*
3886 * Evaluate "->method()".
3887 * "*arg" points to "method".
3888 * Returns FAIL or OK. "*arg" is advanced to after the ')'.
3889 */
3890 static int
eval_method(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int verbose)3891 eval_method(
3892 char_u **arg,
3893 typval_T *rettv,
3894 evalarg_T *evalarg,
3895 int verbose) // give error messages
3896 {
3897 char_u *name;
3898 long len;
3899 char_u *alias;
3900 typval_T base = *rettv;
3901 int ret;
3902 int evaluate = evalarg != NULL
3903 && (evalarg->eval_flags & EVAL_EVALUATE);
3904
3905 rettv->v_type = VAR_UNKNOWN;
3906
3907 name = *arg;
3908 len = get_name_len(arg, &alias, evaluate, TRUE);
3909 if (alias != NULL)
3910 name = alias;
3911
3912 if (len <= 0)
3913 {
3914 if (verbose)
3915 emsg(_("E260: Missing name after ->"));
3916 ret = FAIL;
3917 }
3918 else
3919 {
3920 *arg = skipwhite(*arg);
3921 if (**arg != '(')
3922 {
3923 if (verbose)
3924 semsg(_(e_missing_paren), name);
3925 ret = FAIL;
3926 }
3927 else if (VIM_ISWHITE((*arg)[-1]))
3928 {
3929 if (verbose)
3930 emsg(_(e_nowhitespace));
3931 ret = FAIL;
3932 }
3933 else
3934 ret = eval_func(arg, evalarg, name, len, rettv,
3935 evaluate ? EVAL_EVALUATE : 0, &base);
3936 }
3937
3938 // Clear the funcref afterwards, so that deleting it while
3939 // evaluating the arguments is possible (see test55).
3940 if (evaluate)
3941 clear_tv(&base);
3942
3943 return ret;
3944 }
3945
3946 /*
3947 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
3948 * "*arg" points to the '[' or '.'.
3949 * Returns FAIL or OK. "*arg" is advanced to after the ']'.
3950 */
3951 static int
eval_index(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int verbose)3952 eval_index(
3953 char_u **arg,
3954 typval_T *rettv,
3955 evalarg_T *evalarg,
3956 int verbose) // give error messages
3957 {
3958 int evaluate = evalarg != NULL
3959 && (evalarg->eval_flags & EVAL_EVALUATE);
3960 int empty1 = FALSE, empty2 = FALSE;
3961 typval_T var1, var2;
3962 int range = FALSE;
3963 char_u *key = NULL;
3964 int keylen = -1;
3965 int vim9 = in_vim9script();
3966
3967 if (check_can_index(rettv, evaluate, verbose) == FAIL)
3968 return FAIL;
3969
3970 init_tv(&var1);
3971 init_tv(&var2);
3972 if (**arg == '.')
3973 {
3974 /*
3975 * dict.name
3976 */
3977 key = *arg + 1;
3978 for (keylen = 0; eval_isdictc(key[keylen]); ++keylen)
3979 ;
3980 if (keylen == 0)
3981 return FAIL;
3982 *arg = key + keylen;
3983 }
3984 else
3985 {
3986 /*
3987 * something[idx]
3988 *
3989 * Get the (first) variable from inside the [].
3990 */
3991 *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
3992 if (**arg == ':')
3993 empty1 = TRUE;
3994 else if (eval1(arg, &var1, evalarg) == FAIL) // recursive!
3995 return FAIL;
3996 else if (vim9 && **arg == ':')
3997 {
3998 semsg(_(e_white_space_required_before_and_after_str_at_str),
3999 ":", *arg);
4000 clear_tv(&var1);
4001 return FAIL;
4002 }
4003 else if (evaluate)
4004 {
4005 #ifdef FEAT_FLOAT
4006 // allow for indexing with float
4007 if (vim9 && rettv->v_type == VAR_DICT
4008 && var1.v_type == VAR_FLOAT)
4009 {
4010 var1.vval.v_string = typval_tostring(&var1, TRUE);
4011 var1.v_type = VAR_STRING;
4012 }
4013 #endif
4014 if (tv_get_string_chk(&var1) == NULL)
4015 {
4016 // not a number or string
4017 clear_tv(&var1);
4018 return FAIL;
4019 }
4020 }
4021
4022 /*
4023 * Get the second variable from inside the [:].
4024 */
4025 *arg = skipwhite_and_linebreak(*arg, evalarg);
4026 if (**arg == ':')
4027 {
4028 range = TRUE;
4029 ++*arg;
4030 if (vim9 && !IS_WHITE_OR_NUL(**arg) && **arg != ']')
4031 {
4032 semsg(_(e_white_space_required_before_and_after_str_at_str),
4033 ":", *arg - 1);
4034 if (!empty1)
4035 clear_tv(&var1);
4036 return FAIL;
4037 }
4038 *arg = skipwhite_and_linebreak(*arg, evalarg);
4039 if (**arg == ']')
4040 empty2 = TRUE;
4041 else if (eval1(arg, &var2, evalarg) == FAIL) // recursive!
4042 {
4043 if (!empty1)
4044 clear_tv(&var1);
4045 return FAIL;
4046 }
4047 else if (evaluate && tv_get_string_chk(&var2) == NULL)
4048 {
4049 // not a number or string
4050 if (!empty1)
4051 clear_tv(&var1);
4052 clear_tv(&var2);
4053 return FAIL;
4054 }
4055 }
4056
4057 // Check for the ']'.
4058 *arg = skipwhite_and_linebreak(*arg, evalarg);
4059 if (**arg != ']')
4060 {
4061 if (verbose)
4062 emsg(_(e_missbrac));
4063 clear_tv(&var1);
4064 if (range)
4065 clear_tv(&var2);
4066 return FAIL;
4067 }
4068 *arg = *arg + 1; // skip over the ']'
4069 }
4070
4071 if (evaluate)
4072 {
4073 int res = eval_index_inner(rettv, range,
4074 empty1 ? NULL : &var1, empty2 ? NULL : &var2, FALSE,
4075 key, keylen, verbose);
4076
4077 if (!empty1)
4078 clear_tv(&var1);
4079 if (range)
4080 clear_tv(&var2);
4081 return res;
4082 }
4083 return OK;
4084 }
4085
4086 /*
4087 * Check if "rettv" can have an [index] or [sli:ce]
4088 */
4089 int
check_can_index(typval_T * rettv,int evaluate,int verbose)4090 check_can_index(typval_T *rettv, int evaluate, int verbose)
4091 {
4092 switch (rettv->v_type)
4093 {
4094 case VAR_FUNC:
4095 case VAR_PARTIAL:
4096 if (verbose)
4097 emsg(_("E695: Cannot index a Funcref"));
4098 return FAIL;
4099 case VAR_FLOAT:
4100 #ifdef FEAT_FLOAT
4101 if (verbose)
4102 emsg(_(e_float_as_string));
4103 return FAIL;
4104 #endif
4105 case VAR_BOOL:
4106 case VAR_SPECIAL:
4107 case VAR_JOB:
4108 case VAR_CHANNEL:
4109 case VAR_INSTR:
4110 if (verbose)
4111 emsg(_(e_cannot_index_special_variable));
4112 return FAIL;
4113 case VAR_UNKNOWN:
4114 case VAR_ANY:
4115 case VAR_VOID:
4116 if (evaluate)
4117 {
4118 emsg(_(e_cannot_index_special_variable));
4119 return FAIL;
4120 }
4121 // FALLTHROUGH
4122
4123 case VAR_STRING:
4124 case VAR_LIST:
4125 case VAR_DICT:
4126 case VAR_BLOB:
4127 break;
4128 case VAR_NUMBER:
4129 if (in_vim9script())
4130 emsg(_(e_cannot_index_number));
4131 break;
4132 }
4133 return OK;
4134 }
4135
4136 /*
4137 * slice() function
4138 */
4139 void
f_slice(typval_T * argvars,typval_T * rettv)4140 f_slice(typval_T *argvars, typval_T *rettv)
4141 {
4142 if (in_vim9script()
4143 && ((argvars[0].v_type != VAR_STRING
4144 && argvars[0].v_type != VAR_LIST
4145 && argvars[0].v_type != VAR_BLOB
4146 && check_for_list_arg(argvars, 0) == FAIL)
4147 || check_for_number_arg(argvars, 1) == FAIL
4148 || check_for_opt_number_arg(argvars, 2) == FAIL))
4149 return;
4150
4151 if (check_can_index(argvars, TRUE, FALSE) == OK)
4152 {
4153 copy_tv(argvars, rettv);
4154 eval_index_inner(rettv, TRUE, argvars + 1,
4155 argvars[2].v_type == VAR_UNKNOWN ? NULL : argvars + 2,
4156 TRUE, NULL, 0, FALSE);
4157 }
4158 }
4159
4160 /*
4161 * Apply index or range to "rettv".
4162 * "var1" is the first index, NULL for [:expr].
4163 * "var2" is the second index, NULL for [expr] and [expr: ]
4164 * "exclusive" is TRUE for slice(): second index is exclusive, use character
4165 * index for string.
4166 * Alternatively, "key" is not NULL, then key[keylen] is the dict index.
4167 */
4168 int
eval_index_inner(typval_T * rettv,int is_range,typval_T * var1,typval_T * var2,int exclusive,char_u * key,int keylen,int verbose)4169 eval_index_inner(
4170 typval_T *rettv,
4171 int is_range,
4172 typval_T *var1,
4173 typval_T *var2,
4174 int exclusive,
4175 char_u *key,
4176 int keylen,
4177 int verbose)
4178 {
4179 varnumber_T n1, n2 = 0;
4180 long len;
4181
4182 n1 = 0;
4183 if (var1 != NULL && rettv->v_type != VAR_DICT)
4184 n1 = tv_get_number(var1);
4185
4186 if (is_range)
4187 {
4188 if (rettv->v_type == VAR_DICT)
4189 {
4190 if (verbose)
4191 emsg(_(e_cannot_slice_dictionary));
4192 return FAIL;
4193 }
4194 if (var2 != NULL)
4195 n2 = tv_get_number(var2);
4196 else
4197 n2 = VARNUM_MAX;
4198 }
4199
4200 switch (rettv->v_type)
4201 {
4202 case VAR_UNKNOWN:
4203 case VAR_ANY:
4204 case VAR_VOID:
4205 case VAR_FUNC:
4206 case VAR_PARTIAL:
4207 case VAR_FLOAT:
4208 case VAR_BOOL:
4209 case VAR_SPECIAL:
4210 case VAR_JOB:
4211 case VAR_CHANNEL:
4212 case VAR_INSTR:
4213 break; // not evaluating, skipping over subscript
4214
4215 case VAR_NUMBER:
4216 case VAR_STRING:
4217 {
4218 char_u *s = tv_get_string(rettv);
4219
4220 len = (long)STRLEN(s);
4221 if (in_vim9script() || exclusive)
4222 {
4223 if (is_range)
4224 s = string_slice(s, n1, n2, exclusive);
4225 else
4226 s = char_from_string(s, n1);
4227 }
4228 else if (is_range)
4229 {
4230 // The resulting variable is a substring. If the indexes
4231 // are out of range the result is empty.
4232 if (n1 < 0)
4233 {
4234 n1 = len + n1;
4235 if (n1 < 0)
4236 n1 = 0;
4237 }
4238 if (n2 < 0)
4239 n2 = len + n2;
4240 else if (n2 >= len)
4241 n2 = len;
4242 if (n1 >= len || n2 < 0 || n1 > n2)
4243 s = NULL;
4244 else
4245 s = vim_strnsave(s + n1, n2 - n1 + 1);
4246 }
4247 else
4248 {
4249 // The resulting variable is a string of a single
4250 // character. If the index is too big or negative the
4251 // result is empty.
4252 if (n1 >= len || n1 < 0)
4253 s = NULL;
4254 else
4255 s = vim_strnsave(s + n1, 1);
4256 }
4257 clear_tv(rettv);
4258 rettv->v_type = VAR_STRING;
4259 rettv->vval.v_string = s;
4260 }
4261 break;
4262
4263 case VAR_BLOB:
4264 blob_slice_or_index(rettv->vval.v_blob, is_range, n1, n2,
4265 exclusive, rettv);
4266 break;
4267
4268 case VAR_LIST:
4269 if (var1 == NULL)
4270 n1 = 0;
4271 if (var2 == NULL)
4272 n2 = VARNUM_MAX;
4273 if (list_slice_or_index(rettv->vval.v_list,
4274 is_range, n1, n2, exclusive, rettv, verbose) == FAIL)
4275 return FAIL;
4276 break;
4277
4278 case VAR_DICT:
4279 {
4280 dictitem_T *item;
4281 typval_T tmp;
4282
4283 if (key == NULL)
4284 {
4285 key = tv_get_string_chk(var1);
4286 if (key == NULL)
4287 return FAIL;
4288 }
4289
4290 item = dict_find(rettv->vval.v_dict, key, keylen);
4291
4292 if (item == NULL)
4293 {
4294 if (verbose)
4295 {
4296 if (keylen > 0)
4297 key[keylen] = NUL;
4298 semsg(_(e_dictkey), key);
4299 }
4300 return FAIL;
4301 }
4302
4303 copy_tv(&item->di_tv, &tmp);
4304 clear_tv(rettv);
4305 *rettv = tmp;
4306 }
4307 break;
4308 }
4309 return OK;
4310 }
4311
4312 /*
4313 * Return the function name of partial "pt".
4314 */
4315 char_u *
partial_name(partial_T * pt)4316 partial_name(partial_T *pt)
4317 {
4318 if (pt != NULL)
4319 {
4320 if (pt->pt_name != NULL)
4321 return pt->pt_name;
4322 if (pt->pt_func != NULL)
4323 return pt->pt_func->uf_name;
4324 }
4325 return (char_u *)"";
4326 }
4327
4328 static void
partial_free(partial_T * pt)4329 partial_free(partial_T *pt)
4330 {
4331 int i;
4332
4333 for (i = 0; i < pt->pt_argc; ++i)
4334 clear_tv(&pt->pt_argv[i]);
4335 vim_free(pt->pt_argv);
4336 dict_unref(pt->pt_dict);
4337 if (pt->pt_name != NULL)
4338 {
4339 func_unref(pt->pt_name);
4340 vim_free(pt->pt_name);
4341 }
4342 else
4343 func_ptr_unref(pt->pt_func);
4344
4345 // "out_up" is no longer used, decrement refcount on partial that owns it.
4346 partial_unref(pt->pt_outer.out_up_partial);
4347
4348 // Decrease the reference count for the context of a closure. If down
4349 // to the minimum it may be time to free it.
4350 if (pt->pt_funcstack != NULL)
4351 {
4352 --pt->pt_funcstack->fs_refcount;
4353 funcstack_check_refcount(pt->pt_funcstack);
4354 }
4355
4356 vim_free(pt);
4357 }
4358
4359 /*
4360 * Unreference a closure: decrement the reference count and free it when it
4361 * becomes zero.
4362 */
4363 void
partial_unref(partial_T * pt)4364 partial_unref(partial_T *pt)
4365 {
4366 if (pt != NULL)
4367 {
4368 if (--pt->pt_refcount <= 0)
4369 partial_free(pt);
4370
4371 // If the reference count goes down to one, the funcstack may be the
4372 // only reference and can be freed if no other partials reference it.
4373 else if (pt->pt_refcount == 1 && pt->pt_funcstack != NULL)
4374 funcstack_check_refcount(pt->pt_funcstack);
4375 }
4376 }
4377
4378 /*
4379 * Return the next (unique) copy ID.
4380 * Used for serializing nested structures.
4381 */
4382 int
get_copyID(void)4383 get_copyID(void)
4384 {
4385 current_copyID += COPYID_INC;
4386 return current_copyID;
4387 }
4388
4389 /*
4390 * Garbage collection for lists and dictionaries.
4391 *
4392 * We use reference counts to be able to free most items right away when they
4393 * are no longer used. But for composite items it's possible that it becomes
4394 * unused while the reference count is > 0: When there is a recursive
4395 * reference. Example:
4396 * :let l = [1, 2, 3]
4397 * :let d = {9: l}
4398 * :let l[1] = d
4399 *
4400 * Since this is quite unusual we handle this with garbage collection: every
4401 * once in a while find out which lists and dicts are not referenced from any
4402 * variable.
4403 *
4404 * Here is a good reference text about garbage collection (refers to Python
4405 * but it applies to all reference-counting mechanisms):
4406 * http://python.ca/nas/python/gc/
4407 */
4408
4409 /*
4410 * Do garbage collection for lists and dicts.
4411 * When "testing" is TRUE this is called from test_garbagecollect_now().
4412 * Return TRUE if some memory was freed.
4413 */
4414 int
garbage_collect(int testing)4415 garbage_collect(int testing)
4416 {
4417 int copyID;
4418 int abort = FALSE;
4419 buf_T *buf;
4420 win_T *wp;
4421 int did_free = FALSE;
4422 tabpage_T *tp;
4423
4424 if (!testing)
4425 {
4426 // Only do this once.
4427 want_garbage_collect = FALSE;
4428 may_garbage_collect = FALSE;
4429 garbage_collect_at_exit = FALSE;
4430 }
4431
4432 // The execution stack can grow big, limit the size.
4433 if (exestack.ga_maxlen - exestack.ga_len > 500)
4434 {
4435 size_t new_len;
4436 char_u *pp;
4437 int n;
4438
4439 // Keep 150% of the current size, with a minimum of the growth size.
4440 n = exestack.ga_len / 2;
4441 if (n < exestack.ga_growsize)
4442 n = exestack.ga_growsize;
4443
4444 // Don't make it bigger though.
4445 if (exestack.ga_len + n < exestack.ga_maxlen)
4446 {
4447 new_len = exestack.ga_itemsize * (exestack.ga_len + n);
4448 pp = vim_realloc(exestack.ga_data, new_len);
4449 if (pp == NULL)
4450 return FAIL;
4451 exestack.ga_maxlen = exestack.ga_len + n;
4452 exestack.ga_data = pp;
4453 }
4454 }
4455
4456 // We advance by two because we add one for items referenced through
4457 // previous_funccal.
4458 copyID = get_copyID();
4459
4460 /*
4461 * 1. Go through all accessible variables and mark all lists and dicts
4462 * with copyID.
4463 */
4464
4465 // Don't free variables in the previous_funccal list unless they are only
4466 // referenced through previous_funccal. This must be first, because if
4467 // the item is referenced elsewhere the funccal must not be freed.
4468 abort = abort || set_ref_in_previous_funccal(copyID);
4469
4470 // script-local variables
4471 abort = abort || garbage_collect_scriptvars(copyID);
4472
4473 // buffer-local variables
4474 FOR_ALL_BUFFERS(buf)
4475 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
4476 NULL, NULL);
4477
4478 // window-local variables
4479 FOR_ALL_TAB_WINDOWS(tp, wp)
4480 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
4481 NULL, NULL);
4482 if (aucmd_win != NULL)
4483 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID,
4484 NULL, NULL);
4485 #ifdef FEAT_PROP_POPUP
4486 FOR_ALL_POPUPWINS(wp)
4487 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
4488 NULL, NULL);
4489 FOR_ALL_TABPAGES(tp)
4490 FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
4491 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
4492 NULL, NULL);
4493 #endif
4494
4495 // tabpage-local variables
4496 FOR_ALL_TABPAGES(tp)
4497 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
4498 NULL, NULL);
4499 // global variables
4500 abort = abort || garbage_collect_globvars(copyID);
4501
4502 // function-local variables
4503 abort = abort || set_ref_in_call_stack(copyID);
4504
4505 // named functions (matters for closures)
4506 abort = abort || set_ref_in_functions(copyID);
4507
4508 // function call arguments, if v:testing is set.
4509 abort = abort || set_ref_in_func_args(copyID);
4510
4511 // v: vars
4512 abort = abort || garbage_collect_vimvars(copyID);
4513
4514 // callbacks in buffers
4515 abort = abort || set_ref_in_buffers(copyID);
4516
4517 #ifdef FEAT_LUA
4518 abort = abort || set_ref_in_lua(copyID);
4519 #endif
4520
4521 #ifdef FEAT_PYTHON
4522 abort = abort || set_ref_in_python(copyID);
4523 #endif
4524
4525 #ifdef FEAT_PYTHON3
4526 abort = abort || set_ref_in_python3(copyID);
4527 #endif
4528
4529 #ifdef FEAT_JOB_CHANNEL
4530 abort = abort || set_ref_in_channel(copyID);
4531 abort = abort || set_ref_in_job(copyID);
4532 #endif
4533 #ifdef FEAT_NETBEANS_INTG
4534 abort = abort || set_ref_in_nb_channel(copyID);
4535 #endif
4536
4537 #ifdef FEAT_TIMERS
4538 abort = abort || set_ref_in_timer(copyID);
4539 #endif
4540
4541 #ifdef FEAT_QUICKFIX
4542 abort = abort || set_ref_in_quickfix(copyID);
4543 #endif
4544
4545 #ifdef FEAT_TERMINAL
4546 abort = abort || set_ref_in_term(copyID);
4547 #endif
4548
4549 #ifdef FEAT_PROP_POPUP
4550 abort = abort || set_ref_in_popups(copyID);
4551 #endif
4552
4553 if (!abort)
4554 {
4555 /*
4556 * 2. Free lists and dictionaries that are not referenced.
4557 */
4558 did_free = free_unref_items(copyID);
4559
4560 /*
4561 * 3. Check if any funccal can be freed now.
4562 * This may call us back recursively.
4563 */
4564 free_unref_funccal(copyID, testing);
4565 }
4566 else if (p_verbose > 0)
4567 {
4568 verb_msg(_("Not enough memory to set references, garbage collection aborted!"));
4569 }
4570
4571 return did_free;
4572 }
4573
4574 /*
4575 * Free lists, dictionaries, channels and jobs that are no longer referenced.
4576 */
4577 static int
free_unref_items(int copyID)4578 free_unref_items(int copyID)
4579 {
4580 int did_free = FALSE;
4581
4582 // Let all "free" functions know that we are here. This means no
4583 // dictionaries, lists, channels or jobs are to be freed, because we will
4584 // do that here.
4585 in_free_unref_items = TRUE;
4586
4587 /*
4588 * PASS 1: free the contents of the items. We don't free the items
4589 * themselves yet, so that it is possible to decrement refcount counters
4590 */
4591
4592 // Go through the list of dicts and free items without the copyID.
4593 did_free |= dict_free_nonref(copyID);
4594
4595 // Go through the list of lists and free items without the copyID.
4596 did_free |= list_free_nonref(copyID);
4597
4598 #ifdef FEAT_JOB_CHANNEL
4599 // Go through the list of jobs and free items without the copyID. This
4600 // must happen before doing channels, because jobs refer to channels, but
4601 // the reference from the channel to the job isn't tracked.
4602 did_free |= free_unused_jobs_contents(copyID, COPYID_MASK);
4603
4604 // Go through the list of channels and free items without the copyID.
4605 did_free |= free_unused_channels_contents(copyID, COPYID_MASK);
4606 #endif
4607
4608 /*
4609 * PASS 2: free the items themselves.
4610 */
4611 dict_free_items(copyID);
4612 list_free_items(copyID);
4613
4614 #ifdef FEAT_JOB_CHANNEL
4615 // Go through the list of jobs and free items without the copyID. This
4616 // must happen before doing channels, because jobs refer to channels, but
4617 // the reference from the channel to the job isn't tracked.
4618 free_unused_jobs(copyID, COPYID_MASK);
4619
4620 // Go through the list of channels and free items without the copyID.
4621 free_unused_channels(copyID, COPYID_MASK);
4622 #endif
4623
4624 in_free_unref_items = FALSE;
4625
4626 return did_free;
4627 }
4628
4629 /*
4630 * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
4631 * "list_stack" is used to add lists to be marked. Can be NULL.
4632 *
4633 * Returns TRUE if setting references failed somehow.
4634 */
4635 int
set_ref_in_ht(hashtab_T * ht,int copyID,list_stack_T ** list_stack)4636 set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
4637 {
4638 int todo;
4639 int abort = FALSE;
4640 hashitem_T *hi;
4641 hashtab_T *cur_ht;
4642 ht_stack_T *ht_stack = NULL;
4643 ht_stack_T *tempitem;
4644
4645 cur_ht = ht;
4646 for (;;)
4647 {
4648 if (!abort)
4649 {
4650 // Mark each item in the hashtab. If the item contains a hashtab
4651 // it is added to ht_stack, if it contains a list it is added to
4652 // list_stack.
4653 todo = (int)cur_ht->ht_used;
4654 for (hi = cur_ht->ht_array; todo > 0; ++hi)
4655 if (!HASHITEM_EMPTY(hi))
4656 {
4657 --todo;
4658 abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
4659 &ht_stack, list_stack);
4660 }
4661 }
4662
4663 if (ht_stack == NULL)
4664 break;
4665
4666 // take an item from the stack
4667 cur_ht = ht_stack->ht;
4668 tempitem = ht_stack;
4669 ht_stack = ht_stack->prev;
4670 free(tempitem);
4671 }
4672
4673 return abort;
4674 }
4675
4676 /*
4677 * Mark a dict and its items with "copyID".
4678 * Returns TRUE if setting references failed somehow.
4679 */
4680 int
set_ref_in_dict(dict_T * d,int copyID)4681 set_ref_in_dict(dict_T *d, int copyID)
4682 {
4683 if (d != NULL && d->dv_copyID != copyID)
4684 {
4685 d->dv_copyID = copyID;
4686 return set_ref_in_ht(&d->dv_hashtab, copyID, NULL);
4687 }
4688 return FALSE;
4689 }
4690
4691 /*
4692 * Mark a list and its items with "copyID".
4693 * Returns TRUE if setting references failed somehow.
4694 */
4695 int
set_ref_in_list(list_T * ll,int copyID)4696 set_ref_in_list(list_T *ll, int copyID)
4697 {
4698 if (ll != NULL && ll->lv_copyID != copyID)
4699 {
4700 ll->lv_copyID = copyID;
4701 return set_ref_in_list_items(ll, copyID, NULL);
4702 }
4703 return FALSE;
4704 }
4705
4706 /*
4707 * Mark all lists and dicts referenced through list "l" with "copyID".
4708 * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
4709 *
4710 * Returns TRUE if setting references failed somehow.
4711 */
4712 int
set_ref_in_list_items(list_T * l,int copyID,ht_stack_T ** ht_stack)4713 set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack)
4714 {
4715 listitem_T *li;
4716 int abort = FALSE;
4717 list_T *cur_l;
4718 list_stack_T *list_stack = NULL;
4719 list_stack_T *tempitem;
4720
4721 cur_l = l;
4722 for (;;)
4723 {
4724 if (!abort && cur_l->lv_first != &range_list_item)
4725 // Mark each item in the list. If the item contains a hashtab
4726 // it is added to ht_stack, if it contains a list it is added to
4727 // list_stack.
4728 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
4729 abort = abort || set_ref_in_item(&li->li_tv, copyID,
4730 ht_stack, &list_stack);
4731 if (list_stack == NULL)
4732 break;
4733
4734 // take an item from the stack
4735 cur_l = list_stack->list;
4736 tempitem = list_stack;
4737 list_stack = list_stack->prev;
4738 free(tempitem);
4739 }
4740
4741 return abort;
4742 }
4743
4744 /*
4745 * Mark all lists and dicts referenced through typval "tv" with "copyID".
4746 * "list_stack" is used to add lists to be marked. Can be NULL.
4747 * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
4748 *
4749 * Returns TRUE if setting references failed somehow.
4750 */
4751 int
set_ref_in_item(typval_T * tv,int copyID,ht_stack_T ** ht_stack,list_stack_T ** list_stack)4752 set_ref_in_item(
4753 typval_T *tv,
4754 int copyID,
4755 ht_stack_T **ht_stack,
4756 list_stack_T **list_stack)
4757 {
4758 int abort = FALSE;
4759
4760 if (tv->v_type == VAR_DICT)
4761 {
4762 dict_T *dd = tv->vval.v_dict;
4763
4764 if (dd != NULL && dd->dv_copyID != copyID)
4765 {
4766 // Didn't see this dict yet.
4767 dd->dv_copyID = copyID;
4768 if (ht_stack == NULL)
4769 {
4770 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
4771 }
4772 else
4773 {
4774 ht_stack_T *newitem = ALLOC_ONE(ht_stack_T);
4775
4776 if (newitem == NULL)
4777 abort = TRUE;
4778 else
4779 {
4780 newitem->ht = &dd->dv_hashtab;
4781 newitem->prev = *ht_stack;
4782 *ht_stack = newitem;
4783 }
4784 }
4785 }
4786 }
4787 else if (tv->v_type == VAR_LIST)
4788 {
4789 list_T *ll = tv->vval.v_list;
4790
4791 if (ll != NULL && ll->lv_copyID != copyID)
4792 {
4793 // Didn't see this list yet.
4794 ll->lv_copyID = copyID;
4795 if (list_stack == NULL)
4796 {
4797 abort = set_ref_in_list_items(ll, copyID, ht_stack);
4798 }
4799 else
4800 {
4801 list_stack_T *newitem = ALLOC_ONE(list_stack_T);
4802
4803 if (newitem == NULL)
4804 abort = TRUE;
4805 else
4806 {
4807 newitem->list = ll;
4808 newitem->prev = *list_stack;
4809 *list_stack = newitem;
4810 }
4811 }
4812 }
4813 }
4814 else if (tv->v_type == VAR_FUNC)
4815 {
4816 abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
4817 }
4818 else if (tv->v_type == VAR_PARTIAL)
4819 {
4820 partial_T *pt = tv->vval.v_partial;
4821 int i;
4822
4823 if (pt != NULL && pt->pt_copyID != copyID)
4824 {
4825 // Didn't see this partial yet.
4826 pt->pt_copyID = copyID;
4827
4828 abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
4829
4830 if (pt->pt_dict != NULL)
4831 {
4832 typval_T dtv;
4833
4834 dtv.v_type = VAR_DICT;
4835 dtv.vval.v_dict = pt->pt_dict;
4836 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4837 }
4838
4839 for (i = 0; i < pt->pt_argc; ++i)
4840 abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
4841 ht_stack, list_stack);
4842 if (pt->pt_funcstack != NULL)
4843 {
4844 typval_T *stack = pt->pt_funcstack->fs_ga.ga_data;
4845
4846 for (i = 0; i < pt->pt_funcstack->fs_ga.ga_len; ++i)
4847 abort = abort || set_ref_in_item(stack + i, copyID,
4848 ht_stack, list_stack);
4849 }
4850
4851 }
4852 }
4853 #ifdef FEAT_JOB_CHANNEL
4854 else if (tv->v_type == VAR_JOB)
4855 {
4856 job_T *job = tv->vval.v_job;
4857 typval_T dtv;
4858
4859 if (job != NULL && job->jv_copyID != copyID)
4860 {
4861 job->jv_copyID = copyID;
4862 if (job->jv_channel != NULL)
4863 {
4864 dtv.v_type = VAR_CHANNEL;
4865 dtv.vval.v_channel = job->jv_channel;
4866 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4867 }
4868 if (job->jv_exit_cb.cb_partial != NULL)
4869 {
4870 dtv.v_type = VAR_PARTIAL;
4871 dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
4872 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4873 }
4874 }
4875 }
4876 else if (tv->v_type == VAR_CHANNEL)
4877 {
4878 channel_T *ch =tv->vval.v_channel;
4879 ch_part_T part;
4880 typval_T dtv;
4881 jsonq_T *jq;
4882 cbq_T *cq;
4883
4884 if (ch != NULL && ch->ch_copyID != copyID)
4885 {
4886 ch->ch_copyID = copyID;
4887 for (part = PART_SOCK; part < PART_COUNT; ++part)
4888 {
4889 for (jq = ch->ch_part[part].ch_json_head.jq_next; jq != NULL;
4890 jq = jq->jq_next)
4891 set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack);
4892 for (cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
4893 cq = cq->cq_next)
4894 if (cq->cq_callback.cb_partial != NULL)
4895 {
4896 dtv.v_type = VAR_PARTIAL;
4897 dtv.vval.v_partial = cq->cq_callback.cb_partial;
4898 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4899 }
4900 if (ch->ch_part[part].ch_callback.cb_partial != NULL)
4901 {
4902 dtv.v_type = VAR_PARTIAL;
4903 dtv.vval.v_partial =
4904 ch->ch_part[part].ch_callback.cb_partial;
4905 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4906 }
4907 }
4908 if (ch->ch_callback.cb_partial != NULL)
4909 {
4910 dtv.v_type = VAR_PARTIAL;
4911 dtv.vval.v_partial = ch->ch_callback.cb_partial;
4912 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4913 }
4914 if (ch->ch_close_cb.cb_partial != NULL)
4915 {
4916 dtv.v_type = VAR_PARTIAL;
4917 dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
4918 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
4919 }
4920 }
4921 }
4922 #endif
4923 return abort;
4924 }
4925
4926 /*
4927 * Return a string with the string representation of a variable.
4928 * If the memory is allocated "tofree" is set to it, otherwise NULL.
4929 * "numbuf" is used for a number.
4930 * When "copyID" is not NULL replace recursive lists and dicts with "...".
4931 * When both "echo_style" and "composite_val" are FALSE, put quotes around
4932 * strings as "string()", otherwise does not put quotes around strings, as
4933 * ":echo" displays values.
4934 * When "restore_copyID" is FALSE, repeated items in dictionaries and lists
4935 * are replaced with "...".
4936 * May return NULL.
4937 */
4938 char_u *
echo_string_core(typval_T * tv,char_u ** tofree,char_u * numbuf,int copyID,int echo_style,int restore_copyID,int composite_val)4939 echo_string_core(
4940 typval_T *tv,
4941 char_u **tofree,
4942 char_u *numbuf,
4943 int copyID,
4944 int echo_style,
4945 int restore_copyID,
4946 int composite_val)
4947 {
4948 static int recurse = 0;
4949 char_u *r = NULL;
4950
4951 if (recurse >= DICT_MAXNEST)
4952 {
4953 if (!did_echo_string_emsg)
4954 {
4955 // Only give this message once for a recursive call to avoid
4956 // flooding the user with errors. And stop iterating over lists
4957 // and dicts.
4958 did_echo_string_emsg = TRUE;
4959 emsg(_("E724: variable nested too deep for displaying"));
4960 }
4961 *tofree = NULL;
4962 return (char_u *)"{E724}";
4963 }
4964 ++recurse;
4965
4966 switch (tv->v_type)
4967 {
4968 case VAR_STRING:
4969 if (echo_style && !composite_val)
4970 {
4971 *tofree = NULL;
4972 r = tv->vval.v_string;
4973 if (r == NULL)
4974 r = (char_u *)"";
4975 }
4976 else
4977 {
4978 *tofree = string_quote(tv->vval.v_string, FALSE);
4979 r = *tofree;
4980 }
4981 break;
4982
4983 case VAR_FUNC:
4984 if (echo_style)
4985 {
4986 *tofree = NULL;
4987 r = tv->vval.v_string;
4988 }
4989 else
4990 {
4991 *tofree = string_quote(tv->vval.v_string, TRUE);
4992 r = *tofree;
4993 }
4994 break;
4995
4996 case VAR_PARTIAL:
4997 {
4998 partial_T *pt = tv->vval.v_partial;
4999 char_u *fname = string_quote(pt == NULL ? NULL
5000 : partial_name(pt), FALSE);
5001 garray_T ga;
5002 int i;
5003 char_u *tf;
5004
5005 ga_init2(&ga, 1, 100);
5006 ga_concat(&ga, (char_u *)"function(");
5007 if (fname != NULL)
5008 {
5009 ga_concat(&ga, fname);
5010 vim_free(fname);
5011 }
5012 if (pt != NULL && pt->pt_argc > 0)
5013 {
5014 ga_concat(&ga, (char_u *)", [");
5015 for (i = 0; i < pt->pt_argc; ++i)
5016 {
5017 if (i > 0)
5018 ga_concat(&ga, (char_u *)", ");
5019 ga_concat(&ga,
5020 tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
5021 vim_free(tf);
5022 }
5023 ga_concat(&ga, (char_u *)"]");
5024 }
5025 if (pt != NULL && pt->pt_dict != NULL)
5026 {
5027 typval_T dtv;
5028
5029 ga_concat(&ga, (char_u *)", ");
5030 dtv.v_type = VAR_DICT;
5031 dtv.vval.v_dict = pt->pt_dict;
5032 ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
5033 vim_free(tf);
5034 }
5035 ga_concat(&ga, (char_u *)")");
5036
5037 *tofree = ga.ga_data;
5038 r = *tofree;
5039 break;
5040 }
5041
5042 case VAR_BLOB:
5043 r = blob2string(tv->vval.v_blob, tofree, numbuf);
5044 break;
5045
5046 case VAR_LIST:
5047 if (tv->vval.v_list == NULL)
5048 {
5049 // NULL list is equivalent to empty list.
5050 *tofree = NULL;
5051 r = (char_u *)"[]";
5052 }
5053 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
5054 && tv->vval.v_list->lv_len > 0)
5055 {
5056 *tofree = NULL;
5057 r = (char_u *)"[...]";
5058 }
5059 else
5060 {
5061 int old_copyID = tv->vval.v_list->lv_copyID;
5062
5063 tv->vval.v_list->lv_copyID = copyID;
5064 *tofree = list2string(tv, copyID, restore_copyID);
5065 if (restore_copyID)
5066 tv->vval.v_list->lv_copyID = old_copyID;
5067 r = *tofree;
5068 }
5069 break;
5070
5071 case VAR_DICT:
5072 if (tv->vval.v_dict == NULL)
5073 {
5074 // NULL dict is equivalent to empty dict.
5075 *tofree = NULL;
5076 r = (char_u *)"{}";
5077 }
5078 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
5079 && tv->vval.v_dict->dv_hashtab.ht_used != 0)
5080 {
5081 *tofree = NULL;
5082 r = (char_u *)"{...}";
5083 }
5084 else
5085 {
5086 int old_copyID = tv->vval.v_dict->dv_copyID;
5087
5088 tv->vval.v_dict->dv_copyID = copyID;
5089 *tofree = dict2string(tv, copyID, restore_copyID);
5090 if (restore_copyID)
5091 tv->vval.v_dict->dv_copyID = old_copyID;
5092 r = *tofree;
5093 }
5094 break;
5095
5096 case VAR_NUMBER:
5097 case VAR_UNKNOWN:
5098 case VAR_ANY:
5099 case VAR_VOID:
5100 *tofree = NULL;
5101 r = tv_get_string_buf(tv, numbuf);
5102 break;
5103
5104 case VAR_JOB:
5105 case VAR_CHANNEL:
5106 #ifdef FEAT_JOB_CHANNEL
5107 *tofree = NULL;
5108 r = tv->v_type == VAR_JOB ? job_to_string_buf(tv, numbuf)
5109 : channel_to_string_buf(tv, numbuf);
5110 if (composite_val)
5111 {
5112 *tofree = string_quote(r, FALSE);
5113 r = *tofree;
5114 }
5115 #endif
5116 break;
5117
5118 case VAR_INSTR:
5119 *tofree = NULL;
5120 r = (char_u *)"instructions";
5121 break;
5122
5123 case VAR_FLOAT:
5124 #ifdef FEAT_FLOAT
5125 *tofree = NULL;
5126 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
5127 r = numbuf;
5128 break;
5129 #endif
5130
5131 case VAR_BOOL:
5132 case VAR_SPECIAL:
5133 *tofree = NULL;
5134 r = (char_u *)get_var_special_name(tv->vval.v_number);
5135 break;
5136 }
5137
5138 if (--recurse == 0)
5139 did_echo_string_emsg = FALSE;
5140 return r;
5141 }
5142
5143 /*
5144 * Return a string with the string representation of a variable.
5145 * If the memory is allocated "tofree" is set to it, otherwise NULL.
5146 * "numbuf" is used for a number.
5147 * Does not put quotes around strings, as ":echo" displays values.
5148 * When "copyID" is not NULL replace recursive lists and dicts with "...".
5149 * May return NULL.
5150 */
5151 char_u *
echo_string(typval_T * tv,char_u ** tofree,char_u * numbuf,int copyID)5152 echo_string(
5153 typval_T *tv,
5154 char_u **tofree,
5155 char_u *numbuf,
5156 int copyID)
5157 {
5158 return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE);
5159 }
5160
5161 /*
5162 * Convert the specified byte index of line 'lnum' in buffer 'buf' to a
5163 * character index. Works only for loaded buffers. Returns -1 on failure.
5164 * The index of the first byte and the first character is zero.
5165 */
5166 int
buf_byteidx_to_charidx(buf_T * buf,int lnum,int byteidx)5167 buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx)
5168 {
5169 char_u *str;
5170 char_u *t;
5171 int count;
5172
5173 if (buf == NULL || buf->b_ml.ml_mfp == NULL)
5174 return -1;
5175
5176 if (lnum > buf->b_ml.ml_line_count)
5177 lnum = buf->b_ml.ml_line_count;
5178
5179 str = ml_get_buf(buf, lnum, FALSE);
5180 if (str == NULL)
5181 return -1;
5182
5183 if (*str == NUL)
5184 return 0;
5185
5186 // count the number of characters
5187 t = str;
5188 for (count = 0; *t != NUL && t <= str + byteidx; count++)
5189 t += mb_ptr2len(t);
5190
5191 // In insert mode, when the cursor is at the end of a non-empty line,
5192 // byteidx points to the NUL character immediately past the end of the
5193 // string. In this case, add one to the character count.
5194 if (*t == NUL && byteidx != 0 && t == str + byteidx)
5195 count++;
5196
5197 return count - 1;
5198 }
5199
5200 /*
5201 * Convert the specified character index of line 'lnum' in buffer 'buf' to a
5202 * byte index. Works only for loaded buffers. Returns -1 on failure.
5203 * The index of the first byte and the first character is zero.
5204 */
5205 int
buf_charidx_to_byteidx(buf_T * buf,int lnum,int charidx)5206 buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx)
5207 {
5208 char_u *str;
5209 char_u *t;
5210
5211 if (buf == NULL || buf->b_ml.ml_mfp == NULL)
5212 return -1;
5213
5214 if (lnum > buf->b_ml.ml_line_count)
5215 lnum = buf->b_ml.ml_line_count;
5216
5217 str = ml_get_buf(buf, lnum, FALSE);
5218 if (str == NULL)
5219 return -1;
5220
5221 // Convert the character offset to a byte offset
5222 t = str;
5223 while (*t != NUL && --charidx > 0)
5224 t += mb_ptr2len(t);
5225
5226 return t - str;
5227 }
5228
5229 /*
5230 * Translate a String variable into a position.
5231 * Returns NULL when there is an error.
5232 */
5233 pos_T *
var2fpos(typval_T * varp,int dollar_lnum,int * fnum,int charcol)5234 var2fpos(
5235 typval_T *varp,
5236 int dollar_lnum, // TRUE when $ is last line
5237 int *fnum, // set to fnum for '0, 'A, etc.
5238 int charcol) // return character column
5239 {
5240 char_u *name;
5241 static pos_T pos;
5242 pos_T *pp;
5243
5244 // Argument can be [lnum, col, coladd].
5245 if (varp->v_type == VAR_LIST)
5246 {
5247 list_T *l;
5248 int len;
5249 int error = FALSE;
5250 listitem_T *li;
5251
5252 l = varp->vval.v_list;
5253 if (l == NULL)
5254 return NULL;
5255
5256 // Get the line number
5257 pos.lnum = list_find_nr(l, 0L, &error);
5258 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
5259 return NULL; // invalid line number
5260 if (charcol)
5261 len = (long)mb_charlen(ml_get(pos.lnum));
5262 else
5263 len = (long)STRLEN(ml_get(pos.lnum));
5264
5265 // Get the column number
5266 // We accept "$" for the column number: last column.
5267 li = list_find(l, 1L);
5268 if (li != NULL && li->li_tv.v_type == VAR_STRING
5269 && li->li_tv.vval.v_string != NULL
5270 && STRCMP(li->li_tv.vval.v_string, "$") == 0)
5271 {
5272 pos.col = len + 1;
5273 }
5274 else
5275 {
5276 pos.col = list_find_nr(l, 1L, &error);
5277 if (error)
5278 return NULL;
5279 }
5280
5281 // Accept a position up to the NUL after the line.
5282 if (pos.col == 0 || (int)pos.col > len + 1)
5283 return NULL; // invalid column number
5284 --pos.col;
5285
5286 // Get the virtual offset. Defaults to zero.
5287 pos.coladd = list_find_nr(l, 2L, &error);
5288 if (error)
5289 pos.coladd = 0;
5290
5291 return &pos;
5292 }
5293
5294 if (in_vim9script() && check_for_string_arg(varp, 0) == FAIL)
5295 return NULL;
5296
5297 name = tv_get_string_chk(varp);
5298 if (name == NULL)
5299 return NULL;
5300 if (name[0] == '.') // cursor
5301 {
5302 pos = curwin->w_cursor;
5303 if (charcol)
5304 pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col);
5305 return &pos;
5306 }
5307 if (name[0] == 'v' && name[1] == NUL) // Visual start
5308 {
5309 if (VIsual_active)
5310 pos = VIsual;
5311 else
5312 pos = curwin->w_cursor;
5313 if (charcol)
5314 pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col);
5315 return &pos;
5316 }
5317 if (name[0] == '\'') // mark
5318 {
5319 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
5320 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
5321 return NULL;
5322 if (charcol)
5323 pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col);
5324 return pp;
5325 }
5326
5327 pos.coladd = 0;
5328
5329 if (name[0] == 'w' && dollar_lnum)
5330 {
5331 pos.col = 0;
5332 if (name[1] == '0') // "w0": first visible line
5333 {
5334 update_topline();
5335 // In silent Ex mode topline is zero, but that's not a valid line
5336 // number; use one instead.
5337 pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1;
5338 return &pos;
5339 }
5340 else if (name[1] == '$') // "w$": last visible line
5341 {
5342 validate_botline();
5343 // In silent Ex mode botline is zero, return zero then.
5344 pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0;
5345 return &pos;
5346 }
5347 }
5348 else if (name[0] == '$') // last column or line
5349 {
5350 if (dollar_lnum)
5351 {
5352 pos.lnum = curbuf->b_ml.ml_line_count;
5353 pos.col = 0;
5354 }
5355 else
5356 {
5357 pos.lnum = curwin->w_cursor.lnum;
5358 if (charcol)
5359 pos.col = (colnr_T)mb_charlen(ml_get_curline());
5360 else
5361 pos.col = (colnr_T)STRLEN(ml_get_curline());
5362 }
5363 return &pos;
5364 }
5365 if (in_vim9script())
5366 semsg(_(e_invalid_value_for_line_number_str), name);
5367 return NULL;
5368 }
5369
5370 /*
5371 * Convert list in "arg" into a position and optional file number.
5372 * When "fnump" is NULL there is no file number, only 3 items.
5373 * Note that the column is passed on as-is, the caller may want to decrement
5374 * it to use 1 for the first column.
5375 * Return FAIL when conversion is not possible, doesn't check the position for
5376 * validity.
5377 */
5378 int
list2fpos(typval_T * arg,pos_T * posp,int * fnump,colnr_T * curswantp,int charcol)5379 list2fpos(
5380 typval_T *arg,
5381 pos_T *posp,
5382 int *fnump,
5383 colnr_T *curswantp,
5384 int charcol)
5385 {
5386 list_T *l = arg->vval.v_list;
5387 long i = 0;
5388 long n;
5389
5390 // List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
5391 // there when "fnump" isn't NULL; "coladd" and "curswant" are optional.
5392 if (arg->v_type != VAR_LIST
5393 || l == NULL
5394 || l->lv_len < (fnump == NULL ? 2 : 3)
5395 || l->lv_len > (fnump == NULL ? 4 : 5))
5396 return FAIL;
5397
5398 if (fnump != NULL)
5399 {
5400 n = list_find_nr(l, i++, NULL); // fnum
5401 if (n < 0)
5402 return FAIL;
5403 if (n == 0)
5404 n = curbuf->b_fnum; // current buffer
5405 *fnump = n;
5406 }
5407
5408 n = list_find_nr(l, i++, NULL); // lnum
5409 if (n < 0)
5410 return FAIL;
5411 posp->lnum = n;
5412
5413 n = list_find_nr(l, i++, NULL); // col
5414 if (n < 0)
5415 return FAIL;
5416 // If character position is specified, then convert to byte position
5417 if (charcol)
5418 {
5419 buf_T *buf;
5420
5421 // Get the text for the specified line in a loaded buffer
5422 buf = buflist_findnr(fnump == NULL ? curbuf->b_fnum : *fnump);
5423 if (buf == NULL || buf->b_ml.ml_mfp == NULL)
5424 return FAIL;
5425
5426 n = buf_charidx_to_byteidx(buf, posp->lnum, n) + 1;
5427 }
5428 posp->col = n;
5429
5430 n = list_find_nr(l, i, NULL); // off
5431 if (n < 0)
5432 posp->coladd = 0;
5433 else
5434 posp->coladd = n;
5435
5436 if (curswantp != NULL)
5437 *curswantp = list_find_nr(l, i + 1, NULL); // curswant
5438
5439 return OK;
5440 }
5441
5442 /*
5443 * Get the length of an environment variable name.
5444 * Advance "arg" to the first character after the name.
5445 * Return 0 for error.
5446 */
5447 int
get_env_len(char_u ** arg)5448 get_env_len(char_u **arg)
5449 {
5450 char_u *p;
5451 int len;
5452
5453 for (p = *arg; vim_isIDc(*p); ++p)
5454 ;
5455 if (p == *arg) // no name found
5456 return 0;
5457
5458 len = (int)(p - *arg);
5459 *arg = p;
5460 return len;
5461 }
5462
5463 /*
5464 * Get the length of the name of a function or internal variable.
5465 * "arg" is advanced to after the name.
5466 * Return 0 if something is wrong.
5467 */
5468 int
get_id_len(char_u ** arg)5469 get_id_len(char_u **arg)
5470 {
5471 char_u *p;
5472 int len;
5473
5474 // Find the end of the name.
5475 for (p = *arg; eval_isnamec(*p); ++p)
5476 {
5477 if (*p == ':')
5478 {
5479 // "s:" is start of "s:var", but "n:" is not and can be used in
5480 // slice "[n:]". Also "xx:" is not a namespace.
5481 len = (int)(p - *arg);
5482 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL)
5483 || len > 1)
5484 break;
5485 }
5486 }
5487 if (p == *arg) // no name found
5488 return 0;
5489
5490 len = (int)(p - *arg);
5491 *arg = p;
5492
5493 return len;
5494 }
5495
5496 /*
5497 * Get the length of the name of a variable or function.
5498 * Only the name is recognized, does not handle ".key" or "[idx]".
5499 * "arg" is advanced to the first non-white character after the name.
5500 * Return -1 if curly braces expansion failed.
5501 * Return 0 if something else is wrong.
5502 * If the name contains 'magic' {}'s, expand them and return the
5503 * expanded name in an allocated string via 'alias' - caller must free.
5504 */
5505 int
get_name_len(char_u ** arg,char_u ** alias,int evaluate,int verbose)5506 get_name_len(
5507 char_u **arg,
5508 char_u **alias,
5509 int evaluate,
5510 int verbose)
5511 {
5512 int len;
5513 char_u *p;
5514 char_u *expr_start;
5515 char_u *expr_end;
5516
5517 *alias = NULL; // default to no alias
5518
5519 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
5520 && (*arg)[2] == (int)KE_SNR)
5521 {
5522 // hard coded <SNR>, already translated
5523 *arg += 3;
5524 return get_id_len(arg) + 3;
5525 }
5526 len = eval_fname_script(*arg);
5527 if (len > 0)
5528 {
5529 // literal "<SID>", "s:" or "<SNR>"
5530 *arg += len;
5531 }
5532
5533 /*
5534 * Find the end of the name; check for {} construction.
5535 */
5536 p = find_name_end(*arg, &expr_start, &expr_end,
5537 len > 0 ? 0 : FNE_CHECK_START);
5538 if (expr_start != NULL)
5539 {
5540 char_u *temp_string;
5541
5542 if (!evaluate)
5543 {
5544 len += (int)(p - *arg);
5545 *arg = skipwhite(p);
5546 return len;
5547 }
5548
5549 /*
5550 * Include any <SID> etc in the expanded string:
5551 * Thus the -len here.
5552 */
5553 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
5554 if (temp_string == NULL)
5555 return -1;
5556 *alias = temp_string;
5557 *arg = skipwhite(p);
5558 return (int)STRLEN(temp_string);
5559 }
5560
5561 len += get_id_len(arg);
5562 // Only give an error when there is something, otherwise it will be
5563 // reported at a higher level.
5564 if (len == 0 && verbose && **arg != NUL)
5565 semsg(_(e_invalid_expression_str), *arg);
5566
5567 return len;
5568 }
5569
5570 /*
5571 * Find the end of a variable or function name, taking care of magic braces.
5572 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the
5573 * start and end of the first magic braces item.
5574 * "flags" can have FNE_INCL_BR and FNE_CHECK_START.
5575 * Return a pointer to just after the name. Equal to "arg" if there is no
5576 * valid name.
5577 */
5578 char_u *
find_name_end(char_u * arg,char_u ** expr_start,char_u ** expr_end,int flags)5579 find_name_end(
5580 char_u *arg,
5581 char_u **expr_start,
5582 char_u **expr_end,
5583 int flags)
5584 {
5585 int mb_nest = 0;
5586 int br_nest = 0;
5587 char_u *p;
5588 int len;
5589 int vim9script = in_vim9script();
5590
5591 if (expr_start != NULL)
5592 {
5593 *expr_start = NULL;
5594 *expr_end = NULL;
5595 }
5596
5597 // Quick check for valid starting character.
5598 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg)
5599 && (*arg != '{' || vim9script))
5600 return arg;
5601
5602 for (p = arg; *p != NUL
5603 && (eval_isnamec(*p)
5604 || (*p == '{' && !vim9script)
5605 || ((flags & FNE_INCL_BR) && (*p == '['
5606 || (*p == '.' && eval_isdictc(p[1]))))
5607 || mb_nest != 0
5608 || br_nest != 0); MB_PTR_ADV(p))
5609 {
5610 if (*p == '\'')
5611 {
5612 // skip over 'string' to avoid counting [ and ] inside it.
5613 for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p))
5614 ;
5615 if (*p == NUL)
5616 break;
5617 }
5618 else if (*p == '"')
5619 {
5620 // skip over "str\"ing" to avoid counting [ and ] inside it.
5621 for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
5622 if (*p == '\\' && p[1] != NUL)
5623 ++p;
5624 if (*p == NUL)
5625 break;
5626 }
5627 else if (br_nest == 0 && mb_nest == 0 && *p == ':')
5628 {
5629 // "s:" is start of "s:var", but "n:" is not and can be used in
5630 // slice "[n:]". Also "xx:" is not a namespace. But {ns}: is.
5631 len = (int)(p - arg);
5632 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL)
5633 || (len > 1 && p[-1] != '}'))
5634 break;
5635 }
5636
5637 if (mb_nest == 0)
5638 {
5639 if (*p == '[')
5640 ++br_nest;
5641 else if (*p == ']')
5642 --br_nest;
5643 }
5644
5645 if (br_nest == 0 && !vim9script)
5646 {
5647 if (*p == '{')
5648 {
5649 mb_nest++;
5650 if (expr_start != NULL && *expr_start == NULL)
5651 *expr_start = p;
5652 }
5653 else if (*p == '}')
5654 {
5655 mb_nest--;
5656 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL)
5657 *expr_end = p;
5658 }
5659 }
5660 }
5661
5662 return p;
5663 }
5664
5665 /*
5666 * Expands out the 'magic' {}'s in a variable/function name.
5667 * Note that this can call itself recursively, to deal with
5668 * constructs like foo{bar}{baz}{bam}
5669 * The four pointer arguments point to "foo{expre}ss{ion}bar"
5670 * "in_start" ^
5671 * "expr_start" ^
5672 * "expr_end" ^
5673 * "in_end" ^
5674 *
5675 * Returns a new allocated string, which the caller must free.
5676 * Returns NULL for failure.
5677 */
5678 static char_u *
make_expanded_name(char_u * in_start,char_u * expr_start,char_u * expr_end,char_u * in_end)5679 make_expanded_name(
5680 char_u *in_start,
5681 char_u *expr_start,
5682 char_u *expr_end,
5683 char_u *in_end)
5684 {
5685 char_u c1;
5686 char_u *retval = NULL;
5687 char_u *temp_result;
5688
5689 if (expr_end == NULL || in_end == NULL)
5690 return NULL;
5691 *expr_start = NUL;
5692 *expr_end = NUL;
5693 c1 = *in_end;
5694 *in_end = NUL;
5695
5696 temp_result = eval_to_string(expr_start + 1, FALSE);
5697 if (temp_result != NULL)
5698 {
5699 retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
5700 + (in_end - expr_end) + 1);
5701 if (retval != NULL)
5702 {
5703 STRCPY(retval, in_start);
5704 STRCAT(retval, temp_result);
5705 STRCAT(retval, expr_end + 1);
5706 }
5707 }
5708 vim_free(temp_result);
5709
5710 *in_end = c1; // put char back for error messages
5711 *expr_start = '{';
5712 *expr_end = '}';
5713
5714 if (retval != NULL)
5715 {
5716 temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
5717 if (expr_start != NULL)
5718 {
5719 // Further expansion!
5720 temp_result = make_expanded_name(retval, expr_start,
5721 expr_end, temp_result);
5722 vim_free(retval);
5723 retval = temp_result;
5724 }
5725 }
5726
5727 return retval;
5728 }
5729
5730 /*
5731 * Return TRUE if character "c" can be used in a variable or function name.
5732 * Does not include '{' or '}' for magic braces.
5733 */
5734 int
eval_isnamec(int c)5735 eval_isnamec(int c)
5736 {
5737 return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR;
5738 }
5739
5740 /*
5741 * Return TRUE if character "c" can be used as the first character in a
5742 * variable or function name (excluding '{' and '}').
5743 */
5744 int
eval_isnamec1(int c)5745 eval_isnamec1(int c)
5746 {
5747 return ASCII_ISALPHA(c) || c == '_';
5748 }
5749
5750 /*
5751 * Return TRUE if character "c" can be used as the first character of a
5752 * dictionary key.
5753 */
5754 int
eval_isdictc(int c)5755 eval_isdictc(int c)
5756 {
5757 return ASCII_ISALNUM(c) || c == '_';
5758 }
5759
5760 /*
5761 * Handle:
5762 * - expr[expr], expr[expr:expr] subscript
5763 * - ".name" lookup
5764 * - function call with Funcref variable: func(expr)
5765 * - method call: var->method()
5766 *
5767 * Can all be combined in any order: dict.func(expr)[idx]['func'](expr)->len()
5768 */
5769 int
handle_subscript(char_u ** arg,typval_T * rettv,evalarg_T * evalarg,int verbose)5770 handle_subscript(
5771 char_u **arg,
5772 typval_T *rettv,
5773 evalarg_T *evalarg,
5774 int verbose) // give error messages
5775 {
5776 int evaluate = evalarg != NULL
5777 && (evalarg->eval_flags & EVAL_EVALUATE);
5778 int ret = OK;
5779 dict_T *selfdict = NULL;
5780 int check_white = TRUE;
5781 int getnext;
5782 char_u *p;
5783
5784 while (ret == OK)
5785 {
5786 // When at the end of the line and ".name" or "->{" or "->X" follows in
5787 // the next line then consume the line break.
5788 p = eval_next_non_blank(*arg, evalarg, &getnext);
5789 if (getnext
5790 && ((rettv->v_type == VAR_DICT && *p == '.' && eval_isdictc(p[1]))
5791 || (p[0] == '-' && p[1] == '>' && (p[2] == '{'
5792 || ASCII_ISALPHA(in_vim9script() ? *skipwhite(p + 2)
5793 : p[2])))))
5794 {
5795 *arg = eval_next_line(evalarg);
5796 p = *arg;
5797 check_white = FALSE;
5798 }
5799
5800 if (rettv->v_type == VAR_ANY)
5801 {
5802 char_u *exp_name;
5803 int cc;
5804 int idx;
5805 ufunc_T *ufunc;
5806 type_T *type;
5807
5808 // Found script from "import * as {name}", script item name must
5809 // follow.
5810 if (**arg != '.')
5811 {
5812 if (verbose)
5813 semsg(_(e_expected_str_but_got_str), "'.'", *arg);
5814 ret = FAIL;
5815 break;
5816 }
5817 ++*arg;
5818 if (IS_WHITE_OR_NUL(**arg))
5819 {
5820 if (verbose)
5821 emsg(_(e_no_white_space_allowed_after_dot));
5822 ret = FAIL;
5823 break;
5824 }
5825
5826 // isolate the name
5827 exp_name = *arg;
5828 while (eval_isnamec(**arg))
5829 ++*arg;
5830 cc = **arg;
5831 **arg = NUL;
5832
5833 idx = find_exported(rettv->vval.v_number, exp_name, &ufunc, &type,
5834 evalarg->eval_cctx, verbose);
5835 **arg = cc;
5836 *arg = skipwhite(*arg);
5837
5838 if (idx < 0 && ufunc == NULL)
5839 {
5840 ret = FAIL;
5841 break;
5842 }
5843 if (idx >= 0)
5844 {
5845 scriptitem_T *si = SCRIPT_ITEM(rettv->vval.v_number);
5846 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
5847
5848 copy_tv(sv->sv_tv, rettv);
5849 }
5850 else
5851 {
5852 rettv->v_type = VAR_FUNC;
5853 rettv->vval.v_string = vim_strsave(ufunc->uf_name);
5854 }
5855 }
5856
5857 if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
5858 || rettv->v_type == VAR_PARTIAL))
5859 && (!check_white || !VIM_ISWHITE(*(*arg - 1))))
5860 {
5861 ret = call_func_rettv(arg, evalarg, rettv, evaluate,
5862 selfdict, NULL);
5863
5864 // Stop the expression evaluation when immediately aborting on
5865 // error, or when an interrupt occurred or an exception was thrown
5866 // but not caught.
5867 if (aborting())
5868 {
5869 if (ret == OK)
5870 clear_tv(rettv);
5871 ret = FAIL;
5872 }
5873 dict_unref(selfdict);
5874 selfdict = NULL;
5875 }
5876 else if (p[0] == '-' && p[1] == '>')
5877 {
5878 if (in_vim9script())
5879 *arg = skipwhite(p + 2);
5880 else
5881 *arg = p + 2;
5882 if (ret == OK)
5883 {
5884 if (VIM_ISWHITE(**arg))
5885 {
5886 emsg(_(e_nowhitespace));
5887 ret = FAIL;
5888 }
5889 else if ((**arg == '{' && !in_vim9script()) || **arg == '(')
5890 // expr->{lambda}() or expr->(lambda)()
5891 ret = eval_lambda(arg, rettv, evalarg, verbose);
5892 else
5893 // expr->name()
5894 ret = eval_method(arg, rettv, evalarg, verbose);
5895 }
5896 }
5897 // "." is ".name" lookup when we found a dict or when evaluating and
5898 // scriptversion is at least 2, where string concatenation is "..".
5899 else if (**arg == '['
5900 || (**arg == '.' && (rettv->v_type == VAR_DICT
5901 || (!evaluate
5902 && (*arg)[1] != '.'
5903 && !in_old_script(2)))))
5904 {
5905 dict_unref(selfdict);
5906 if (rettv->v_type == VAR_DICT)
5907 {
5908 selfdict = rettv->vval.v_dict;
5909 if (selfdict != NULL)
5910 ++selfdict->dv_refcount;
5911 }
5912 else
5913 selfdict = NULL;
5914 if (eval_index(arg, rettv, evalarg, verbose) == FAIL)
5915 {
5916 clear_tv(rettv);
5917 ret = FAIL;
5918 }
5919 }
5920 else
5921 break;
5922 }
5923
5924 // Turn "dict.Func" into a partial for "Func" bound to "dict".
5925 // Don't do this when "Func" is already a partial that was bound
5926 // explicitly (pt_auto is FALSE).
5927 if (selfdict != NULL
5928 && (rettv->v_type == VAR_FUNC
5929 || (rettv->v_type == VAR_PARTIAL
5930 && (rettv->vval.v_partial->pt_auto
5931 || rettv->vval.v_partial->pt_dict == NULL))))
5932 selfdict = make_partial(selfdict, rettv);
5933
5934 dict_unref(selfdict);
5935 return ret;
5936 }
5937
5938 /*
5939 * Make a copy of an item.
5940 * Lists and Dictionaries are also copied. A deep copy if "deep" is set.
5941 * For deepcopy() "copyID" is zero for a full copy or the ID for when a
5942 * reference to an already copied list/dict can be used.
5943 * Returns FAIL or OK.
5944 */
5945 int
item_copy(typval_T * from,typval_T * to,int deep,int copyID)5946 item_copy(
5947 typval_T *from,
5948 typval_T *to,
5949 int deep,
5950 int copyID)
5951 {
5952 static int recurse = 0;
5953 int ret = OK;
5954
5955 if (recurse >= DICT_MAXNEST)
5956 {
5957 emsg(_("E698: variable nested too deep for making a copy"));
5958 return FAIL;
5959 }
5960 ++recurse;
5961
5962 switch (from->v_type)
5963 {
5964 case VAR_NUMBER:
5965 case VAR_FLOAT:
5966 case VAR_STRING:
5967 case VAR_FUNC:
5968 case VAR_PARTIAL:
5969 case VAR_BOOL:
5970 case VAR_SPECIAL:
5971 case VAR_JOB:
5972 case VAR_CHANNEL:
5973 case VAR_INSTR:
5974 copy_tv(from, to);
5975 break;
5976 case VAR_LIST:
5977 to->v_type = VAR_LIST;
5978 to->v_lock = 0;
5979 if (from->vval.v_list == NULL)
5980 to->vval.v_list = NULL;
5981 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID)
5982 {
5983 // use the copy made earlier
5984 to->vval.v_list = from->vval.v_list->lv_copylist;
5985 ++to->vval.v_list->lv_refcount;
5986 }
5987 else
5988 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
5989 if (to->vval.v_list == NULL)
5990 ret = FAIL;
5991 break;
5992 case VAR_BLOB:
5993 ret = blob_copy(from->vval.v_blob, to);
5994 break;
5995 case VAR_DICT:
5996 to->v_type = VAR_DICT;
5997 to->v_lock = 0;
5998 if (from->vval.v_dict == NULL)
5999 to->vval.v_dict = NULL;
6000 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID)
6001 {
6002 // use the copy made earlier
6003 to->vval.v_dict = from->vval.v_dict->dv_copydict;
6004 ++to->vval.v_dict->dv_refcount;
6005 }
6006 else
6007 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
6008 if (to->vval.v_dict == NULL)
6009 ret = FAIL;
6010 break;
6011 case VAR_UNKNOWN:
6012 case VAR_ANY:
6013 case VAR_VOID:
6014 internal_error_no_abort("item_copy(UNKNOWN)");
6015 ret = FAIL;
6016 }
6017 --recurse;
6018 return ret;
6019 }
6020
6021 void
echo_one(typval_T * rettv,int with_space,int * atstart,int * needclr)6022 echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr)
6023 {
6024 char_u *tofree;
6025 char_u numbuf[NUMBUFLEN];
6026 char_u *p = echo_string(rettv, &tofree, numbuf, get_copyID());
6027
6028 if (*atstart)
6029 {
6030 *atstart = FALSE;
6031 // Call msg_start() after eval1(), evaluating the expression
6032 // may cause a message to appear.
6033 if (with_space)
6034 {
6035 // Mark the saved text as finishing the line, so that what
6036 // follows is displayed on a new line when scrolling back
6037 // at the more prompt.
6038 msg_sb_eol();
6039 msg_start();
6040 }
6041 }
6042 else if (with_space)
6043 msg_puts_attr(" ", echo_attr);
6044
6045 if (p != NULL)
6046 for ( ; *p != NUL && !got_int; ++p)
6047 {
6048 if (*p == '\n' || *p == '\r' || *p == TAB)
6049 {
6050 if (*p != TAB && *needclr)
6051 {
6052 // remove any text still there from the command
6053 msg_clr_eos();
6054 *needclr = FALSE;
6055 }
6056 msg_putchar_attr(*p, echo_attr);
6057 }
6058 else
6059 {
6060 if (has_mbyte)
6061 {
6062 int i = (*mb_ptr2len)(p);
6063
6064 (void)msg_outtrans_len_attr(p, i, echo_attr);
6065 p += i - 1;
6066 }
6067 else
6068 (void)msg_outtrans_len_attr(p, 1, echo_attr);
6069 }
6070 }
6071 vim_free(tofree);
6072 }
6073
6074 /*
6075 * ":echo expr1 ..." print each argument separated with a space, add a
6076 * newline at the end.
6077 * ":echon expr1 ..." print each argument plain.
6078 */
6079 void
ex_echo(exarg_T * eap)6080 ex_echo(exarg_T *eap)
6081 {
6082 char_u *arg = eap->arg;
6083 typval_T rettv;
6084 char_u *arg_start;
6085 int needclr = TRUE;
6086 int atstart = TRUE;
6087 int did_emsg_before = did_emsg;
6088 int called_emsg_before = called_emsg;
6089 evalarg_T evalarg;
6090
6091 fill_evalarg_from_eap(&evalarg, eap, eap->skip);
6092
6093 if (eap->skip)
6094 ++emsg_skip;
6095 while ((!ends_excmd2(eap->cmd, arg) || *arg == '"') && !got_int)
6096 {
6097 // If eval1() causes an error message the text from the command may
6098 // still need to be cleared. E.g., "echo 22,44".
6099 need_clr_eos = needclr;
6100
6101 arg_start = arg;
6102 if (eval1(&arg, &rettv, &evalarg) == FAIL)
6103 {
6104 /*
6105 * Report the invalid expression unless the expression evaluation
6106 * has been cancelled due to an aborting error, an interrupt, or an
6107 * exception.
6108 */
6109 if (!aborting() && did_emsg == did_emsg_before
6110 && called_emsg == called_emsg_before)
6111 semsg(_(e_invalid_expression_str), arg_start);
6112 need_clr_eos = FALSE;
6113 break;
6114 }
6115 need_clr_eos = FALSE;
6116
6117 if (!eap->skip)
6118 {
6119 if (rettv.v_type == VAR_VOID)
6120 {
6121 semsg(_(e_expression_does_not_result_in_value_str), arg_start);
6122 break;
6123 }
6124 echo_one(&rettv, eap->cmdidx == CMD_echo, &atstart, &needclr);
6125 }
6126
6127 clear_tv(&rettv);
6128 arg = skipwhite(arg);
6129 }
6130 set_nextcmd(eap, arg);
6131 clear_evalarg(&evalarg, eap);
6132
6133 if (eap->skip)
6134 --emsg_skip;
6135 else
6136 {
6137 // remove text that may still be there from the command
6138 if (needclr)
6139 msg_clr_eos();
6140 if (eap->cmdidx == CMD_echo)
6141 msg_end();
6142 }
6143 }
6144
6145 /*
6146 * ":echohl {name}".
6147 */
6148 void
ex_echohl(exarg_T * eap)6149 ex_echohl(exarg_T *eap)
6150 {
6151 echo_attr = syn_name2attr(eap->arg);
6152 }
6153
6154 /*
6155 * Returns the :echo attribute
6156 */
6157 int
get_echo_attr(void)6158 get_echo_attr(void)
6159 {
6160 return echo_attr;
6161 }
6162
6163 /*
6164 * ":execute expr1 ..." execute the result of an expression.
6165 * ":echomsg expr1 ..." Print a message
6166 * ":echoerr expr1 ..." Print an error
6167 * ":echoconsole expr1 ..." Print a message on stdout
6168 * Each gets spaces around each argument and a newline at the end for
6169 * echo commands
6170 */
6171 void
ex_execute(exarg_T * eap)6172 ex_execute(exarg_T *eap)
6173 {
6174 char_u *arg = eap->arg;
6175 typval_T rettv;
6176 int ret = OK;
6177 char_u *p;
6178 garray_T ga;
6179 int len;
6180 long start_lnum = SOURCING_LNUM;
6181
6182 ga_init2(&ga, 1, 80);
6183
6184 if (eap->skip)
6185 ++emsg_skip;
6186 while (!ends_excmd2(eap->cmd, arg) || *arg == '"')
6187 {
6188 ret = eval1_emsg(&arg, &rettv, eap);
6189 if (ret == FAIL)
6190 break;
6191
6192 if (!eap->skip)
6193 {
6194 char_u buf[NUMBUFLEN];
6195
6196 if (eap->cmdidx == CMD_execute)
6197 {
6198 if (rettv.v_type == VAR_CHANNEL || rettv.v_type == VAR_JOB)
6199 {
6200 semsg(_(e_using_invalid_value_as_string_str),
6201 vartype_name(rettv.v_type));
6202 p = NULL;
6203 }
6204 else
6205 p = tv_get_string_buf(&rettv, buf);
6206 }
6207 else
6208 p = tv_stringify(&rettv, buf);
6209 if (p == NULL)
6210 {
6211 clear_tv(&rettv);
6212 ret = FAIL;
6213 break;
6214 }
6215 len = (int)STRLEN(p);
6216 if (ga_grow(&ga, len + 2) == FAIL)
6217 {
6218 clear_tv(&rettv);
6219 ret = FAIL;
6220 break;
6221 }
6222 if (ga.ga_len)
6223 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
6224 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
6225 ga.ga_len += len;
6226 }
6227
6228 clear_tv(&rettv);
6229 arg = skipwhite(arg);
6230 }
6231
6232 if (ret != FAIL && ga.ga_data != NULL)
6233 {
6234 // use the first line of continuation lines for messages
6235 SOURCING_LNUM = start_lnum;
6236
6237 if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr)
6238 {
6239 // Mark the already saved text as finishing the line, so that what
6240 // follows is displayed on a new line when scrolling back at the
6241 // more prompt.
6242 msg_sb_eol();
6243 }
6244
6245 if (eap->cmdidx == CMD_echomsg)
6246 {
6247 msg_attr(ga.ga_data, echo_attr);
6248 out_flush();
6249 }
6250 else if (eap->cmdidx == CMD_echoconsole)
6251 {
6252 ui_write(ga.ga_data, (int)STRLEN(ga.ga_data), TRUE);
6253 ui_write((char_u *)"\r\n", 2, TRUE);
6254 }
6255 else if (eap->cmdidx == CMD_echoerr)
6256 {
6257 int save_did_emsg = did_emsg;
6258
6259 // We don't want to abort following commands, restore did_emsg.
6260 emsg(ga.ga_data);
6261 if (!force_abort)
6262 did_emsg = save_did_emsg;
6263 }
6264 else if (eap->cmdidx == CMD_execute)
6265 do_cmdline((char_u *)ga.ga_data,
6266 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
6267 }
6268
6269 ga_clear(&ga);
6270
6271 if (eap->skip)
6272 --emsg_skip;
6273
6274 set_nextcmd(eap, arg);
6275 }
6276
6277 /*
6278 * Skip over the name of an option: "&option", "&g:option" or "&l:option".
6279 * "arg" points to the "&" or '+' when called, to "option" when returning.
6280 * Returns NULL when no option name found. Otherwise pointer to the char
6281 * after the option name.
6282 */
6283 char_u *
find_option_end(char_u ** arg,int * opt_flags)6284 find_option_end(char_u **arg, int *opt_flags)
6285 {
6286 char_u *p = *arg;
6287
6288 ++p;
6289 if (*p == 'g' && p[1] == ':')
6290 {
6291 *opt_flags = OPT_GLOBAL;
6292 p += 2;
6293 }
6294 else if (*p == 'l' && p[1] == ':')
6295 {
6296 *opt_flags = OPT_LOCAL;
6297 p += 2;
6298 }
6299 else
6300 *opt_flags = 0;
6301
6302 if (!ASCII_ISALPHA(*p))
6303 return NULL;
6304 *arg = p;
6305
6306 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
6307 p += 4; // termcap option
6308 else
6309 while (ASCII_ISALPHA(*p))
6310 ++p;
6311 return p;
6312 }
6313
6314 /*
6315 * Display script name where an item was last set.
6316 * Should only be invoked when 'verbose' is non-zero.
6317 */
6318 void
last_set_msg(sctx_T script_ctx)6319 last_set_msg(sctx_T script_ctx)
6320 {
6321 char_u *p;
6322
6323 if (script_ctx.sc_sid != 0)
6324 {
6325 p = home_replace_save(NULL, get_scriptname(script_ctx.sc_sid));
6326 if (p != NULL)
6327 {
6328 verbose_enter();
6329 msg_puts(_("\n\tLast set from "));
6330 msg_puts((char *)p);
6331 if (script_ctx.sc_lnum > 0)
6332 {
6333 msg_puts(_(line_msg));
6334 msg_outnum((long)script_ctx.sc_lnum);
6335 }
6336 verbose_leave();
6337 vim_free(p);
6338 }
6339 }
6340 }
6341
6342 #endif // FEAT_EVAL
6343
6344 /*
6345 * Perform a substitution on "str" with pattern "pat" and substitute "sub".
6346 * When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL.
6347 * "flags" can be "g" to do a global substitute.
6348 * Returns an allocated string, NULL for error.
6349 */
6350 char_u *
do_string_sub(char_u * str,char_u * pat,char_u * sub,typval_T * expr,char_u * flags)6351 do_string_sub(
6352 char_u *str,
6353 char_u *pat,
6354 char_u *sub,
6355 typval_T *expr,
6356 char_u *flags)
6357 {
6358 int sublen;
6359 regmatch_T regmatch;
6360 int i;
6361 int do_all;
6362 char_u *tail;
6363 char_u *end;
6364 garray_T ga;
6365 char_u *ret;
6366 char_u *save_cpo;
6367 char_u *zero_width = NULL;
6368
6369 // Make 'cpoptions' empty, so that the 'l' flag doesn't work here
6370 save_cpo = p_cpo;
6371 p_cpo = empty_option;
6372
6373 ga_init2(&ga, 1, 200);
6374
6375 do_all = (flags[0] == 'g');
6376
6377 regmatch.rm_ic = p_ic;
6378 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
6379 if (regmatch.regprog != NULL)
6380 {
6381 tail = str;
6382 end = str + STRLEN(str);
6383 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str)))
6384 {
6385 // Skip empty match except for first match.
6386 if (regmatch.startp[0] == regmatch.endp[0])
6387 {
6388 if (zero_width == regmatch.startp[0])
6389 {
6390 // avoid getting stuck on a match with an empty string
6391 i = mb_ptr2len(tail);
6392 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail,
6393 (size_t)i);
6394 ga.ga_len += i;
6395 tail += i;
6396 continue;
6397 }
6398 zero_width = regmatch.startp[0];
6399 }
6400
6401 /*
6402 * Get some space for a temporary buffer to do the substitution
6403 * into. It will contain:
6404 * - The text up to where the match is.
6405 * - The substituted text.
6406 * - The text after the match.
6407 */
6408 sublen = vim_regsub(®match, sub, expr, tail, FALSE, TRUE, FALSE);
6409 if (ga_grow(&ga, (int)((end - tail) + sublen -
6410 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
6411 {
6412 ga_clear(&ga);
6413 break;
6414 }
6415
6416 // copy the text up to where the match is
6417 i = (int)(regmatch.startp[0] - tail);
6418 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
6419 // add the substituted text
6420 (void)vim_regsub(®match, sub, expr, (char_u *)ga.ga_data
6421 + ga.ga_len + i, TRUE, TRUE, FALSE);
6422 ga.ga_len += i + sublen - 1;
6423 tail = regmatch.endp[0];
6424 if (*tail == NUL)
6425 break;
6426 if (!do_all)
6427 break;
6428 }
6429
6430 if (ga.ga_data != NULL)
6431 STRCPY((char *)ga.ga_data + ga.ga_len, tail);
6432
6433 vim_regfree(regmatch.regprog);
6434 }
6435
6436 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
6437 ga_clear(&ga);
6438 if (p_cpo == empty_option)
6439 p_cpo = save_cpo;
6440 else
6441 {
6442 // Darn, evaluating {sub} expression or {expr} changed the value.
6443 // If it's still empty it was changed and restored, need to restore in
6444 // the complicated way.
6445 if (*p_cpo == NUL)
6446 set_option_value((char_u *)"cpo", 0L, save_cpo, 0);
6447 free_string_option(save_cpo);
6448 }
6449
6450 return ret;
6451 }
6452