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 * evalvars.c: functions for dealing with variables 12 */ 13 14 #include "vim.h" 15 16 #if defined(FEAT_EVAL) || defined(PROTO) 17 18 static dictitem_T globvars_var; // variable used for g: 19 static dict_T globvardict; // Dictionary with g: variables 20 #define globvarht globvardict.dv_hashtab 21 22 /* 23 * Old Vim variables such as "v:version" are also available without the "v:". 24 * Also in functions. We need a special hashtable for them. 25 */ 26 static hashtab_T compat_hashtab; 27 28 /* 29 * Array to hold the value of v: variables. 30 * The value is in a dictitem, so that it can also be used in the v: scope. 31 * The reason to use this table anyway is for very quick access to the 32 * variables with the VV_ defines. 33 */ 34 35 // values for vv_flags: 36 #define VV_COMPAT 1 // compatible, also used without "v:" 37 #define VV_RO 2 // read-only 38 #define VV_RO_SBX 4 // read-only in the sandbox 39 40 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}} 41 42 typedef struct vimvar vimvar_T; 43 44 static struct vimvar 45 { 46 char *vv_name; // name of variable, without v: 47 dictitem16_T vv_di; // value and name for key (max 16 chars!) 48 char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX 49 } vimvars[VV_LEN] = 50 { 51 // The order here must match the VV_ defines in vim.h! 52 // Initializing a union does not work, leave tv.vval empty to get zero's. 53 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 54 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 55 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 56 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 57 {VV_NAME("warningmsg", VAR_STRING), 0}, 58 {VV_NAME("statusmsg", VAR_STRING), 0}, 59 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 60 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 61 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 62 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 63 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 64 {VV_NAME("fname", VAR_STRING), VV_RO}, 65 {VV_NAME("lang", VAR_STRING), VV_RO}, 66 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 67 {VV_NAME("ctype", VAR_STRING), VV_RO}, 68 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 69 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 70 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 71 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 72 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 73 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 74 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 75 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 76 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 77 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 78 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 79 {VV_NAME("progname", VAR_STRING), VV_RO}, 80 {VV_NAME("servername", VAR_STRING), VV_RO}, 81 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 82 {VV_NAME("exception", VAR_STRING), VV_RO}, 83 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 84 {VV_NAME("register", VAR_STRING), VV_RO}, 85 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 86 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 87 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 88 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 89 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 90 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 91 {VV_NAME("fcs_choice", VAR_STRING), 0}, 92 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 93 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 94 {VV_NAME("beval_winid", VAR_NUMBER), VV_RO}, 95 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 96 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 97 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 98 {VV_NAME("scrollstart", VAR_STRING), 0}, 99 {VV_NAME("swapname", VAR_STRING), VV_RO}, 100 {VV_NAME("swapchoice", VAR_STRING), 0}, 101 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 102 {VV_NAME("char", VAR_STRING), 0}, 103 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 104 {VV_NAME("mouse_winid", VAR_NUMBER), 0}, 105 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 106 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 107 {VV_NAME("operator", VAR_STRING), VV_RO}, 108 {VV_NAME("searchforward", VAR_NUMBER), 0}, 109 {VV_NAME("hlsearch", VAR_NUMBER), 0}, 110 {VV_NAME("oldfiles", VAR_LIST), 0}, 111 {VV_NAME("windowid", VAR_NUMBER), VV_RO}, 112 {VV_NAME("progpath", VAR_STRING), VV_RO}, 113 {VV_NAME("completed_item", VAR_DICT), VV_RO}, 114 {VV_NAME("option_new", VAR_STRING), VV_RO}, 115 {VV_NAME("option_old", VAR_STRING), VV_RO}, 116 {VV_NAME("option_oldlocal", VAR_STRING), VV_RO}, 117 {VV_NAME("option_oldglobal", VAR_STRING), VV_RO}, 118 {VV_NAME("option_command", VAR_STRING), VV_RO}, 119 {VV_NAME("option_type", VAR_STRING), VV_RO}, 120 {VV_NAME("errors", VAR_LIST), 0}, 121 {VV_NAME("false", VAR_BOOL), VV_RO}, 122 {VV_NAME("true", VAR_BOOL), VV_RO}, 123 {VV_NAME("none", VAR_SPECIAL), VV_RO}, 124 {VV_NAME("null", VAR_SPECIAL), VV_RO}, 125 {VV_NAME("numbermax", VAR_NUMBER), VV_RO}, 126 {VV_NAME("numbermin", VAR_NUMBER), VV_RO}, 127 {VV_NAME("numbersize", VAR_NUMBER), VV_RO}, 128 {VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO}, 129 {VV_NAME("testing", VAR_NUMBER), 0}, 130 {VV_NAME("t_number", VAR_NUMBER), VV_RO}, 131 {VV_NAME("t_string", VAR_NUMBER), VV_RO}, 132 {VV_NAME("t_func", VAR_NUMBER), VV_RO}, 133 {VV_NAME("t_list", VAR_NUMBER), VV_RO}, 134 {VV_NAME("t_dict", VAR_NUMBER), VV_RO}, 135 {VV_NAME("t_float", VAR_NUMBER), VV_RO}, 136 {VV_NAME("t_bool", VAR_NUMBER), VV_RO}, 137 {VV_NAME("t_none", VAR_NUMBER), VV_RO}, 138 {VV_NAME("t_job", VAR_NUMBER), VV_RO}, 139 {VV_NAME("t_channel", VAR_NUMBER), VV_RO}, 140 {VV_NAME("t_blob", VAR_NUMBER), VV_RO}, 141 {VV_NAME("termrfgresp", VAR_STRING), VV_RO}, 142 {VV_NAME("termrbgresp", VAR_STRING), VV_RO}, 143 {VV_NAME("termu7resp", VAR_STRING), VV_RO}, 144 {VV_NAME("termstyleresp", VAR_STRING), VV_RO}, 145 {VV_NAME("termblinkresp", VAR_STRING), VV_RO}, 146 {VV_NAME("event", VAR_DICT), VV_RO}, 147 {VV_NAME("versionlong", VAR_NUMBER), VV_RO}, 148 {VV_NAME("echospace", VAR_NUMBER), VV_RO}, 149 {VV_NAME("argv", VAR_LIST), VV_RO}, 150 {VV_NAME("collate", VAR_STRING), VV_RO}, 151 {VV_NAME("exiting", VAR_SPECIAL), VV_RO}, 152 }; 153 154 // shorthand 155 #define vv_type vv_di.di_tv.v_type 156 #define vv_nr vv_di.di_tv.vval.v_number 157 #define vv_float vv_di.di_tv.vval.v_float 158 #define vv_str vv_di.di_tv.vval.v_string 159 #define vv_list vv_di.di_tv.vval.v_list 160 #define vv_dict vv_di.di_tv.vval.v_dict 161 #define vv_blob vv_di.di_tv.vval.v_blob 162 #define vv_tv vv_di.di_tv 163 164 static dictitem_T vimvars_var; // variable used for v: 165 static dict_T vimvardict; // Dictionary with v: variables 166 #define vimvarht vimvardict.dv_hashtab 167 168 // for VIM_VERSION_ defines 169 #include "version.h" 170 171 static void list_glob_vars(int *first); 172 static void list_buf_vars(int *first); 173 static void list_win_vars(int *first); 174 static void list_tab_vars(int *first); 175 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); 176 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags, char_u *endchars, char_u *op, int var_idx); 177 static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie); 178 static int do_lock_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie); 179 static void list_one_var(dictitem_T *v, char *prefix, int *first); 180 static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first); 181 182 /* 183 * Initialize global and vim special variables 184 */ 185 void 186 evalvars_init(void) 187 { 188 int i; 189 struct vimvar *p; 190 191 init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); 192 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); 193 vimvardict.dv_lock = VAR_FIXED; 194 hash_init(&compat_hashtab); 195 196 for (i = 0; i < VV_LEN; ++i) 197 { 198 p = &vimvars[i]; 199 if (STRLEN(p->vv_name) > DICTITEM16_KEY_LEN) 200 { 201 iemsg("INTERNAL: name too long, increase size of dictitem16_T"); 202 getout(1); 203 } 204 STRCPY(p->vv_di.di_key, p->vv_name); 205 if (p->vv_flags & VV_RO) 206 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 207 else if (p->vv_flags & VV_RO_SBX) 208 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 209 else 210 p->vv_di.di_flags = DI_FLAGS_FIX; 211 212 // add to v: scope dict, unless the value is not always available 213 if (p->vv_type != VAR_UNKNOWN) 214 hash_add(&vimvarht, p->vv_di.di_key); 215 if (p->vv_flags & VV_COMPAT) 216 // add to compat scope dict 217 hash_add(&compat_hashtab, p->vv_di.di_key); 218 } 219 set_vim_var_nr(VV_VERSION, VIM_VERSION_100); 220 set_vim_var_nr(VV_VERSIONLONG, VIM_VERSION_100 * 10000 + highest_patch()); 221 222 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 223 set_vim_var_nr(VV_HLSEARCH, 1L); 224 set_vim_var_nr(VV_EXITING, VVAL_NULL); 225 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); 226 set_vim_var_list(VV_ERRORS, list_alloc()); 227 set_vim_var_dict(VV_EVENT, dict_alloc_lock(VAR_FIXED)); 228 229 set_vim_var_nr(VV_FALSE, VVAL_FALSE); 230 set_vim_var_nr(VV_TRUE, VVAL_TRUE); 231 set_vim_var_nr(VV_NONE, VVAL_NONE); 232 set_vim_var_nr(VV_NULL, VVAL_NULL); 233 set_vim_var_nr(VV_NUMBERMAX, VARNUM_MAX); 234 set_vim_var_nr(VV_NUMBERMIN, VARNUM_MIN); 235 set_vim_var_nr(VV_NUMBERSIZE, sizeof(varnumber_T) * 8); 236 237 set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER); 238 set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING); 239 set_vim_var_nr(VV_TYPE_FUNC, VAR_TYPE_FUNC); 240 set_vim_var_nr(VV_TYPE_LIST, VAR_TYPE_LIST); 241 set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT); 242 set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT); 243 set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL); 244 set_vim_var_nr(VV_TYPE_NONE, VAR_TYPE_NONE); 245 set_vim_var_nr(VV_TYPE_JOB, VAR_TYPE_JOB); 246 set_vim_var_nr(VV_TYPE_CHANNEL, VAR_TYPE_CHANNEL); 247 set_vim_var_nr(VV_TYPE_BLOB, VAR_TYPE_BLOB); 248 249 set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); 250 251 // Default for v:register is not 0 but '"'. This is adjusted once the 252 // clipboard has been setup by calling reset_reg_var(). 253 set_reg_var(0); 254 } 255 256 #if defined(EXITFREE) || defined(PROTO) 257 /* 258 * Free all vim variables information on exit 259 */ 260 void 261 evalvars_clear(void) 262 { 263 int i; 264 struct vimvar *p; 265 266 for (i = 0; i < VV_LEN; ++i) 267 { 268 p = &vimvars[i]; 269 if (p->vv_di.di_tv.v_type == VAR_STRING) 270 VIM_CLEAR(p->vv_str); 271 else if (p->vv_di.di_tv.v_type == VAR_LIST) 272 { 273 list_unref(p->vv_list); 274 p->vv_list = NULL; 275 } 276 } 277 hash_clear(&vimvarht); 278 hash_init(&vimvarht); // garbage_collect() will access it 279 hash_clear(&compat_hashtab); 280 281 // global variables 282 vars_clear(&globvarht); 283 284 // Script-local variables. Clear all the variables here. 285 // The scriptvar_T is cleared later in free_scriptnames(), because a 286 // variable in one script might hold a reference to the whole scope of 287 // another script. 288 for (i = 1; i <= script_items.ga_len; ++i) 289 vars_clear(&SCRIPT_VARS(i)); 290 } 291 #endif 292 293 int 294 garbage_collect_globvars(int copyID) 295 { 296 return set_ref_in_ht(&globvarht, copyID, NULL); 297 } 298 299 int 300 garbage_collect_vimvars(int copyID) 301 { 302 return set_ref_in_ht(&vimvarht, copyID, NULL); 303 } 304 305 int 306 garbage_collect_scriptvars(int copyID) 307 { 308 int i; 309 int idx; 310 int abort = FALSE; 311 scriptitem_T *si; 312 313 for (i = 1; i <= script_items.ga_len; ++i) 314 { 315 abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); 316 317 si = SCRIPT_ITEM(i); 318 for (idx = 0; idx < si->sn_var_vals.ga_len; ++idx) 319 { 320 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; 321 322 if (sv->sv_name != NULL) 323 abort = abort || set_ref_in_item(sv->sv_tv, copyID, NULL, NULL); 324 } 325 } 326 327 return abort; 328 } 329 330 /* 331 * Set an internal variable to a string value. Creates the variable if it does 332 * not already exist. 333 */ 334 void 335 set_internal_string_var(char_u *name, char_u *value) 336 { 337 char_u *val; 338 typval_T *tvp; 339 340 val = vim_strsave(value); 341 if (val != NULL) 342 { 343 tvp = alloc_string_tv(val); 344 if (tvp != NULL) 345 { 346 set_var(name, tvp, FALSE); 347 free_tv(tvp); 348 } 349 } 350 } 351 352 int 353 eval_charconvert( 354 char_u *enc_from, 355 char_u *enc_to, 356 char_u *fname_from, 357 char_u *fname_to) 358 { 359 int err = FALSE; 360 361 set_vim_var_string(VV_CC_FROM, enc_from, -1); 362 set_vim_var_string(VV_CC_TO, enc_to, -1); 363 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 364 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 365 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 366 err = TRUE; 367 set_vim_var_string(VV_CC_FROM, NULL, -1); 368 set_vim_var_string(VV_CC_TO, NULL, -1); 369 set_vim_var_string(VV_FNAME_IN, NULL, -1); 370 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 371 372 if (err) 373 return FAIL; 374 return OK; 375 } 376 377 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 378 int 379 eval_printexpr(char_u *fname, char_u *args) 380 { 381 int err = FALSE; 382 383 set_vim_var_string(VV_FNAME_IN, fname, -1); 384 set_vim_var_string(VV_CMDARG, args, -1); 385 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 386 err = TRUE; 387 set_vim_var_string(VV_FNAME_IN, NULL, -1); 388 set_vim_var_string(VV_CMDARG, NULL, -1); 389 390 if (err) 391 { 392 mch_remove(fname); 393 return FAIL; 394 } 395 return OK; 396 } 397 # endif 398 399 # if defined(FEAT_DIFF) || defined(PROTO) 400 void 401 eval_diff( 402 char_u *origfile, 403 char_u *newfile, 404 char_u *outfile) 405 { 406 int err = FALSE; 407 408 set_vim_var_string(VV_FNAME_IN, origfile, -1); 409 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 410 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 411 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 412 set_vim_var_string(VV_FNAME_IN, NULL, -1); 413 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 414 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 415 } 416 417 void 418 eval_patch( 419 char_u *origfile, 420 char_u *difffile, 421 char_u *outfile) 422 { 423 int err; 424 425 set_vim_var_string(VV_FNAME_IN, origfile, -1); 426 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 427 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 428 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 429 set_vim_var_string(VV_FNAME_IN, NULL, -1); 430 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 431 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 432 } 433 # endif 434 435 #if defined(FEAT_SPELL) || defined(PROTO) 436 /* 437 * Evaluate an expression to a list with suggestions. 438 * For the "expr:" part of 'spellsuggest'. 439 * Returns NULL when there is an error. 440 */ 441 list_T * 442 eval_spell_expr(char_u *badword, char_u *expr) 443 { 444 typval_T save_val; 445 typval_T rettv; 446 list_T *list = NULL; 447 char_u *p = skipwhite(expr); 448 449 // Set "v:val" to the bad word. 450 prepare_vimvar(VV_VAL, &save_val); 451 set_vim_var_string(VV_VAL, badword, -1); 452 if (p_verbose == 0) 453 ++emsg_off; 454 455 if (eval1(&p, &rettv, &EVALARG_EVALUATE) == OK) 456 { 457 if (rettv.v_type != VAR_LIST) 458 clear_tv(&rettv); 459 else 460 list = rettv.vval.v_list; 461 } 462 463 if (p_verbose == 0) 464 --emsg_off; 465 clear_tv(get_vim_var_tv(VV_VAL)); 466 restore_vimvar(VV_VAL, &save_val); 467 468 return list; 469 } 470 471 /* 472 * "list" is supposed to contain two items: a word and a number. Return the 473 * word in "pp" and the number as the return value. 474 * Return -1 if anything isn't right. 475 * Used to get the good word and score from the eval_spell_expr() result. 476 */ 477 int 478 get_spellword(list_T *list, char_u **pp) 479 { 480 listitem_T *li; 481 482 li = list->lv_first; 483 if (li == NULL) 484 return -1; 485 *pp = tv_get_string(&li->li_tv); 486 487 li = li->li_next; 488 if (li == NULL) 489 return -1; 490 return (int)tv_get_number(&li->li_tv); 491 } 492 #endif 493 494 /* 495 * Prepare v: variable "idx" to be used. 496 * Save the current typeval in "save_tv" and clear it. 497 * When not used yet add the variable to the v: hashtable. 498 */ 499 void 500 prepare_vimvar(int idx, typval_T *save_tv) 501 { 502 *save_tv = vimvars[idx].vv_tv; 503 vimvars[idx].vv_str = NULL; // don't free it now 504 if (vimvars[idx].vv_type == VAR_UNKNOWN) 505 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 506 } 507 508 /* 509 * Restore v: variable "idx" to typeval "save_tv". 510 * Note that the v: variable must have been cleared already. 511 * When no longer defined, remove the variable from the v: hashtable. 512 */ 513 void 514 restore_vimvar(int idx, typval_T *save_tv) 515 { 516 hashitem_T *hi; 517 518 vimvars[idx].vv_tv = *save_tv; 519 if (vimvars[idx].vv_type == VAR_UNKNOWN) 520 { 521 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 522 if (HASHITEM_EMPTY(hi)) 523 internal_error("restore_vimvar()"); 524 else 525 hash_remove(&vimvarht, hi); 526 } 527 } 528 529 /* 530 * List Vim variables. 531 */ 532 static void 533 list_vim_vars(int *first) 534 { 535 list_hashtable_vars(&vimvarht, "v:", FALSE, first); 536 } 537 538 /* 539 * List script-local variables, if there is a script. 540 */ 541 static void 542 list_script_vars(int *first) 543 { 544 if (SCRIPT_ID_VALID(current_sctx.sc_sid)) 545 list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), 546 "s:", FALSE, first); 547 } 548 549 /* 550 * Get a list of lines from a HERE document. The here document is a list of 551 * lines surrounded by a marker. 552 * cmd << {marker} 553 * {line1} 554 * {line2} 555 * .... 556 * {marker} 557 * 558 * The {marker} is a string. If the optional 'trim' word is supplied before the 559 * marker, then the leading indentation before the lines (matching the 560 * indentation in the 'cmd' line) is stripped. 561 * 562 * When getting lines for an embedded script (e.g. python, lua, perl, ruby, 563 * tcl, mzscheme), script_get is set to TRUE. In this case, if the marker is 564 * missing, then '.' is accepted as a marker. 565 * 566 * Returns a List with {lines} or NULL. 567 */ 568 list_T * 569 heredoc_get(exarg_T *eap, char_u *cmd, int script_get) 570 { 571 char_u *theline; 572 char_u *marker; 573 list_T *l; 574 char_u *p; 575 int marker_indent_len = 0; 576 int text_indent_len = 0; 577 char_u *text_indent = NULL; 578 char_u dot[] = "."; 579 int comment_char = in_vim9script() ? '#' : '"'; 580 581 if (eap->getline == NULL) 582 { 583 emsg(_("E991: cannot use =<< here")); 584 return NULL; 585 } 586 587 // Check for the optional 'trim' word before the marker 588 cmd = skipwhite(cmd); 589 if (STRNCMP(cmd, "trim", 4) == 0 && (cmd[4] == NUL || VIM_ISWHITE(cmd[4]))) 590 { 591 cmd = skipwhite(cmd + 4); 592 593 // Trim the indentation from all the lines in the here document. 594 // The amount of indentation trimmed is the same as the indentation of 595 // the first line after the :let command line. To find the end marker 596 // the indent of the :let command line is trimmed. 597 p = *eap->cmdlinep; 598 while (VIM_ISWHITE(*p)) 599 { 600 p++; 601 marker_indent_len++; 602 } 603 text_indent_len = -1; 604 } 605 606 // The marker is the next word. 607 if (*cmd != NUL && *cmd != comment_char) 608 { 609 marker = skipwhite(cmd); 610 p = skiptowhite(marker); 611 if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char) 612 { 613 semsg(_(e_trailing_arg), p); 614 return NULL; 615 } 616 *p = NUL; 617 if (!script_get && vim_islower(*marker)) 618 { 619 emsg(_("E221: Marker cannot start with lower case letter")); 620 return NULL; 621 } 622 } 623 else 624 { 625 // When getting lines for an embedded script, if the marker is missing, 626 // accept '.' as the marker. 627 if (script_get) 628 marker = dot; 629 else 630 { 631 emsg(_("E172: Missing marker")); 632 return NULL; 633 } 634 } 635 636 l = list_alloc(); 637 if (l == NULL) 638 return NULL; 639 640 for (;;) 641 { 642 int mi = 0; 643 int ti = 0; 644 645 theline = eap->getline(NUL, eap->cookie, 0, FALSE); 646 if (theline == NULL) 647 { 648 semsg(_("E990: Missing end marker '%s'"), marker); 649 break; 650 } 651 652 // with "trim": skip the indent matching the :let line to find the 653 // marker 654 if (marker_indent_len > 0 655 && STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) 656 mi = marker_indent_len; 657 if (STRCMP(marker, theline + mi) == 0) 658 { 659 vim_free(theline); 660 break; 661 } 662 663 if (text_indent_len == -1 && *theline != NUL) 664 { 665 // set the text indent from the first line. 666 p = theline; 667 text_indent_len = 0; 668 while (VIM_ISWHITE(*p)) 669 { 670 p++; 671 text_indent_len++; 672 } 673 text_indent = vim_strnsave(theline, text_indent_len); 674 } 675 // with "trim": skip the indent matching the first line 676 if (text_indent != NULL) 677 for (ti = 0; ti < text_indent_len; ++ti) 678 if (theline[ti] != text_indent[ti]) 679 break; 680 681 if (list_append_string(l, theline + ti, -1) == FAIL) 682 break; 683 vim_free(theline); 684 } 685 vim_free(text_indent); 686 687 return l; 688 } 689 690 /* 691 * Vim9 variable declaration: 692 * ":var name" 693 * ":var name: type" 694 * ":var name = expr" 695 * ":var name: type = expr" 696 * etc. 697 */ 698 void 699 ex_var(exarg_T *eap) 700 { 701 if (!in_vim9script()) 702 { 703 semsg(_(e_str_cannot_be_used_in_legacy_vim_script), ":var"); 704 return; 705 } 706 ex_let(eap); 707 } 708 709 /* 710 * ":let" list all variable values 711 * ":let var1 var2" list variable values 712 * ":let var = expr" assignment command. 713 * ":let var += expr" assignment command. 714 * ":let var -= expr" assignment command. 715 * ":let var *= expr" assignment command. 716 * ":let var /= expr" assignment command. 717 * ":let var %= expr" assignment command. 718 * ":let var .= expr" assignment command. 719 * ":let var ..= expr" assignment command. 720 * ":let [var1, var2] = expr" unpack list. 721 * ":let var =<< ..." heredoc 722 * ":let var: string" Vim9 declaration 723 * 724 * ":final var = expr" assignment command. 725 * ":final [var1, var2] = expr" unpack list. 726 * 727 * ":const" list all variable values 728 * ":const var1 var2" list variable values 729 * ":const var = expr" assignment command. 730 * ":const [var1, var2] = expr" unpack list. 731 */ 732 void 733 ex_let(exarg_T *eap) 734 { 735 char_u *arg = eap->arg; 736 char_u *expr = NULL; 737 typval_T rettv; 738 int i; 739 int var_count = 0; 740 int semicolon = 0; 741 char_u op[4]; 742 char_u *argend; 743 int first = TRUE; 744 int concat; 745 int has_assign; 746 int flags = 0; 747 int vim9script = in_vim9script(); 748 749 if (eap->cmdidx == CMD_final && !vim9script) 750 { 751 // In legacy Vim script ":final" is short for ":finally". 752 ex_finally(eap); 753 return; 754 } 755 if (eap->cmdidx == CMD_let && vim9script) 756 { 757 emsg(_(e_cannot_use_let_in_vim9_script)); 758 return; 759 } 760 761 if (eap->cmdidx == CMD_const) 762 flags |= ASSIGN_CONST; 763 else if (eap->cmdidx == CMD_final) 764 flags |= ASSIGN_FINAL; 765 766 // Vim9 assignment without ":let", ":const" or ":final" 767 if (eap->arg == eap->cmd) 768 flags |= ASSIGN_NO_DECL; 769 770 argend = skip_var_list(arg, TRUE, &var_count, &semicolon, FALSE); 771 if (argend == NULL) 772 return; 773 if (argend > arg && argend[-1] == '.') // for var.='str' 774 --argend; 775 expr = skipwhite(argend); 776 concat = expr[0] == '.' 777 && ((expr[1] == '=' && in_old_script(2)) 778 || (expr[1] == '.' && expr[2] == '=')); 779 has_assign = *expr == '=' || (vim_strchr((char_u *)"+-*/%", *expr) != NULL 780 && expr[1] == '='); 781 if (!has_assign && !concat) 782 { 783 // ":let" without "=": list variables 784 if (*arg == '[') 785 emsg(_(e_invarg)); 786 else if (expr[0] == '.' && expr[1] == '=') 787 emsg(_("E985: .= is not supported with script version >= 2")); 788 else if (!ends_excmd2(eap->cmd, arg)) 789 { 790 if (vim9script) 791 { 792 if (!ends_excmd2(eap->cmd, skipwhite(argend))) 793 semsg(_(e_trailing_arg), argend); 794 else 795 // Vim9 declaration ":var name: type" 796 arg = vim9_declare_scriptvar(eap, arg); 797 } 798 else 799 { 800 // ":let var1 var2" - list values 801 arg = list_arg_vars(eap, arg, &first); 802 } 803 } 804 else if (!eap->skip) 805 { 806 // ":let" 807 list_glob_vars(&first); 808 list_buf_vars(&first); 809 list_win_vars(&first); 810 list_tab_vars(&first); 811 list_script_vars(&first); 812 list_func_vars(&first); 813 list_vim_vars(&first); 814 } 815 set_nextcmd(eap, arg); 816 } 817 else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<') 818 { 819 list_T *l; 820 long cur_lnum = SOURCING_LNUM; 821 822 // HERE document 823 l = heredoc_get(eap, expr + 3, FALSE); 824 if (l != NULL) 825 { 826 rettv_list_set(&rettv, l); 827 if (!eap->skip) 828 { 829 // errors are for the assignment, not the end marker 830 SOURCING_LNUM = cur_lnum; 831 op[0] = '='; 832 op[1] = NUL; 833 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 834 flags, op); 835 } 836 clear_tv(&rettv); 837 } 838 } 839 else 840 { 841 evalarg_T evalarg; 842 int len = 1; 843 844 CLEAR_FIELD(rettv); 845 i = FAIL; 846 if (has_assign || concat) 847 { 848 int cur_lnum; 849 850 op[0] = '='; 851 op[1] = NUL; 852 if (*expr != '=') 853 { 854 if (vim9script && (flags & ASSIGN_NO_DECL) == 0) 855 { 856 // +=, /=, etc. require an existing variable 857 semsg(_(e_cannot_use_operator_on_new_variable), eap->arg); 858 i = FAIL; 859 } 860 else if (vim_strchr((char_u *)"+-*/%.", *expr) != NULL) 861 { 862 op[0] = *expr; // +=, -=, *=, /=, %= or .= 863 ++len; 864 if (expr[0] == '.' && expr[1] == '.') // ..= 865 { 866 ++expr; 867 ++len; 868 } 869 } 870 expr += 2; 871 } 872 else 873 ++expr; 874 875 if (vim9script && (!VIM_ISWHITE(*argend) 876 || !IS_WHITE_OR_NUL(*expr))) 877 { 878 vim_strncpy(op, expr - len, len); 879 semsg(_(e_white_space_required_before_and_after_str_at_str), 880 op, argend); 881 i = FAIL; 882 } 883 884 if (eap->skip) 885 ++emsg_skip; 886 fill_evalarg_from_eap(&evalarg, eap, eap->skip); 887 expr = skipwhite_and_linebreak(expr, &evalarg); 888 cur_lnum = SOURCING_LNUM; 889 i = eval0(expr, &rettv, eap, &evalarg); 890 if (eap->skip) 891 --emsg_skip; 892 clear_evalarg(&evalarg, eap); 893 894 // Restore the line number so that any type error is given for the 895 // declaration, not the expression. 896 SOURCING_LNUM = cur_lnum; 897 } 898 if (eap->skip) 899 { 900 if (i != FAIL) 901 clear_tv(&rettv); 902 } 903 else if (i != FAIL) 904 { 905 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 906 flags, op); 907 clear_tv(&rettv); 908 } 909 } 910 } 911 912 /* 913 * Assign the typeval "tv" to the variable or variables at "arg_start". 914 * Handles both "var" with any type and "[var, var; var]" with a list type. 915 * When "op" is not NULL it points to a string with characters that 916 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 917 * or concatenate. 918 * Returns OK or FAIL; 919 */ 920 int 921 ex_let_vars( 922 char_u *arg_start, 923 typval_T *tv, 924 int copy, // copy values from "tv", don't move 925 int semicolon, // from skip_var_list() 926 int var_count, // from skip_var_list() 927 int flags, // ASSIGN_FINAL, ASSIGN_CONST, etc. 928 char_u *op) 929 { 930 char_u *arg = arg_start; 931 list_T *l; 932 int i; 933 int var_idx = 0; 934 listitem_T *item; 935 typval_T ltv; 936 937 if (*arg != '[') 938 { 939 // ":let var = expr" or ":for var in list" 940 if (ex_let_one(arg, tv, copy, flags, op, op, var_idx) == NULL) 941 return FAIL; 942 return OK; 943 } 944 945 // ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 946 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 947 { 948 emsg(_(e_listreq)); 949 return FAIL; 950 } 951 952 i = list_len(l); 953 if (semicolon == 0 && var_count < i) 954 { 955 emsg(_("E687: Less targets than List items")); 956 return FAIL; 957 } 958 if (var_count - semicolon > i) 959 { 960 emsg(_("E688: More targets than List items")); 961 return FAIL; 962 } 963 964 CHECK_LIST_MATERIALIZE(l); 965 item = l->lv_first; 966 while (*arg != ']') 967 { 968 arg = skipwhite(arg + 1); 969 ++var_idx; 970 arg = ex_let_one(arg, &item->li_tv, TRUE, 971 flags | ASSIGN_UNPACK, (char_u *)",;]", op, var_idx); 972 item = item->li_next; 973 if (arg == NULL) 974 return FAIL; 975 976 arg = skipwhite(arg); 977 if (*arg == ';') 978 { 979 // Put the rest of the list (may be empty) in the var after ';'. 980 // Create a new list for this. 981 l = list_alloc(); 982 if (l == NULL) 983 return FAIL; 984 while (item != NULL) 985 { 986 list_append_tv(l, &item->li_tv); 987 item = item->li_next; 988 } 989 990 ltv.v_type = VAR_LIST; 991 ltv.v_lock = 0; 992 ltv.vval.v_list = l; 993 l->lv_refcount = 1; 994 ++var_idx; 995 996 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 997 flags | ASSIGN_UNPACK, (char_u *)"]", op, var_idx); 998 clear_tv(<v); 999 if (arg == NULL) 1000 return FAIL; 1001 break; 1002 } 1003 else if (*arg != ',' && *arg != ']') 1004 { 1005 internal_error("ex_let_vars()"); 1006 return FAIL; 1007 } 1008 } 1009 1010 return OK; 1011 } 1012 1013 /* 1014 * Skip over assignable variable "var" or list of variables "[var, var]". 1015 * Used for ":let varvar = expr" and ":for varvar in expr". 1016 * For "[var, var]" increment "*var_count" for each variable. 1017 * for "[var, var; var]" set "semicolon" to 1. 1018 * If "silent" is TRUE do not give an "invalid argument" error message. 1019 * Return NULL for an error. 1020 */ 1021 char_u * 1022 skip_var_list( 1023 char_u *arg, 1024 int include_type, 1025 int *var_count, 1026 int *semicolon, 1027 int silent) 1028 { 1029 char_u *p, *s; 1030 1031 if (*arg == '[') 1032 { 1033 // "[var, var]": find the matching ']'. 1034 p = arg; 1035 for (;;) 1036 { 1037 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' 1038 s = skip_var_one(p, include_type); 1039 if (s == p) 1040 { 1041 if (!silent) 1042 semsg(_(e_invarg2), p); 1043 return NULL; 1044 } 1045 ++*var_count; 1046 1047 p = skipwhite(s); 1048 if (*p == ']') 1049 break; 1050 else if (*p == ';') 1051 { 1052 if (*semicolon == 1) 1053 { 1054 emsg(_("E452: Double ; in list of variables")); 1055 return NULL; 1056 } 1057 *semicolon = 1; 1058 } 1059 else if (*p != ',') 1060 { 1061 if (!silent) 1062 semsg(_(e_invarg2), p); 1063 return NULL; 1064 } 1065 } 1066 return p + 1; 1067 } 1068 else 1069 return skip_var_one(arg, include_type); 1070 } 1071 1072 /* 1073 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 1074 * l[idx]. 1075 * In Vim9 script also skip over ": type" if "include_type" is TRUE. 1076 */ 1077 char_u * 1078 skip_var_one(char_u *arg, int include_type) 1079 { 1080 char_u *end; 1081 int vim9 = in_vim9script(); 1082 1083 if (*arg == '@' && arg[1] != NUL) 1084 return arg + 2; 1085 end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1086 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1087 1088 // "a: type" is declaring variable "a" with a type, not "a:". 1089 // Same for "s: type". 1090 if (vim9 && end == arg + 2 && end[-1] == ':') 1091 --end; 1092 1093 if (include_type && vim9) 1094 { 1095 if (*end == ':') 1096 end = skip_type(skipwhite(end + 1), FALSE); 1097 } 1098 return end; 1099 } 1100 1101 /* 1102 * List variables for hashtab "ht" with prefix "prefix". 1103 * If "empty" is TRUE also list NULL strings as empty strings. 1104 */ 1105 void 1106 list_hashtable_vars( 1107 hashtab_T *ht, 1108 char *prefix, 1109 int empty, 1110 int *first) 1111 { 1112 hashitem_T *hi; 1113 dictitem_T *di; 1114 int todo; 1115 char_u buf[IOSIZE]; 1116 1117 todo = (int)ht->ht_used; 1118 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1119 { 1120 if (!HASHITEM_EMPTY(hi)) 1121 { 1122 --todo; 1123 di = HI2DI(hi); 1124 1125 // apply :filter /pat/ to variable name 1126 vim_strncpy((char_u *)buf, (char_u *)prefix, IOSIZE - 1); 1127 vim_strcat((char_u *)buf, di->di_key, IOSIZE); 1128 if (message_filtered(buf)) 1129 continue; 1130 1131 if (empty || di->di_tv.v_type != VAR_STRING 1132 || di->di_tv.vval.v_string != NULL) 1133 list_one_var(di, prefix, first); 1134 } 1135 } 1136 } 1137 1138 /* 1139 * List global variables. 1140 */ 1141 static void 1142 list_glob_vars(int *first) 1143 { 1144 list_hashtable_vars(&globvarht, "", TRUE, first); 1145 } 1146 1147 /* 1148 * List buffer variables. 1149 */ 1150 static void 1151 list_buf_vars(int *first) 1152 { 1153 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, "b:", TRUE, first); 1154 } 1155 1156 /* 1157 * List window variables. 1158 */ 1159 static void 1160 list_win_vars(int *first) 1161 { 1162 list_hashtable_vars(&curwin->w_vars->dv_hashtab, "w:", TRUE, first); 1163 } 1164 1165 /* 1166 * List tab page variables. 1167 */ 1168 static void 1169 list_tab_vars(int *first) 1170 { 1171 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, "t:", TRUE, first); 1172 } 1173 1174 /* 1175 * List variables in "arg". 1176 */ 1177 static char_u * 1178 list_arg_vars(exarg_T *eap, char_u *arg, int *first) 1179 { 1180 int error = FALSE; 1181 int len; 1182 char_u *name; 1183 char_u *name_start; 1184 char_u *arg_subsc; 1185 char_u *tofree; 1186 typval_T tv; 1187 1188 while (!ends_excmd2(eap->cmd, arg) && !got_int) 1189 { 1190 if (error || eap->skip) 1191 { 1192 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1193 if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg)) 1194 { 1195 emsg_severe = TRUE; 1196 if (!did_emsg) 1197 semsg(_(e_trailing_arg), arg); 1198 break; 1199 } 1200 } 1201 else 1202 { 1203 // get_name_len() takes care of expanding curly braces 1204 name_start = name = arg; 1205 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1206 if (len <= 0) 1207 { 1208 // This is mainly to keep test 49 working: when expanding 1209 // curly braces fails overrule the exception error message. 1210 if (len < 0 && !aborting()) 1211 { 1212 emsg_severe = TRUE; 1213 semsg(_(e_invarg2), arg); 1214 break; 1215 } 1216 error = TRUE; 1217 } 1218 else 1219 { 1220 arg = skipwhite(arg); 1221 if (tofree != NULL) 1222 name = tofree; 1223 if (eval_variable(name, len, &tv, NULL, 1224 EVAL_VAR_VERBOSE) == FAIL) 1225 error = TRUE; 1226 else 1227 { 1228 // handle d.key, l[idx], f(expr) 1229 arg_subsc = arg; 1230 if (handle_subscript(&arg, &tv, &EVALARG_EVALUATE, TRUE) 1231 == FAIL) 1232 error = TRUE; 1233 else 1234 { 1235 if (arg == arg_subsc && len == 2 && name[1] == ':') 1236 { 1237 switch (*name) 1238 { 1239 case 'g': list_glob_vars(first); break; 1240 case 'b': list_buf_vars(first); break; 1241 case 'w': list_win_vars(first); break; 1242 case 't': list_tab_vars(first); break; 1243 case 'v': list_vim_vars(first); break; 1244 case 's': list_script_vars(first); break; 1245 case 'l': list_func_vars(first); break; 1246 default: 1247 semsg(_("E738: Can't list variables for %s"), name); 1248 } 1249 } 1250 else 1251 { 1252 char_u numbuf[NUMBUFLEN]; 1253 char_u *tf; 1254 int c; 1255 char_u *s; 1256 1257 s = echo_string(&tv, &tf, numbuf, 0); 1258 c = *arg; 1259 *arg = NUL; 1260 list_one_var_a("", 1261 arg == arg_subsc ? name : name_start, 1262 tv.v_type, 1263 s == NULL ? (char_u *)"" : s, 1264 first); 1265 *arg = c; 1266 vim_free(tf); 1267 } 1268 clear_tv(&tv); 1269 } 1270 } 1271 } 1272 1273 vim_free(tofree); 1274 } 1275 1276 arg = skipwhite(arg); 1277 } 1278 1279 return arg; 1280 } 1281 1282 /* 1283 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 1284 * Returns a pointer to the char just after the var name. 1285 * Returns NULL if there is an error. 1286 */ 1287 static char_u * 1288 ex_let_one( 1289 char_u *arg, // points to variable name 1290 typval_T *tv, // value to assign to variable 1291 int copy, // copy value from "tv" 1292 int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc. 1293 char_u *endchars, // valid chars after variable name or NULL 1294 char_u *op, // "+", "-", "." or NULL 1295 int var_idx) // variable index for "let [a, b] = list" 1296 { 1297 int c1; 1298 char_u *name; 1299 char_u *p; 1300 char_u *arg_end = NULL; 1301 int len; 1302 int opt_flags; 1303 char_u *tofree = NULL; 1304 1305 if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 1306 && (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0 1307 && vim_strchr((char_u *)"$@&", *arg) != NULL) 1308 { 1309 vim9_declare_error(arg); 1310 return NULL; 1311 } 1312 1313 // ":let $VAR = expr": Set environment variable. 1314 if (*arg == '$') 1315 { 1316 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1317 && (flags & ASSIGN_FOR_LOOP) == 0) 1318 { 1319 emsg(_("E996: Cannot lock an environment variable")); 1320 return NULL; 1321 } 1322 1323 // Find the end of the name. 1324 ++arg; 1325 name = arg; 1326 len = get_env_len(&arg); 1327 if (len == 0) 1328 semsg(_(e_invarg2), name - 1); 1329 else 1330 { 1331 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL) 1332 semsg(_(e_letwrong), op); 1333 else if (endchars != NULL 1334 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 1335 emsg(_(e_unexpected_characters_in_let)); 1336 else if (!check_secure()) 1337 { 1338 c1 = name[len]; 1339 name[len] = NUL; 1340 p = tv_get_string_chk(tv); 1341 if (p != NULL && op != NULL && *op == '.') 1342 { 1343 int mustfree = FALSE; 1344 char_u *s = vim_getenv(name, &mustfree); 1345 1346 if (s != NULL) 1347 { 1348 p = tofree = concat_str(s, p); 1349 if (mustfree) 1350 vim_free(s); 1351 } 1352 } 1353 if (p != NULL) 1354 { 1355 vim_setenv_ext(name, p); 1356 arg_end = arg; 1357 } 1358 name[len] = c1; 1359 vim_free(tofree); 1360 } 1361 } 1362 } 1363 1364 // ":let &option = expr": Set option value. 1365 // ":let &l:option = expr": Set local option value. 1366 // ":let &g:option = expr": Set global option value. 1367 // ":for &ts in range(8)": Set option value for for loop 1368 else if (*arg == '&') 1369 { 1370 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1371 && (flags & ASSIGN_FOR_LOOP) == 0) 1372 { 1373 emsg(_(e_const_option)); 1374 return NULL; 1375 } 1376 // Find the end of the name. 1377 p = find_option_end(&arg, &opt_flags); 1378 if (p == NULL || (endchars != NULL 1379 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 1380 emsg(_(e_unexpected_characters_in_let)); 1381 else 1382 { 1383 long n = 0; 1384 getoption_T opt_type; 1385 long numval; 1386 char_u *stringval = NULL; 1387 char_u *s = NULL; 1388 int failed = FALSE; 1389 1390 c1 = *p; 1391 *p = NUL; 1392 1393 opt_type = get_option_value(arg, &numval, &stringval, opt_flags); 1394 if ((opt_type == gov_bool 1395 || opt_type == gov_number 1396 || opt_type == gov_hidden_bool 1397 || opt_type == gov_hidden_number) 1398 && (tv->v_type != VAR_STRING || !in_vim9script())) 1399 { 1400 if (opt_type == gov_bool || opt_type == gov_hidden_bool) 1401 // bool, possibly hidden 1402 n = (long)tv_get_bool(tv); 1403 else 1404 // number, possibly hidden 1405 n = (long)tv_get_number(tv); 1406 } 1407 1408 // Avoid setting a string option to the text "v:false" or similar. 1409 // In Vim9 script also don't convert a number to string. 1410 if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL 1411 && (!in_vim9script() || tv->v_type != VAR_NUMBER)) 1412 s = tv_get_string_chk(tv); 1413 1414 if (op != NULL && *op != '=') 1415 { 1416 if (((opt_type == gov_bool || opt_type == gov_number) 1417 && *op == '.') 1418 || (opt_type == gov_string && *op != '.')) 1419 { 1420 semsg(_(e_letwrong), op); 1421 failed = TRUE; // don't set the value 1422 1423 } 1424 else 1425 { 1426 // number, in legacy script also bool 1427 if (opt_type == gov_number 1428 || (opt_type == gov_bool && !in_vim9script())) 1429 { 1430 switch (*op) 1431 { 1432 case '+': n = numval + n; break; 1433 case '-': n = numval - n; break; 1434 case '*': n = numval * n; break; 1435 case '/': n = (long)num_divide(numval, n, 1436 &failed); break; 1437 case '%': n = (long)num_modulus(numval, n, 1438 &failed); break; 1439 } 1440 s = NULL; 1441 } 1442 else if (opt_type == gov_string 1443 && stringval != NULL && s != NULL) 1444 { 1445 // string 1446 s = concat_str(stringval, s); 1447 vim_free(stringval); 1448 stringval = s; 1449 } 1450 } 1451 } 1452 1453 if (!failed) 1454 { 1455 if (opt_type != gov_string || s != NULL) 1456 { 1457 set_option_value(arg, n, s, opt_flags); 1458 arg_end = p; 1459 } 1460 else 1461 emsg(_(e_stringreq)); 1462 } 1463 *p = c1; 1464 vim_free(stringval); 1465 } 1466 } 1467 1468 // ":let @r = expr": Set register contents. 1469 else if (*arg == '@') 1470 { 1471 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1472 && (flags & ASSIGN_FOR_LOOP) == 0) 1473 { 1474 emsg(_("E996: Cannot lock a register")); 1475 return NULL; 1476 } 1477 ++arg; 1478 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL) 1479 semsg(_(e_letwrong), op); 1480 else if (endchars != NULL 1481 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 1482 emsg(_(e_unexpected_characters_in_let)); 1483 else 1484 { 1485 char_u *ptofree = NULL; 1486 char_u *s; 1487 1488 p = tv_get_string_chk(tv); 1489 if (p != NULL && op != NULL && *op == '.') 1490 { 1491 s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); 1492 if (s != NULL) 1493 { 1494 p = ptofree = concat_str(s, p); 1495 vim_free(s); 1496 } 1497 } 1498 if (p != NULL) 1499 { 1500 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 1501 arg_end = arg + 1; 1502 } 1503 vim_free(ptofree); 1504 } 1505 } 1506 1507 // ":let var = expr": Set internal variable. 1508 // ":let var: type = expr": Set internal variable with type. 1509 // ":let {expr} = expr": Idem, name made with curly braces 1510 else if (eval_isnamec1(*arg) || *arg == '{') 1511 { 1512 lval_T lv; 1513 1514 p = get_lval(arg, tv, &lv, FALSE, FALSE, 1515 (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) 1516 ? GLV_NO_DECL : 0, FNE_CHECK_START); 1517 if (p != NULL && lv.ll_name != NULL) 1518 { 1519 if (endchars != NULL && vim_strchr(endchars, 1520 *skipwhite(lv.ll_name_end)) == NULL) 1521 emsg(_(e_unexpected_characters_in_let)); 1522 else 1523 { 1524 set_var_lval(&lv, p, tv, copy, flags, op, var_idx); 1525 arg_end = lv.ll_name_end; 1526 } 1527 } 1528 clear_lval(&lv); 1529 } 1530 1531 else 1532 semsg(_(e_invarg2), arg); 1533 1534 return arg_end; 1535 } 1536 1537 /* 1538 * ":unlet[!] var1 ... " command. 1539 */ 1540 void 1541 ex_unlet(exarg_T *eap) 1542 { 1543 ex_unletlock(eap, eap->arg, 0, 0, do_unlet_var, NULL); 1544 } 1545 1546 /* 1547 * ":lockvar" and ":unlockvar" commands 1548 */ 1549 void 1550 ex_lockvar(exarg_T *eap) 1551 { 1552 char_u *arg = eap->arg; 1553 int deep = 2; 1554 1555 if (eap->forceit) 1556 deep = -1; 1557 else if (vim_isdigit(*arg)) 1558 { 1559 deep = getdigits(&arg); 1560 arg = skipwhite(arg); 1561 } 1562 1563 ex_unletlock(eap, arg, deep, 0, do_lock_var, NULL); 1564 } 1565 1566 /* 1567 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 1568 * Also used for Vim9 script. "callback" is invoked as: 1569 * callback(&lv, name_end, eap, deep, cookie) 1570 */ 1571 void 1572 ex_unletlock( 1573 exarg_T *eap, 1574 char_u *argstart, 1575 int deep, 1576 int glv_flags, 1577 int (*callback)(lval_T *, char_u *, exarg_T *, int, void *), 1578 void *cookie) 1579 { 1580 char_u *arg = argstart; 1581 char_u *name_end; 1582 int error = FALSE; 1583 lval_T lv; 1584 1585 do 1586 { 1587 if (*arg == '$') 1588 { 1589 lv.ll_name = arg; 1590 lv.ll_tv = NULL; 1591 ++arg; 1592 if (get_env_len(&arg) == 0) 1593 { 1594 semsg(_(e_invarg2), arg - 1); 1595 return; 1596 } 1597 if (!error && !eap->skip 1598 && callback(&lv, arg, eap, deep, cookie) == FAIL) 1599 error = TRUE; 1600 name_end = arg; 1601 } 1602 else 1603 { 1604 // Parse the name and find the end. 1605 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 1606 glv_flags | GLV_NO_DECL, FNE_CHECK_START); 1607 if (lv.ll_name == NULL) 1608 error = TRUE; // error but continue parsing 1609 if (name_end == NULL || (!VIM_ISWHITE(*name_end) 1610 && !ends_excmd(*name_end))) 1611 { 1612 if (name_end != NULL) 1613 { 1614 emsg_severe = TRUE; 1615 semsg(_(e_trailing_arg), name_end); 1616 } 1617 if (!(eap->skip || error)) 1618 clear_lval(&lv); 1619 break; 1620 } 1621 1622 if (!error && !eap->skip 1623 && callback(&lv, name_end, eap, deep, cookie) == FAIL) 1624 error = TRUE; 1625 1626 if (!eap->skip) 1627 clear_lval(&lv); 1628 } 1629 1630 arg = skipwhite(name_end); 1631 } while (!ends_excmd2(name_end, arg)); 1632 1633 set_nextcmd(eap, arg); 1634 } 1635 1636 static int 1637 do_unlet_var( 1638 lval_T *lp, 1639 char_u *name_end, 1640 exarg_T *eap, 1641 int deep UNUSED, 1642 void *cookie UNUSED) 1643 { 1644 int forceit = eap->forceit; 1645 int ret = OK; 1646 int cc; 1647 1648 if (lp->ll_tv == NULL) 1649 { 1650 cc = *name_end; 1651 *name_end = NUL; 1652 1653 // Environment variable, normal name or expanded name. 1654 if (*lp->ll_name == '$') 1655 vim_unsetenv(lp->ll_name + 1); 1656 else if (do_unlet(lp->ll_name, forceit) == FAIL) 1657 ret = FAIL; 1658 *name_end = cc; 1659 } 1660 else if ((lp->ll_list != NULL 1661 && value_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) 1662 || (lp->ll_dict != NULL 1663 && value_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) 1664 return FAIL; 1665 else if (lp->ll_range) 1666 { 1667 if (list_unlet_range(lp->ll_list, lp->ll_li, lp->ll_name, lp->ll_n1, 1668 !lp->ll_empty2, lp->ll_n2) == FAIL) 1669 return FAIL; 1670 } 1671 else 1672 { 1673 if (lp->ll_list != NULL) 1674 // unlet a List item. 1675 listitem_remove(lp->ll_list, lp->ll_li); 1676 else 1677 // unlet a Dictionary item. 1678 dictitem_remove(lp->ll_dict, lp->ll_di); 1679 } 1680 1681 return ret; 1682 } 1683 1684 /* 1685 * Unlet one item or a range of items from a list. 1686 * Return OK or FAIL. 1687 */ 1688 int 1689 list_unlet_range( 1690 list_T *l, 1691 listitem_T *li_first, 1692 char_u *name, 1693 long n1_arg, 1694 int has_n2, 1695 long n2) 1696 { 1697 listitem_T *li = li_first; 1698 int n1 = n1_arg; 1699 1700 while (li != NULL && (!has_n2 || n2 >= n1)) 1701 { 1702 if (value_check_lock(li->li_tv.v_lock, name, FALSE)) 1703 return FAIL; 1704 li = li->li_next; 1705 ++n1; 1706 } 1707 1708 // Delete a range of List items. 1709 li = li_first; 1710 n1 = n1_arg; 1711 while (li != NULL && (!has_n2 || n2 >= n1)) 1712 { 1713 listitem_T *next = li->li_next; 1714 1715 listitem_remove(l, li); 1716 li = next; 1717 ++n1; 1718 } 1719 return OK; 1720 } 1721 /* 1722 * "unlet" a variable. Return OK if it existed, FAIL if not. 1723 * When "forceit" is TRUE don't complain if the variable doesn't exist. 1724 */ 1725 int 1726 do_unlet(char_u *name, int forceit) 1727 { 1728 hashtab_T *ht; 1729 hashitem_T *hi; 1730 char_u *varname; 1731 dict_T *d; 1732 dictitem_T *di; 1733 1734 // can't :unlet a script variable in Vim9 script 1735 if (in_vim9script() && check_vim9_unlet(name) == FAIL) 1736 return FAIL; 1737 1738 ht = find_var_ht(name, &varname); 1739 1740 // can't :unlet a script variable in Vim9 script from a function 1741 if (ht == get_script_local_ht() 1742 && SCRIPT_ID_VALID(current_sctx.sc_sid) 1743 && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version 1744 == SCRIPT_VERSION_VIM9 1745 && check_vim9_unlet(name) == FAIL) 1746 return FAIL; 1747 1748 if (ht != NULL && *varname != NUL) 1749 { 1750 d = get_current_funccal_dict(ht); 1751 if (d == NULL) 1752 { 1753 if (ht == &globvarht) 1754 d = &globvardict; 1755 else if (ht == &compat_hashtab) 1756 d = &vimvardict; 1757 else 1758 { 1759 di = find_var_in_ht(ht, *name, (char_u *)"", FALSE); 1760 d = di == NULL ? NULL : di->di_tv.vval.v_dict; 1761 } 1762 if (d == NULL) 1763 { 1764 internal_error("do_unlet()"); 1765 return FAIL; 1766 } 1767 } 1768 hi = hash_find(ht, varname); 1769 if (HASHITEM_EMPTY(hi)) 1770 hi = find_hi_in_scoped_ht(name, &ht); 1771 if (hi != NULL && !HASHITEM_EMPTY(hi)) 1772 { 1773 di = HI2DI(hi); 1774 if (var_check_fixed(di->di_flags, name, FALSE) 1775 || var_check_ro(di->di_flags, name, FALSE) 1776 || value_check_lock(d->dv_lock, name, FALSE)) 1777 return FAIL; 1778 1779 delete_var(ht, hi); 1780 return OK; 1781 } 1782 } 1783 if (forceit) 1784 return OK; 1785 semsg(_("E108: No such variable: \"%s\""), name); 1786 return FAIL; 1787 } 1788 1789 /* 1790 * Lock or unlock variable indicated by "lp". 1791 * "deep" is the levels to go (-1 for unlimited); 1792 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 1793 */ 1794 static int 1795 do_lock_var( 1796 lval_T *lp, 1797 char_u *name_end, 1798 exarg_T *eap, 1799 int deep, 1800 void *cookie UNUSED) 1801 { 1802 int lock = eap->cmdidx == CMD_lockvar; 1803 int ret = OK; 1804 int cc; 1805 dictitem_T *di; 1806 1807 if (lp->ll_tv == NULL) 1808 { 1809 cc = *name_end; 1810 *name_end = NUL; 1811 if (*lp->ll_name == '$') 1812 { 1813 semsg(_(e_lock_unlock), lp->ll_name); 1814 ret = FAIL; 1815 } 1816 else 1817 { 1818 // Normal name or expanded name. 1819 di = find_var(lp->ll_name, NULL, TRUE); 1820 if (di == NULL) 1821 ret = FAIL; 1822 else if ((di->di_flags & DI_FLAGS_FIX) 1823 && di->di_tv.v_type != VAR_DICT 1824 && di->di_tv.v_type != VAR_LIST) 1825 { 1826 // For historic reasons this error is not given for a list or 1827 // dict. E.g., the b: dict could be locked/unlocked. 1828 semsg(_(e_lock_unlock), lp->ll_name); 1829 ret = FAIL; 1830 } 1831 else 1832 { 1833 if (lock) 1834 di->di_flags |= DI_FLAGS_LOCK; 1835 else 1836 di->di_flags &= ~DI_FLAGS_LOCK; 1837 if (deep != 0) 1838 item_lock(&di->di_tv, deep, lock, FALSE); 1839 } 1840 } 1841 *name_end = cc; 1842 } 1843 else if (deep == 0) 1844 { 1845 // nothing to do 1846 } 1847 else if (lp->ll_range) 1848 { 1849 listitem_T *li = lp->ll_li; 1850 1851 // (un)lock a range of List items. 1852 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 1853 { 1854 item_lock(&li->li_tv, deep, lock, FALSE); 1855 li = li->li_next; 1856 ++lp->ll_n1; 1857 } 1858 } 1859 else if (lp->ll_list != NULL) 1860 // (un)lock a List item. 1861 item_lock(&lp->ll_li->li_tv, deep, lock, FALSE); 1862 else 1863 // (un)lock a Dictionary item. 1864 item_lock(&lp->ll_di->di_tv, deep, lock, FALSE); 1865 1866 return ret; 1867 } 1868 1869 /* 1870 * Lock or unlock an item. "deep" is nr of levels to go. 1871 * When "check_refcount" is TRUE do not lock a list or dict with a reference 1872 * count larger than 1. 1873 */ 1874 void 1875 item_lock(typval_T *tv, int deep, int lock, int check_refcount) 1876 { 1877 static int recurse = 0; 1878 list_T *l; 1879 listitem_T *li; 1880 dict_T *d; 1881 blob_T *b; 1882 hashitem_T *hi; 1883 int todo; 1884 1885 if (recurse >= DICT_MAXNEST) 1886 { 1887 emsg(_("E743: variable nested too deep for (un)lock")); 1888 return; 1889 } 1890 if (deep == 0) 1891 return; 1892 ++recurse; 1893 1894 // lock/unlock the item itself 1895 if (lock) 1896 tv->v_lock |= VAR_LOCKED; 1897 else 1898 tv->v_lock &= ~VAR_LOCKED; 1899 1900 switch (tv->v_type) 1901 { 1902 case VAR_UNKNOWN: 1903 case VAR_ANY: 1904 case VAR_VOID: 1905 case VAR_NUMBER: 1906 case VAR_BOOL: 1907 case VAR_STRING: 1908 case VAR_FUNC: 1909 case VAR_PARTIAL: 1910 case VAR_FLOAT: 1911 case VAR_SPECIAL: 1912 case VAR_JOB: 1913 case VAR_CHANNEL: 1914 case VAR_INSTR: 1915 break; 1916 1917 case VAR_BLOB: 1918 if ((b = tv->vval.v_blob) != NULL 1919 && !(check_refcount && b->bv_refcount > 1)) 1920 { 1921 if (lock) 1922 b->bv_lock |= VAR_LOCKED; 1923 else 1924 b->bv_lock &= ~VAR_LOCKED; 1925 } 1926 break; 1927 case VAR_LIST: 1928 if ((l = tv->vval.v_list) != NULL 1929 && !(check_refcount && l->lv_refcount > 1)) 1930 { 1931 if (lock) 1932 l->lv_lock |= VAR_LOCKED; 1933 else 1934 l->lv_lock &= ~VAR_LOCKED; 1935 if ((deep < 0 || deep > 1) && l->lv_first != &range_list_item) 1936 // recursive: lock/unlock the items the List contains 1937 FOR_ALL_LIST_ITEMS(l, li) 1938 item_lock(&li->li_tv, deep - 1, lock, check_refcount); 1939 } 1940 break; 1941 case VAR_DICT: 1942 if ((d = tv->vval.v_dict) != NULL 1943 && !(check_refcount && d->dv_refcount > 1)) 1944 { 1945 if (lock) 1946 d->dv_lock |= VAR_LOCKED; 1947 else 1948 d->dv_lock &= ~VAR_LOCKED; 1949 if (deep < 0 || deep > 1) 1950 { 1951 // recursive: lock/unlock the items the List contains 1952 todo = (int)d->dv_hashtab.ht_used; 1953 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 1954 { 1955 if (!HASHITEM_EMPTY(hi)) 1956 { 1957 --todo; 1958 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock, 1959 check_refcount); 1960 } 1961 } 1962 } 1963 } 1964 } 1965 --recurse; 1966 } 1967 1968 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 1969 /* 1970 * Delete all "menutrans_" variables. 1971 */ 1972 void 1973 del_menutrans_vars(void) 1974 { 1975 hashitem_T *hi; 1976 int todo; 1977 1978 hash_lock(&globvarht); 1979 todo = (int)globvarht.ht_used; 1980 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 1981 { 1982 if (!HASHITEM_EMPTY(hi)) 1983 { 1984 --todo; 1985 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 1986 delete_var(&globvarht, hi); 1987 } 1988 } 1989 hash_unlock(&globvarht); 1990 } 1991 #endif 1992 1993 /* 1994 * Local string buffer for the next two functions to store a variable name 1995 * with its prefix. Allocated in cat_prefix_varname(), freed later in 1996 * get_user_var_name(). 1997 */ 1998 1999 static char_u *varnamebuf = NULL; 2000 static int varnamebuflen = 0; 2001 2002 /* 2003 * Function to concatenate a prefix and a variable name. 2004 */ 2005 char_u * 2006 cat_prefix_varname(int prefix, char_u *name) 2007 { 2008 int len; 2009 2010 len = (int)STRLEN(name) + 3; 2011 if (len > varnamebuflen) 2012 { 2013 vim_free(varnamebuf); 2014 len += 10; // some additional space 2015 varnamebuf = alloc(len); 2016 if (varnamebuf == NULL) 2017 { 2018 varnamebuflen = 0; 2019 return NULL; 2020 } 2021 varnamebuflen = len; 2022 } 2023 *varnamebuf = prefix; 2024 varnamebuf[1] = ':'; 2025 STRCPY(varnamebuf + 2, name); 2026 return varnamebuf; 2027 } 2028 2029 /* 2030 * Function given to ExpandGeneric() to obtain the list of user defined 2031 * (global/buffer/window/built-in) variable names. 2032 */ 2033 char_u * 2034 get_user_var_name(expand_T *xp, int idx) 2035 { 2036 static long_u gdone; 2037 static long_u bdone; 2038 static long_u wdone; 2039 static long_u tdone; 2040 static int vidx; 2041 static hashitem_T *hi; 2042 hashtab_T *ht; 2043 2044 if (idx == 0) 2045 { 2046 gdone = bdone = wdone = vidx = 0; 2047 tdone = 0; 2048 } 2049 2050 // Global variables 2051 if (gdone < globvarht.ht_used) 2052 { 2053 if (gdone++ == 0) 2054 hi = globvarht.ht_array; 2055 else 2056 ++hi; 2057 while (HASHITEM_EMPTY(hi)) 2058 ++hi; 2059 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 2060 return cat_prefix_varname('g', hi->hi_key); 2061 return hi->hi_key; 2062 } 2063 2064 // b: variables 2065 ht = 2066 #ifdef FEAT_CMDWIN 2067 // In cmdwin, the alternative buffer should be used. 2068 (cmdwin_type != 0 && get_cmdline_type() == NUL) ? 2069 &prevwin->w_buffer->b_vars->dv_hashtab : 2070 #endif 2071 &curbuf->b_vars->dv_hashtab; 2072 if (bdone < ht->ht_used) 2073 { 2074 if (bdone++ == 0) 2075 hi = ht->ht_array; 2076 else 2077 ++hi; 2078 while (HASHITEM_EMPTY(hi)) 2079 ++hi; 2080 return cat_prefix_varname('b', hi->hi_key); 2081 } 2082 2083 // w: variables 2084 ht = 2085 #ifdef FEAT_CMDWIN 2086 // In cmdwin, the alternative window should be used. 2087 (cmdwin_type != 0 && get_cmdline_type() == NUL) ? 2088 &prevwin->w_vars->dv_hashtab : 2089 #endif 2090 &curwin->w_vars->dv_hashtab; 2091 if (wdone < ht->ht_used) 2092 { 2093 if (wdone++ == 0) 2094 hi = ht->ht_array; 2095 else 2096 ++hi; 2097 while (HASHITEM_EMPTY(hi)) 2098 ++hi; 2099 return cat_prefix_varname('w', hi->hi_key); 2100 } 2101 2102 // t: variables 2103 ht = &curtab->tp_vars->dv_hashtab; 2104 if (tdone < ht->ht_used) 2105 { 2106 if (tdone++ == 0) 2107 hi = ht->ht_array; 2108 else 2109 ++hi; 2110 while (HASHITEM_EMPTY(hi)) 2111 ++hi; 2112 return cat_prefix_varname('t', hi->hi_key); 2113 } 2114 2115 // v: variables 2116 if (vidx < VV_LEN) 2117 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 2118 2119 VIM_CLEAR(varnamebuf); 2120 varnamebuflen = 0; 2121 return NULL; 2122 } 2123 2124 char * 2125 get_var_special_name(int nr) 2126 { 2127 switch (nr) 2128 { 2129 case VVAL_FALSE: return in_vim9script() ? "false" : "v:false"; 2130 case VVAL_TRUE: return in_vim9script() ? "true" : "v:true"; 2131 case VVAL_NULL: return in_vim9script() ? "null" : "v:null"; 2132 case VVAL_NONE: return "v:none"; 2133 } 2134 internal_error("get_var_special_name()"); 2135 return "42"; 2136 } 2137 2138 /* 2139 * Returns the global variable dictionary 2140 */ 2141 dict_T * 2142 get_globvar_dict(void) 2143 { 2144 return &globvardict; 2145 } 2146 2147 /* 2148 * Returns the global variable hash table 2149 */ 2150 hashtab_T * 2151 get_globvar_ht(void) 2152 { 2153 return &globvarht; 2154 } 2155 2156 /* 2157 * Returns the v: variable dictionary 2158 */ 2159 dict_T * 2160 get_vimvar_dict(void) 2161 { 2162 return &vimvardict; 2163 } 2164 2165 /* 2166 * Returns the index of a v:variable. Negative if not found. 2167 * Returns DI_ flags in "di_flags". 2168 */ 2169 int 2170 find_vim_var(char_u *name, int *di_flags) 2171 { 2172 dictitem_T *di = find_var_in_ht(&vimvarht, 0, name, TRUE); 2173 struct vimvar *vv; 2174 2175 if (di == NULL) 2176 return -1; 2177 *di_flags = di->di_flags; 2178 vv = (struct vimvar *)((char *)di - offsetof(vimvar_T, vv_di)); 2179 return (int)(vv - vimvars); 2180 } 2181 2182 2183 /* 2184 * Set type of v: variable to "type". 2185 */ 2186 void 2187 set_vim_var_type(int idx, vartype_T type) 2188 { 2189 vimvars[idx].vv_type = type; 2190 } 2191 2192 /* 2193 * Set number v: variable to "val". 2194 * Note that this does not set the type, use set_vim_var_type() for that. 2195 */ 2196 void 2197 set_vim_var_nr(int idx, varnumber_T val) 2198 { 2199 vimvars[idx].vv_nr = val; 2200 } 2201 2202 char * 2203 get_vim_var_name(int idx) 2204 { 2205 return vimvars[idx].vv_name; 2206 } 2207 2208 /* 2209 * Get typval_T v: variable value. 2210 */ 2211 typval_T * 2212 get_vim_var_tv(int idx) 2213 { 2214 return &vimvars[idx].vv_tv; 2215 } 2216 2217 /* 2218 * Set v: variable to "tv". Only accepts the same type. 2219 * Takes over the value of "tv". 2220 */ 2221 int 2222 set_vim_var_tv(int idx, typval_T *tv) 2223 { 2224 if (vimvars[idx].vv_type != tv->v_type) 2225 { 2226 emsg(_(e_type_mismatch_for_v_variable)); 2227 clear_tv(tv); 2228 return FAIL; 2229 } 2230 // VV_RO is also checked when compiling, but let's check here as well. 2231 if (vimvars[idx].vv_flags & VV_RO) 2232 { 2233 semsg(_(e_cannot_change_readonly_variable_str), vimvars[idx].vv_name); 2234 return FAIL; 2235 } 2236 if (sandbox && (vimvars[idx].vv_flags & VV_RO_SBX)) 2237 { 2238 semsg(_(e_readonlysbx), vimvars[idx].vv_name); 2239 return FAIL; 2240 } 2241 clear_tv(&vimvars[idx].vv_di.di_tv); 2242 vimvars[idx].vv_di.di_tv = *tv; 2243 return OK; 2244 } 2245 2246 /* 2247 * Get number v: variable value. 2248 */ 2249 varnumber_T 2250 get_vim_var_nr(int idx) 2251 { 2252 return vimvars[idx].vv_nr; 2253 } 2254 2255 /* 2256 * Get string v: variable value. Uses a static buffer, can only be used once. 2257 * If the String variable has never been set, return an empty string. 2258 * Never returns NULL; 2259 */ 2260 char_u * 2261 get_vim_var_str(int idx) 2262 { 2263 return tv_get_string(&vimvars[idx].vv_tv); 2264 } 2265 2266 /* 2267 * Get List v: variable value. Caller must take care of reference count when 2268 * needed. 2269 */ 2270 list_T * 2271 get_vim_var_list(int idx) 2272 { 2273 return vimvars[idx].vv_list; 2274 } 2275 2276 /* 2277 * Get Dict v: variable value. Caller must take care of reference count when 2278 * needed. 2279 */ 2280 dict_T * 2281 get_vim_var_dict(int idx) 2282 { 2283 return vimvars[idx].vv_dict; 2284 } 2285 2286 /* 2287 * Set v:char to character "c". 2288 */ 2289 void 2290 set_vim_var_char(int c) 2291 { 2292 char_u buf[MB_MAXBYTES + 1]; 2293 2294 if (has_mbyte) 2295 buf[(*mb_char2bytes)(c, buf)] = NUL; 2296 else 2297 { 2298 buf[0] = c; 2299 buf[1] = NUL; 2300 } 2301 set_vim_var_string(VV_CHAR, buf, -1); 2302 } 2303 2304 /* 2305 * Set v:count to "count" and v:count1 to "count1". 2306 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 2307 */ 2308 void 2309 set_vcount( 2310 long count, 2311 long count1, 2312 int set_prevcount) 2313 { 2314 if (set_prevcount) 2315 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 2316 vimvars[VV_COUNT].vv_nr = count; 2317 vimvars[VV_COUNT1].vv_nr = count1; 2318 } 2319 2320 /* 2321 * Save variables that might be changed as a side effect. Used when executing 2322 * a timer callback. 2323 */ 2324 void 2325 save_vimvars(vimvars_save_T *vvsave) 2326 { 2327 vvsave->vv_prevcount = vimvars[VV_PREVCOUNT].vv_nr; 2328 vvsave->vv_count = vimvars[VV_COUNT].vv_nr; 2329 vvsave->vv_count1 = vimvars[VV_COUNT1].vv_nr; 2330 } 2331 2332 /* 2333 * Restore variables saved by save_vimvars(). 2334 */ 2335 void 2336 restore_vimvars(vimvars_save_T *vvsave) 2337 { 2338 vimvars[VV_PREVCOUNT].vv_nr = vvsave->vv_prevcount; 2339 vimvars[VV_COUNT].vv_nr = vvsave->vv_count; 2340 vimvars[VV_COUNT1].vv_nr = vvsave->vv_count1; 2341 } 2342 2343 /* 2344 * Set string v: variable to a copy of "val". If 'copy' is FALSE, then set the 2345 * value. 2346 */ 2347 void 2348 set_vim_var_string( 2349 int idx, 2350 char_u *val, 2351 int len) // length of "val" to use or -1 (whole string) 2352 { 2353 clear_tv(&vimvars[idx].vv_di.di_tv); 2354 vimvars[idx].vv_type = VAR_STRING; 2355 if (val == NULL) 2356 vimvars[idx].vv_str = NULL; 2357 else if (len == -1) 2358 vimvars[idx].vv_str = vim_strsave(val); 2359 else 2360 vimvars[idx].vv_str = vim_strnsave(val, len); 2361 } 2362 2363 /* 2364 * Set List v: variable to "val". 2365 */ 2366 void 2367 set_vim_var_list(int idx, list_T *val) 2368 { 2369 clear_tv(&vimvars[idx].vv_di.di_tv); 2370 vimvars[idx].vv_type = VAR_LIST; 2371 vimvars[idx].vv_list = val; 2372 if (val != NULL) 2373 ++val->lv_refcount; 2374 } 2375 2376 /* 2377 * Set Dictionary v: variable to "val". 2378 */ 2379 void 2380 set_vim_var_dict(int idx, dict_T *val) 2381 { 2382 clear_tv(&vimvars[idx].vv_di.di_tv); 2383 vimvars[idx].vv_type = VAR_DICT; 2384 vimvars[idx].vv_dict = val; 2385 if (val != NULL) 2386 { 2387 ++val->dv_refcount; 2388 dict_set_items_ro(val); 2389 } 2390 } 2391 2392 /* 2393 * Set the v:argv list. 2394 */ 2395 void 2396 set_argv_var(char **argv, int argc) 2397 { 2398 list_T *l = list_alloc(); 2399 int i; 2400 2401 if (l == NULL) 2402 getout(1); 2403 l->lv_lock = VAR_FIXED; 2404 for (i = 0; i < argc; ++i) 2405 { 2406 if (list_append_string(l, (char_u *)argv[i], -1) == FAIL) 2407 getout(1); 2408 l->lv_u.mat.lv_last->li_tv.v_lock = VAR_FIXED; 2409 } 2410 set_vim_var_list(VV_ARGV, l); 2411 } 2412 2413 /* 2414 * Reset v:register, taking the 'clipboard' setting into account. 2415 */ 2416 void 2417 reset_reg_var(void) 2418 { 2419 int regname = 0; 2420 2421 // Adjust the register according to 'clipboard', so that when 2422 // "unnamed" is present it becomes '*' or '+' instead of '"'. 2423 #ifdef FEAT_CLIPBOARD 2424 adjust_clip_reg(®name); 2425 #endif 2426 set_reg_var(regname); 2427 } 2428 2429 /* 2430 * Set v:register if needed. 2431 */ 2432 void 2433 set_reg_var(int c) 2434 { 2435 char_u regname; 2436 2437 if (c == 0 || c == ' ') 2438 regname = '"'; 2439 else 2440 regname = c; 2441 // Avoid free/alloc when the value is already right. 2442 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 2443 set_vim_var_string(VV_REG, ®name, 1); 2444 } 2445 2446 /* 2447 * Get or set v:exception. If "oldval" == NULL, return the current value. 2448 * Otherwise, restore the value to "oldval" and return NULL. 2449 * Must always be called in pairs to save and restore v:exception! Does not 2450 * take care of memory allocations. 2451 */ 2452 char_u * 2453 v_exception(char_u *oldval) 2454 { 2455 if (oldval == NULL) 2456 return vimvars[VV_EXCEPTION].vv_str; 2457 2458 vimvars[VV_EXCEPTION].vv_str = oldval; 2459 return NULL; 2460 } 2461 2462 /* 2463 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 2464 * Otherwise, restore the value to "oldval" and return NULL. 2465 * Must always be called in pairs to save and restore v:throwpoint! Does not 2466 * take care of memory allocations. 2467 */ 2468 char_u * 2469 v_throwpoint(char_u *oldval) 2470 { 2471 if (oldval == NULL) 2472 return vimvars[VV_THROWPOINT].vv_str; 2473 2474 vimvars[VV_THROWPOINT].vv_str = oldval; 2475 return NULL; 2476 } 2477 2478 /* 2479 * Set v:cmdarg. 2480 * If "eap" != NULL, use "eap" to generate the value and return the old value. 2481 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 2482 * Must always be called in pairs! 2483 */ 2484 char_u * 2485 set_cmdarg(exarg_T *eap, char_u *oldarg) 2486 { 2487 char_u *oldval; 2488 char_u *newval; 2489 unsigned len; 2490 2491 oldval = vimvars[VV_CMDARG].vv_str; 2492 if (eap == NULL) 2493 { 2494 vim_free(oldval); 2495 vimvars[VV_CMDARG].vv_str = oldarg; 2496 return NULL; 2497 } 2498 2499 if (eap->force_bin == FORCE_BIN) 2500 len = 6; 2501 else if (eap->force_bin == FORCE_NOBIN) 2502 len = 8; 2503 else 2504 len = 0; 2505 2506 if (eap->read_edit) 2507 len += 7; 2508 2509 if (eap->force_ff != 0) 2510 len += 10; // " ++ff=unix" 2511 if (eap->force_enc != 0) 2512 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 2513 if (eap->bad_char != 0) 2514 len += 7 + 4; // " ++bad=" + "keep" or "drop" 2515 2516 newval = alloc(len + 1); 2517 if (newval == NULL) 2518 return NULL; 2519 2520 if (eap->force_bin == FORCE_BIN) 2521 sprintf((char *)newval, " ++bin"); 2522 else if (eap->force_bin == FORCE_NOBIN) 2523 sprintf((char *)newval, " ++nobin"); 2524 else 2525 *newval = NUL; 2526 2527 if (eap->read_edit) 2528 STRCAT(newval, " ++edit"); 2529 2530 if (eap->force_ff != 0) 2531 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 2532 eap->force_ff == 'u' ? "unix" 2533 : eap->force_ff == 'd' ? "dos" 2534 : "mac"); 2535 if (eap->force_enc != 0) 2536 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 2537 eap->cmd + eap->force_enc); 2538 if (eap->bad_char == BAD_KEEP) 2539 STRCPY(newval + STRLEN(newval), " ++bad=keep"); 2540 else if (eap->bad_char == BAD_DROP) 2541 STRCPY(newval + STRLEN(newval), " ++bad=drop"); 2542 else if (eap->bad_char != 0) 2543 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); 2544 vimvars[VV_CMDARG].vv_str = newval; 2545 return oldval; 2546 } 2547 2548 /* 2549 * Get the value of internal variable "name". 2550 * If "flags" has EVAL_VAR_IMPORT may return a VAR_ANY with v_number set to the 2551 * imported script ID. 2552 * Return OK or FAIL. If OK is returned "rettv" must be cleared. 2553 */ 2554 int 2555 eval_variable( 2556 char_u *name, 2557 int len, // length of "name" 2558 typval_T *rettv, // NULL when only checking existence 2559 dictitem_T **dip, // non-NULL when typval's dict item is needed 2560 int flags) // EVAL_VAR_ flags 2561 { 2562 int ret = OK; 2563 typval_T *tv = NULL; 2564 int found = FALSE; 2565 hashtab_T *ht = NULL; 2566 int cc; 2567 type_T *type = NULL; 2568 2569 // truncate the name, so that we can use strcmp() 2570 cc = name[len]; 2571 name[len] = NUL; 2572 2573 // Check for local variable when debugging. 2574 if ((tv = lookup_debug_var(name)) == NULL) 2575 { 2576 // Check for user-defined variables. 2577 dictitem_T *v = find_var(name, &ht, flags & EVAL_VAR_NOAUTOLOAD); 2578 2579 if (v != NULL) 2580 { 2581 tv = &v->di_tv; 2582 if (dip != NULL) 2583 *dip = v; 2584 } 2585 else 2586 ht = NULL; 2587 } 2588 2589 if (tv == NULL && (in_vim9script() || STRNCMP(name, "s:", 2) == 0)) 2590 { 2591 imported_T *import; 2592 char_u *p = STRNCMP(name, "s:", 2) == 0 ? name + 2 : name; 2593 2594 import = find_imported(p, 0, NULL); 2595 2596 // imported variable from another script 2597 if (import != NULL) 2598 { 2599 if (import->imp_funcname != NULL) 2600 { 2601 found = TRUE; 2602 if (rettv != NULL) 2603 { 2604 rettv->v_type = VAR_FUNC; 2605 rettv->vval.v_string = vim_strsave(import->imp_funcname); 2606 } 2607 } 2608 else if (import->imp_flags & IMP_FLAGS_STAR) 2609 { 2610 if ((flags & EVAL_VAR_IMPORT) == 0) 2611 { 2612 if (flags & EVAL_VAR_VERBOSE) 2613 emsg(_(e_import_as_name_not_supported_here)); 2614 ret = FAIL; 2615 } 2616 else 2617 { 2618 if (rettv != NULL) 2619 { 2620 rettv->v_type = VAR_ANY; 2621 rettv->vval.v_number = import->imp_sid; 2622 } 2623 found = TRUE; 2624 } 2625 } 2626 else 2627 { 2628 scriptitem_T *si = SCRIPT_ITEM(import->imp_sid); 2629 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) 2630 + import->imp_var_vals_idx; 2631 tv = sv->sv_tv; 2632 type = sv->sv_type; 2633 } 2634 } 2635 else if (in_vim9script()) 2636 { 2637 ufunc_T *ufunc = find_func(name, FALSE, NULL); 2638 2639 // In Vim9 script we can get a function reference by using the 2640 // function name. 2641 if (ufunc != NULL) 2642 { 2643 found = TRUE; 2644 if (rettv != NULL) 2645 { 2646 rettv->v_type = VAR_FUNC; 2647 rettv->vval.v_string = vim_strsave(ufunc->uf_name); 2648 if (rettv->vval.v_string != NULL) 2649 func_ref(ufunc->uf_name); 2650 } 2651 } 2652 } 2653 } 2654 2655 if (!found) 2656 { 2657 if (tv == NULL) 2658 { 2659 if (rettv != NULL && (flags & EVAL_VAR_VERBOSE)) 2660 semsg(_(e_undefined_variable_str), name); 2661 ret = FAIL; 2662 } 2663 else if (rettv != NULL) 2664 { 2665 if (ht != NULL && ht == get_script_local_ht() 2666 && tv != &SCRIPT_SV(current_sctx.sc_sid)->sv_var.di_tv) 2667 { 2668 svar_T *sv = find_typval_in_script(tv); 2669 2670 if (sv != NULL) 2671 type = sv->sv_type; 2672 } 2673 2674 // If a list or dict variable wasn't initialized, do it now. 2675 if (tv->v_type == VAR_DICT && tv->vval.v_dict == NULL) 2676 { 2677 tv->vval.v_dict = dict_alloc(); 2678 if (tv->vval.v_dict != NULL) 2679 { 2680 ++tv->vval.v_dict->dv_refcount; 2681 tv->vval.v_dict->dv_type = alloc_type(type); 2682 } 2683 } 2684 else if (tv->v_type == VAR_LIST && tv->vval.v_list == NULL) 2685 { 2686 tv->vval.v_list = list_alloc(); 2687 if (tv->vval.v_list != NULL) 2688 { 2689 ++tv->vval.v_list->lv_refcount; 2690 tv->vval.v_list->lv_type = alloc_type(type); 2691 } 2692 } 2693 else if (tv->v_type == VAR_BLOB && tv->vval.v_blob == NULL) 2694 { 2695 tv->vval.v_blob = blob_alloc(); 2696 if (tv->vval.v_blob != NULL) 2697 ++tv->vval.v_blob->bv_refcount; 2698 } 2699 copy_tv(tv, rettv); 2700 } 2701 } 2702 2703 name[len] = cc; 2704 2705 return ret; 2706 } 2707 2708 /* 2709 * Check if variable "name[len]" is a local variable or an argument. 2710 * If so, "*eval_lavars_used" is set to TRUE. 2711 */ 2712 void 2713 check_vars(char_u *name, int len) 2714 { 2715 int cc; 2716 char_u *varname; 2717 hashtab_T *ht; 2718 2719 if (eval_lavars_used == NULL) 2720 return; 2721 2722 // truncate the name, so that we can use strcmp() 2723 cc = name[len]; 2724 name[len] = NUL; 2725 2726 ht = find_var_ht(name, &varname); 2727 if (ht == get_funccal_local_ht() || ht == get_funccal_args_ht()) 2728 { 2729 if (find_var(name, NULL, TRUE) != NULL) 2730 *eval_lavars_used = TRUE; 2731 } 2732 2733 name[len] = cc; 2734 } 2735 2736 /* 2737 * Find variable "name" in the list of variables. 2738 * Return a pointer to it if found, NULL if not found. 2739 * Careful: "a:0" variables don't have a name. 2740 * When "htp" is not NULL set "htp" to the hashtab_T used. 2741 */ 2742 dictitem_T * 2743 find_var(char_u *name, hashtab_T **htp, int no_autoload) 2744 { 2745 char_u *varname; 2746 hashtab_T *ht; 2747 dictitem_T *ret = NULL; 2748 2749 ht = find_var_ht(name, &varname); 2750 if (htp != NULL) 2751 *htp = ht; 2752 if (ht == NULL) 2753 return NULL; 2754 ret = find_var_in_ht(ht, *name, varname, no_autoload); 2755 if (ret != NULL) 2756 return ret; 2757 2758 // Search in parent scope for lambda 2759 ret = find_var_in_scoped_ht(name, no_autoload); 2760 if (ret != NULL) 2761 return ret; 2762 2763 // in Vim9 script items without a scope can be script-local 2764 if (in_vim9script() && name[0] != NUL && name[1] != ':') 2765 { 2766 ht = get_script_local_ht(); 2767 if (ht != NULL) 2768 { 2769 ret = find_var_in_ht(ht, *name, varname, no_autoload); 2770 if (ret != NULL) 2771 { 2772 if (htp != NULL) 2773 *htp = ht; 2774 return ret; 2775 } 2776 } 2777 } 2778 2779 return NULL; 2780 } 2781 2782 /* 2783 * Find variable "varname" in hashtab "ht" with name "htname". 2784 * When "varname" is empty returns curwin/curtab/etc vars dictionary. 2785 * Returns NULL if not found. 2786 */ 2787 dictitem_T * 2788 find_var_in_ht( 2789 hashtab_T *ht, 2790 int htname, 2791 char_u *varname, 2792 int no_autoload) 2793 { 2794 hashitem_T *hi; 2795 2796 if (*varname == NUL) 2797 { 2798 // Must be something like "s:", otherwise "ht" would be NULL. 2799 switch (htname) 2800 { 2801 case 's': return &SCRIPT_SV(current_sctx.sc_sid)->sv_var; 2802 case 'g': return &globvars_var; 2803 case 'v': return &vimvars_var; 2804 case 'b': return &curbuf->b_bufvar; 2805 case 'w': return &curwin->w_winvar; 2806 case 't': return &curtab->tp_winvar; 2807 case 'l': return get_funccal_local_var(); 2808 case 'a': return get_funccal_args_var(); 2809 } 2810 return NULL; 2811 } 2812 2813 hi = hash_find(ht, varname); 2814 if (HASHITEM_EMPTY(hi)) 2815 { 2816 // For global variables we may try auto-loading the script. If it 2817 // worked find the variable again. Don't auto-load a script if it was 2818 // loaded already, otherwise it would be loaded every time when 2819 // checking if a function name is a Funcref variable. 2820 if (ht == &globvarht && !no_autoload) 2821 { 2822 // Note: script_autoload() may make "hi" invalid. It must either 2823 // be obtained again or not used. 2824 if (!script_autoload(varname, FALSE) || aborting()) 2825 return NULL; 2826 hi = hash_find(ht, varname); 2827 } 2828 if (HASHITEM_EMPTY(hi)) 2829 return NULL; 2830 } 2831 return HI2DI(hi); 2832 } 2833 2834 /* 2835 * Get the script-local hashtab. NULL if not in a script context. 2836 */ 2837 hashtab_T * 2838 get_script_local_ht(void) 2839 { 2840 scid_T sid = current_sctx.sc_sid; 2841 2842 if (SCRIPT_ID_VALID(sid)) 2843 return &SCRIPT_VARS(sid); 2844 return NULL; 2845 } 2846 2847 /* 2848 * Look for "name[len]" in script-local variables and functions. 2849 * When "cmd" is TRUE it must look like a command, a function must be followed 2850 * by "(" or "->". 2851 * Return OK when found, FAIL when not found. 2852 */ 2853 int 2854 lookup_scriptitem( 2855 char_u *name, 2856 size_t len, 2857 int cmd, 2858 cctx_T *dummy UNUSED) 2859 { 2860 hashtab_T *ht = get_script_local_ht(); 2861 char_u buffer[30]; 2862 char_u *p; 2863 int res; 2864 hashitem_T *hi; 2865 int is_global = FALSE; 2866 char_u *fname = name; 2867 2868 if (ht == NULL) 2869 return FAIL; 2870 if (len < sizeof(buffer) - 1) 2871 { 2872 // avoid an alloc/free for short names 2873 vim_strncpy(buffer, name, len); 2874 p = buffer; 2875 } 2876 else 2877 { 2878 p = vim_strnsave(name, len); 2879 if (p == NULL) 2880 return FAIL; 2881 } 2882 2883 hi = hash_find(ht, p); 2884 res = HASHITEM_EMPTY(hi) ? FAIL : OK; 2885 2886 // if not script-local, then perhaps imported 2887 if (res == FAIL && find_imported(p, 0, NULL) != NULL) 2888 res = OK; 2889 if (p != buffer) 2890 vim_free(p); 2891 2892 // Find a function, so that a following "->" works. 2893 // When used as a command require "(" or "->" to follow, "Cmd" is a user 2894 // command while "Cmd()" is a function call. 2895 if (res != OK) 2896 { 2897 p = skipwhite(name + len); 2898 2899 if (!cmd || name[len] == '(' || (p[0] == '-' && p[1] == '>')) 2900 { 2901 // Do not check for an internal function, since it might also be a 2902 // valid command, such as ":split" versus "split()". 2903 // Skip "g:" before a function name. 2904 if (name[0] == 'g' && name[1] == ':') 2905 { 2906 is_global = TRUE; 2907 fname = name + 2; 2908 } 2909 if (find_func(fname, is_global, NULL) != NULL) 2910 res = OK; 2911 } 2912 } 2913 2914 return res; 2915 } 2916 2917 /* 2918 * Find the hashtab used for a variable name. 2919 * Return NULL if the name is not valid. 2920 * Set "varname" to the start of name without ':'. 2921 */ 2922 hashtab_T * 2923 find_var_ht(char_u *name, char_u **varname) 2924 { 2925 hashitem_T *hi; 2926 hashtab_T *ht; 2927 2928 if (name[0] == NUL) 2929 return NULL; 2930 if (name[1] != ':') 2931 { 2932 // The name must not start with a colon or #. 2933 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 2934 return NULL; 2935 *varname = name; 2936 2937 // "version" is "v:version" in all scopes if scriptversion < 3. 2938 // Same for a few other variables marked with VV_COMPAT. 2939 if (in_old_script(3)) 2940 { 2941 hi = hash_find(&compat_hashtab, name); 2942 if (!HASHITEM_EMPTY(hi)) 2943 return &compat_hashtab; 2944 } 2945 2946 ht = get_funccal_local_ht(); 2947 if (ht != NULL) 2948 return ht; // local variable 2949 2950 // In Vim9 script items at the script level are script-local, except 2951 // for autoload names. 2952 if (in_vim9script() && vim_strchr(name, AUTOLOAD_CHAR) == NULL) 2953 { 2954 ht = get_script_local_ht(); 2955 if (ht != NULL) 2956 return ht; 2957 } 2958 2959 return &globvarht; // global variable 2960 } 2961 *varname = name + 2; 2962 if (*name == 'g') // global variable 2963 return &globvarht; 2964 // There must be no ':' or '#' in the rest of the name, unless g: is used 2965 if (vim_strchr(name + 2, ':') != NULL 2966 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 2967 return NULL; 2968 if (*name == 'b') // buffer variable 2969 return &curbuf->b_vars->dv_hashtab; 2970 if (*name == 'w') // window variable 2971 return &curwin->w_vars->dv_hashtab; 2972 if (*name == 't') // tab page variable 2973 return &curtab->tp_vars->dv_hashtab; 2974 if (*name == 'v') // v: variable 2975 return &vimvarht; 2976 if (get_current_funccal() != NULL 2977 && get_current_funccal()->func->uf_def_status == UF_NOT_COMPILED) 2978 { 2979 // a: and l: are only used in functions defined with ":function" 2980 if (*name == 'a') // a: function argument 2981 return get_funccal_args_ht(); 2982 if (*name == 'l') // l: local function variable 2983 return get_funccal_local_ht(); 2984 } 2985 if (*name == 's') // script variable 2986 { 2987 ht = get_script_local_ht(); 2988 if (ht != NULL) 2989 return ht; 2990 } 2991 return NULL; 2992 } 2993 2994 /* 2995 * Get the string value of a (global/local) variable. 2996 * Note: see tv_get_string() for how long the pointer remains valid. 2997 * Returns NULL when it doesn't exist. 2998 */ 2999 char_u * 3000 get_var_value(char_u *name) 3001 { 3002 dictitem_T *v; 3003 3004 v = find_var(name, NULL, FALSE); 3005 if (v == NULL) 3006 return NULL; 3007 return tv_get_string(&v->di_tv); 3008 } 3009 3010 /* 3011 * Allocate a new hashtab for a sourced script. It will be used while 3012 * sourcing this script and when executing functions defined in the script. 3013 */ 3014 void 3015 new_script_vars(scid_T id) 3016 { 3017 scriptvar_T *sv; 3018 3019 sv = ALLOC_CLEAR_ONE(scriptvar_T); 3020 if (sv == NULL) 3021 return; 3022 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); 3023 SCRIPT_ITEM(id)->sn_vars = sv; 3024 } 3025 3026 /* 3027 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 3028 * point to it. 3029 */ 3030 void 3031 init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope) 3032 { 3033 hash_init(&dict->dv_hashtab); 3034 dict->dv_lock = 0; 3035 dict->dv_scope = scope; 3036 dict->dv_refcount = DO_NOT_FREE_CNT; 3037 dict->dv_copyID = 0; 3038 dict_var->di_tv.vval.v_dict = dict; 3039 dict_var->di_tv.v_type = VAR_DICT; 3040 dict_var->di_tv.v_lock = VAR_FIXED; 3041 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 3042 dict_var->di_key[0] = NUL; 3043 } 3044 3045 /* 3046 * Unreference a dictionary initialized by init_var_dict(). 3047 */ 3048 void 3049 unref_var_dict(dict_T *dict) 3050 { 3051 // Now the dict needs to be freed if no one else is using it, go back to 3052 // normal reference counting. 3053 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; 3054 dict_unref(dict); 3055 } 3056 3057 /* 3058 * Clean up a list of internal variables. 3059 * Frees all allocated variables and the value they contain. 3060 * Clears hashtab "ht", does not free it. 3061 */ 3062 void 3063 vars_clear(hashtab_T *ht) 3064 { 3065 vars_clear_ext(ht, TRUE); 3066 } 3067 3068 /* 3069 * Like vars_clear(), but only free the value if "free_val" is TRUE. 3070 */ 3071 void 3072 vars_clear_ext(hashtab_T *ht, int free_val) 3073 { 3074 int todo; 3075 hashitem_T *hi; 3076 dictitem_T *v; 3077 3078 hash_lock(ht); 3079 todo = (int)ht->ht_used; 3080 for (hi = ht->ht_array; todo > 0; ++hi) 3081 { 3082 if (!HASHITEM_EMPTY(hi)) 3083 { 3084 --todo; 3085 3086 // Free the variable. Don't remove it from the hashtab, 3087 // ht_array might change then. hash_clear() takes care of it 3088 // later. 3089 v = HI2DI(hi); 3090 if (free_val) 3091 clear_tv(&v->di_tv); 3092 if (v->di_flags & DI_FLAGS_ALLOC) 3093 vim_free(v); 3094 } 3095 } 3096 hash_clear(ht); 3097 hash_init(ht); 3098 } 3099 3100 /* 3101 * Delete a variable from hashtab "ht" at item "hi". 3102 * Clear the variable value and free the dictitem. 3103 */ 3104 void 3105 delete_var(hashtab_T *ht, hashitem_T *hi) 3106 { 3107 dictitem_T *di = HI2DI(hi); 3108 3109 hash_remove(ht, hi); 3110 clear_tv(&di->di_tv); 3111 vim_free(di); 3112 } 3113 3114 /* 3115 * List the value of one internal variable. 3116 */ 3117 static void 3118 list_one_var(dictitem_T *v, char *prefix, int *first) 3119 { 3120 char_u *tofree; 3121 char_u *s; 3122 char_u numbuf[NUMBUFLEN]; 3123 3124 s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID()); 3125 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 3126 s == NULL ? (char_u *)"" : s, first); 3127 vim_free(tofree); 3128 } 3129 3130 static void 3131 list_one_var_a( 3132 char *prefix, 3133 char_u *name, 3134 int type, 3135 char_u *string, 3136 int *first) // when TRUE clear rest of screen and set to FALSE 3137 { 3138 // don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" 3139 msg_start(); 3140 msg_puts(prefix); 3141 if (name != NULL) // "a:" vars don't have a name stored 3142 msg_puts((char *)name); 3143 msg_putchar(' '); 3144 msg_advance(22); 3145 if (type == VAR_NUMBER) 3146 msg_putchar('#'); 3147 else if (type == VAR_FUNC || type == VAR_PARTIAL) 3148 msg_putchar('*'); 3149 else if (type == VAR_LIST) 3150 { 3151 msg_putchar('['); 3152 if (*string == '[') 3153 ++string; 3154 } 3155 else if (type == VAR_DICT) 3156 { 3157 msg_putchar('{'); 3158 if (*string == '{') 3159 ++string; 3160 } 3161 else 3162 msg_putchar(' '); 3163 3164 msg_outtrans(string); 3165 3166 if (type == VAR_FUNC || type == VAR_PARTIAL) 3167 msg_puts("()"); 3168 if (*first) 3169 { 3170 msg_clr_eos(); 3171 *first = FALSE; 3172 } 3173 } 3174 3175 /* 3176 * Set variable "name" to value in "tv". 3177 * If the variable already exists, the value is updated. 3178 * Otherwise the variable is created. 3179 */ 3180 void 3181 set_var( 3182 char_u *name, 3183 typval_T *tv, 3184 int copy) // make copy of value in "tv" 3185 { 3186 set_var_const(name, NULL, tv, copy, ASSIGN_DECL, 0); 3187 } 3188 3189 /* 3190 * Set variable "name" to value in "tv". 3191 * If the variable already exists and "is_const" is FALSE the value is updated. 3192 * Otherwise the variable is created. 3193 */ 3194 void 3195 set_var_const( 3196 char_u *name, 3197 type_T *type, 3198 typval_T *tv_arg, 3199 int copy, // make copy of value in "tv" 3200 int flags_arg, // ASSIGN_CONST, ASSIGN_FINAL, etc. 3201 int var_idx) // index for ":let [a, b] = list" 3202 { 3203 typval_T *tv = tv_arg; 3204 typval_T bool_tv; 3205 dictitem_T *di; 3206 typval_T *dest_tv = NULL; 3207 char_u *varname; 3208 hashtab_T *ht; 3209 int is_script_local; 3210 int vim9script = in_vim9script(); 3211 int var_in_vim9script; 3212 int flags = flags_arg; 3213 3214 ht = find_var_ht(name, &varname); 3215 if (ht == NULL || *varname == NUL) 3216 { 3217 semsg(_(e_illvar), name); 3218 goto failed; 3219 } 3220 is_script_local = ht == get_script_local_ht(); 3221 3222 if (vim9script 3223 && !is_script_local 3224 && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 3225 && (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0 3226 && name[1] == ':') 3227 { 3228 vim9_declare_error(name); 3229 goto failed; 3230 } 3231 if ((flags & ASSIGN_FOR_LOOP) && name[1] == ':' 3232 && vim_strchr((char_u *)"gwbt", name[0]) != NULL) 3233 // Do not make g:var, w:var, b:var or t:var final. 3234 flags &= ~ASSIGN_FINAL; 3235 3236 var_in_vim9script = is_script_local && current_script_is_vim9(); 3237 if (var_in_vim9script && name[0] == '_' && name[1] == NUL) 3238 { 3239 // For "[a, _] = list" the underscore is ignored. 3240 if ((flags & ASSIGN_UNPACK) == 0) 3241 emsg(_(e_cannot_use_underscore_here)); 3242 goto failed; 3243 } 3244 3245 di = find_var_in_ht(ht, 0, varname, TRUE); 3246 3247 if (di == NULL && var_in_vim9script) 3248 { 3249 imported_T *import = find_imported(varname, 0, NULL); 3250 3251 if (import != NULL) 3252 { 3253 scriptitem_T *si = SCRIPT_ITEM(import->imp_sid); 3254 svar_T *sv; 3255 where_T where = WHERE_INIT; 3256 3257 // imported variable from another script 3258 if ((flags & ASSIGN_NO_DECL) == 0) 3259 { 3260 semsg(_(e_redefining_imported_item_str), name); 3261 goto failed; 3262 } 3263 sv = ((svar_T *)si->sn_var_vals.ga_data) + import->imp_var_vals_idx; 3264 3265 where.wt_variable = TRUE; 3266 if (check_typval_type(sv->sv_type, tv, where) == FAIL 3267 || value_check_lock(sv->sv_tv->v_lock, name, FALSE)) 3268 { 3269 goto failed; 3270 } 3271 3272 dest_tv = sv->sv_tv; 3273 clear_tv(dest_tv); 3274 } 3275 } 3276 3277 if (dest_tv == NULL) 3278 { 3279 // Search in parent scope which is possible to reference from lambda 3280 if (di == NULL) 3281 di = find_var_in_scoped_ht(name, TRUE); 3282 3283 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) 3284 && var_wrong_func_name(name, di == NULL)) 3285 goto failed; 3286 3287 if (need_convert_to_bool(type, tv)) 3288 { 3289 // Destination is a bool and the value is not, but it can be 3290 // converted. 3291 CLEAR_FIELD(bool_tv); 3292 bool_tv.v_type = VAR_BOOL; 3293 bool_tv.vval.v_number = tv2bool(tv) ? VVAL_TRUE : VVAL_FALSE; 3294 tv = &bool_tv; 3295 } 3296 3297 if (di != NULL) 3298 { 3299 // Item already exists. Allowed to replace when reloading. 3300 if ((di->di_flags & DI_FLAGS_RELOAD) == 0) 3301 { 3302 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 3303 && (flags & ASSIGN_FOR_LOOP) == 0) 3304 { 3305 emsg(_(e_cannot_mod)); 3306 goto failed; 3307 } 3308 3309 if (is_script_local && vim9script 3310 && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0) 3311 { 3312 semsg(_(e_redefining_script_item_str), name); 3313 goto failed; 3314 } 3315 3316 if (var_in_vim9script) 3317 { 3318 where_T where = WHERE_INIT; 3319 3320 // check the type and adjust to bool if needed 3321 where.wt_index = var_idx; 3322 where.wt_variable = TRUE; 3323 if (check_script_var_type(&di->di_tv, tv, name, where) 3324 == FAIL) 3325 goto failed; 3326 } 3327 3328 if (var_check_permission(di, name) == FAIL) 3329 goto failed; 3330 } 3331 else 3332 { 3333 // can only redefine once 3334 di->di_flags &= ~DI_FLAGS_RELOAD; 3335 3336 // A Vim9 script-local variable is also present in sn_all_vars 3337 // and sn_var_vals. It may set "type" from "tv". 3338 if (var_in_vim9script) 3339 update_vim9_script_var(FALSE, di, flags, tv, &type, 3340 (flags & ASSIGN_NO_MEMBER_TYPE) == 0); 3341 } 3342 3343 // existing variable, need to clear the value 3344 3345 // Handle setting internal di: variables separately where needed to 3346 // prevent changing the type. 3347 if (ht == &vimvarht) 3348 { 3349 if (di->di_tv.v_type == VAR_STRING) 3350 { 3351 VIM_CLEAR(di->di_tv.vval.v_string); 3352 if (copy || tv->v_type != VAR_STRING) 3353 { 3354 char_u *val = tv_get_string(tv); 3355 3356 // Careful: when assigning to v:errmsg and 3357 // tv_get_string() causes an error message the variable 3358 // will already be set. 3359 if (di->di_tv.vval.v_string == NULL) 3360 di->di_tv.vval.v_string = vim_strsave(val); 3361 } 3362 else 3363 { 3364 // Take over the string to avoid an extra alloc/free. 3365 di->di_tv.vval.v_string = tv->vval.v_string; 3366 tv->vval.v_string = NULL; 3367 } 3368 goto failed; 3369 } 3370 else if (di->di_tv.v_type == VAR_NUMBER) 3371 { 3372 di->di_tv.vval.v_number = tv_get_number(tv); 3373 if (STRCMP(varname, "searchforward") == 0) 3374 set_search_direction(di->di_tv.vval.v_number 3375 ? '/' : '?'); 3376 #ifdef FEAT_SEARCH_EXTRA 3377 else if (STRCMP(varname, "hlsearch") == 0) 3378 { 3379 no_hlsearch = !di->di_tv.vval.v_number; 3380 redraw_all_later(SOME_VALID); 3381 } 3382 #endif 3383 goto failed; 3384 } 3385 else if (di->di_tv.v_type != tv->v_type) 3386 { 3387 semsg(_("E963: setting %s to value with wrong type"), name); 3388 goto failed; 3389 } 3390 } 3391 3392 clear_tv(&di->di_tv); 3393 } 3394 else 3395 { 3396 // Item not found, check if a function already exists. 3397 if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 3398 && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK) 3399 { 3400 semsg(_(e_redefining_script_item_str), name); 3401 goto failed; 3402 } 3403 3404 // add a new variable 3405 if (var_in_vim9script && (flags & ASSIGN_NO_DECL)) 3406 { 3407 semsg(_(e_unknown_variable_str), name); 3408 goto failed; 3409 } 3410 3411 // Can't add "v:" or "a:" variable. 3412 if (ht == &vimvarht || ht == get_funccal_args_ht()) 3413 { 3414 semsg(_(e_illvar), name); 3415 goto failed; 3416 } 3417 3418 // Make sure the variable name is valid. In Vim9 script an autoload 3419 // variable must be prefixed with "g:". 3420 if (!valid_varname(varname, !vim9script 3421 || STRNCMP(name, "g:", 2) == 0)) 3422 goto failed; 3423 3424 di = alloc(sizeof(dictitem_T) + STRLEN(varname)); 3425 if (di == NULL) 3426 goto failed; 3427 STRCPY(di->di_key, varname); 3428 if (hash_add(ht, DI2HIKEY(di)) == FAIL) 3429 { 3430 vim_free(di); 3431 goto failed; 3432 } 3433 di->di_flags = DI_FLAGS_ALLOC; 3434 if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) 3435 di->di_flags |= DI_FLAGS_LOCK; 3436 3437 // A Vim9 script-local variable is also added to sn_all_vars and 3438 // sn_var_vals. It may set "type" from "tv". 3439 if (var_in_vim9script) 3440 update_vim9_script_var(TRUE, di, flags, tv, &type, 3441 (flags & ASSIGN_NO_MEMBER_TYPE) == 0); 3442 } 3443 3444 dest_tv = &di->di_tv; 3445 } 3446 3447 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 3448 copy_tv(tv, dest_tv); 3449 else 3450 { 3451 *dest_tv = *tv; 3452 dest_tv->v_lock = 0; 3453 init_tv(tv); 3454 } 3455 3456 if (vim9script && type != NULL) 3457 { 3458 if (type->tt_type == VAR_DICT && dest_tv->vval.v_dict != NULL) 3459 dest_tv->vval.v_dict->dv_type = alloc_type(type); 3460 else if (type->tt_type == VAR_LIST && dest_tv->vval.v_list != NULL) 3461 dest_tv->vval.v_list->lv_type = alloc_type(type); 3462 } 3463 3464 // ":const var = value" locks the value 3465 // ":final var = value" locks "var" 3466 if (flags & ASSIGN_CONST) 3467 // Like :lockvar! name: lock the value and what it contains, but only 3468 // if the reference count is up to one. That locks only literal 3469 // values. 3470 item_lock(dest_tv, DICT_MAXNEST, TRUE, TRUE); 3471 return; 3472 3473 failed: 3474 if (!copy) 3475 clear_tv(tv_arg); 3476 } 3477 3478 /* 3479 * Check in this order for backwards compatibility: 3480 * - Whether the variable is read-only 3481 * - Whether the variable value is locked 3482 * - Whether the variable is locked 3483 */ 3484 int 3485 var_check_permission(dictitem_T *di, char_u *name) 3486 { 3487 if (var_check_ro(di->di_flags, name, FALSE) 3488 || value_check_lock(di->di_tv.v_lock, name, FALSE) 3489 || var_check_lock(di->di_flags, name, FALSE)) 3490 return FAIL; 3491 return OK; 3492 } 3493 3494 /* 3495 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 3496 * Also give an error message. 3497 */ 3498 int 3499 var_check_ro(int flags, char_u *name, int use_gettext) 3500 { 3501 if (flags & DI_FLAGS_RO) 3502 { 3503 semsg(_(e_cannot_change_readonly_variable_str), 3504 use_gettext ? (char_u *)_(name) : name); 3505 return TRUE; 3506 } 3507 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 3508 { 3509 semsg(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name); 3510 return TRUE; 3511 } 3512 return FALSE; 3513 } 3514 3515 /* 3516 * Return TRUE if di_flags "flags" indicates variable "name" is locked. 3517 * Also give an error message. 3518 */ 3519 int 3520 var_check_lock(int flags, char_u *name, int use_gettext) 3521 { 3522 if (flags & DI_FLAGS_LOCK) 3523 { 3524 semsg(_(e_variable_is_locked_str), 3525 use_gettext ? (char_u *)_(name) : name); 3526 return TRUE; 3527 } 3528 return FALSE; 3529 } 3530 3531 /* 3532 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 3533 * Also give an error message. 3534 */ 3535 int 3536 var_check_fixed(int flags, char_u *name, int use_gettext) 3537 { 3538 if (flags & DI_FLAGS_FIX) 3539 { 3540 semsg(_("E795: Cannot delete variable %s"), 3541 use_gettext ? (char_u *)_(name) : name); 3542 return TRUE; 3543 } 3544 return FALSE; 3545 } 3546 3547 /* 3548 * Check if a funcref is assigned to a valid variable name. 3549 * Return TRUE and give an error if not. 3550 */ 3551 int 3552 var_wrong_func_name( 3553 char_u *name, // points to start of variable name 3554 int new_var) // TRUE when creating the variable 3555 { 3556 // Allow for w: b: s: and t:. In Vim9 script s: is not allowed, because 3557 // the name can be used without the s: prefix. 3558 if (!((vim_strchr((char_u *)"wbt", name[0]) != NULL 3559 || (!in_vim9script() && name[0] == 's')) && name[1] == ':') 3560 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 3561 ? name[2] : name[0])) 3562 { 3563 semsg(_("E704: Funcref variable name must start with a capital: %s"), 3564 name); 3565 return TRUE; 3566 } 3567 // Don't allow hiding a function. When "v" is not NULL we might be 3568 // assigning another function to the same var, the type is checked 3569 // below. 3570 if (new_var && function_exists(name, FALSE)) 3571 { 3572 semsg(_("E705: Variable name conflicts with existing function: %s"), 3573 name); 3574 return TRUE; 3575 } 3576 return FALSE; 3577 } 3578 3579 /* 3580 * Return TRUE if "flags" indicates variable "name" has a locked (immutable) 3581 * value. Also give an error message, using "name" or _("name") when 3582 * "use_gettext" is TRUE. 3583 */ 3584 int 3585 value_check_lock(int lock, char_u *name, int use_gettext) 3586 { 3587 if (lock & VAR_LOCKED) 3588 { 3589 semsg(_("E741: Value is locked: %s"), 3590 name == NULL ? (char_u *)_("Unknown") 3591 : use_gettext ? (char_u *)_(name) 3592 : name); 3593 return TRUE; 3594 } 3595 if (lock & VAR_FIXED) 3596 { 3597 semsg(_("E742: Cannot change value of %s"), 3598 name == NULL ? (char_u *)_("Unknown") 3599 : use_gettext ? (char_u *)_(name) 3600 : name); 3601 return TRUE; 3602 } 3603 return FALSE; 3604 } 3605 3606 /* 3607 * Check if a variable name is valid. When "autoload" is true "#" is allowed. 3608 * Return FALSE and give an error if not. 3609 */ 3610 int 3611 valid_varname(char_u *varname, int autoload) 3612 { 3613 char_u *p; 3614 3615 for (p = varname; *p != NUL; ++p) 3616 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 3617 && !(autoload && *p == AUTOLOAD_CHAR)) 3618 { 3619 semsg(_(e_illvar), varname); 3620 return FALSE; 3621 } 3622 return TRUE; 3623 } 3624 3625 /* 3626 * getwinvar() and gettabwinvar() 3627 */ 3628 static void 3629 getwinvar( 3630 typval_T *argvars, 3631 typval_T *rettv, 3632 int off) // 1 for gettabwinvar() 3633 { 3634 win_T *win; 3635 char_u *varname; 3636 dictitem_T *v; 3637 tabpage_T *tp = NULL; 3638 int done = FALSE; 3639 win_T *oldcurwin; 3640 tabpage_T *oldtabpage; 3641 int need_switch_win; 3642 3643 if (off == 1) 3644 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 3645 else 3646 tp = curtab; 3647 win = find_win_by_nr(&argvars[off], tp); 3648 varname = tv_get_string_chk(&argvars[off + 1]); 3649 ++emsg_off; 3650 3651 rettv->v_type = VAR_STRING; 3652 rettv->vval.v_string = NULL; 3653 3654 if (win != NULL && varname != NULL) 3655 { 3656 // Set curwin to be our win, temporarily. Also set the tabpage, 3657 // otherwise the window is not valid. Only do this when needed, 3658 // autocommands get blocked. 3659 need_switch_win = !(tp == curtab && win == curwin); 3660 if (!need_switch_win 3661 || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) 3662 { 3663 if (*varname == '&') 3664 { 3665 if (varname[1] == NUL) 3666 { 3667 // get all window-local options in a dict 3668 dict_T *opts = get_winbuf_options(FALSE); 3669 3670 if (opts != NULL) 3671 { 3672 rettv_dict_set(rettv, opts); 3673 done = TRUE; 3674 } 3675 } 3676 else if (eval_option(&varname, rettv, 1) == OK) 3677 // window-local-option 3678 done = TRUE; 3679 } 3680 else 3681 { 3682 // Look up the variable. 3683 // Let getwinvar({nr}, "") return the "w:" dictionary. 3684 v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', 3685 varname, FALSE); 3686 if (v != NULL) 3687 { 3688 copy_tv(&v->di_tv, rettv); 3689 done = TRUE; 3690 } 3691 } 3692 } 3693 3694 if (need_switch_win) 3695 // restore previous notion of curwin 3696 restore_win(oldcurwin, oldtabpage, TRUE); 3697 } 3698 3699 if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) 3700 // use the default return value 3701 copy_tv(&argvars[off + 2], rettv); 3702 3703 --emsg_off; 3704 } 3705 3706 /* 3707 * Set option "varname" to the value of "varp" for the current buffer/window. 3708 */ 3709 static void 3710 set_option_from_tv(char_u *varname, typval_T *varp) 3711 { 3712 long numval = 0; 3713 char_u *strval; 3714 char_u nbuf[NUMBUFLEN]; 3715 int error = FALSE; 3716 3717 if (varp->v_type == VAR_BOOL) 3718 { 3719 numval = (long)varp->vval.v_number; 3720 strval = (char_u *)"0"; // avoid using "false" 3721 } 3722 else 3723 { 3724 if (!in_vim9script() || varp->v_type != VAR_STRING) 3725 numval = (long)tv_get_number_chk(varp, &error); 3726 strval = tv_get_string_buf_chk(varp, nbuf); 3727 } 3728 if (!error && strval != NULL) 3729 set_option_value(varname, numval, strval, OPT_LOCAL); 3730 } 3731 3732 /* 3733 * "setwinvar()" and "settabwinvar()" functions 3734 */ 3735 static void 3736 setwinvar(typval_T *argvars, int off) 3737 { 3738 win_T *win; 3739 win_T *save_curwin; 3740 tabpage_T *save_curtab; 3741 int need_switch_win; 3742 char_u *varname, *winvarname; 3743 typval_T *varp; 3744 tabpage_T *tp = NULL; 3745 3746 if (check_secure()) 3747 return; 3748 3749 if (off == 1) 3750 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 3751 else 3752 tp = curtab; 3753 win = find_win_by_nr(&argvars[off], tp); 3754 varname = tv_get_string_chk(&argvars[off + 1]); 3755 varp = &argvars[off + 2]; 3756 3757 if (win != NULL && varname != NULL && varp != NULL) 3758 { 3759 need_switch_win = !(tp == curtab && win == curwin); 3760 if (!need_switch_win 3761 || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) 3762 { 3763 if (*varname == '&') 3764 set_option_from_tv(varname + 1, varp); 3765 else 3766 { 3767 winvarname = alloc(STRLEN(varname) + 3); 3768 if (winvarname != NULL) 3769 { 3770 STRCPY(winvarname, "w:"); 3771 STRCPY(winvarname + 2, varname); 3772 set_var(winvarname, varp, TRUE); 3773 vim_free(winvarname); 3774 } 3775 } 3776 } 3777 if (need_switch_win) 3778 restore_win(save_curwin, save_curtab, TRUE); 3779 } 3780 } 3781 3782 /* 3783 * reset v:option_new, v:option_old, v:option_oldlocal, v:option_oldglobal, 3784 * v:option_type, and v:option_command. 3785 */ 3786 void 3787 reset_v_option_vars(void) 3788 { 3789 set_vim_var_string(VV_OPTION_NEW, NULL, -1); 3790 set_vim_var_string(VV_OPTION_OLD, NULL, -1); 3791 set_vim_var_string(VV_OPTION_OLDLOCAL, NULL, -1); 3792 set_vim_var_string(VV_OPTION_OLDGLOBAL, NULL, -1); 3793 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); 3794 set_vim_var_string(VV_OPTION_COMMAND, NULL, -1); 3795 } 3796 3797 /* 3798 * Add an assert error to v:errors. 3799 */ 3800 void 3801 assert_error(garray_T *gap) 3802 { 3803 struct vimvar *vp = &vimvars[VV_ERRORS]; 3804 3805 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) 3806 // Make sure v:errors is a list. 3807 set_vim_var_list(VV_ERRORS, list_alloc()); 3808 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); 3809 } 3810 3811 int 3812 var_exists(char_u *var) 3813 { 3814 char_u *arg = var; 3815 char_u *name; 3816 char_u *tofree; 3817 typval_T tv; 3818 int len = 0; 3819 int n = FALSE; 3820 3821 // get_name_len() takes care of expanding curly braces 3822 name = var; 3823 len = get_name_len(&arg, &tofree, TRUE, FALSE); 3824 if (len > 0) 3825 { 3826 if (tofree != NULL) 3827 name = tofree; 3828 n = (eval_variable(name, len, &tv, NULL, 3829 EVAL_VAR_NOAUTOLOAD + EVAL_VAR_IMPORT) == OK); 3830 if (n) 3831 { 3832 // handle d.key, l[idx], f(expr) 3833 arg = skipwhite(arg); 3834 n = (handle_subscript(&arg, &tv, &EVALARG_EVALUATE, FALSE) == OK); 3835 if (n) 3836 clear_tv(&tv); 3837 } 3838 } 3839 if (*arg != NUL) 3840 n = FALSE; 3841 3842 vim_free(tofree); 3843 return n; 3844 } 3845 3846 static lval_T *redir_lval = NULL; 3847 #define EVALCMD_BUSY (redir_lval == (lval_T *)&redir_lval) 3848 static garray_T redir_ga; // only valid when redir_lval is not NULL 3849 static char_u *redir_endp = NULL; 3850 static char_u *redir_varname = NULL; 3851 3852 int 3853 alloc_redir_lval(void) 3854 { 3855 redir_lval = ALLOC_CLEAR_ONE(lval_T); 3856 if (redir_lval == NULL) 3857 return FAIL; 3858 return OK; 3859 } 3860 3861 void 3862 clear_redir_lval(void) 3863 { 3864 VIM_CLEAR(redir_lval); 3865 } 3866 3867 void 3868 init_redir_ga(void) 3869 { 3870 ga_init2(&redir_ga, (int)sizeof(char), 500); 3871 } 3872 3873 /* 3874 * Start recording command output to a variable 3875 * When "append" is TRUE append to an existing variable. 3876 * Returns OK if successfully completed the setup. FAIL otherwise. 3877 */ 3878 int 3879 var_redir_start(char_u *name, int append) 3880 { 3881 int called_emsg_before; 3882 typval_T tv; 3883 3884 // Catch a bad name early. 3885 if (!eval_isnamec1(*name)) 3886 { 3887 emsg(_(e_invarg)); 3888 return FAIL; 3889 } 3890 3891 // Make a copy of the name, it is used in redir_lval until redir ends. 3892 redir_varname = vim_strsave(name); 3893 if (redir_varname == NULL) 3894 return FAIL; 3895 3896 if (alloc_redir_lval() == FAIL) 3897 { 3898 var_redir_stop(); 3899 return FAIL; 3900 } 3901 3902 // The output is stored in growarray "redir_ga" until redirection ends. 3903 init_redir_ga(); 3904 3905 // Parse the variable name (can be a dict or list entry). 3906 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0, 3907 FNE_CHECK_START); 3908 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 3909 { 3910 clear_lval(redir_lval); 3911 if (redir_endp != NULL && *redir_endp != NUL) 3912 // Trailing characters are present after the variable name 3913 semsg(_(e_trailing_arg), redir_endp); 3914 else 3915 semsg(_(e_invarg2), name); 3916 redir_endp = NULL; // don't store a value, only cleanup 3917 var_redir_stop(); 3918 return FAIL; 3919 } 3920 3921 // check if we can write to the variable: set it to or append an empty 3922 // string 3923 called_emsg_before = called_emsg; 3924 tv.v_type = VAR_STRING; 3925 tv.vval.v_string = (char_u *)""; 3926 if (append) 3927 set_var_lval(redir_lval, redir_endp, &tv, TRUE, 3928 ASSIGN_NO_DECL, (char_u *)".", 0); 3929 else 3930 set_var_lval(redir_lval, redir_endp, &tv, TRUE, 3931 ASSIGN_NO_DECL, (char_u *)"=", 0); 3932 clear_lval(redir_lval); 3933 if (called_emsg > called_emsg_before) 3934 { 3935 redir_endp = NULL; // don't store a value, only cleanup 3936 var_redir_stop(); 3937 return FAIL; 3938 } 3939 3940 return OK; 3941 } 3942 3943 /* 3944 * Append "value[value_len]" to the variable set by var_redir_start(). 3945 * The actual appending is postponed until redirection ends, because the value 3946 * appended may in fact be the string we write to, changing it may cause freed 3947 * memory to be used: 3948 * :redir => foo 3949 * :let foo 3950 * :redir END 3951 */ 3952 void 3953 var_redir_str(char_u *value, int value_len) 3954 { 3955 int len; 3956 3957 if (redir_lval == NULL) 3958 return; 3959 3960 if (value_len == -1) 3961 len = (int)STRLEN(value); // Append the entire string 3962 else 3963 len = value_len; // Append only "value_len" characters 3964 3965 if (ga_grow(&redir_ga, len) == OK) 3966 { 3967 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 3968 redir_ga.ga_len += len; 3969 } 3970 else 3971 var_redir_stop(); 3972 } 3973 3974 /* 3975 * Stop redirecting command output to a variable. 3976 * Frees the allocated memory. 3977 */ 3978 void 3979 var_redir_stop(void) 3980 { 3981 typval_T tv; 3982 3983 if (EVALCMD_BUSY) 3984 { 3985 redir_lval = NULL; 3986 return; 3987 } 3988 3989 if (redir_lval != NULL) 3990 { 3991 // If there was no error: assign the text to the variable. 3992 if (redir_endp != NULL) 3993 { 3994 ga_append(&redir_ga, NUL); // Append the trailing NUL. 3995 tv.v_type = VAR_STRING; 3996 tv.vval.v_string = redir_ga.ga_data; 3997 // Call get_lval() again, if it's inside a Dict or List it may 3998 // have changed. 3999 redir_endp = get_lval(redir_varname, NULL, redir_lval, 4000 FALSE, FALSE, 0, FNE_CHECK_START); 4001 if (redir_endp != NULL && redir_lval->ll_name != NULL) 4002 set_var_lval(redir_lval, redir_endp, &tv, FALSE, 0, 4003 (char_u *)".", 0); 4004 clear_lval(redir_lval); 4005 } 4006 4007 // free the collected output 4008 VIM_CLEAR(redir_ga.ga_data); 4009 4010 VIM_CLEAR(redir_lval); 4011 } 4012 VIM_CLEAR(redir_varname); 4013 } 4014 4015 /* 4016 * Get the collected redirected text and clear redir_ga. 4017 */ 4018 char_u * 4019 get_clear_redir_ga(void) 4020 { 4021 char_u *res; 4022 4023 ga_append(&redir_ga, NUL); // Append the trailing NUL. 4024 res = redir_ga.ga_data; 4025 redir_ga.ga_data = NULL; 4026 return res; 4027 } 4028 4029 /* 4030 * "gettabvar()" function 4031 */ 4032 void 4033 f_gettabvar(typval_T *argvars, typval_T *rettv) 4034 { 4035 win_T *oldcurwin; 4036 tabpage_T *tp, *oldtabpage; 4037 dictitem_T *v; 4038 char_u *varname; 4039 int done = FALSE; 4040 4041 rettv->v_type = VAR_STRING; 4042 rettv->vval.v_string = NULL; 4043 4044 if (in_vim9script() 4045 && (check_for_number_arg(argvars, 0) == FAIL 4046 || check_for_string_arg(argvars, 1) == FAIL)) 4047 return; 4048 4049 varname = tv_get_string_chk(&argvars[1]); 4050 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 4051 if (tp != NULL && varname != NULL) 4052 { 4053 // Set tp to be our tabpage, temporarily. Also set the window to the 4054 // first window in the tabpage, otherwise the window is not valid. 4055 if (switch_win(&oldcurwin, &oldtabpage, 4056 tp == curtab || tp->tp_firstwin == NULL ? firstwin 4057 : tp->tp_firstwin, tp, TRUE) == OK) 4058 { 4059 // look up the variable 4060 // Let gettabvar({nr}, "") return the "t:" dictionary. 4061 v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); 4062 if (v != NULL) 4063 { 4064 copy_tv(&v->di_tv, rettv); 4065 done = TRUE; 4066 } 4067 } 4068 4069 // restore previous notion of curwin 4070 restore_win(oldcurwin, oldtabpage, TRUE); 4071 } 4072 4073 if (!done && argvars[2].v_type != VAR_UNKNOWN) 4074 copy_tv(&argvars[2], rettv); 4075 } 4076 4077 /* 4078 * "gettabwinvar()" function 4079 */ 4080 void 4081 f_gettabwinvar(typval_T *argvars, typval_T *rettv) 4082 { 4083 if (in_vim9script() 4084 && (check_for_number_arg(argvars, 0) == FAIL 4085 || check_for_number_arg(argvars, 1) == FAIL 4086 || check_for_string_arg(argvars, 2) == FAIL)) 4087 return; 4088 4089 getwinvar(argvars, rettv, 1); 4090 } 4091 4092 /* 4093 * "getwinvar()" function 4094 */ 4095 void 4096 f_getwinvar(typval_T *argvars, typval_T *rettv) 4097 { 4098 if (in_vim9script() 4099 && (check_for_number_arg(argvars, 0) == FAIL 4100 || check_for_string_arg(argvars, 1) == FAIL)) 4101 return; 4102 4103 getwinvar(argvars, rettv, 0); 4104 } 4105 4106 /* 4107 * "getbufvar()" function 4108 */ 4109 void 4110 f_getbufvar(typval_T *argvars, typval_T *rettv) 4111 { 4112 buf_T *buf; 4113 char_u *varname; 4114 dictitem_T *v; 4115 int done = FALSE; 4116 4117 if (in_vim9script() 4118 && (check_for_buffer_arg(argvars, 0) == FAIL 4119 || check_for_string_arg(argvars, 1) == FAIL)) 4120 return; 4121 4122 varname = tv_get_string_chk(&argvars[1]); 4123 buf = tv_get_buf_from_arg(&argvars[0]); 4124 4125 rettv->v_type = VAR_STRING; 4126 rettv->vval.v_string = NULL; 4127 4128 if (buf != NULL && varname != NULL) 4129 { 4130 if (*varname == '&') 4131 { 4132 buf_T *save_curbuf = curbuf; 4133 4134 // set curbuf to be our buf, temporarily 4135 curbuf = buf; 4136 4137 if (varname[1] == NUL) 4138 { 4139 // get all buffer-local options in a dict 4140 dict_T *opts = get_winbuf_options(TRUE); 4141 4142 if (opts != NULL) 4143 { 4144 rettv_dict_set(rettv, opts); 4145 done = TRUE; 4146 } 4147 } 4148 else if (eval_option(&varname, rettv, TRUE) == OK) 4149 // buffer-local-option 4150 done = TRUE; 4151 4152 // restore previous notion of curbuf 4153 curbuf = save_curbuf; 4154 } 4155 else 4156 { 4157 // Look up the variable. 4158 if (*varname == NUL) 4159 // Let getbufvar({nr}, "") return the "b:" dictionary. 4160 v = &buf->b_bufvar; 4161 else 4162 v = find_var_in_ht(&buf->b_vars->dv_hashtab, 'b', 4163 varname, FALSE); 4164 if (v != NULL) 4165 { 4166 copy_tv(&v->di_tv, rettv); 4167 done = TRUE; 4168 } 4169 } 4170 } 4171 4172 if (!done && argvars[2].v_type != VAR_UNKNOWN) 4173 // use the default value 4174 copy_tv(&argvars[2], rettv); 4175 } 4176 4177 /* 4178 * "settabvar()" function 4179 */ 4180 void 4181 f_settabvar(typval_T *argvars, typval_T *rettv UNUSED) 4182 { 4183 tabpage_T *save_curtab; 4184 tabpage_T *tp; 4185 char_u *varname, *tabvarname; 4186 typval_T *varp; 4187 4188 if (check_secure()) 4189 return; 4190 4191 if (in_vim9script() 4192 && (check_for_number_arg(argvars, 0) == FAIL 4193 || check_for_string_arg(argvars, 1) == FAIL)) 4194 return; 4195 4196 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 4197 varname = tv_get_string_chk(&argvars[1]); 4198 varp = &argvars[2]; 4199 4200 if (varname != NULL && varp != NULL && tp != NULL) 4201 { 4202 save_curtab = curtab; 4203 goto_tabpage_tp(tp, FALSE, FALSE); 4204 4205 tabvarname = alloc(STRLEN(varname) + 3); 4206 if (tabvarname != NULL) 4207 { 4208 STRCPY(tabvarname, "t:"); 4209 STRCPY(tabvarname + 2, varname); 4210 set_var(tabvarname, varp, TRUE); 4211 vim_free(tabvarname); 4212 } 4213 4214 // Restore current tabpage 4215 if (valid_tabpage(save_curtab)) 4216 goto_tabpage_tp(save_curtab, FALSE, FALSE); 4217 } 4218 } 4219 4220 /* 4221 * "settabwinvar()" function 4222 */ 4223 void 4224 f_settabwinvar(typval_T *argvars, typval_T *rettv UNUSED) 4225 { 4226 if (in_vim9script() 4227 && (check_for_number_arg(argvars, 0) == FAIL 4228 || check_for_number_arg(argvars, 1) == FAIL 4229 || check_for_string_arg(argvars, 2) == FAIL)) 4230 return; 4231 4232 setwinvar(argvars, 1); 4233 } 4234 4235 /* 4236 * "setwinvar()" function 4237 */ 4238 void 4239 f_setwinvar(typval_T *argvars, typval_T *rettv UNUSED) 4240 { 4241 if (in_vim9script() 4242 && (check_for_number_arg(argvars, 0) == FAIL 4243 || check_for_string_arg(argvars, 1) == FAIL)) 4244 return; 4245 4246 setwinvar(argvars, 0); 4247 } 4248 4249 /* 4250 * "setbufvar()" function 4251 */ 4252 void 4253 f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) 4254 { 4255 buf_T *buf; 4256 char_u *varname, *bufvarname; 4257 typval_T *varp; 4258 4259 if (check_secure()) 4260 return; 4261 4262 if (in_vim9script() 4263 && (check_for_buffer_arg(argvars, 0) == FAIL 4264 || check_for_string_arg(argvars, 1) == FAIL)) 4265 return; 4266 4267 varname = tv_get_string_chk(&argvars[1]); 4268 buf = tv_get_buf_from_arg(&argvars[0]); 4269 varp = &argvars[2]; 4270 4271 if (buf != NULL && varname != NULL && varp != NULL) 4272 { 4273 if (*varname == '&') 4274 { 4275 aco_save_T aco; 4276 4277 // set curbuf to be our buf, temporarily 4278 aucmd_prepbuf(&aco, buf); 4279 4280 set_option_from_tv(varname + 1, varp); 4281 4282 // reset notion of buffer 4283 aucmd_restbuf(&aco); 4284 } 4285 else 4286 { 4287 bufvarname = alloc(STRLEN(varname) + 3); 4288 if (bufvarname != NULL) 4289 { 4290 buf_T *save_curbuf = curbuf; 4291 4292 curbuf = buf; 4293 STRCPY(bufvarname, "b:"); 4294 STRCPY(bufvarname + 2, varname); 4295 set_var(bufvarname, varp, TRUE); 4296 vim_free(bufvarname); 4297 curbuf = save_curbuf; 4298 } 4299 } 4300 } 4301 } 4302 4303 /* 4304 * Get a callback from "arg". It can be a Funcref or a function name. 4305 * When "arg" is zero return an empty string. 4306 * "cb_name" is not allocated. 4307 * "cb_name" is set to NULL for an invalid argument. 4308 */ 4309 callback_T 4310 get_callback(typval_T *arg) 4311 { 4312 callback_T res; 4313 int r = OK; 4314 4315 res.cb_free_name = FALSE; 4316 if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) 4317 { 4318 res.cb_partial = arg->vval.v_partial; 4319 ++res.cb_partial->pt_refcount; 4320 res.cb_name = partial_name(res.cb_partial); 4321 } 4322 else 4323 { 4324 res.cb_partial = NULL; 4325 if (arg->v_type == VAR_STRING && arg->vval.v_string != NULL 4326 && isdigit(*arg->vval.v_string)) 4327 r = FAIL; 4328 else if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) 4329 { 4330 // Note that we don't make a copy of the string. 4331 res.cb_name = arg->vval.v_string; 4332 func_ref(res.cb_name); 4333 } 4334 else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) 4335 res.cb_name = (char_u *)""; 4336 else 4337 r = FAIL; 4338 4339 if (r == FAIL) 4340 { 4341 emsg(_("E921: Invalid callback argument")); 4342 res.cb_name = NULL; 4343 } 4344 } 4345 return res; 4346 } 4347 4348 /* 4349 * Copy a callback into a typval_T. 4350 */ 4351 void 4352 put_callback(callback_T *cb, typval_T *tv) 4353 { 4354 if (cb->cb_partial != NULL) 4355 { 4356 tv->v_type = VAR_PARTIAL; 4357 tv->vval.v_partial = cb->cb_partial; 4358 ++tv->vval.v_partial->pt_refcount; 4359 } 4360 else 4361 { 4362 tv->v_type = VAR_FUNC; 4363 tv->vval.v_string = vim_strsave(cb->cb_name); 4364 func_ref(cb->cb_name); 4365 } 4366 } 4367 4368 /* 4369 * Make a copy of "src" into "dest", allocating the function name if needed, 4370 * without incrementing the refcount. 4371 */ 4372 void 4373 set_callback(callback_T *dest, callback_T *src) 4374 { 4375 if (src->cb_partial == NULL) 4376 { 4377 // just a function name, make a copy 4378 dest->cb_name = vim_strsave(src->cb_name); 4379 dest->cb_free_name = TRUE; 4380 } 4381 else 4382 { 4383 // cb_name is a pointer into cb_partial 4384 dest->cb_name = src->cb_name; 4385 dest->cb_free_name = FALSE; 4386 } 4387 dest->cb_partial = src->cb_partial; 4388 } 4389 4390 /* 4391 * Copy callback from "src" to "dest", incrementing the refcounts. 4392 */ 4393 void 4394 copy_callback(callback_T *dest, callback_T *src) 4395 { 4396 dest->cb_partial = src->cb_partial; 4397 if (dest->cb_partial != NULL) 4398 { 4399 dest->cb_name = src->cb_name; 4400 dest->cb_free_name = FALSE; 4401 ++dest->cb_partial->pt_refcount; 4402 } 4403 else 4404 { 4405 dest->cb_name = vim_strsave(src->cb_name); 4406 dest->cb_free_name = TRUE; 4407 func_ref(src->cb_name); 4408 } 4409 } 4410 4411 /* 4412 * Unref/free "callback" returned by get_callback() or set_callback(). 4413 */ 4414 void 4415 free_callback(callback_T *callback) 4416 { 4417 if (callback->cb_partial != NULL) 4418 { 4419 partial_unref(callback->cb_partial); 4420 callback->cb_partial = NULL; 4421 } 4422 else if (callback->cb_name != NULL) 4423 func_unref(callback->cb_name); 4424 if (callback->cb_free_name) 4425 { 4426 vim_free(callback->cb_name); 4427 callback->cb_free_name = FALSE; 4428 } 4429 callback->cb_name = NULL; 4430 } 4431 4432 #endif // FEAT_EVAL 4433