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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 * 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 * 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 * 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 * 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 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 * 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 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 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 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 * 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 * 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 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 * 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, 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 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 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 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 * 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 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 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 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 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 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 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 * 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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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, (int)keylen); 4291 4292 if (item == NULL && verbose) 4293 semsg(_(e_dictkey), key); 4294 if (item == NULL) 4295 return FAIL; 4296 4297 copy_tv(&item->di_tv, &tmp); 4298 clear_tv(rettv); 4299 *rettv = tmp; 4300 } 4301 break; 4302 } 4303 return OK; 4304 } 4305 4306 /* 4307 * Return the function name of partial "pt". 4308 */ 4309 char_u * 4310 partial_name(partial_T *pt) 4311 { 4312 if (pt != NULL) 4313 { 4314 if (pt->pt_name != NULL) 4315 return pt->pt_name; 4316 if (pt->pt_func != NULL) 4317 return pt->pt_func->uf_name; 4318 } 4319 return (char_u *)""; 4320 } 4321 4322 static void 4323 partial_free(partial_T *pt) 4324 { 4325 int i; 4326 4327 for (i = 0; i < pt->pt_argc; ++i) 4328 clear_tv(&pt->pt_argv[i]); 4329 vim_free(pt->pt_argv); 4330 dict_unref(pt->pt_dict); 4331 if (pt->pt_name != NULL) 4332 { 4333 func_unref(pt->pt_name); 4334 vim_free(pt->pt_name); 4335 } 4336 else 4337 func_ptr_unref(pt->pt_func); 4338 4339 // "out_up" is no longer used, decrement refcount on partial that owns it. 4340 partial_unref(pt->pt_outer.out_up_partial); 4341 4342 // Decrease the reference count for the context of a closure. If down 4343 // to the minimum it may be time to free it. 4344 if (pt->pt_funcstack != NULL) 4345 { 4346 --pt->pt_funcstack->fs_refcount; 4347 funcstack_check_refcount(pt->pt_funcstack); 4348 } 4349 4350 vim_free(pt); 4351 } 4352 4353 /* 4354 * Unreference a closure: decrement the reference count and free it when it 4355 * becomes zero. 4356 */ 4357 void 4358 partial_unref(partial_T *pt) 4359 { 4360 if (pt != NULL) 4361 { 4362 if (--pt->pt_refcount <= 0) 4363 partial_free(pt); 4364 4365 // If the reference count goes down to one, the funcstack may be the 4366 // only reference and can be freed if no other partials reference it. 4367 else if (pt->pt_refcount == 1 && pt->pt_funcstack != NULL) 4368 funcstack_check_refcount(pt->pt_funcstack); 4369 } 4370 } 4371 4372 /* 4373 * Return the next (unique) copy ID. 4374 * Used for serializing nested structures. 4375 */ 4376 int 4377 get_copyID(void) 4378 { 4379 current_copyID += COPYID_INC; 4380 return current_copyID; 4381 } 4382 4383 /* 4384 * Garbage collection for lists and dictionaries. 4385 * 4386 * We use reference counts to be able to free most items right away when they 4387 * are no longer used. But for composite items it's possible that it becomes 4388 * unused while the reference count is > 0: When there is a recursive 4389 * reference. Example: 4390 * :let l = [1, 2, 3] 4391 * :let d = {9: l} 4392 * :let l[1] = d 4393 * 4394 * Since this is quite unusual we handle this with garbage collection: every 4395 * once in a while find out which lists and dicts are not referenced from any 4396 * variable. 4397 * 4398 * Here is a good reference text about garbage collection (refers to Python 4399 * but it applies to all reference-counting mechanisms): 4400 * http://python.ca/nas/python/gc/ 4401 */ 4402 4403 /* 4404 * Do garbage collection for lists and dicts. 4405 * When "testing" is TRUE this is called from test_garbagecollect_now(). 4406 * Return TRUE if some memory was freed. 4407 */ 4408 int 4409 garbage_collect(int testing) 4410 { 4411 int copyID; 4412 int abort = FALSE; 4413 buf_T *buf; 4414 win_T *wp; 4415 int did_free = FALSE; 4416 tabpage_T *tp; 4417 4418 if (!testing) 4419 { 4420 // Only do this once. 4421 want_garbage_collect = FALSE; 4422 may_garbage_collect = FALSE; 4423 garbage_collect_at_exit = FALSE; 4424 } 4425 4426 // The execution stack can grow big, limit the size. 4427 if (exestack.ga_maxlen - exestack.ga_len > 500) 4428 { 4429 size_t new_len; 4430 char_u *pp; 4431 int n; 4432 4433 // Keep 150% of the current size, with a minimum of the growth size. 4434 n = exestack.ga_len / 2; 4435 if (n < exestack.ga_growsize) 4436 n = exestack.ga_growsize; 4437 4438 // Don't make it bigger though. 4439 if (exestack.ga_len + n < exestack.ga_maxlen) 4440 { 4441 new_len = exestack.ga_itemsize * (exestack.ga_len + n); 4442 pp = vim_realloc(exestack.ga_data, new_len); 4443 if (pp == NULL) 4444 return FAIL; 4445 exestack.ga_maxlen = exestack.ga_len + n; 4446 exestack.ga_data = pp; 4447 } 4448 } 4449 4450 // We advance by two because we add one for items referenced through 4451 // previous_funccal. 4452 copyID = get_copyID(); 4453 4454 /* 4455 * 1. Go through all accessible variables and mark all lists and dicts 4456 * with copyID. 4457 */ 4458 4459 // Don't free variables in the previous_funccal list unless they are only 4460 // referenced through previous_funccal. This must be first, because if 4461 // the item is referenced elsewhere the funccal must not be freed. 4462 abort = abort || set_ref_in_previous_funccal(copyID); 4463 4464 // script-local variables 4465 abort = abort || garbage_collect_scriptvars(copyID); 4466 4467 // buffer-local variables 4468 FOR_ALL_BUFFERS(buf) 4469 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID, 4470 NULL, NULL); 4471 4472 // window-local variables 4473 FOR_ALL_TAB_WINDOWS(tp, wp) 4474 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, 4475 NULL, NULL); 4476 if (aucmd_win != NULL) 4477 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID, 4478 NULL, NULL); 4479 #ifdef FEAT_PROP_POPUP 4480 FOR_ALL_POPUPWINS(wp) 4481 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, 4482 NULL, NULL); 4483 FOR_ALL_TABPAGES(tp) 4484 FOR_ALL_POPUPWINS_IN_TAB(tp, wp) 4485 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, 4486 NULL, NULL); 4487 #endif 4488 4489 // tabpage-local variables 4490 FOR_ALL_TABPAGES(tp) 4491 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID, 4492 NULL, NULL); 4493 // global variables 4494 abort = abort || garbage_collect_globvars(copyID); 4495 4496 // function-local variables 4497 abort = abort || set_ref_in_call_stack(copyID); 4498 4499 // named functions (matters for closures) 4500 abort = abort || set_ref_in_functions(copyID); 4501 4502 // function call arguments, if v:testing is set. 4503 abort = abort || set_ref_in_func_args(copyID); 4504 4505 // v: vars 4506 abort = abort || garbage_collect_vimvars(copyID); 4507 4508 // callbacks in buffers 4509 abort = abort || set_ref_in_buffers(copyID); 4510 4511 #ifdef FEAT_LUA 4512 abort = abort || set_ref_in_lua(copyID); 4513 #endif 4514 4515 #ifdef FEAT_PYTHON 4516 abort = abort || set_ref_in_python(copyID); 4517 #endif 4518 4519 #ifdef FEAT_PYTHON3 4520 abort = abort || set_ref_in_python3(copyID); 4521 #endif 4522 4523 #ifdef FEAT_JOB_CHANNEL 4524 abort = abort || set_ref_in_channel(copyID); 4525 abort = abort || set_ref_in_job(copyID); 4526 #endif 4527 #ifdef FEAT_NETBEANS_INTG 4528 abort = abort || set_ref_in_nb_channel(copyID); 4529 #endif 4530 4531 #ifdef FEAT_TIMERS 4532 abort = abort || set_ref_in_timer(copyID); 4533 #endif 4534 4535 #ifdef FEAT_QUICKFIX 4536 abort = abort || set_ref_in_quickfix(copyID); 4537 #endif 4538 4539 #ifdef FEAT_TERMINAL 4540 abort = abort || set_ref_in_term(copyID); 4541 #endif 4542 4543 #ifdef FEAT_PROP_POPUP 4544 abort = abort || set_ref_in_popups(copyID); 4545 #endif 4546 4547 if (!abort) 4548 { 4549 /* 4550 * 2. Free lists and dictionaries that are not referenced. 4551 */ 4552 did_free = free_unref_items(copyID); 4553 4554 /* 4555 * 3. Check if any funccal can be freed now. 4556 * This may call us back recursively. 4557 */ 4558 free_unref_funccal(copyID, testing); 4559 } 4560 else if (p_verbose > 0) 4561 { 4562 verb_msg(_("Not enough memory to set references, garbage collection aborted!")); 4563 } 4564 4565 return did_free; 4566 } 4567 4568 /* 4569 * Free lists, dictionaries, channels and jobs that are no longer referenced. 4570 */ 4571 static int 4572 free_unref_items(int copyID) 4573 { 4574 int did_free = FALSE; 4575 4576 // Let all "free" functions know that we are here. This means no 4577 // dictionaries, lists, channels or jobs are to be freed, because we will 4578 // do that here. 4579 in_free_unref_items = TRUE; 4580 4581 /* 4582 * PASS 1: free the contents of the items. We don't free the items 4583 * themselves yet, so that it is possible to decrement refcount counters 4584 */ 4585 4586 // Go through the list of dicts and free items without the copyID. 4587 did_free |= dict_free_nonref(copyID); 4588 4589 // Go through the list of lists and free items without the copyID. 4590 did_free |= list_free_nonref(copyID); 4591 4592 #ifdef FEAT_JOB_CHANNEL 4593 // Go through the list of jobs and free items without the copyID. This 4594 // must happen before doing channels, because jobs refer to channels, but 4595 // the reference from the channel to the job isn't tracked. 4596 did_free |= free_unused_jobs_contents(copyID, COPYID_MASK); 4597 4598 // Go through the list of channels and free items without the copyID. 4599 did_free |= free_unused_channels_contents(copyID, COPYID_MASK); 4600 #endif 4601 4602 /* 4603 * PASS 2: free the items themselves. 4604 */ 4605 dict_free_items(copyID); 4606 list_free_items(copyID); 4607 4608 #ifdef FEAT_JOB_CHANNEL 4609 // Go through the list of jobs and free items without the copyID. This 4610 // must happen before doing channels, because jobs refer to channels, but 4611 // the reference from the channel to the job isn't tracked. 4612 free_unused_jobs(copyID, COPYID_MASK); 4613 4614 // Go through the list of channels and free items without the copyID. 4615 free_unused_channels(copyID, COPYID_MASK); 4616 #endif 4617 4618 in_free_unref_items = FALSE; 4619 4620 return did_free; 4621 } 4622 4623 /* 4624 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 4625 * "list_stack" is used to add lists to be marked. Can be NULL. 4626 * 4627 * Returns TRUE if setting references failed somehow. 4628 */ 4629 int 4630 set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack) 4631 { 4632 int todo; 4633 int abort = FALSE; 4634 hashitem_T *hi; 4635 hashtab_T *cur_ht; 4636 ht_stack_T *ht_stack = NULL; 4637 ht_stack_T *tempitem; 4638 4639 cur_ht = ht; 4640 for (;;) 4641 { 4642 if (!abort) 4643 { 4644 // Mark each item in the hashtab. If the item contains a hashtab 4645 // it is added to ht_stack, if it contains a list it is added to 4646 // list_stack. 4647 todo = (int)cur_ht->ht_used; 4648 for (hi = cur_ht->ht_array; todo > 0; ++hi) 4649 if (!HASHITEM_EMPTY(hi)) 4650 { 4651 --todo; 4652 abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID, 4653 &ht_stack, list_stack); 4654 } 4655 } 4656 4657 if (ht_stack == NULL) 4658 break; 4659 4660 // take an item from the stack 4661 cur_ht = ht_stack->ht; 4662 tempitem = ht_stack; 4663 ht_stack = ht_stack->prev; 4664 free(tempitem); 4665 } 4666 4667 return abort; 4668 } 4669 4670 /* 4671 * Mark a dict and its items with "copyID". 4672 * Returns TRUE if setting references failed somehow. 4673 */ 4674 int 4675 set_ref_in_dict(dict_T *d, int copyID) 4676 { 4677 if (d != NULL && d->dv_copyID != copyID) 4678 { 4679 d->dv_copyID = copyID; 4680 return set_ref_in_ht(&d->dv_hashtab, copyID, NULL); 4681 } 4682 return FALSE; 4683 } 4684 4685 /* 4686 * Mark a list and its items with "copyID". 4687 * Returns TRUE if setting references failed somehow. 4688 */ 4689 int 4690 set_ref_in_list(list_T *ll, int copyID) 4691 { 4692 if (ll != NULL && ll->lv_copyID != copyID) 4693 { 4694 ll->lv_copyID = copyID; 4695 return set_ref_in_list_items(ll, copyID, NULL); 4696 } 4697 return FALSE; 4698 } 4699 4700 /* 4701 * Mark all lists and dicts referenced through list "l" with "copyID". 4702 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 4703 * 4704 * Returns TRUE if setting references failed somehow. 4705 */ 4706 int 4707 set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack) 4708 { 4709 listitem_T *li; 4710 int abort = FALSE; 4711 list_T *cur_l; 4712 list_stack_T *list_stack = NULL; 4713 list_stack_T *tempitem; 4714 4715 cur_l = l; 4716 for (;;) 4717 { 4718 if (!abort && cur_l->lv_first != &range_list_item) 4719 // Mark each item in the list. If the item contains a hashtab 4720 // it is added to ht_stack, if it contains a list it is added to 4721 // list_stack. 4722 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next) 4723 abort = abort || set_ref_in_item(&li->li_tv, copyID, 4724 ht_stack, &list_stack); 4725 if (list_stack == NULL) 4726 break; 4727 4728 // take an item from the stack 4729 cur_l = list_stack->list; 4730 tempitem = list_stack; 4731 list_stack = list_stack->prev; 4732 free(tempitem); 4733 } 4734 4735 return abort; 4736 } 4737 4738 /* 4739 * Mark all lists and dicts referenced through typval "tv" with "copyID". 4740 * "list_stack" is used to add lists to be marked. Can be NULL. 4741 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 4742 * 4743 * Returns TRUE if setting references failed somehow. 4744 */ 4745 int 4746 set_ref_in_item( 4747 typval_T *tv, 4748 int copyID, 4749 ht_stack_T **ht_stack, 4750 list_stack_T **list_stack) 4751 { 4752 int abort = FALSE; 4753 4754 if (tv->v_type == VAR_DICT) 4755 { 4756 dict_T *dd = tv->vval.v_dict; 4757 4758 if (dd != NULL && dd->dv_copyID != copyID) 4759 { 4760 // Didn't see this dict yet. 4761 dd->dv_copyID = copyID; 4762 if (ht_stack == NULL) 4763 { 4764 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); 4765 } 4766 else 4767 { 4768 ht_stack_T *newitem = ALLOC_ONE(ht_stack_T); 4769 4770 if (newitem == NULL) 4771 abort = TRUE; 4772 else 4773 { 4774 newitem->ht = &dd->dv_hashtab; 4775 newitem->prev = *ht_stack; 4776 *ht_stack = newitem; 4777 } 4778 } 4779 } 4780 } 4781 else if (tv->v_type == VAR_LIST) 4782 { 4783 list_T *ll = tv->vval.v_list; 4784 4785 if (ll != NULL && ll->lv_copyID != copyID) 4786 { 4787 // Didn't see this list yet. 4788 ll->lv_copyID = copyID; 4789 if (list_stack == NULL) 4790 { 4791 abort = set_ref_in_list_items(ll, copyID, ht_stack); 4792 } 4793 else 4794 { 4795 list_stack_T *newitem = ALLOC_ONE(list_stack_T); 4796 4797 if (newitem == NULL) 4798 abort = TRUE; 4799 else 4800 { 4801 newitem->list = ll; 4802 newitem->prev = *list_stack; 4803 *list_stack = newitem; 4804 } 4805 } 4806 } 4807 } 4808 else if (tv->v_type == VAR_FUNC) 4809 { 4810 abort = set_ref_in_func(tv->vval.v_string, NULL, copyID); 4811 } 4812 else if (tv->v_type == VAR_PARTIAL) 4813 { 4814 partial_T *pt = tv->vval.v_partial; 4815 int i; 4816 4817 if (pt != NULL && pt->pt_copyID != copyID) 4818 { 4819 // Didn't see this partial yet. 4820 pt->pt_copyID = copyID; 4821 4822 abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID); 4823 4824 if (pt->pt_dict != NULL) 4825 { 4826 typval_T dtv; 4827 4828 dtv.v_type = VAR_DICT; 4829 dtv.vval.v_dict = pt->pt_dict; 4830 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4831 } 4832 4833 for (i = 0; i < pt->pt_argc; ++i) 4834 abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID, 4835 ht_stack, list_stack); 4836 if (pt->pt_funcstack != NULL) 4837 { 4838 typval_T *stack = pt->pt_funcstack->fs_ga.ga_data; 4839 4840 for (i = 0; i < pt->pt_funcstack->fs_ga.ga_len; ++i) 4841 abort = abort || set_ref_in_item(stack + i, copyID, 4842 ht_stack, list_stack); 4843 } 4844 4845 } 4846 } 4847 #ifdef FEAT_JOB_CHANNEL 4848 else if (tv->v_type == VAR_JOB) 4849 { 4850 job_T *job = tv->vval.v_job; 4851 typval_T dtv; 4852 4853 if (job != NULL && job->jv_copyID != copyID) 4854 { 4855 job->jv_copyID = copyID; 4856 if (job->jv_channel != NULL) 4857 { 4858 dtv.v_type = VAR_CHANNEL; 4859 dtv.vval.v_channel = job->jv_channel; 4860 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4861 } 4862 if (job->jv_exit_cb.cb_partial != NULL) 4863 { 4864 dtv.v_type = VAR_PARTIAL; 4865 dtv.vval.v_partial = job->jv_exit_cb.cb_partial; 4866 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4867 } 4868 } 4869 } 4870 else if (tv->v_type == VAR_CHANNEL) 4871 { 4872 channel_T *ch =tv->vval.v_channel; 4873 ch_part_T part; 4874 typval_T dtv; 4875 jsonq_T *jq; 4876 cbq_T *cq; 4877 4878 if (ch != NULL && ch->ch_copyID != copyID) 4879 { 4880 ch->ch_copyID = copyID; 4881 for (part = PART_SOCK; part < PART_COUNT; ++part) 4882 { 4883 for (jq = ch->ch_part[part].ch_json_head.jq_next; jq != NULL; 4884 jq = jq->jq_next) 4885 set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack); 4886 for (cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL; 4887 cq = cq->cq_next) 4888 if (cq->cq_callback.cb_partial != NULL) 4889 { 4890 dtv.v_type = VAR_PARTIAL; 4891 dtv.vval.v_partial = cq->cq_callback.cb_partial; 4892 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4893 } 4894 if (ch->ch_part[part].ch_callback.cb_partial != NULL) 4895 { 4896 dtv.v_type = VAR_PARTIAL; 4897 dtv.vval.v_partial = 4898 ch->ch_part[part].ch_callback.cb_partial; 4899 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4900 } 4901 } 4902 if (ch->ch_callback.cb_partial != NULL) 4903 { 4904 dtv.v_type = VAR_PARTIAL; 4905 dtv.vval.v_partial = ch->ch_callback.cb_partial; 4906 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4907 } 4908 if (ch->ch_close_cb.cb_partial != NULL) 4909 { 4910 dtv.v_type = VAR_PARTIAL; 4911 dtv.vval.v_partial = ch->ch_close_cb.cb_partial; 4912 set_ref_in_item(&dtv, copyID, ht_stack, list_stack); 4913 } 4914 } 4915 } 4916 #endif 4917 return abort; 4918 } 4919 4920 /* 4921 * Return a string with the string representation of a variable. 4922 * If the memory is allocated "tofree" is set to it, otherwise NULL. 4923 * "numbuf" is used for a number. 4924 * When "copyID" is not NULL replace recursive lists and dicts with "...". 4925 * When both "echo_style" and "composite_val" are FALSE, put quotes around 4926 * strings as "string()", otherwise does not put quotes around strings, as 4927 * ":echo" displays values. 4928 * When "restore_copyID" is FALSE, repeated items in dictionaries and lists 4929 * are replaced with "...". 4930 * May return NULL. 4931 */ 4932 char_u * 4933 echo_string_core( 4934 typval_T *tv, 4935 char_u **tofree, 4936 char_u *numbuf, 4937 int copyID, 4938 int echo_style, 4939 int restore_copyID, 4940 int composite_val) 4941 { 4942 static int recurse = 0; 4943 char_u *r = NULL; 4944 4945 if (recurse >= DICT_MAXNEST) 4946 { 4947 if (!did_echo_string_emsg) 4948 { 4949 // Only give this message once for a recursive call to avoid 4950 // flooding the user with errors. And stop iterating over lists 4951 // and dicts. 4952 did_echo_string_emsg = TRUE; 4953 emsg(_("E724: variable nested too deep for displaying")); 4954 } 4955 *tofree = NULL; 4956 return (char_u *)"{E724}"; 4957 } 4958 ++recurse; 4959 4960 switch (tv->v_type) 4961 { 4962 case VAR_STRING: 4963 if (echo_style && !composite_val) 4964 { 4965 *tofree = NULL; 4966 r = tv->vval.v_string; 4967 if (r == NULL) 4968 r = (char_u *)""; 4969 } 4970 else 4971 { 4972 *tofree = string_quote(tv->vval.v_string, FALSE); 4973 r = *tofree; 4974 } 4975 break; 4976 4977 case VAR_FUNC: 4978 if (echo_style) 4979 { 4980 *tofree = NULL; 4981 r = tv->vval.v_string; 4982 } 4983 else 4984 { 4985 *tofree = string_quote(tv->vval.v_string, TRUE); 4986 r = *tofree; 4987 } 4988 break; 4989 4990 case VAR_PARTIAL: 4991 { 4992 partial_T *pt = tv->vval.v_partial; 4993 char_u *fname = string_quote(pt == NULL ? NULL 4994 : partial_name(pt), FALSE); 4995 garray_T ga; 4996 int i; 4997 char_u *tf; 4998 4999 ga_init2(&ga, 1, 100); 5000 ga_concat(&ga, (char_u *)"function("); 5001 if (fname != NULL) 5002 { 5003 ga_concat(&ga, fname); 5004 vim_free(fname); 5005 } 5006 if (pt != NULL && pt->pt_argc > 0) 5007 { 5008 ga_concat(&ga, (char_u *)", ["); 5009 for (i = 0; i < pt->pt_argc; ++i) 5010 { 5011 if (i > 0) 5012 ga_concat(&ga, (char_u *)", "); 5013 ga_concat(&ga, 5014 tv2string(&pt->pt_argv[i], &tf, numbuf, copyID)); 5015 vim_free(tf); 5016 } 5017 ga_concat(&ga, (char_u *)"]"); 5018 } 5019 if (pt != NULL && pt->pt_dict != NULL) 5020 { 5021 typval_T dtv; 5022 5023 ga_concat(&ga, (char_u *)", "); 5024 dtv.v_type = VAR_DICT; 5025 dtv.vval.v_dict = pt->pt_dict; 5026 ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID)); 5027 vim_free(tf); 5028 } 5029 ga_concat(&ga, (char_u *)")"); 5030 5031 *tofree = ga.ga_data; 5032 r = *tofree; 5033 break; 5034 } 5035 5036 case VAR_BLOB: 5037 r = blob2string(tv->vval.v_blob, tofree, numbuf); 5038 break; 5039 5040 case VAR_LIST: 5041 if (tv->vval.v_list == NULL) 5042 { 5043 // NULL list is equivalent to empty list. 5044 *tofree = NULL; 5045 r = (char_u *)"[]"; 5046 } 5047 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID 5048 && tv->vval.v_list->lv_len > 0) 5049 { 5050 *tofree = NULL; 5051 r = (char_u *)"[...]"; 5052 } 5053 else 5054 { 5055 int old_copyID = tv->vval.v_list->lv_copyID; 5056 5057 tv->vval.v_list->lv_copyID = copyID; 5058 *tofree = list2string(tv, copyID, restore_copyID); 5059 if (restore_copyID) 5060 tv->vval.v_list->lv_copyID = old_copyID; 5061 r = *tofree; 5062 } 5063 break; 5064 5065 case VAR_DICT: 5066 if (tv->vval.v_dict == NULL) 5067 { 5068 // NULL dict is equivalent to empty dict. 5069 *tofree = NULL; 5070 r = (char_u *)"{}"; 5071 } 5072 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID 5073 && tv->vval.v_dict->dv_hashtab.ht_used != 0) 5074 { 5075 *tofree = NULL; 5076 r = (char_u *)"{...}"; 5077 } 5078 else 5079 { 5080 int old_copyID = tv->vval.v_dict->dv_copyID; 5081 5082 tv->vval.v_dict->dv_copyID = copyID; 5083 *tofree = dict2string(tv, copyID, restore_copyID); 5084 if (restore_copyID) 5085 tv->vval.v_dict->dv_copyID = old_copyID; 5086 r = *tofree; 5087 } 5088 break; 5089 5090 case VAR_NUMBER: 5091 case VAR_UNKNOWN: 5092 case VAR_ANY: 5093 case VAR_VOID: 5094 *tofree = NULL; 5095 r = tv_get_string_buf(tv, numbuf); 5096 break; 5097 5098 case VAR_JOB: 5099 case VAR_CHANNEL: 5100 #ifdef FEAT_JOB_CHANNEL 5101 *tofree = NULL; 5102 r = tv->v_type == VAR_JOB ? job_to_string_buf(tv, numbuf) 5103 : channel_to_string_buf(tv, numbuf); 5104 if (composite_val) 5105 { 5106 *tofree = string_quote(r, FALSE); 5107 r = *tofree; 5108 } 5109 #endif 5110 break; 5111 5112 case VAR_INSTR: 5113 *tofree = NULL; 5114 r = (char_u *)"instructions"; 5115 break; 5116 5117 case VAR_FLOAT: 5118 #ifdef FEAT_FLOAT 5119 *tofree = NULL; 5120 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 5121 r = numbuf; 5122 break; 5123 #endif 5124 5125 case VAR_BOOL: 5126 case VAR_SPECIAL: 5127 *tofree = NULL; 5128 r = (char_u *)get_var_special_name(tv->vval.v_number); 5129 break; 5130 } 5131 5132 if (--recurse == 0) 5133 did_echo_string_emsg = FALSE; 5134 return r; 5135 } 5136 5137 /* 5138 * Return a string with the string representation of a variable. 5139 * If the memory is allocated "tofree" is set to it, otherwise NULL. 5140 * "numbuf" is used for a number. 5141 * Does not put quotes around strings, as ":echo" displays values. 5142 * When "copyID" is not NULL replace recursive lists and dicts with "...". 5143 * May return NULL. 5144 */ 5145 char_u * 5146 echo_string( 5147 typval_T *tv, 5148 char_u **tofree, 5149 char_u *numbuf, 5150 int copyID) 5151 { 5152 return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE); 5153 } 5154 5155 /* 5156 * Convert the specified byte index of line 'lnum' in buffer 'buf' to a 5157 * character index. Works only for loaded buffers. Returns -1 on failure. 5158 * The index of the first byte and the first character is zero. 5159 */ 5160 int 5161 buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx) 5162 { 5163 char_u *str; 5164 char_u *t; 5165 int count; 5166 5167 if (buf == NULL || buf->b_ml.ml_mfp == NULL) 5168 return -1; 5169 5170 if (lnum > buf->b_ml.ml_line_count) 5171 lnum = buf->b_ml.ml_line_count; 5172 5173 str = ml_get_buf(buf, lnum, FALSE); 5174 if (str == NULL) 5175 return -1; 5176 5177 if (*str == NUL) 5178 return 0; 5179 5180 // count the number of characters 5181 t = str; 5182 for (count = 0; *t != NUL && t <= str + byteidx; count++) 5183 t += mb_ptr2len(t); 5184 5185 // In insert mode, when the cursor is at the end of a non-empty line, 5186 // byteidx points to the NUL character immediately past the end of the 5187 // string. In this case, add one to the character count. 5188 if (*t == NUL && byteidx != 0 && t == str + byteidx) 5189 count++; 5190 5191 return count - 1; 5192 } 5193 5194 /* 5195 * Convert the specified character index of line 'lnum' in buffer 'buf' to a 5196 * byte index. Works only for loaded buffers. Returns -1 on failure. 5197 * The index of the first byte and the first character is zero. 5198 */ 5199 int 5200 buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx) 5201 { 5202 char_u *str; 5203 char_u *t; 5204 5205 if (buf == NULL || buf->b_ml.ml_mfp == NULL) 5206 return -1; 5207 5208 if (lnum > buf->b_ml.ml_line_count) 5209 lnum = buf->b_ml.ml_line_count; 5210 5211 str = ml_get_buf(buf, lnum, FALSE); 5212 if (str == NULL) 5213 return -1; 5214 5215 // Convert the character offset to a byte offset 5216 t = str; 5217 while (*t != NUL && --charidx > 0) 5218 t += mb_ptr2len(t); 5219 5220 return t - str; 5221 } 5222 5223 /* 5224 * Translate a String variable into a position. 5225 * Returns NULL when there is an error. 5226 */ 5227 pos_T * 5228 var2fpos( 5229 typval_T *varp, 5230 int dollar_lnum, // TRUE when $ is last line 5231 int *fnum, // set to fnum for '0, 'A, etc. 5232 int charcol) // return character column 5233 { 5234 char_u *name; 5235 static pos_T pos; 5236 pos_T *pp; 5237 5238 // Argument can be [lnum, col, coladd]. 5239 if (varp->v_type == VAR_LIST) 5240 { 5241 list_T *l; 5242 int len; 5243 int error = FALSE; 5244 listitem_T *li; 5245 5246 l = varp->vval.v_list; 5247 if (l == NULL) 5248 return NULL; 5249 5250 // Get the line number 5251 pos.lnum = list_find_nr(l, 0L, &error); 5252 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 5253 return NULL; // invalid line number 5254 if (charcol) 5255 len = (long)mb_charlen(ml_get(pos.lnum)); 5256 else 5257 len = (long)STRLEN(ml_get(pos.lnum)); 5258 5259 // Get the column number 5260 // We accept "$" for the column number: last column. 5261 li = list_find(l, 1L); 5262 if (li != NULL && li->li_tv.v_type == VAR_STRING 5263 && li->li_tv.vval.v_string != NULL 5264 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 5265 { 5266 pos.col = len + 1; 5267 } 5268 else 5269 { 5270 pos.col = list_find_nr(l, 1L, &error); 5271 if (error) 5272 return NULL; 5273 } 5274 5275 // Accept a position up to the NUL after the line. 5276 if (pos.col == 0 || (int)pos.col > len + 1) 5277 return NULL; // invalid column number 5278 --pos.col; 5279 5280 // Get the virtual offset. Defaults to zero. 5281 pos.coladd = list_find_nr(l, 2L, &error); 5282 if (error) 5283 pos.coladd = 0; 5284 5285 return &pos; 5286 } 5287 5288 if (in_vim9script() && check_for_string_arg(varp, 0) == FAIL) 5289 return NULL; 5290 5291 name = tv_get_string_chk(varp); 5292 if (name == NULL) 5293 return NULL; 5294 if (name[0] == '.') // cursor 5295 { 5296 pos = curwin->w_cursor; 5297 if (charcol) 5298 pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); 5299 return &pos; 5300 } 5301 if (name[0] == 'v' && name[1] == NUL) // Visual start 5302 { 5303 if (VIsual_active) 5304 pos = VIsual; 5305 else 5306 pos = curwin->w_cursor; 5307 if (charcol) 5308 pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); 5309 return &pos; 5310 } 5311 if (name[0] == '\'') // mark 5312 { 5313 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); 5314 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 5315 return NULL; 5316 if (charcol) 5317 pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col); 5318 return pp; 5319 } 5320 5321 pos.coladd = 0; 5322 5323 if (name[0] == 'w' && dollar_lnum) 5324 { 5325 pos.col = 0; 5326 if (name[1] == '0') // "w0": first visible line 5327 { 5328 update_topline(); 5329 // In silent Ex mode topline is zero, but that's not a valid line 5330 // number; use one instead. 5331 pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1; 5332 return &pos; 5333 } 5334 else if (name[1] == '$') // "w$": last visible line 5335 { 5336 validate_botline(); 5337 // In silent Ex mode botline is zero, return zero then. 5338 pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0; 5339 return &pos; 5340 } 5341 } 5342 else if (name[0] == '$') // last column or line 5343 { 5344 if (dollar_lnum) 5345 { 5346 pos.lnum = curbuf->b_ml.ml_line_count; 5347 pos.col = 0; 5348 } 5349 else 5350 { 5351 pos.lnum = curwin->w_cursor.lnum; 5352 if (charcol) 5353 pos.col = (colnr_T)mb_charlen(ml_get_curline()); 5354 else 5355 pos.col = (colnr_T)STRLEN(ml_get_curline()); 5356 } 5357 return &pos; 5358 } 5359 if (in_vim9script()) 5360 semsg(_(e_invalid_value_for_line_number_str), name); 5361 return NULL; 5362 } 5363 5364 /* 5365 * Convert list in "arg" into a position and optional file number. 5366 * When "fnump" is NULL there is no file number, only 3 items. 5367 * Note that the column is passed on as-is, the caller may want to decrement 5368 * it to use 1 for the first column. 5369 * Return FAIL when conversion is not possible, doesn't check the position for 5370 * validity. 5371 */ 5372 int 5373 list2fpos( 5374 typval_T *arg, 5375 pos_T *posp, 5376 int *fnump, 5377 colnr_T *curswantp, 5378 int charcol) 5379 { 5380 list_T *l = arg->vval.v_list; 5381 long i = 0; 5382 long n; 5383 5384 // List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only 5385 // there when "fnump" isn't NULL; "coladd" and "curswant" are optional. 5386 if (arg->v_type != VAR_LIST 5387 || l == NULL 5388 || l->lv_len < (fnump == NULL ? 2 : 3) 5389 || l->lv_len > (fnump == NULL ? 4 : 5)) 5390 return FAIL; 5391 5392 if (fnump != NULL) 5393 { 5394 n = list_find_nr(l, i++, NULL); // fnum 5395 if (n < 0) 5396 return FAIL; 5397 if (n == 0) 5398 n = curbuf->b_fnum; // current buffer 5399 *fnump = n; 5400 } 5401 5402 n = list_find_nr(l, i++, NULL); // lnum 5403 if (n < 0) 5404 return FAIL; 5405 posp->lnum = n; 5406 5407 n = list_find_nr(l, i++, NULL); // col 5408 if (n < 0) 5409 return FAIL; 5410 // If character position is specified, then convert to byte position 5411 if (charcol) 5412 { 5413 buf_T *buf; 5414 5415 // Get the text for the specified line in a loaded buffer 5416 buf = buflist_findnr(fnump == NULL ? curbuf->b_fnum : *fnump); 5417 if (buf == NULL || buf->b_ml.ml_mfp == NULL) 5418 return FAIL; 5419 5420 n = buf_charidx_to_byteidx(buf, posp->lnum, n) + 1; 5421 } 5422 posp->col = n; 5423 5424 n = list_find_nr(l, i, NULL); // off 5425 if (n < 0) 5426 posp->coladd = 0; 5427 else 5428 posp->coladd = n; 5429 5430 if (curswantp != NULL) 5431 *curswantp = list_find_nr(l, i + 1, NULL); // curswant 5432 5433 return OK; 5434 } 5435 5436 /* 5437 * Get the length of an environment variable name. 5438 * Advance "arg" to the first character after the name. 5439 * Return 0 for error. 5440 */ 5441 int 5442 get_env_len(char_u **arg) 5443 { 5444 char_u *p; 5445 int len; 5446 5447 for (p = *arg; vim_isIDc(*p); ++p) 5448 ; 5449 if (p == *arg) // no name found 5450 return 0; 5451 5452 len = (int)(p - *arg); 5453 *arg = p; 5454 return len; 5455 } 5456 5457 /* 5458 * Get the length of the name of a function or internal variable. 5459 * "arg" is advanced to after the name. 5460 * Return 0 if something is wrong. 5461 */ 5462 int 5463 get_id_len(char_u **arg) 5464 { 5465 char_u *p; 5466 int len; 5467 5468 // Find the end of the name. 5469 for (p = *arg; eval_isnamec(*p); ++p) 5470 { 5471 if (*p == ':') 5472 { 5473 // "s:" is start of "s:var", but "n:" is not and can be used in 5474 // slice "[n:]". Also "xx:" is not a namespace. 5475 len = (int)(p - *arg); 5476 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL) 5477 || len > 1) 5478 break; 5479 } 5480 } 5481 if (p == *arg) // no name found 5482 return 0; 5483 5484 len = (int)(p - *arg); 5485 *arg = p; 5486 5487 return len; 5488 } 5489 5490 /* 5491 * Get the length of the name of a variable or function. 5492 * Only the name is recognized, does not handle ".key" or "[idx]". 5493 * "arg" is advanced to the first non-white character after the name. 5494 * Return -1 if curly braces expansion failed. 5495 * Return 0 if something else is wrong. 5496 * If the name contains 'magic' {}'s, expand them and return the 5497 * expanded name in an allocated string via 'alias' - caller must free. 5498 */ 5499 int 5500 get_name_len( 5501 char_u **arg, 5502 char_u **alias, 5503 int evaluate, 5504 int verbose) 5505 { 5506 int len; 5507 char_u *p; 5508 char_u *expr_start; 5509 char_u *expr_end; 5510 5511 *alias = NULL; // default to no alias 5512 5513 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 5514 && (*arg)[2] == (int)KE_SNR) 5515 { 5516 // hard coded <SNR>, already translated 5517 *arg += 3; 5518 return get_id_len(arg) + 3; 5519 } 5520 len = eval_fname_script(*arg); 5521 if (len > 0) 5522 { 5523 // literal "<SID>", "s:" or "<SNR>" 5524 *arg += len; 5525 } 5526 5527 /* 5528 * Find the end of the name; check for {} construction. 5529 */ 5530 p = find_name_end(*arg, &expr_start, &expr_end, 5531 len > 0 ? 0 : FNE_CHECK_START); 5532 if (expr_start != NULL) 5533 { 5534 char_u *temp_string; 5535 5536 if (!evaluate) 5537 { 5538 len += (int)(p - *arg); 5539 *arg = skipwhite(p); 5540 return len; 5541 } 5542 5543 /* 5544 * Include any <SID> etc in the expanded string: 5545 * Thus the -len here. 5546 */ 5547 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 5548 if (temp_string == NULL) 5549 return -1; 5550 *alias = temp_string; 5551 *arg = skipwhite(p); 5552 return (int)STRLEN(temp_string); 5553 } 5554 5555 len += get_id_len(arg); 5556 // Only give an error when there is something, otherwise it will be 5557 // reported at a higher level. 5558 if (len == 0 && verbose && **arg != NUL) 5559 semsg(_(e_invalid_expression_str), *arg); 5560 5561 return len; 5562 } 5563 5564 /* 5565 * Find the end of a variable or function name, taking care of magic braces. 5566 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 5567 * start and end of the first magic braces item. 5568 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 5569 * Return a pointer to just after the name. Equal to "arg" if there is no 5570 * valid name. 5571 */ 5572 char_u * 5573 find_name_end( 5574 char_u *arg, 5575 char_u **expr_start, 5576 char_u **expr_end, 5577 int flags) 5578 { 5579 int mb_nest = 0; 5580 int br_nest = 0; 5581 char_u *p; 5582 int len; 5583 int vim9script = in_vim9script(); 5584 5585 if (expr_start != NULL) 5586 { 5587 *expr_start = NULL; 5588 *expr_end = NULL; 5589 } 5590 5591 // Quick check for valid starting character. 5592 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) 5593 && (*arg != '{' || vim9script)) 5594 return arg; 5595 5596 for (p = arg; *p != NUL 5597 && (eval_isnamec(*p) 5598 || (*p == '{' && !vim9script) 5599 || ((flags & FNE_INCL_BR) && (*p == '[' 5600 || (*p == '.' && eval_isdictc(p[1])))) 5601 || mb_nest != 0 5602 || br_nest != 0); MB_PTR_ADV(p)) 5603 { 5604 if (*p == '\'') 5605 { 5606 // skip over 'string' to avoid counting [ and ] inside it. 5607 for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p)) 5608 ; 5609 if (*p == NUL) 5610 break; 5611 } 5612 else if (*p == '"') 5613 { 5614 // skip over "str\"ing" to avoid counting [ and ] inside it. 5615 for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) 5616 if (*p == '\\' && p[1] != NUL) 5617 ++p; 5618 if (*p == NUL) 5619 break; 5620 } 5621 else if (br_nest == 0 && mb_nest == 0 && *p == ':') 5622 { 5623 // "s:" is start of "s:var", but "n:" is not and can be used in 5624 // slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. 5625 len = (int)(p - arg); 5626 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL) 5627 || (len > 1 && p[-1] != '}')) 5628 break; 5629 } 5630 5631 if (mb_nest == 0) 5632 { 5633 if (*p == '[') 5634 ++br_nest; 5635 else if (*p == ']') 5636 --br_nest; 5637 } 5638 5639 if (br_nest == 0 && !vim9script) 5640 { 5641 if (*p == '{') 5642 { 5643 mb_nest++; 5644 if (expr_start != NULL && *expr_start == NULL) 5645 *expr_start = p; 5646 } 5647 else if (*p == '}') 5648 { 5649 mb_nest--; 5650 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 5651 *expr_end = p; 5652 } 5653 } 5654 } 5655 5656 return p; 5657 } 5658 5659 /* 5660 * Expands out the 'magic' {}'s in a variable/function name. 5661 * Note that this can call itself recursively, to deal with 5662 * constructs like foo{bar}{baz}{bam} 5663 * The four pointer arguments point to "foo{expre}ss{ion}bar" 5664 * "in_start" ^ 5665 * "expr_start" ^ 5666 * "expr_end" ^ 5667 * "in_end" ^ 5668 * 5669 * Returns a new allocated string, which the caller must free. 5670 * Returns NULL for failure. 5671 */ 5672 static char_u * 5673 make_expanded_name( 5674 char_u *in_start, 5675 char_u *expr_start, 5676 char_u *expr_end, 5677 char_u *in_end) 5678 { 5679 char_u c1; 5680 char_u *retval = NULL; 5681 char_u *temp_result; 5682 5683 if (expr_end == NULL || in_end == NULL) 5684 return NULL; 5685 *expr_start = NUL; 5686 *expr_end = NUL; 5687 c1 = *in_end; 5688 *in_end = NUL; 5689 5690 temp_result = eval_to_string(expr_start + 1, FALSE); 5691 if (temp_result != NULL) 5692 { 5693 retval = alloc(STRLEN(temp_result) + (expr_start - in_start) 5694 + (in_end - expr_end) + 1); 5695 if (retval != NULL) 5696 { 5697 STRCPY(retval, in_start); 5698 STRCAT(retval, temp_result); 5699 STRCAT(retval, expr_end + 1); 5700 } 5701 } 5702 vim_free(temp_result); 5703 5704 *in_end = c1; // put char back for error messages 5705 *expr_start = '{'; 5706 *expr_end = '}'; 5707 5708 if (retval != NULL) 5709 { 5710 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 5711 if (expr_start != NULL) 5712 { 5713 // Further expansion! 5714 temp_result = make_expanded_name(retval, expr_start, 5715 expr_end, temp_result); 5716 vim_free(retval); 5717 retval = temp_result; 5718 } 5719 } 5720 5721 return retval; 5722 } 5723 5724 /* 5725 * Return TRUE if character "c" can be used in a variable or function name. 5726 * Does not include '{' or '}' for magic braces. 5727 */ 5728 int 5729 eval_isnamec(int c) 5730 { 5731 return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR; 5732 } 5733 5734 /* 5735 * Return TRUE if character "c" can be used as the first character in a 5736 * variable or function name (excluding '{' and '}'). 5737 */ 5738 int 5739 eval_isnamec1(int c) 5740 { 5741 return ASCII_ISALPHA(c) || c == '_'; 5742 } 5743 5744 /* 5745 * Return TRUE if character "c" can be used as the first character of a 5746 * dictionary key. 5747 */ 5748 int 5749 eval_isdictc(int c) 5750 { 5751 return ASCII_ISALNUM(c) || c == '_'; 5752 } 5753 5754 /* 5755 * Handle: 5756 * - expr[expr], expr[expr:expr] subscript 5757 * - ".name" lookup 5758 * - function call with Funcref variable: func(expr) 5759 * - method call: var->method() 5760 * 5761 * Can all be combined in any order: dict.func(expr)[idx]['func'](expr)->len() 5762 */ 5763 int 5764 handle_subscript( 5765 char_u **arg, 5766 typval_T *rettv, 5767 evalarg_T *evalarg, 5768 int verbose) // give error messages 5769 { 5770 int evaluate = evalarg != NULL 5771 && (evalarg->eval_flags & EVAL_EVALUATE); 5772 int ret = OK; 5773 dict_T *selfdict = NULL; 5774 int check_white = TRUE; 5775 int getnext; 5776 char_u *p; 5777 5778 while (ret == OK) 5779 { 5780 // When at the end of the line and ".name" or "->{" or "->X" follows in 5781 // the next line then consume the line break. 5782 p = eval_next_non_blank(*arg, evalarg, &getnext); 5783 if (getnext 5784 && ((rettv->v_type == VAR_DICT && *p == '.' && eval_isdictc(p[1])) 5785 || (p[0] == '-' && p[1] == '>' && (p[2] == '{' 5786 || ASCII_ISALPHA(in_vim9script() ? *skipwhite(p + 2) 5787 : p[2]))))) 5788 { 5789 *arg = eval_next_line(evalarg); 5790 p = *arg; 5791 check_white = FALSE; 5792 } 5793 5794 if (rettv->v_type == VAR_ANY) 5795 { 5796 char_u *exp_name; 5797 int cc; 5798 int idx; 5799 ufunc_T *ufunc; 5800 type_T *type; 5801 5802 // Found script from "import * as {name}", script item name must 5803 // follow. 5804 if (**arg != '.') 5805 { 5806 if (verbose) 5807 semsg(_(e_expected_str_but_got_str), "'.'", *arg); 5808 ret = FAIL; 5809 break; 5810 } 5811 ++*arg; 5812 if (IS_WHITE_OR_NUL(**arg)) 5813 { 5814 if (verbose) 5815 emsg(_(e_no_white_space_allowed_after_dot)); 5816 ret = FAIL; 5817 break; 5818 } 5819 5820 // isolate the name 5821 exp_name = *arg; 5822 while (eval_isnamec(**arg)) 5823 ++*arg; 5824 cc = **arg; 5825 **arg = NUL; 5826 5827 idx = find_exported(rettv->vval.v_number, exp_name, &ufunc, &type, 5828 evalarg->eval_cctx, verbose); 5829 **arg = cc; 5830 *arg = skipwhite(*arg); 5831 5832 if (idx < 0 && ufunc == NULL) 5833 { 5834 ret = FAIL; 5835 break; 5836 } 5837 if (idx >= 0) 5838 { 5839 scriptitem_T *si = SCRIPT_ITEM(rettv->vval.v_number); 5840 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; 5841 5842 copy_tv(sv->sv_tv, rettv); 5843 } 5844 else 5845 { 5846 rettv->v_type = VAR_FUNC; 5847 rettv->vval.v_string = vim_strsave(ufunc->uf_name); 5848 } 5849 } 5850 5851 if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC 5852 || rettv->v_type == VAR_PARTIAL)) 5853 && (!check_white || !VIM_ISWHITE(*(*arg - 1)))) 5854 { 5855 ret = call_func_rettv(arg, evalarg, rettv, evaluate, 5856 selfdict, NULL); 5857 5858 // Stop the expression evaluation when immediately aborting on 5859 // error, or when an interrupt occurred or an exception was thrown 5860 // but not caught. 5861 if (aborting()) 5862 { 5863 if (ret == OK) 5864 clear_tv(rettv); 5865 ret = FAIL; 5866 } 5867 dict_unref(selfdict); 5868 selfdict = NULL; 5869 } 5870 else if (p[0] == '-' && p[1] == '>') 5871 { 5872 if (in_vim9script()) 5873 *arg = skipwhite(p + 2); 5874 else 5875 *arg = p + 2; 5876 if (ret == OK) 5877 { 5878 if (VIM_ISWHITE(**arg)) 5879 { 5880 emsg(_(e_nowhitespace)); 5881 ret = FAIL; 5882 } 5883 else if ((**arg == '{' && !in_vim9script()) || **arg == '(') 5884 // expr->{lambda}() or expr->(lambda)() 5885 ret = eval_lambda(arg, rettv, evalarg, verbose); 5886 else 5887 // expr->name() 5888 ret = eval_method(arg, rettv, evalarg, verbose); 5889 } 5890 } 5891 // "." is ".name" lookup when we found a dict or when evaluating and 5892 // scriptversion is at least 2, where string concatenation is "..". 5893 else if (**arg == '[' 5894 || (**arg == '.' && (rettv->v_type == VAR_DICT 5895 || (!evaluate 5896 && (*arg)[1] != '.' 5897 && !in_old_script(2))))) 5898 { 5899 dict_unref(selfdict); 5900 if (rettv->v_type == VAR_DICT) 5901 { 5902 selfdict = rettv->vval.v_dict; 5903 if (selfdict != NULL) 5904 ++selfdict->dv_refcount; 5905 } 5906 else 5907 selfdict = NULL; 5908 if (eval_index(arg, rettv, evalarg, verbose) == FAIL) 5909 { 5910 clear_tv(rettv); 5911 ret = FAIL; 5912 } 5913 } 5914 else 5915 break; 5916 } 5917 5918 // Turn "dict.Func" into a partial for "Func" bound to "dict". 5919 // Don't do this when "Func" is already a partial that was bound 5920 // explicitly (pt_auto is FALSE). 5921 if (selfdict != NULL 5922 && (rettv->v_type == VAR_FUNC 5923 || (rettv->v_type == VAR_PARTIAL 5924 && (rettv->vval.v_partial->pt_auto 5925 || rettv->vval.v_partial->pt_dict == NULL)))) 5926 selfdict = make_partial(selfdict, rettv); 5927 5928 dict_unref(selfdict); 5929 return ret; 5930 } 5931 5932 /* 5933 * Make a copy of an item. 5934 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 5935 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 5936 * reference to an already copied list/dict can be used. 5937 * Returns FAIL or OK. 5938 */ 5939 int 5940 item_copy( 5941 typval_T *from, 5942 typval_T *to, 5943 int deep, 5944 int copyID) 5945 { 5946 static int recurse = 0; 5947 int ret = OK; 5948 5949 if (recurse >= DICT_MAXNEST) 5950 { 5951 emsg(_("E698: variable nested too deep for making a copy")); 5952 return FAIL; 5953 } 5954 ++recurse; 5955 5956 switch (from->v_type) 5957 { 5958 case VAR_NUMBER: 5959 case VAR_FLOAT: 5960 case VAR_STRING: 5961 case VAR_FUNC: 5962 case VAR_PARTIAL: 5963 case VAR_BOOL: 5964 case VAR_SPECIAL: 5965 case VAR_JOB: 5966 case VAR_CHANNEL: 5967 case VAR_INSTR: 5968 copy_tv(from, to); 5969 break; 5970 case VAR_LIST: 5971 to->v_type = VAR_LIST; 5972 to->v_lock = 0; 5973 if (from->vval.v_list == NULL) 5974 to->vval.v_list = NULL; 5975 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 5976 { 5977 // use the copy made earlier 5978 to->vval.v_list = from->vval.v_list->lv_copylist; 5979 ++to->vval.v_list->lv_refcount; 5980 } 5981 else 5982 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 5983 if (to->vval.v_list == NULL) 5984 ret = FAIL; 5985 break; 5986 case VAR_BLOB: 5987 ret = blob_copy(from->vval.v_blob, to); 5988 break; 5989 case VAR_DICT: 5990 to->v_type = VAR_DICT; 5991 to->v_lock = 0; 5992 if (from->vval.v_dict == NULL) 5993 to->vval.v_dict = NULL; 5994 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 5995 { 5996 // use the copy made earlier 5997 to->vval.v_dict = from->vval.v_dict->dv_copydict; 5998 ++to->vval.v_dict->dv_refcount; 5999 } 6000 else 6001 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 6002 if (to->vval.v_dict == NULL) 6003 ret = FAIL; 6004 break; 6005 case VAR_UNKNOWN: 6006 case VAR_ANY: 6007 case VAR_VOID: 6008 internal_error_no_abort("item_copy(UNKNOWN)"); 6009 ret = FAIL; 6010 } 6011 --recurse; 6012 return ret; 6013 } 6014 6015 void 6016 echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr) 6017 { 6018 char_u *tofree; 6019 char_u numbuf[NUMBUFLEN]; 6020 char_u *p = echo_string(rettv, &tofree, numbuf, get_copyID()); 6021 6022 if (*atstart) 6023 { 6024 *atstart = FALSE; 6025 // Call msg_start() after eval1(), evaluating the expression 6026 // may cause a message to appear. 6027 if (with_space) 6028 { 6029 // Mark the saved text as finishing the line, so that what 6030 // follows is displayed on a new line when scrolling back 6031 // at the more prompt. 6032 msg_sb_eol(); 6033 msg_start(); 6034 } 6035 } 6036 else if (with_space) 6037 msg_puts_attr(" ", echo_attr); 6038 6039 if (p != NULL) 6040 for ( ; *p != NUL && !got_int; ++p) 6041 { 6042 if (*p == '\n' || *p == '\r' || *p == TAB) 6043 { 6044 if (*p != TAB && *needclr) 6045 { 6046 // remove any text still there from the command 6047 msg_clr_eos(); 6048 *needclr = FALSE; 6049 } 6050 msg_putchar_attr(*p, echo_attr); 6051 } 6052 else 6053 { 6054 if (has_mbyte) 6055 { 6056 int i = (*mb_ptr2len)(p); 6057 6058 (void)msg_outtrans_len_attr(p, i, echo_attr); 6059 p += i - 1; 6060 } 6061 else 6062 (void)msg_outtrans_len_attr(p, 1, echo_attr); 6063 } 6064 } 6065 vim_free(tofree); 6066 } 6067 6068 /* 6069 * ":echo expr1 ..." print each argument separated with a space, add a 6070 * newline at the end. 6071 * ":echon expr1 ..." print each argument plain. 6072 */ 6073 void 6074 ex_echo(exarg_T *eap) 6075 { 6076 char_u *arg = eap->arg; 6077 typval_T rettv; 6078 char_u *arg_start; 6079 int needclr = TRUE; 6080 int atstart = TRUE; 6081 int did_emsg_before = did_emsg; 6082 int called_emsg_before = called_emsg; 6083 evalarg_T evalarg; 6084 6085 fill_evalarg_from_eap(&evalarg, eap, eap->skip); 6086 6087 if (eap->skip) 6088 ++emsg_skip; 6089 while ((!ends_excmd2(eap->cmd, arg) || *arg == '"') && !got_int) 6090 { 6091 // If eval1() causes an error message the text from the command may 6092 // still need to be cleared. E.g., "echo 22,44". 6093 need_clr_eos = needclr; 6094 6095 arg_start = arg; 6096 if (eval1(&arg, &rettv, &evalarg) == FAIL) 6097 { 6098 /* 6099 * Report the invalid expression unless the expression evaluation 6100 * has been cancelled due to an aborting error, an interrupt, or an 6101 * exception. 6102 */ 6103 if (!aborting() && did_emsg == did_emsg_before 6104 && called_emsg == called_emsg_before) 6105 semsg(_(e_invalid_expression_str), arg_start); 6106 need_clr_eos = FALSE; 6107 break; 6108 } 6109 need_clr_eos = FALSE; 6110 6111 if (!eap->skip) 6112 { 6113 if (rettv.v_type == VAR_VOID) 6114 { 6115 semsg(_(e_expression_does_not_result_in_value_str), arg_start); 6116 break; 6117 } 6118 echo_one(&rettv, eap->cmdidx == CMD_echo, &atstart, &needclr); 6119 } 6120 6121 clear_tv(&rettv); 6122 arg = skipwhite(arg); 6123 } 6124 set_nextcmd(eap, arg); 6125 clear_evalarg(&evalarg, eap); 6126 6127 if (eap->skip) 6128 --emsg_skip; 6129 else 6130 { 6131 // remove text that may still be there from the command 6132 if (needclr) 6133 msg_clr_eos(); 6134 if (eap->cmdidx == CMD_echo) 6135 msg_end(); 6136 } 6137 } 6138 6139 /* 6140 * ":echohl {name}". 6141 */ 6142 void 6143 ex_echohl(exarg_T *eap) 6144 { 6145 echo_attr = syn_name2attr(eap->arg); 6146 } 6147 6148 /* 6149 * Returns the :echo attribute 6150 */ 6151 int 6152 get_echo_attr(void) 6153 { 6154 return echo_attr; 6155 } 6156 6157 /* 6158 * ":execute expr1 ..." execute the result of an expression. 6159 * ":echomsg expr1 ..." Print a message 6160 * ":echoerr expr1 ..." Print an error 6161 * ":echoconsole expr1 ..." Print a message on stdout 6162 * Each gets spaces around each argument and a newline at the end for 6163 * echo commands 6164 */ 6165 void 6166 ex_execute(exarg_T *eap) 6167 { 6168 char_u *arg = eap->arg; 6169 typval_T rettv; 6170 int ret = OK; 6171 char_u *p; 6172 garray_T ga; 6173 int len; 6174 long start_lnum = SOURCING_LNUM; 6175 6176 ga_init2(&ga, 1, 80); 6177 6178 if (eap->skip) 6179 ++emsg_skip; 6180 while (!ends_excmd2(eap->cmd, arg) || *arg == '"') 6181 { 6182 ret = eval1_emsg(&arg, &rettv, eap); 6183 if (ret == FAIL) 6184 break; 6185 6186 if (!eap->skip) 6187 { 6188 char_u buf[NUMBUFLEN]; 6189 6190 if (eap->cmdidx == CMD_execute) 6191 { 6192 if (rettv.v_type == VAR_CHANNEL || rettv.v_type == VAR_JOB) 6193 { 6194 semsg(_(e_using_invalid_value_as_string_str), 6195 vartype_name(rettv.v_type)); 6196 p = NULL; 6197 } 6198 else 6199 p = tv_get_string_buf(&rettv, buf); 6200 } 6201 else 6202 p = tv_stringify(&rettv, buf); 6203 if (p == NULL) 6204 { 6205 clear_tv(&rettv); 6206 ret = FAIL; 6207 break; 6208 } 6209 len = (int)STRLEN(p); 6210 if (ga_grow(&ga, len + 2) == FAIL) 6211 { 6212 clear_tv(&rettv); 6213 ret = FAIL; 6214 break; 6215 } 6216 if (ga.ga_len) 6217 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 6218 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 6219 ga.ga_len += len; 6220 } 6221 6222 clear_tv(&rettv); 6223 arg = skipwhite(arg); 6224 } 6225 6226 if (ret != FAIL && ga.ga_data != NULL) 6227 { 6228 // use the first line of continuation lines for messages 6229 SOURCING_LNUM = start_lnum; 6230 6231 if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) 6232 { 6233 // Mark the already saved text as finishing the line, so that what 6234 // follows is displayed on a new line when scrolling back at the 6235 // more prompt. 6236 msg_sb_eol(); 6237 } 6238 6239 if (eap->cmdidx == CMD_echomsg) 6240 { 6241 msg_attr(ga.ga_data, echo_attr); 6242 out_flush(); 6243 } 6244 else if (eap->cmdidx == CMD_echoconsole) 6245 { 6246 ui_write(ga.ga_data, (int)STRLEN(ga.ga_data), TRUE); 6247 ui_write((char_u *)"\r\n", 2, TRUE); 6248 } 6249 else if (eap->cmdidx == CMD_echoerr) 6250 { 6251 int save_did_emsg = did_emsg; 6252 6253 // We don't want to abort following commands, restore did_emsg. 6254 emsg(ga.ga_data); 6255 if (!force_abort) 6256 did_emsg = save_did_emsg; 6257 } 6258 else if (eap->cmdidx == CMD_execute) 6259 do_cmdline((char_u *)ga.ga_data, 6260 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 6261 } 6262 6263 ga_clear(&ga); 6264 6265 if (eap->skip) 6266 --emsg_skip; 6267 6268 set_nextcmd(eap, arg); 6269 } 6270 6271 /* 6272 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 6273 * "arg" points to the "&" or '+' when called, to "option" when returning. 6274 * Returns NULL when no option name found. Otherwise pointer to the char 6275 * after the option name. 6276 */ 6277 char_u * 6278 find_option_end(char_u **arg, int *opt_flags) 6279 { 6280 char_u *p = *arg; 6281 6282 ++p; 6283 if (*p == 'g' && p[1] == ':') 6284 { 6285 *opt_flags = OPT_GLOBAL; 6286 p += 2; 6287 } 6288 else if (*p == 'l' && p[1] == ':') 6289 { 6290 *opt_flags = OPT_LOCAL; 6291 p += 2; 6292 } 6293 else 6294 *opt_flags = 0; 6295 6296 if (!ASCII_ISALPHA(*p)) 6297 return NULL; 6298 *arg = p; 6299 6300 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 6301 p += 4; // termcap option 6302 else 6303 while (ASCII_ISALPHA(*p)) 6304 ++p; 6305 return p; 6306 } 6307 6308 /* 6309 * Display script name where an item was last set. 6310 * Should only be invoked when 'verbose' is non-zero. 6311 */ 6312 void 6313 last_set_msg(sctx_T script_ctx) 6314 { 6315 char_u *p; 6316 6317 if (script_ctx.sc_sid != 0) 6318 { 6319 p = home_replace_save(NULL, get_scriptname(script_ctx.sc_sid)); 6320 if (p != NULL) 6321 { 6322 verbose_enter(); 6323 msg_puts(_("\n\tLast set from ")); 6324 msg_puts((char *)p); 6325 if (script_ctx.sc_lnum > 0) 6326 { 6327 msg_puts(_(line_msg)); 6328 msg_outnum((long)script_ctx.sc_lnum); 6329 } 6330 verbose_leave(); 6331 vim_free(p); 6332 } 6333 } 6334 } 6335 6336 #endif // FEAT_EVAL 6337 6338 /* 6339 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 6340 * When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL. 6341 * "flags" can be "g" to do a global substitute. 6342 * Returns an allocated string, NULL for error. 6343 */ 6344 char_u * 6345 do_string_sub( 6346 char_u *str, 6347 char_u *pat, 6348 char_u *sub, 6349 typval_T *expr, 6350 char_u *flags) 6351 { 6352 int sublen; 6353 regmatch_T regmatch; 6354 int i; 6355 int do_all; 6356 char_u *tail; 6357 char_u *end; 6358 garray_T ga; 6359 char_u *ret; 6360 char_u *save_cpo; 6361 char_u *zero_width = NULL; 6362 6363 // Make 'cpoptions' empty, so that the 'l' flag doesn't work here 6364 save_cpo = p_cpo; 6365 p_cpo = empty_option; 6366 6367 ga_init2(&ga, 1, 200); 6368 6369 do_all = (flags[0] == 'g'); 6370 6371 regmatch.rm_ic = p_ic; 6372 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 6373 if (regmatch.regprog != NULL) 6374 { 6375 tail = str; 6376 end = str + STRLEN(str); 6377 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 6378 { 6379 // Skip empty match except for first match. 6380 if (regmatch.startp[0] == regmatch.endp[0]) 6381 { 6382 if (zero_width == regmatch.startp[0]) 6383 { 6384 // avoid getting stuck on a match with an empty string 6385 i = mb_ptr2len(tail); 6386 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, 6387 (size_t)i); 6388 ga.ga_len += i; 6389 tail += i; 6390 continue; 6391 } 6392 zero_width = regmatch.startp[0]; 6393 } 6394 6395 /* 6396 * Get some space for a temporary buffer to do the substitution 6397 * into. It will contain: 6398 * - The text up to where the match is. 6399 * - The substituted text. 6400 * - The text after the match. 6401 */ 6402 sublen = vim_regsub(®match, sub, expr, tail, FALSE, TRUE, FALSE); 6403 if (ga_grow(&ga, (int)((end - tail) + sublen - 6404 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 6405 { 6406 ga_clear(&ga); 6407 break; 6408 } 6409 6410 // copy the text up to where the match is 6411 i = (int)(regmatch.startp[0] - tail); 6412 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 6413 // add the substituted text 6414 (void)vim_regsub(®match, sub, expr, (char_u *)ga.ga_data 6415 + ga.ga_len + i, TRUE, TRUE, FALSE); 6416 ga.ga_len += i + sublen - 1; 6417 tail = regmatch.endp[0]; 6418 if (*tail == NUL) 6419 break; 6420 if (!do_all) 6421 break; 6422 } 6423 6424 if (ga.ga_data != NULL) 6425 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 6426 6427 vim_regfree(regmatch.regprog); 6428 } 6429 6430 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 6431 ga_clear(&ga); 6432 if (p_cpo == empty_option) 6433 p_cpo = save_cpo; 6434 else 6435 { 6436 // Darn, evaluating {sub} expression or {expr} changed the value. 6437 // If it's still empty it was changed and restored, need to restore in 6438 // the complicated way. 6439 if (*p_cpo == NUL) 6440 set_option_value((char_u *)"cpo", 0L, save_cpo, 0); 6441 free_string_option(save_cpo); 6442 } 6443 6444 return ret; 6445 } 6446