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