vars.c (109425B)
1 // eval/vars.c: functions for dealing with variables 2 3 #include <assert.h> 4 #include <ctype.h> 5 #include <stdbool.h> 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <uv.h> 11 12 #include "nvim/ascii_defs.h" 13 #include "nvim/autocmd.h" 14 #include "nvim/autocmd_defs.h" 15 #include "nvim/buffer_defs.h" 16 #include "nvim/charset.h" 17 #include "nvim/drawscreen.h" 18 #include "nvim/errors.h" 19 #include "nvim/eval.h" 20 #include "nvim/eval/encode.h" 21 #include "nvim/eval/funcs.h" 22 #include "nvim/eval/typval.h" 23 #include "nvim/eval/typval_defs.h" 24 #include "nvim/eval/userfunc.h" 25 #include "nvim/eval/vars.h" 26 #include "nvim/eval/window.h" 27 #include "nvim/eval_defs.h" 28 #include "nvim/ex_cmds.h" 29 #include "nvim/ex_cmds_defs.h" 30 #include "nvim/ex_docmd.h" 31 #include "nvim/ex_eval.h" 32 #include "nvim/garray.h" 33 #include "nvim/gettext_defs.h" 34 #include "nvim/globals.h" 35 #include "nvim/hashtab.h" 36 #include "nvim/lua/executor.h" 37 #include "nvim/macros_defs.h" 38 #include "nvim/mbyte.h" 39 #include "nvim/memory.h" 40 #include "nvim/message.h" 41 #include "nvim/option.h" 42 #include "nvim/option_defs.h" 43 #include "nvim/os/os.h" 44 #include "nvim/register.h" 45 #include "nvim/runtime.h" 46 #include "nvim/search.h" 47 #include "nvim/strings.h" 48 #include "nvim/types_defs.h" 49 #include "nvim/version.h" 50 #include "nvim/vim_defs.h" 51 #include "nvim/window.h" 52 53 typedef int (*ex_unletlock_callback)(lval_T *, char *, exarg_T *, int); 54 55 #include "eval/vars.c.generated.h" 56 57 // TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead 58 59 #define DICT_MAXNEST 100 // maximum nesting of lists and dicts 60 61 static const char *e_letunexp = N_("E18: Unexpected characters in :let"); 62 static const char e_double_semicolon_in_list_of_variables[] 63 = N_("E452: Double ; in list of variables"); 64 static const char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s"); 65 static const char e_setting_v_str_to_value_with_wrong_type[] 66 = N_("E963: Setting v:%s to value with wrong type"); 67 static const char e_missing_end_marker_str[] = N_("E990: Missing end marker '%s'"); 68 static const char e_cannot_use_heredoc_here[] = N_("E991: Cannot use =<< here"); 69 70 /// Variable used for g: 71 static ScopeDictDictItem globvars_var; 72 static dict_T globvardict; // Dict with g: variables 73 /// g: value 74 #define globvarht globvardict.dv_hashtab 75 76 /// Old Vim variables such as "v:version" are also available without the "v:". 77 /// Also in functions. We need a special hashtable for them. 78 static hashtab_T compat_hashtab; 79 80 // values for vv_flags: 81 #define VV_COMPAT 1 // compatible, also used without "v:" 82 #define VV_RO 2 // read-only 83 #define VV_RO_SBX 4 // read-only in the sandbox 84 85 #define VV(idx, name, type, flags) \ 86 [idx] = { \ 87 .vv_name = (name), \ 88 .vv_di = { \ 89 .di_tv = { .v_type = (type) }, \ 90 .di_flags = 0, \ 91 .di_key = { 0 }, \ 92 }, \ 93 .vv_flags = (flags), \ 94 } 95 96 #define VIMVAR_KEY_LEN 16 // Maximum length of the key of v:variables 97 98 // Array to hold the value of v: variables. 99 // The value is in a dictitem, so that it can also be used in the v: scope. 100 // The reason to use this table anyway is for very quick access to the 101 // variables with the VV_ defines. 102 static struct vimvar { 103 char *vv_name; ///< Name of the variable, without v:. 104 TV_DICTITEM_STRUCT(VIMVAR_KEY_LEN + 1) vv_di; ///< Value and name for key (max 16 chars). 105 char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX. 106 } vimvars[] = { 107 // VV_ tails differing from upcased string literals: 108 // VV_CC_FROM "charconvert_from" 109 // VV_CC_TO "charconvert_to" 110 // VV_SEND_SERVER "servername" 111 // VV_REG "register" 112 // VV_OP "operator" 113 VV(VV_COUNT, "count", VAR_NUMBER, VV_RO), 114 VV(VV_COUNT1, "count1", VAR_NUMBER, VV_RO), 115 VV(VV_PREVCOUNT, "prevcount", VAR_NUMBER, VV_RO), 116 VV(VV_ERRMSG, "errmsg", VAR_STRING, 0), 117 VV(VV_WARNINGMSG, "warningmsg", VAR_STRING, 0), 118 VV(VV_STATUSMSG, "statusmsg", VAR_STRING, 0), 119 VV(VV_SHELL_ERROR, "shell_error", VAR_NUMBER, VV_RO), 120 VV(VV_THIS_SESSION, "this_session", VAR_STRING, 0), 121 VV(VV_VERSION, "version", VAR_NUMBER, VV_COMPAT + VV_RO), 122 VV(VV_LNUM, "lnum", VAR_NUMBER, VV_RO_SBX), 123 VV(VV_TERMRESPONSE, "termresponse", VAR_STRING, VV_RO), 124 VV(VV_TERMREQUEST, "termrequest", VAR_STRING, VV_RO), 125 VV(VV_FNAME, "fname", VAR_STRING, VV_RO), 126 VV(VV_LANG, "lang", VAR_STRING, VV_RO), 127 VV(VV_LC_TIME, "lc_time", VAR_STRING, VV_RO), 128 VV(VV_CTYPE, "ctype", VAR_STRING, VV_RO), 129 VV(VV_CC_FROM, "charconvert_from", VAR_STRING, VV_RO), 130 VV(VV_CC_TO, "charconvert_to", VAR_STRING, VV_RO), 131 VV(VV_FNAME_IN, "fname_in", VAR_STRING, VV_RO), 132 VV(VV_FNAME_OUT, "fname_out", VAR_STRING, VV_RO), 133 VV(VV_FNAME_NEW, "fname_new", VAR_STRING, VV_RO), 134 VV(VV_FNAME_DIFF, "fname_diff", VAR_STRING, VV_RO), 135 VV(VV_CMDARG, "cmdarg", VAR_STRING, VV_RO), 136 VV(VV_FOLDSTART, "foldstart", VAR_NUMBER, VV_RO_SBX), 137 VV(VV_FOLDEND, "foldend", VAR_NUMBER, VV_RO_SBX), 138 VV(VV_FOLDDASHES, "folddashes", VAR_STRING, VV_RO_SBX), 139 VV(VV_FOLDLEVEL, "foldlevel", VAR_NUMBER, VV_RO_SBX), 140 VV(VV_PROGNAME, "progname", VAR_STRING, VV_RO), 141 VV(VV_SEND_SERVER, "servername", VAR_STRING, VV_RO), 142 VV(VV_DYING, "dying", VAR_NUMBER, VV_RO), 143 VV(VV_EXCEPTION, "exception", VAR_STRING, VV_RO), 144 VV(VV_THROWPOINT, "throwpoint", VAR_STRING, VV_RO), 145 VV(VV_REG, "register", VAR_STRING, VV_RO), 146 VV(VV_CMDBANG, "cmdbang", VAR_NUMBER, VV_RO), 147 VV(VV_INSERTMODE, "insertmode", VAR_STRING, VV_RO), 148 VV(VV_VAL, "val", VAR_UNKNOWN, VV_RO), 149 VV(VV_KEY, "key", VAR_UNKNOWN, VV_RO), 150 VV(VV_PROFILING, "profiling", VAR_NUMBER, VV_RO), 151 VV(VV_FCS_REASON, "fcs_reason", VAR_STRING, VV_RO), 152 VV(VV_FCS_CHOICE, "fcs_choice", VAR_STRING, 0), 153 VV(VV_BEVAL_BUFNR, "beval_bufnr", VAR_NUMBER, VV_RO), 154 VV(VV_BEVAL_WINNR, "beval_winnr", VAR_NUMBER, VV_RO), 155 VV(VV_BEVAL_WINID, "beval_winid", VAR_NUMBER, VV_RO), 156 VV(VV_BEVAL_LNUM, "beval_lnum", VAR_NUMBER, VV_RO), 157 VV(VV_BEVAL_COL, "beval_col", VAR_NUMBER, VV_RO), 158 VV(VV_BEVAL_TEXT, "beval_text", VAR_STRING, VV_RO), 159 VV(VV_SCROLLSTART, "scrollstart", VAR_STRING, 0), 160 VV(VV_SWAPNAME, "swapname", VAR_STRING, VV_RO), 161 VV(VV_SWAPCHOICE, "swapchoice", VAR_STRING, 0), 162 VV(VV_SWAPCOMMAND, "swapcommand", VAR_STRING, VV_RO), 163 VV(VV_CHAR, "char", VAR_STRING, 0), 164 VV(VV_MOUSE_WIN, "mouse_win", VAR_NUMBER, 0), 165 VV(VV_MOUSE_WINID, "mouse_winid", VAR_NUMBER, 0), 166 VV(VV_MOUSE_LNUM, "mouse_lnum", VAR_NUMBER, 0), 167 VV(VV_MOUSE_COL, "mouse_col", VAR_NUMBER, 0), 168 VV(VV_OP, "operator", VAR_STRING, VV_RO), 169 VV(VV_SEARCHFORWARD, "searchforward", VAR_NUMBER, 0), 170 VV(VV_HLSEARCH, "hlsearch", VAR_NUMBER, 0), 171 VV(VV_OLDFILES, "oldfiles", VAR_LIST, 0), 172 VV(VV_WINDOWID, "windowid", VAR_NUMBER, VV_RO_SBX), 173 VV(VV_PROGPATH, "progpath", VAR_STRING, VV_RO), 174 VV(VV_COMPLETED_ITEM, "completed_item", VAR_DICT, 0), 175 VV(VV_OPTION_NEW, "option_new", VAR_STRING, VV_RO), 176 VV(VV_OPTION_OLD, "option_old", VAR_STRING, VV_RO), 177 VV(VV_OPTION_OLDLOCAL, "option_oldlocal", VAR_STRING, VV_RO), 178 VV(VV_OPTION_OLDGLOBAL, "option_oldglobal", VAR_STRING, VV_RO), 179 VV(VV_OPTION_COMMAND, "option_command", VAR_STRING, VV_RO), 180 VV(VV_OPTION_TYPE, "option_type", VAR_STRING, VV_RO), 181 VV(VV_ERRORS, "errors", VAR_LIST, 0), 182 VV(VV_FALSE, "false", VAR_BOOL, VV_RO), 183 VV(VV_TRUE, "true", VAR_BOOL, VV_RO), 184 VV(VV_NULL, "null", VAR_SPECIAL, VV_RO), 185 VV(VV_NUMBERMAX, "numbermax", VAR_NUMBER, VV_RO), 186 VV(VV_NUMBERMIN, "numbermin", VAR_NUMBER, VV_RO), 187 VV(VV_NUMBERSIZE, "numbersize", VAR_NUMBER, VV_RO), 188 VV(VV_VIM_DID_ENTER, "vim_did_enter", VAR_NUMBER, VV_RO), 189 VV(VV_TESTING, "testing", VAR_NUMBER, 0), 190 VV(VV_TYPE_NUMBER, "t_number", VAR_NUMBER, VV_RO), 191 VV(VV_TYPE_STRING, "t_string", VAR_NUMBER, VV_RO), 192 VV(VV_TYPE_FUNC, "t_func", VAR_NUMBER, VV_RO), 193 VV(VV_TYPE_LIST, "t_list", VAR_NUMBER, VV_RO), 194 VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO), 195 VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO), 196 VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO), 197 VV(VV_TYPE_BLOB, "t_blob", VAR_NUMBER, VV_RO), 198 VV(VV_EVENT, "event", VAR_DICT, VV_RO), 199 VV(VV_VERSIONLONG, "versionlong", VAR_NUMBER, VV_RO), 200 VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO), 201 VV(VV_ARGF, "argf", VAR_LIST, VV_RO), 202 VV(VV_ARGV, "argv", VAR_LIST, VV_RO), 203 VV(VV_COLLATE, "collate", VAR_STRING, VV_RO), 204 VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO), 205 VV(VV_MAXCOL, "maxcol", VAR_NUMBER, VV_RO), 206 VV(VV_STACKTRACE, "stacktrace", VAR_LIST, VV_RO), 207 VV(VV_VIM_DID_INIT, "vim_did_init", VAR_NUMBER, VV_RO), 208 // Neovim 209 VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO), 210 VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO), 211 VV(VV__NULL_STRING, "_null_string", VAR_STRING, VV_RO), 212 VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO), 213 VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO), 214 VV(VV__NULL_BLOB, "_null_blob", VAR_BLOB, VV_RO), 215 VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO), 216 VV(VV_RELNUM, "relnum", VAR_NUMBER, VV_RO), 217 VV(VV_VIRTNUM, "virtnum", VAR_NUMBER, VV_RO), 218 }; 219 #undef VV 220 221 // shorthand 222 #define vv_type vv_di.di_tv.v_type 223 #define vv_str vv_di.di_tv.vval.v_string 224 #define vv_list vv_di.di_tv.vval.v_list 225 #define vv_tv vv_di.di_tv 226 227 /// Variable used for v: 228 static ScopeDictDictItem vimvars_var; 229 static dict_T vimvardict; // Dict with v: variables 230 /// v: hashtab 231 #define vimvarht vimvardict.dv_hashtab 232 233 static const char *const msgpack_type_names[] = { 234 [kMPNil] = "nil", 235 [kMPBoolean] = "boolean", 236 [kMPInteger] = "integer", 237 [kMPFloat] = "float", 238 [kMPString] = "string", 239 [kMPArray] = "array", 240 [kMPMap] = "map", 241 [kMPExt] = "ext", 242 }; 243 const list_T *eval_msgpack_type_lists[] = { 244 [kMPNil] = NULL, 245 [kMPBoolean] = NULL, 246 [kMPInteger] = NULL, 247 [kMPFloat] = NULL, 248 [kMPString] = NULL, 249 [kMPArray] = NULL, 250 [kMPMap] = NULL, 251 [kMPExt] = NULL, 252 }; 253 254 #define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars) 255 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) 256 257 void evalvars_init(void) 258 { 259 init_var_dict(get_globvar_dict(), &globvars_var, VAR_DEF_SCOPE); 260 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); 261 vimvardict.dv_lock = VAR_FIXED; 262 hash_init(&compat_hashtab); 263 264 for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) { 265 struct vimvar *p = &vimvars[i]; 266 assert(strlen(p->vv_name) <= VIMVAR_KEY_LEN); 267 STRCPY(p->vv_di.di_key, p->vv_name); 268 if (p->vv_flags & VV_RO) { 269 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 270 } else if (p->vv_flags & VV_RO_SBX) { 271 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 272 } else { 273 p->vv_di.di_flags = DI_FLAGS_FIX; 274 } 275 276 // add to v: scope dict, unless the value is not always available 277 if (p->vv_type != VAR_UNKNOWN) { 278 hash_add(&vimvarht, p->vv_di.di_key); 279 } 280 if (p->vv_flags & VV_COMPAT) { 281 // add to compat scope dict 282 hash_add(&compat_hashtab, p->vv_di.di_key); 283 } 284 } 285 const int vim_version = min_vim_version(); 286 set_vim_var_nr(VV_VERSION, vim_version); 287 set_vim_var_nr(VV_VERSIONLONG, vim_version * 10000 + highest_patch()); 288 289 dict_T *const msgpack_types_dict = tv_dict_alloc(); 290 for (size_t i = 0; i < ARRAY_SIZE(msgpack_type_names); i++) { 291 list_T *const type_list = tv_list_alloc(0); 292 tv_list_set_lock(type_list, VAR_FIXED); 293 tv_list_ref(type_list); 294 dictitem_T *const di = tv_dict_item_alloc(msgpack_type_names[i]); 295 di->di_flags |= DI_FLAGS_RO|DI_FLAGS_FIX; 296 di->di_tv = (typval_T) { 297 .v_type = VAR_LIST, 298 .vval = { .v_list = type_list, }, 299 }; 300 eval_msgpack_type_lists[i] = type_list; 301 if (tv_dict_add(msgpack_types_dict, di) == FAIL) { 302 // There must not be duplicate items in this dictionary by definition. 303 abort(); 304 } 305 } 306 msgpack_types_dict->dv_lock = VAR_FIXED; 307 308 set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict); 309 set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc_lock(VAR_FIXED)); 310 311 set_vim_var_dict(VV_EVENT, tv_dict_alloc_lock(VAR_FIXED)); 312 set_vim_var_list(VV_ERRORS, tv_list_alloc(kListLenUnknown)); 313 set_vim_var_nr(VV_STDERR, CHAN_STDERR); 314 set_vim_var_nr(VV_SEARCHFORWARD, 1); 315 set_vim_var_nr(VV_HLSEARCH, 1); 316 set_vim_var_nr(VV_COUNT1, 1); 317 set_vim_var_special(VV_EXITING, kSpecialVarNull); 318 319 set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER); 320 set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING); 321 set_vim_var_nr(VV_TYPE_FUNC, VAR_TYPE_FUNC); 322 set_vim_var_nr(VV_TYPE_LIST, VAR_TYPE_LIST); 323 set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT); 324 set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT); 325 set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL); 326 set_vim_var_nr(VV_TYPE_BLOB, VAR_TYPE_BLOB); 327 328 set_vim_var_bool(VV_FALSE, kBoolVarFalse); 329 set_vim_var_bool(VV_TRUE, kBoolVarTrue); 330 set_vim_var_special(VV_NULL, kSpecialVarNull); 331 set_vim_var_nr(VV_NUMBERMAX, VARNUMBER_MAX); 332 set_vim_var_nr(VV_NUMBERMIN, VARNUMBER_MIN); 333 set_vim_var_nr(VV_NUMBERSIZE, sizeof(varnumber_T) * 8); 334 set_vim_var_nr(VV_MAXCOL, MAXCOL); 335 336 set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); 337 338 // vimvars[VV_LUA].vv_type = VAR_PARTIAL; 339 partial_T *vvlua_partial = xcalloc(1, sizeof(partial_T)); 340 // this value shouldn't be printed, but if it is, do not crash 341 vvlua_partial->pt_name = xmallocz(0); 342 vvlua_partial->pt_refcount++; 343 set_vim_var_partial(VV_LUA, vvlua_partial); 344 345 set_reg_var(0); // default for v:register is not 0 but '"' 346 } 347 348 #if defined(EXITFREE) 349 void evalvars_clear(void) 350 { 351 for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) { 352 struct vimvar *p = &vimvars[i]; 353 if (p->vv_di.di_tv.v_type == VAR_STRING) { 354 XFREE_CLEAR(p->vv_str); 355 } else if (p->vv_di.di_tv.v_type == VAR_LIST) { 356 tv_list_unref(p->vv_list); 357 p->vv_list = NULL; 358 } 359 } 360 361 partial_unref(get_vim_var_partial(VV_LUA)); 362 set_vim_var_partial(VV_LUA, NULL); 363 hash_clear(&vimvarht); 364 hash_init(&vimvarht); // garbage_collect() will access it 365 hash_clear(&compat_hashtab); 366 367 // global variables 368 vars_clear(get_globvar_ht()); 369 370 // Script-local variables. Clear all the variables here. 371 // The scriptvar_T is cleared later in free_scriptnames(), because a 372 // variable in one script might hold a reference to the whole scope of 373 // another script. 374 for (int i = 1; i <= script_items.ga_len; i++) { 375 vars_clear(&SCRIPT_VARS(i)); 376 } 377 } 378 #endif 379 380 int garbage_collect_globvars(int copyID) 381 { 382 return set_ref_in_ht(&globvarht, copyID, NULL); 383 } 384 385 bool garbage_collect_vimvars(int copyID) 386 { 387 return set_ref_in_ht(&vimvarht, copyID, NULL); 388 } 389 390 bool garbage_collect_scriptvars(int copyID) 391 { 392 bool abort = false; 393 394 for (int i = 1; i <= script_items.ga_len; i++) { 395 abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); 396 } 397 398 return abort; 399 } 400 401 /// Set an internal variable to a string value. Creates the variable if it does 402 /// not already exist. 403 void set_internal_string_var(const char *name, char *value) // NOLINT(readability-non-const-parameter) 404 FUNC_ATTR_NONNULL_ARG(1) 405 { 406 typval_T tv = { 407 .v_type = VAR_STRING, 408 .vval.v_string = value, 409 }; 410 411 set_var(name, strlen(name), &tv, true); 412 } 413 414 int eval_charconvert(const char *const enc_from, const char *const enc_to, 415 const char *const fname_from, const char *const fname_to) 416 { 417 const sctx_T saved_sctx = current_sctx; 418 419 set_vim_var_string(VV_CC_FROM, enc_from, -1); 420 set_vim_var_string(VV_CC_TO, enc_to, -1); 421 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 422 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 423 sctx_T *ctx = get_option_sctx(kOptCharconvert); 424 if (ctx != NULL) { 425 current_sctx = *ctx; 426 } 427 428 bool err = false; 429 if (eval_to_bool(p_ccv, &err, NULL, false, true)) { 430 err = true; 431 } 432 433 set_vim_var_string(VV_CC_FROM, NULL, -1); 434 set_vim_var_string(VV_CC_TO, NULL, -1); 435 set_vim_var_string(VV_FNAME_IN, NULL, -1); 436 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 437 current_sctx = saved_sctx; 438 439 if (err) { 440 return FAIL; 441 } 442 return OK; 443 } 444 445 void eval_diff(const char *const origfile, const char *const newfile, const char *const outfile) 446 { 447 const sctx_T saved_sctx = current_sctx; 448 set_vim_var_string(VV_FNAME_IN, origfile, -1); 449 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 450 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 451 452 sctx_T *ctx = get_option_sctx(kOptDiffexpr); 453 if (ctx != NULL) { 454 current_sctx = *ctx; 455 } 456 457 // errors are ignored 458 typval_T *tv = eval_expr_ext(p_dex, NULL, true); 459 tv_free(tv); 460 461 set_vim_var_string(VV_FNAME_IN, NULL, -1); 462 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 463 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 464 current_sctx = saved_sctx; 465 } 466 467 void eval_patch(const char *const origfile, const char *const difffile, const char *const outfile) 468 { 469 const sctx_T saved_sctx = current_sctx; 470 set_vim_var_string(VV_FNAME_IN, origfile, -1); 471 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 472 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 473 474 sctx_T *ctx = get_option_sctx(kOptPatchexpr); 475 if (ctx != NULL) { 476 current_sctx = *ctx; 477 } 478 479 // errors are ignored 480 typval_T *tv = eval_expr_ext(p_pex, NULL, true); 481 tv_free(tv); 482 483 set_vim_var_string(VV_FNAME_IN, NULL, -1); 484 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 485 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 486 current_sctx = saved_sctx; 487 } 488 489 /// Evaluate an expression to a list with suggestions. 490 /// For the "expr:" part of 'spellsuggest'. 491 /// 492 /// @return NULL when there is an error. 493 list_T *eval_spell_expr(char *badword, char *expr) 494 { 495 typval_T save_val; 496 typval_T rettv; 497 list_T *list = NULL; 498 char *p = skipwhite(expr); 499 const sctx_T saved_sctx = current_sctx; 500 501 // Set "v:val" to the bad word. 502 prepare_vimvar(VV_VAL, &save_val); 503 set_vim_var_string(VV_VAL, badword, -1); 504 if (p_verbose == 0) { 505 emsg_off++; 506 } 507 sctx_T *ctx = get_option_sctx(kOptSpellsuggest); 508 if (ctx != NULL) { 509 current_sctx = *ctx; 510 } 511 512 int r = may_call_simple_func(p, &rettv); 513 if (r == NOTDONE) { 514 r = eval1(&p, &rettv, &EVALARG_EVALUATE); 515 } 516 if (r == OK) { 517 if (rettv.v_type != VAR_LIST) { 518 tv_clear(&rettv); 519 } else { 520 list = rettv.vval.v_list; 521 } 522 } 523 524 if (p_verbose == 0) { 525 emsg_off--; 526 } 527 tv_clear(get_vim_var_tv(VV_VAL)); 528 restore_vimvar(VV_VAL, &save_val); 529 current_sctx = saved_sctx; 530 531 return list; 532 } 533 534 /// Get spell word from an entry from spellsuggest=expr: 535 /// 536 /// Entry in question is supposed to be a list (to be checked by the caller) 537 /// with two items: a word and a score represented as an unsigned number 538 /// (whether it actually is unsigned is not checked). 539 /// 540 /// Used to get the good word and score from the eval_spell_expr() result. 541 /// 542 /// @param[in] list List to get values from. 543 /// @param[out] ret_word Suggested word. Not initialized if return value is 544 /// -1. 545 /// 546 /// @return -1 in case of error, score otherwise. 547 int get_spellword(list_T *const list, const char **ret_word) 548 { 549 if (tv_list_len(list) != 2) { 550 emsg(_("E5700: Expression from 'spellsuggest' must yield lists with " 551 "exactly two values")); 552 return -1; 553 } 554 *ret_word = tv_list_find_str(list, 0); 555 if (*ret_word == NULL) { 556 return -1; 557 } 558 return (int)tv_list_find_nr(list, -1, NULL); 559 } 560 561 /// Prepare v: variable "idx" to be used. 562 /// Save the current typeval in "save_tv" and clear it. 563 /// When not used yet add the variable to the v: hashtable. 564 void prepare_vimvar(int idx, typval_T *save_tv) 565 { 566 *save_tv = vimvars[idx].vv_tv; 567 vimvars[idx].vv_str = NULL; // don't free it now 568 if (vimvars[idx].vv_type == VAR_UNKNOWN) { 569 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 570 } 571 } 572 573 /// Restore v: variable "idx" to typeval "save_tv". 574 /// Note that the v: variable must have been cleared already. 575 /// When no longer defined, remove the variable from the v: hashtable. 576 void restore_vimvar(int idx, typval_T *save_tv) 577 { 578 vimvars[idx].vv_tv = *save_tv; 579 if (vimvars[idx].vv_type != VAR_UNKNOWN) { 580 return; 581 } 582 583 hashitem_T *hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 584 if (HASHITEM_EMPTY(hi)) { 585 internal_error("restore_vimvar()"); 586 } else { 587 hash_remove(&vimvarht, hi); 588 } 589 } 590 591 /// List Vim variables. 592 static void list_vim_vars(int *first) 593 { 594 list_hashtable_vars(&vimvarht, "v:", false, first); 595 } 596 597 /// List script-local variables, if there is a script. 598 static void list_script_vars(int *first) 599 { 600 if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) { 601 list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", false, first); 602 } 603 } 604 605 /// Evaluate one Vim expression {expr} in string "p" and append the 606 /// resulting string to "gap". "p" points to the opening "{". 607 /// When "evaluate" is false only skip over the expression. 608 /// Return a pointer to the character after "}", NULL for an error. 609 char *eval_one_expr_in_str(char *p, garray_T *gap, bool evaluate) 610 { 611 char *block_start = skipwhite(p + 1); // skip the opening { 612 char *block_end = block_start; 613 614 if (*block_start == NUL) { 615 semsg(_(e_missing_close_curly_str), p); 616 return NULL; 617 } 618 if (skip_expr(&block_end, NULL) == FAIL) { 619 return NULL; 620 } 621 block_end = skipwhite(block_end); 622 if (*block_end != '}') { 623 semsg(_(e_missing_close_curly_str), p); 624 return NULL; 625 } 626 if (evaluate) { 627 *block_end = NUL; 628 char *expr_val = eval_to_string(block_start, false, false); 629 *block_end = '}'; 630 if (expr_val == NULL) { 631 return NULL; 632 } 633 ga_concat(gap, expr_val); 634 xfree(expr_val); 635 } 636 637 return block_end + 1; 638 } 639 640 /// Evaluate all the Vim expressions {expr} in "str" and return the resulting 641 /// string in allocated memory. "{{" is reduced to "{" and "}}" to "}". 642 /// Used for a heredoc assignment. 643 /// Returns NULL for an error. 644 static char *eval_all_expr_in_str(char *str) 645 { 646 garray_T ga; 647 ga_init(&ga, 1, 80); 648 char *p = str; 649 650 while (*p != NUL) { 651 bool escaped_brace = false; 652 653 // Look for a block start. 654 char *lit_start = p; 655 while (*p != '{' && *p != '}' && *p != NUL) { 656 p++; 657 } 658 659 if (*p != NUL && *p == p[1]) { 660 // Escaped brace, unescape and continue. 661 // Include the brace in the literal string. 662 p++; 663 escaped_brace = true; 664 } else if (*p == '}') { 665 semsg(_(e_stray_closing_curly_str), str); 666 ga_clear(&ga); 667 return NULL; 668 } 669 670 // Append the literal part. 671 ga_concat_len(&ga, lit_start, (size_t)(p - lit_start)); 672 673 if (*p == NUL) { 674 break; 675 } 676 677 if (escaped_brace) { 678 // Skip the second brace. 679 p++; 680 continue; 681 } 682 683 // Evaluate the expression and append the result. 684 p = eval_one_expr_in_str(p, &ga, true); 685 if (p == NULL) { 686 ga_clear(&ga); 687 return NULL; 688 } 689 } 690 ga_append(&ga, NUL); 691 692 return ga.ga_data; 693 } 694 695 /// Get a list of lines from a HERE document. The here document is a list of 696 /// lines surrounded by a marker. 697 /// cmd << {marker} 698 /// {line1} 699 /// {line2} 700 /// .... 701 /// {marker} 702 /// 703 /// The {marker} is a string. If the optional 'trim' word is supplied before the 704 /// marker, then the leading indentation before the lines (matching the 705 /// indentation in the 'cmd' line) is stripped. 706 /// 707 /// When getting lines for an embedded script (e.g. python, lua, perl, ruby, 708 /// tcl, mzscheme), "script_get" is set to true. In this case, if the marker is 709 /// missing, then '.' is accepted as a marker. 710 /// 711 /// @return a List with {lines} or NULL on failure. 712 list_T *heredoc_get(exarg_T *eap, char *cmd, bool script_get) 713 { 714 char *marker; 715 int marker_indent_len = 0; 716 int text_indent_len = 0; 717 char *text_indent = NULL; 718 char dot[] = "."; 719 bool heredoc_in_string = false; 720 char *line_arg = NULL; 721 char *nl_ptr = vim_strchr(cmd, '\n'); 722 723 if (nl_ptr != NULL) { 724 heredoc_in_string = true; 725 line_arg = nl_ptr + 1; 726 *nl_ptr = NUL; 727 } else if (eap->ea_getline == NULL) { 728 emsg(_(e_cannot_use_heredoc_here)); 729 return NULL; 730 } 731 732 // Check for the optional 'trim' word before the marker 733 cmd = skipwhite(cmd); 734 bool evalstr = false; 735 bool eval_failed = false; 736 while (true) { 737 if (strncmp(cmd, "trim", 4) == 0 738 && (cmd[4] == NUL || ascii_iswhite(cmd[4]))) { 739 cmd = skipwhite(cmd + 4); 740 741 // Trim the indentation from all the lines in the here document. 742 // The amount of indentation trimmed is the same as the indentation 743 // of the first line after the :let command line. To find the end 744 // marker the indent of the :let command line is trimmed. 745 char *p = *eap->cmdlinep; 746 while (ascii_iswhite(*p)) { 747 p++; 748 marker_indent_len++; 749 } 750 text_indent_len = -1; 751 752 continue; 753 } 754 if (strncmp(cmd, "eval", 4) == 0 755 && (cmd[4] == NUL || ascii_iswhite(cmd[4]))) { 756 cmd = skipwhite(cmd + 4); 757 evalstr = true; 758 continue; 759 } 760 break; 761 } 762 763 const char comment_char = '"'; 764 // The marker is the next word. 765 if (*cmd != NUL && *cmd != comment_char) { 766 marker = skipwhite(cmd); 767 char *p = skiptowhite(marker); 768 if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char) { 769 semsg(_(e_trailing_arg), p); 770 return NULL; 771 } 772 *p = NUL; 773 if (!script_get && islower((uint8_t)(*marker))) { 774 emsg(_("E221: Marker cannot start with lower case letter")); 775 return NULL; 776 } 777 } else { 778 // When getting lines for an embedded script, if the marker is missing, 779 // accept '.' as the marker. 780 if (script_get) { 781 marker = dot; 782 } else { 783 emsg(_("E172: Missing marker")); 784 return NULL; 785 } 786 } 787 788 char *theline = NULL; 789 list_T *l = tv_list_alloc(0); 790 while (true) { 791 int mi = 0; 792 int ti = 0; 793 794 if (heredoc_in_string) { 795 // heredoc in a string separated by newlines. Get the next line 796 // from the string. 797 798 if (*line_arg == NUL) { 799 if (!script_get) { 800 semsg(_(e_missing_end_marker_str), marker); 801 } 802 break; 803 } 804 805 theline = line_arg; 806 char *next_line = vim_strchr(theline, '\n'); 807 if (next_line == NULL) { 808 line_arg += strlen(line_arg); 809 } else { 810 *next_line = NUL; 811 line_arg = next_line + 1; 812 } 813 } else { 814 xfree(theline); 815 theline = eap->ea_getline(NUL, eap->cookie, 0, false); 816 if (theline == NULL) { 817 if (!script_get) { 818 semsg(_(e_missing_end_marker_str), marker); 819 } 820 break; 821 } 822 } 823 824 // with "trim": skip the indent matching the :let line to find the 825 // marker 826 if (marker_indent_len > 0 827 && strncmp(theline, *eap->cmdlinep, (size_t)marker_indent_len) == 0) { 828 mi = marker_indent_len; 829 } 830 if (strcmp(marker, theline + mi) == 0) { 831 break; 832 } 833 834 // If expression evaluation failed in the heredoc, then skip till the 835 // end marker. 836 if (eval_failed) { 837 continue; 838 } 839 840 if (text_indent_len == -1 && *theline != NUL) { 841 // set the text indent from the first line. 842 char *p = theline; 843 text_indent_len = 0; 844 while (ascii_iswhite(*p)) { 845 p++; 846 text_indent_len++; 847 } 848 text_indent = xmemdupz(theline, (size_t)text_indent_len); 849 } 850 // with "trim": skip the indent matching the first line 851 if (text_indent != NULL) { 852 for (ti = 0; ti < text_indent_len; ti++) { 853 if (theline[ti] != text_indent[ti]) { 854 break; 855 } 856 } 857 } 858 859 char *str = theline + ti; 860 if (evalstr && !eap->skip) { 861 str = eval_all_expr_in_str(str); 862 if (str == NULL) { 863 // expression evaluation failed 864 eval_failed = true; 865 continue; 866 } 867 tv_list_append_allocated_string(l, str); 868 } else { 869 tv_list_append_string(l, str, -1); 870 } 871 } 872 if (heredoc_in_string) { 873 // Next command follows the heredoc in the string. 874 eap->nextcmd = line_arg; 875 } else { 876 xfree(theline); 877 } 878 xfree(text_indent); 879 880 if (eval_failed) { 881 // expression evaluation in the heredoc failed 882 tv_list_free(l); 883 return NULL; 884 } 885 return l; 886 } 887 888 /// ":let" list all variable values 889 /// ":let var1 var2" list variable values 890 /// ":let var = expr" assignment command. 891 /// ":let var += expr" assignment command. 892 /// ":let var -= expr" assignment command. 893 /// ":let var *= expr" assignment command. 894 /// ":let var /= expr" assignment command. 895 /// ":let var %= expr" assignment command. 896 /// ":let var .= expr" assignment command. 897 /// ":let var ..= expr" assignment command. 898 /// ":let [var1, var2] = expr" unpack list. 899 /// ":let [name, ..., ; lastname] = expr" unpack list. 900 /// 901 /// ":cons[t] var = expr1" define constant 902 /// ":cons[t] [name1, name2, ...] = expr1" define constants unpacking list 903 /// ":cons[t] [name, ..., ; lastname] = expr" define constants unpacking list 904 void ex_let(exarg_T *eap) 905 { 906 const bool is_const = eap->cmdidx == CMD_const; 907 char *arg = eap->arg; 908 char *expr = NULL; 909 typval_T rettv; 910 int var_count = 0; 911 int semicolon = 0; 912 char op[2]; 913 const char *argend; 914 int first = true; 915 916 argend = skip_var_list(arg, &var_count, &semicolon, false); 917 if (argend == NULL) { 918 return; 919 } 920 expr = skipwhite(argend); 921 bool concat = strncmp(expr, "..=", 3) == 0; 922 bool has_assign = *expr == '=' || (vim_strchr("+-*/%.", (uint8_t)(*expr)) != NULL 923 && expr[1] == '='); 924 if (!has_assign && !concat) { 925 // ":let" without "=": list variables 926 if (*arg == '[') { 927 emsg(_(e_invarg)); 928 } else if (!ends_excmd(*arg)) { 929 // ":let var1 var2" 930 arg = (char *)list_arg_vars(eap, arg, &first); 931 } else if (!eap->skip) { 932 // ":let" 933 list_glob_vars(&first); 934 list_buf_vars(&first); 935 list_win_vars(&first); 936 list_tab_vars(&first); 937 list_script_vars(&first); 938 list_func_vars(&first); 939 list_vim_vars(&first); 940 } 941 eap->nextcmd = check_nextcmd(arg); 942 return; 943 } 944 945 if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<') { 946 // HERE document 947 list_T *l = heredoc_get(eap, expr + 3, false); 948 if (l != NULL) { 949 tv_list_set_ret(&rettv, l); 950 if (!eap->skip) { 951 op[0] = '='; 952 op[1] = NUL; 953 ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, is_const, op); 954 } 955 tv_clear(&rettv); 956 } 957 return; 958 } 959 960 rettv.v_type = VAR_UNKNOWN; 961 962 op[0] = '='; 963 op[1] = NUL; 964 if (*expr != '=') { 965 if (vim_strchr("+-*/%.", (uint8_t)(*expr)) != NULL) { 966 op[0] = *expr; // +=, -=, *=, /=, %= or .= 967 if (expr[0] == '.' && expr[1] == '.') { // ..= 968 expr++; 969 } 970 } 971 expr += 2; 972 } else { 973 expr += 1; 974 } 975 976 expr = skipwhite(expr); 977 978 if (eap->skip) { 979 emsg_skip++; 980 } 981 evalarg_T evalarg; 982 fill_evalarg_from_eap(&evalarg, eap, eap->skip); 983 int eval_res = eval0(expr, &rettv, eap, &evalarg); 984 if (eap->skip) { 985 emsg_skip--; 986 } 987 clear_evalarg(&evalarg, eap); 988 989 if (!eap->skip && eval_res != FAIL) { 990 ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, is_const, op); 991 } 992 if (eval_res != FAIL) { 993 tv_clear(&rettv); 994 } 995 } 996 997 /// Assign the typevalue "tv" to the variable or variables at "arg_start". 998 /// Handles both "var" with any type and "[var, var; var]" with a list type. 999 /// When "op" is not NULL it points to a string with characters that 1000 /// must appear after the variable(s). Use "+", "-" or "." for add, subtract 1001 /// or concatenate. 1002 /// 1003 /// @param copy copy values from "tv", don't move 1004 /// @param semicolon from skip_var_list() 1005 /// @param var_count from skip_var_list() 1006 /// @param is_const lock variables for :const 1007 /// 1008 /// @return OK or FAIL; 1009 int ex_let_vars(char *arg_start, typval_T *tv, int copy, int semicolon, int var_count, int is_const, 1010 char *op) 1011 { 1012 char *arg = arg_start; 1013 typval_T ltv; 1014 1015 if (*arg != '[') { 1016 // ":let var = expr" or ":for var in list" 1017 if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) { 1018 return FAIL; 1019 } 1020 return OK; 1021 } 1022 1023 // ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1024 if (tv->v_type != VAR_LIST) { 1025 emsg(_(e_listreq)); 1026 return FAIL; 1027 } 1028 list_T *const l = tv->vval.v_list; 1029 1030 const int len = tv_list_len(l); 1031 if (semicolon == 0 && var_count < len) { 1032 emsg(_("E687: Less targets than List items")); 1033 return FAIL; 1034 } 1035 if (var_count - semicolon > len) { 1036 emsg(_("E688: More targets than List items")); 1037 return FAIL; 1038 } 1039 // List l may actually be NULL, but it should fail with E688 or even earlier 1040 // if you try to do ":let [] = v:_null_list". 1041 assert(l != NULL); 1042 1043 listitem_T *item = tv_list_first(l); 1044 size_t rest_len = (size_t)tv_list_len(l); 1045 while (*arg != ']') { 1046 arg = skipwhite(arg + 1); 1047 arg = ex_let_one(arg, TV_LIST_ITEM_TV(item), true, is_const, ",;]", op); 1048 if (arg == NULL) { 1049 return FAIL; 1050 } 1051 rest_len--; 1052 1053 item = TV_LIST_ITEM_NEXT(l, item); 1054 arg = skipwhite(arg); 1055 if (*arg == ';') { 1056 // Put the rest of the list (may be empty) in the var after ';'. 1057 // Create a new list for this. 1058 list_T *const rest_list = tv_list_alloc((ptrdiff_t)rest_len); 1059 while (item != NULL) { 1060 tv_list_append_tv(rest_list, TV_LIST_ITEM_TV(item)); 1061 item = TV_LIST_ITEM_NEXT(l, item); 1062 } 1063 1064 ltv.v_type = VAR_LIST; 1065 ltv.v_lock = VAR_UNLOCKED; 1066 ltv.vval.v_list = rest_list; 1067 tv_list_ref(rest_list); 1068 1069 arg = ex_let_one(skipwhite(arg + 1), <v, false, is_const, "]", op); 1070 tv_clear(<v); 1071 if (arg == NULL) { 1072 return FAIL; 1073 } 1074 break; 1075 } else if (*arg != ',' && *arg != ']') { 1076 internal_error("ex_let_vars()"); 1077 return FAIL; 1078 } 1079 } 1080 1081 return OK; 1082 } 1083 1084 /// Skip over assignable variable "var" or list of variables "[var, var]". 1085 /// Used for ":let varvar = expr" and ":for varvar in expr". 1086 /// For "[var, var]" increment "*var_count" for each variable. 1087 /// for "[var, var; var]" set "semicolon" to 1. 1088 /// If "silent" is true do not give an "invalid argument" error message. 1089 /// 1090 /// @return NULL for an error. 1091 const char *skip_var_list(const char *arg, int *var_count, int *semicolon, bool silent) 1092 { 1093 if (*arg == '[') { 1094 const char *s; 1095 // "[var, var]": find the matching ']'. 1096 const char *p = arg; 1097 while (true) { 1098 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' 1099 s = skip_var_one(p); 1100 if (s == p) { 1101 if (!silent) { 1102 semsg(_(e_invarg2), p); 1103 } 1104 return NULL; 1105 } 1106 (*var_count)++; 1107 1108 p = skipwhite(s); 1109 if (*p == ']') { 1110 break; 1111 } else if (*p == ';') { 1112 if (*semicolon == 1) { 1113 if (!silent) { 1114 emsg(_(e_double_semicolon_in_list_of_variables)); 1115 } 1116 return NULL; 1117 } 1118 *semicolon = 1; 1119 } else if (*p != ',') { 1120 if (!silent) { 1121 semsg(_(e_invarg2), p); 1122 } 1123 return NULL; 1124 } 1125 } 1126 return p + 1; 1127 } 1128 return skip_var_one(arg); 1129 } 1130 1131 /// Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 1132 /// l[idx]. 1133 static const char *skip_var_one(const char *arg) 1134 { 1135 if (*arg == '@' && arg[1] != NUL) { 1136 return arg + 2; 1137 } 1138 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1139 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1140 } 1141 1142 /// List variables for hashtab "ht" with prefix "prefix". 1143 /// 1144 /// @param empty if true also list NULL strings as empty strings. 1145 void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, int *first) 1146 { 1147 hashitem_T *hi; 1148 dictitem_T *di; 1149 int todo; 1150 1151 todo = (int)ht->ht_used; 1152 for (hi = ht->ht_array; todo > 0 && !got_int; hi++) { 1153 if (!HASHITEM_EMPTY(hi)) { 1154 todo--; 1155 di = TV_DICT_HI2DI(hi); 1156 char buf[IOSIZE]; 1157 1158 // apply :filter /pat/ to variable name 1159 xstrlcpy(buf, prefix, IOSIZE); 1160 xstrlcat(buf, di->di_key, IOSIZE); 1161 if (message_filtered(buf)) { 1162 continue; 1163 } 1164 1165 if (empty || di->di_tv.v_type != VAR_STRING 1166 || di->di_tv.vval.v_string != NULL) { 1167 list_one_var(di, prefix, first); 1168 } 1169 } 1170 } 1171 } 1172 1173 /// List global variables. 1174 static void list_glob_vars(int *first) 1175 { 1176 list_hashtable_vars(&globvarht, "", true, first); 1177 } 1178 1179 /// List buffer variables. 1180 static void list_buf_vars(int *first) 1181 { 1182 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, "b:", true, first); 1183 } 1184 1185 /// List window variables. 1186 static void list_win_vars(int *first) 1187 { 1188 list_hashtable_vars(&curwin->w_vars->dv_hashtab, "w:", true, first); 1189 } 1190 1191 /// List tab page variables. 1192 static void list_tab_vars(int *first) 1193 { 1194 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, "t:", true, first); 1195 } 1196 1197 /// List variables in "arg". 1198 static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) 1199 { 1200 bool error = false; 1201 int len; 1202 const char *name; 1203 const char *name_start; 1204 typval_T tv; 1205 1206 while (!ends_excmd(*arg) && !got_int) { 1207 if (error || eap->skip) { 1208 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1209 if (!ascii_iswhite(*arg) && !ends_excmd(*arg)) { 1210 emsg_severe = true; 1211 semsg(_(e_trailing_arg), arg); 1212 break; 1213 } 1214 } else { 1215 // get_name_len() takes care of expanding curly braces 1216 name_start = name = arg; 1217 char *tofree; 1218 len = get_name_len(&arg, &tofree, true, true); 1219 if (len <= 0) { 1220 // This is mainly to keep test 49 working: when expanding 1221 // curly braces fails overrule the exception error message. 1222 if (len < 0 && !aborting()) { 1223 emsg_severe = true; 1224 semsg(_(e_invarg2), arg); 1225 break; 1226 } 1227 error = true; 1228 } else { 1229 if (tofree != NULL) { 1230 name = tofree; 1231 } 1232 if (eval_variable(name, len, &tv, NULL, true, false) == FAIL) { 1233 error = true; 1234 } else { 1235 // handle d.key, l[idx], f(expr) 1236 const char *const arg_subsc = arg; 1237 if (handle_subscript(&arg, &tv, &EVALARG_EVALUATE, true) == FAIL) { 1238 error = true; 1239 } else { 1240 if (arg == arg_subsc && len == 2 && name[1] == ':') { 1241 switch (*name) { 1242 case 'g': 1243 list_glob_vars(first); break; 1244 case 'b': 1245 list_buf_vars(first); break; 1246 case 'w': 1247 list_win_vars(first); break; 1248 case 't': 1249 list_tab_vars(first); break; 1250 case 'v': 1251 list_vim_vars(first); break; 1252 case 's': 1253 list_script_vars(first); break; 1254 case 'l': 1255 list_func_vars(first); break; 1256 default: 1257 semsg(_("E738: Can't list variables for %s"), name); 1258 } 1259 } else { 1260 char *const s = encode_tv2echo(&tv, NULL); 1261 const char *const used_name = (arg == arg_subsc 1262 ? name 1263 : name_start); 1264 assert(used_name != NULL); 1265 const ptrdiff_t name_size = (used_name == tofree 1266 ? (ptrdiff_t)strlen(used_name) 1267 : (arg - used_name)); 1268 list_one_var_a("", used_name, name_size, 1269 tv.v_type, s == NULL ? "" : s, first); 1270 xfree(s); 1271 } 1272 tv_clear(&tv); 1273 } 1274 } 1275 } 1276 1277 xfree(tofree); 1278 } 1279 1280 arg = skipwhite(arg); 1281 } 1282 1283 return arg; 1284 } 1285 1286 /// Set an environment variable, part of ex_let_one(). 1287 static char *ex_let_env(char *arg, typval_T *const tv, const bool is_const, 1288 const char *const endchars, const char *const op) 1289 FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT 1290 { 1291 if (is_const) { 1292 emsg(_("E996: Cannot lock an environment variable")); 1293 return NULL; 1294 } 1295 1296 // Find the end of the name. 1297 char *arg_end = NULL; 1298 arg++; 1299 char *name = arg; 1300 int len = get_env_len((const char **)&arg); 1301 if (len == 0) { 1302 semsg(_(e_invarg2), name - 1); 1303 } else { 1304 if (op != NULL && vim_strchr("+-*/%", (uint8_t)(*op)) != NULL) { 1305 semsg(_(e_letwrong), op); 1306 } else if (endchars != NULL 1307 && vim_strchr(endchars, (uint8_t)(*skipwhite(arg))) == NULL) { 1308 emsg(_(e_letunexp)); 1309 } else if (!check_secure()) { 1310 char *tofree = NULL; 1311 const char c1 = name[len]; 1312 name[len] = NUL; 1313 const char *p = tv_get_string_chk(tv); 1314 if (p != NULL && op != NULL && *op == '.') { 1315 char *s = vim_getenv(name); 1316 if (s != NULL) { 1317 tofree = concat_str(s, p); 1318 p = tofree; 1319 xfree(s); 1320 } 1321 } 1322 if (p != NULL) { 1323 vim_setenv_ext(name, p); 1324 arg_end = arg; 1325 } 1326 name[len] = c1; 1327 xfree(tofree); 1328 } 1329 } 1330 return arg_end; 1331 } 1332 1333 /// Set an option, part of ex_let_one(). 1334 static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, 1335 const char *const endchars, const char *const op) 1336 FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT 1337 { 1338 if (is_const) { 1339 emsg(_("E996: Cannot lock an option")); 1340 return NULL; 1341 } 1342 1343 // Find the end of the name. 1344 char *arg_end = NULL; 1345 OptIndex opt_idx; 1346 int opt_flags; 1347 1348 char *const p = (char *)find_option_var_end((const char **)&arg, &opt_idx, &opt_flags); 1349 1350 if (p == NULL || (endchars != NULL && vim_strchr(endchars, (uint8_t)(*skipwhite(p))) == NULL)) { 1351 emsg(_(e_letunexp)); 1352 return NULL; 1353 } 1354 1355 const char c1 = *p; 1356 *p = NUL; 1357 1358 bool is_tty_opt = is_tty_option(arg); 1359 bool hidden = is_option_hidden(opt_idx); 1360 OptVal curval = is_tty_opt ? get_tty_option(arg) : get_option_value(opt_idx, opt_flags); 1361 OptVal newval = NIL_OPTVAL; 1362 1363 if (curval.type == kOptValTypeNil) { 1364 semsg(_(e_unknown_option2), arg); 1365 goto theend; 1366 } 1367 if (op != NULL && *op != '=' 1368 && ((curval.type != kOptValTypeString && *op == '.') 1369 || (curval.type == kOptValTypeString && *op != '.'))) { 1370 semsg(_(e_letwrong), op); 1371 goto theend; 1372 } 1373 1374 bool error; 1375 newval = tv_to_optval(tv, opt_idx, arg, &error); 1376 if (error) { 1377 goto theend; 1378 } 1379 1380 // Current value and new value must have the same type. 1381 assert(curval.type == newval.type); 1382 const bool is_num = curval.type == kOptValTypeNumber || curval.type == kOptValTypeBoolean; 1383 const bool is_string = curval.type == kOptValTypeString; 1384 1385 if (op != NULL && *op != '=') { 1386 if (!hidden && is_num) { // number or bool 1387 OptInt cur_n = curval.type == kOptValTypeNumber ? curval.data.number : curval.data.boolean; 1388 OptInt new_n = newval.type == kOptValTypeNumber ? newval.data.number : newval.data.boolean; 1389 1390 switch (*op) { 1391 case '+': 1392 new_n = cur_n + new_n; break; 1393 case '-': 1394 new_n = cur_n - new_n; break; 1395 case '*': 1396 new_n = cur_n * new_n; break; 1397 case '/': 1398 new_n = num_divide(cur_n, new_n); break; 1399 case '%': 1400 new_n = num_modulus(cur_n, new_n); break; 1401 } 1402 1403 if (curval.type == kOptValTypeNumber) { 1404 newval = NUMBER_OPTVAL(new_n); 1405 } else { 1406 newval = BOOLEAN_OPTVAL(TRISTATE_FROM_INT(new_n)); 1407 } 1408 } else if (!hidden && is_string) { // string 1409 const char *curval_data = curval.data.string.data; 1410 const char *newval_data = newval.data.string.data; 1411 1412 if (curval_data != NULL && newval_data != NULL) { 1413 OptVal newval_old = newval; 1414 newval = CSTR_AS_OPTVAL(concat_str(curval_data, newval_data)); 1415 optval_free(newval_old); 1416 } 1417 } 1418 } 1419 1420 const char *err = set_option_value_handle_tty(arg, opt_idx, newval, opt_flags); 1421 arg_end = p; 1422 if (err != NULL) { 1423 emsg(_(err)); 1424 } 1425 1426 theend: 1427 *p = c1; 1428 optval_free(curval); 1429 optval_free(newval); 1430 return arg_end; 1431 } 1432 1433 /// Set a register, part of ex_let_one(). 1434 static char *ex_let_register(char *arg, typval_T *const tv, const bool is_const, 1435 const char *const endchars, const char *const op) 1436 FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT 1437 { 1438 if (is_const) { 1439 emsg(_("E996: Cannot lock a register")); 1440 return NULL; 1441 } 1442 1443 char *arg_end = NULL; 1444 arg++; 1445 if (op != NULL && vim_strchr("+-*/%", (uint8_t)(*op)) != NULL) { 1446 semsg(_(e_letwrong), op); 1447 } else if (endchars != NULL 1448 && vim_strchr(endchars, (uint8_t)(*skipwhite(arg + 1))) == NULL) { 1449 emsg(_(e_letunexp)); 1450 } else { 1451 char *ptofree = NULL; 1452 const char *p = tv_get_string_chk(tv); 1453 if (p != NULL && op != NULL && *op == '.') { 1454 char *s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); 1455 if (s != NULL) { 1456 ptofree = concat_str(s, p); 1457 p = ptofree; 1458 xfree(s); 1459 } 1460 } 1461 if (p != NULL) { 1462 write_reg_contents(*arg == '@' ? '"' : *arg, p, (ssize_t)strlen(p), false); 1463 arg_end = arg + 1; 1464 } 1465 xfree(ptofree); 1466 } 1467 return arg_end; 1468 } 1469 1470 /// Set one item of `:let var = expr` or `:let [v1, v2] = list` to its value 1471 /// 1472 /// @param[in] arg Start of the variable name. 1473 /// @param[in] tv Value to assign to the variable. 1474 /// @param[in] copy If true, copy value from `tv`. 1475 /// @param[in] endchars Valid characters after variable name or NULL. 1476 /// @param[in] op Operation performed: *op is `+`, `-`, `.` for `+=`, etc. 1477 /// NULL for `=`. 1478 /// 1479 /// @return a pointer to the char just after the var name or NULL in case of 1480 /// error. 1481 static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bool is_const, 1482 const char *const endchars, const char *const op) 1483 FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT 1484 { 1485 char *arg_end = NULL; 1486 1487 if (*arg == '$') { 1488 // ":let $VAR = expr": Set environment variable. 1489 return ex_let_env(arg, tv, is_const, endchars, op); 1490 } else if (*arg == '&') { 1491 // ":let &option = expr": Set option value. 1492 // ":let &l:option = expr": Set local option value. 1493 // ":let &g:option = expr": Set global option value. 1494 return ex_let_option(arg, tv, is_const, endchars, op); 1495 } else if (*arg == '@') { 1496 // ":let @r = expr": Set register contents. 1497 return ex_let_register(arg, tv, is_const, endchars, op); 1498 } else if (eval_isnamec1(*arg) || *arg == '{') { 1499 // ":let var = expr": Set internal variable. 1500 // ":let {expr} = expr": Idem, name made with curly braces 1501 lval_T lv; 1502 char *const p = get_lval(arg, tv, &lv, false, false, 0, FNE_CHECK_START); 1503 if (p != NULL && lv.ll_name != NULL) { 1504 if (endchars != NULL && vim_strchr(endchars, (uint8_t)(*skipwhite(p))) == NULL) { 1505 emsg(_(e_letunexp)); 1506 } else { 1507 set_var_lval(&lv, p, tv, copy, is_const, op); 1508 arg_end = p; 1509 } 1510 } 1511 clear_lval(&lv); 1512 } else { 1513 semsg(_(e_invarg2), arg); 1514 } 1515 1516 return arg_end; 1517 } 1518 1519 /// ":unlet[!] var1 ... " command. 1520 void ex_unlet(exarg_T *eap) 1521 { 1522 ex_unletlock(eap, eap->arg, 0, eap->forceit ? GLV_QUIET : 0, do_unlet_var); 1523 } 1524 1525 /// ":lockvar" and ":unlockvar" commands 1526 void ex_lockvar(exarg_T *eap) 1527 { 1528 char *arg = eap->arg; 1529 int deep = 2; 1530 1531 if (eap->forceit) { 1532 deep = -1; 1533 } else if (ascii_isdigit(*arg)) { 1534 deep = getdigits_int(&arg, false, -1); 1535 arg = skipwhite(arg); 1536 } 1537 1538 ex_unletlock(eap, arg, deep, 0, do_lock_var); 1539 } 1540 1541 /// Common parsing logic for :unlet, :lockvar and :unlockvar. 1542 /// 1543 /// Invokes `callback` afterwards if successful and `eap->skip == false`. 1544 /// 1545 /// @param[in] eap Ex command arguments for the command. 1546 /// @param[in] argstart Start of the string argument for the command. 1547 /// @param[in] deep Levels to (un)lock for :(un)lockvar, -1 to (un)lock 1548 /// everything. 1549 /// @param[in] callback Appropriate handler for the command. 1550 static void ex_unletlock(exarg_T *eap, char *argstart, int deep, int glv_flags, 1551 ex_unletlock_callback callback) 1552 FUNC_ATTR_NONNULL_ALL 1553 { 1554 char *arg = argstart; 1555 char *name_end; 1556 bool error = false; 1557 lval_T lv; 1558 1559 do { 1560 if (*arg == '$') { 1561 lv.ll_name = arg; 1562 lv.ll_tv = NULL; 1563 arg++; 1564 if (get_env_len((const char **)&arg) == 0) { 1565 semsg(_(e_invarg2), arg - 1); 1566 return; 1567 } 1568 assert(*lv.ll_name == '$'); // suppress clang "Uninitialized argument value" 1569 if (!error && !eap->skip && callback(&lv, arg, eap, deep) == FAIL) { 1570 error = true; 1571 } 1572 name_end = arg; 1573 } else { 1574 // Parse the name and find the end. 1575 name_end = get_lval(arg, NULL, &lv, true, eap->skip || error, 1576 glv_flags, FNE_CHECK_START); 1577 if (lv.ll_name == NULL) { 1578 error = true; // error, but continue parsing. 1579 } 1580 if (name_end == NULL 1581 || (!ascii_iswhite(*name_end) && !ends_excmd(*name_end))) { 1582 if (name_end != NULL) { 1583 emsg_severe = true; 1584 semsg(_(e_trailing_arg), name_end); 1585 } 1586 if (!(eap->skip || error)) { 1587 clear_lval(&lv); 1588 } 1589 break; 1590 } 1591 1592 if (!error && !eap->skip && callback(&lv, name_end, eap, deep) == FAIL) { 1593 error = true; 1594 } 1595 1596 if (!eap->skip) { 1597 clear_lval(&lv); 1598 } 1599 } 1600 arg = skipwhite(name_end); 1601 } while (!ends_excmd(*arg)); 1602 1603 eap->nextcmd = check_nextcmd(arg); 1604 } 1605 1606 /// Unlet a variable indicated by `lp`. 1607 /// 1608 /// @param[in] lp The lvalue. 1609 /// @param[in] name_end End of the string argument for the command. 1610 /// @param[in] eap Ex command arguments for :unlet. 1611 /// @param[in] deep Unused. 1612 /// 1613 /// @return OK on success, or FAIL on failure. 1614 static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_ATTR_UNUSED) 1615 FUNC_ATTR_NONNULL_ALL 1616 { 1617 int forceit = eap->forceit; 1618 int ret = OK; 1619 1620 if (lp->ll_tv == NULL) { 1621 int cc = (uint8_t)(*name_end); 1622 *name_end = NUL; 1623 1624 // Environment variable, normal name or expanded name. 1625 if (*lp->ll_name == '$') { 1626 vim_unsetenv_ext(lp->ll_name + 1); 1627 } else if (do_unlet(lp->ll_name, lp->ll_name_len, forceit) == FAIL) { 1628 ret = FAIL; 1629 } 1630 *name_end = (char)cc; 1631 } else if ((lp->ll_list != NULL 1632 // ll_list is not NULL when lvalue is not in a list, NULL lists 1633 // yield E689. 1634 && value_check_lock(tv_list_locked(lp->ll_list), 1635 lp->ll_name, 1636 lp->ll_name_len)) 1637 || (lp->ll_dict != NULL 1638 && value_check_lock(lp->ll_dict->dv_lock, 1639 lp->ll_name, 1640 lp->ll_name_len))) { 1641 return FAIL; 1642 } else if (lp->ll_range) { 1643 tv_list_unlet_range(lp->ll_list, lp->ll_li, lp->ll_n1, !lp->ll_empty2, lp->ll_n2); 1644 } else if (lp->ll_list != NULL) { 1645 // unlet a List item. 1646 tv_list_item_remove(lp->ll_list, lp->ll_li); 1647 } else { 1648 // unlet a Dict item. 1649 dict_T *d = lp->ll_dict; 1650 assert(d != NULL); 1651 dictitem_T *di = lp->ll_di; 1652 bool watched = tv_dict_is_watched(d); 1653 char *key = NULL; 1654 typval_T oldtv; 1655 1656 if (watched) { 1657 tv_copy(&di->di_tv, &oldtv); 1658 // need to save key because dictitem_remove will free it 1659 key = xstrdup(di->di_key); 1660 } 1661 1662 tv_dict_item_remove(d, di); 1663 1664 if (watched) { 1665 tv_dict_watcher_notify(d, key, NULL, &oldtv); 1666 tv_clear(&oldtv); 1667 xfree(key); 1668 } 1669 } 1670 1671 return ret; 1672 } 1673 1674 /// Unlet one item or a range of items from a list. 1675 /// Return OK or FAIL. 1676 static void tv_list_unlet_range(list_T *const l, listitem_T *const li_first, const int n1_arg, 1677 const bool has_n2, const int n2) 1678 { 1679 assert(l != NULL); 1680 // Delete a range of List items. 1681 listitem_T *li_last = li_first; 1682 int n1 = n1_arg; 1683 while (true) { 1684 listitem_T *const li = TV_LIST_ITEM_NEXT(l, li_last); 1685 n1++; 1686 if (li == NULL || (has_n2 && n2 < n1)) { 1687 break; 1688 } 1689 li_last = li; 1690 } 1691 tv_list_remove_items(l, li_first, li_last); 1692 } 1693 1694 /// unlet a variable 1695 /// 1696 /// @param[in] name Variable name to unlet. 1697 /// @param[in] name_len Variable name length. 1698 /// @param[in] forceit If true, do not complain if variable doesn’t exist. 1699 /// 1700 /// @return OK if it existed, FAIL otherwise. 1701 int do_unlet(const char *const name, const size_t name_len, const bool forceit) 1702 FUNC_ATTR_NONNULL_ALL 1703 { 1704 const char *varname = NULL; // init to shut up gcc 1705 dict_T *dict; 1706 hashtab_T *ht = find_var_ht_dict(name, name_len, &varname, &dict); 1707 1708 if (ht != NULL && *varname != NUL) { 1709 dict_T *d = get_current_funccal_dict(ht); 1710 if (d == NULL) { 1711 if (ht == &globvarht) { 1712 d = &globvardict; 1713 } else if (ht == &compat_hashtab) { 1714 d = &vimvardict; 1715 } else { 1716 dictitem_T *const di = find_var_in_ht(ht, *name, "", 0, false); 1717 d = di->di_tv.vval.v_dict; 1718 } 1719 if (d == NULL) { 1720 internal_error("do_unlet()"); 1721 return FAIL; 1722 } 1723 } 1724 1725 hashitem_T *hi = hash_find(ht, varname); 1726 if (HASHITEM_EMPTY(hi)) { 1727 hi = find_hi_in_scoped_ht(name, &ht); 1728 } 1729 if (hi != NULL && !HASHITEM_EMPTY(hi)) { 1730 dictitem_T *const di = TV_DICT_HI2DI(hi); 1731 if (var_check_fixed(di->di_flags, name, TV_CSTRING) 1732 || var_check_ro(di->di_flags, name, TV_CSTRING) 1733 || value_check_lock(d->dv_lock, name, TV_CSTRING)) { 1734 return FAIL; 1735 } 1736 1737 if (value_check_lock(d->dv_lock, name, TV_CSTRING)) { 1738 return FAIL; 1739 } 1740 1741 typval_T oldtv; 1742 bool watched = tv_dict_is_watched(dict); 1743 1744 if (watched) { 1745 tv_copy(&di->di_tv, &oldtv); 1746 } 1747 1748 delete_var(ht, hi); 1749 1750 if (watched) { 1751 tv_dict_watcher_notify(dict, varname, NULL, &oldtv); 1752 tv_clear(&oldtv); 1753 } 1754 return OK; 1755 } 1756 } 1757 if (forceit) { 1758 return OK; 1759 } 1760 semsg(_("E108: No such variable: \"%s\""), name); 1761 return FAIL; 1762 } 1763 1764 /// Lock or unlock variable indicated by `lp`. 1765 /// 1766 /// Locks if `eap->cmdidx == CMD_lockvar`, unlocks otherwise. 1767 /// 1768 /// @param[in] lp The lvalue. 1769 /// @param[in] name_end Unused. 1770 /// @param[in] eap Ex command arguments for :(un)lockvar. 1771 /// @param[in] deep Levels to (un)lock, -1 to (un)lock everything. 1772 /// 1773 /// @return OK on success, or FAIL on failure. 1774 static int do_lock_var(lval_T *lp, char *name_end FUNC_ATTR_UNUSED, exarg_T *eap, int deep) 1775 FUNC_ATTR_NONNULL_ARG(1, 3) 1776 { 1777 bool lock = eap->cmdidx == CMD_lockvar; 1778 int ret = OK; 1779 1780 if (lp->ll_tv == NULL) { 1781 if (*lp->ll_name == '$') { 1782 semsg(_(e_lock_unlock), lp->ll_name); 1783 ret = FAIL; 1784 } else { 1785 // Normal name or expanded name. 1786 dictitem_T *const di = find_var(lp->ll_name, lp->ll_name_len, NULL, 1787 true); 1788 if (di == NULL) { 1789 ret = FAIL; 1790 } else if ((di->di_flags & DI_FLAGS_FIX) 1791 && di->di_tv.v_type != VAR_DICT 1792 && di->di_tv.v_type != VAR_LIST) { 1793 // For historical reasons this error is not given for Lists and 1794 // Dictionaries. E.g. b: dictionary may be locked/unlocked. 1795 semsg(_(e_lock_unlock), lp->ll_name); 1796 ret = FAIL; 1797 } else { 1798 if (lock) { 1799 di->di_flags |= DI_FLAGS_LOCK; 1800 } else { 1801 di->di_flags &= (uint8_t)(~DI_FLAGS_LOCK); 1802 } 1803 if (deep != 0) { 1804 tv_item_lock(&di->di_tv, deep, lock, false); 1805 } 1806 } 1807 } 1808 } else if (deep == 0) { 1809 // nothing to do 1810 } else if (lp->ll_range) { 1811 listitem_T *li = lp->ll_li; 1812 1813 // (un)lock a range of List items. 1814 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) { 1815 tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock, false); 1816 li = TV_LIST_ITEM_NEXT(lp->ll_list, li); 1817 lp->ll_n1++; 1818 } 1819 } else if (lp->ll_list != NULL) { 1820 // (un)lock a List item. 1821 tv_item_lock(TV_LIST_ITEM_TV(lp->ll_li), deep, lock, false); 1822 } else { 1823 // (un)lock a Dict item. 1824 tv_item_lock(&lp->ll_di->di_tv, deep, lock, false); 1825 } 1826 1827 return ret; 1828 } 1829 1830 /// Delete all "menutrans_" variables. 1831 void del_menutrans_vars(void) 1832 { 1833 hash_lock(&globvarht); 1834 HASHTAB_ITER(&globvarht, hi, { 1835 if (strncmp(hi->hi_key, "menutrans_", 10) == 0) { 1836 delete_var(&globvarht, hi); 1837 } 1838 }); 1839 hash_unlock(&globvarht); 1840 } 1841 1842 /// @return global variable dictionary 1843 dict_T *get_globvar_dict(void) 1844 FUNC_ATTR_PURE FUNC_ATTR_NONNULL_RET 1845 { 1846 return &globvardict; 1847 } 1848 1849 /// @return global variable hash table 1850 hashtab_T *get_globvar_ht(void) 1851 { 1852 return &globvarht; 1853 } 1854 1855 /// @return v: variable dictionary 1856 dict_T *get_vimvar_dict(void) 1857 FUNC_ATTR_PURE FUNC_ATTR_NONNULL_RET 1858 { 1859 return &vimvardict; 1860 } 1861 1862 /// Set v:variable to tv. 1863 /// 1864 /// @param[in] idx Index of variable to set. 1865 /// @param[in] val Value to set to. Will be copied. 1866 void set_vim_var_tv(const VimVarIndex idx, typval_T *const tv) 1867 { 1868 typval_T *tv_out = get_vim_var_tv(idx); 1869 tv_clear(tv_out); 1870 tv_copy(tv, tv_out); 1871 } 1872 1873 char *get_vim_var_name(const VimVarIndex idx) 1874 FUNC_ATTR_NONNULL_RET 1875 { 1876 return vimvars[idx].vv_name; 1877 } 1878 1879 /// Get typval_T v: variable value. 1880 typval_T *get_vim_var_tv(const VimVarIndex idx) 1881 { 1882 return &vimvars[idx].vv_tv; 1883 } 1884 1885 /// Get number v: variable value. 1886 varnumber_T get_vim_var_nr(const VimVarIndex idx) FUNC_ATTR_PURE 1887 { 1888 typval_T *tv = get_vim_var_tv(idx); 1889 return tv->vval.v_number; 1890 } 1891 1892 /// Get List v: variable value. Caller must take care of reference count when 1893 /// needed. 1894 list_T *get_vim_var_list(const VimVarIndex idx) FUNC_ATTR_PURE 1895 { 1896 typval_T *tv = get_vim_var_tv(idx); 1897 return tv->vval.v_list; 1898 } 1899 1900 /// Get Dictionary v: variable value. Caller must take care of reference count 1901 /// when needed. 1902 dict_T *get_vim_var_dict(const VimVarIndex idx) FUNC_ATTR_PURE 1903 { 1904 typval_T *tv = get_vim_var_tv(idx); 1905 return tv->vval.v_dict; 1906 } 1907 1908 /// Get string v: variable value. Uses a static buffer, can only be used once. 1909 /// If the String variable has never been set, return an empty string. 1910 /// Never returns NULL. 1911 char *get_vim_var_str(const VimVarIndex idx) 1912 FUNC_ATTR_PURE FUNC_ATTR_NONNULL_RET 1913 { 1914 return (char *)tv_get_string(get_vim_var_tv(idx)); 1915 } 1916 1917 /// Get Partial v: variable value. Caller must take care of reference count 1918 /// when needed. 1919 partial_T *get_vim_var_partial(const VimVarIndex idx) FUNC_ATTR_PURE 1920 { 1921 typval_T *tv = get_vim_var_tv(idx); 1922 return tv->vval.v_partial; 1923 } 1924 1925 /// Local string buffer for the next two functions to store a variable name 1926 /// with its prefix. Allocated in cat_prefix_varname(), freed later in 1927 /// get_user_var_name(). 1928 1929 static char *varnamebuf = NULL; 1930 static size_t varnamebuflen = 0; 1931 1932 /// Function to concatenate a prefix and a variable name. 1933 char *cat_prefix_varname(int prefix, const char *name) 1934 FUNC_ATTR_NONNULL_ALL 1935 { 1936 size_t len = strlen(name) + 3; 1937 1938 if (len > varnamebuflen) { 1939 xfree(varnamebuf); 1940 len += 10; // some additional space 1941 varnamebuf = xmalloc(len); 1942 varnamebuflen = len; 1943 } 1944 *varnamebuf = (char)prefix; 1945 varnamebuf[1] = ':'; 1946 STRCPY(varnamebuf + 2, name); 1947 return varnamebuf; 1948 } 1949 1950 /// Function given to ExpandGeneric() to obtain the list of user defined 1951 /// (global/buffer/window/built-in) variable names. 1952 char *get_user_var_name(expand_T *xp, int idx) 1953 { 1954 static size_t gdone; 1955 static size_t bdone; 1956 static size_t wdone; 1957 static size_t tdone; 1958 static size_t vidx; 1959 static hashitem_T *hi; 1960 1961 if (idx == 0) { 1962 gdone = bdone = wdone = vidx = 0; 1963 tdone = 0; 1964 } 1965 1966 // Global variables 1967 if (gdone < globvarht.ht_used) { 1968 if (gdone++ == 0) { 1969 hi = globvarht.ht_array; 1970 } else { 1971 hi++; 1972 } 1973 while (HASHITEM_EMPTY(hi)) { 1974 hi++; 1975 } 1976 if (strncmp("g:", xp->xp_pattern, 2) == 0) { 1977 return cat_prefix_varname('g', hi->hi_key); 1978 } 1979 return hi->hi_key; 1980 } 1981 1982 // b: variables 1983 const hashtab_T *ht = &prevwin_curwin()->w_buffer->b_vars->dv_hashtab; 1984 if (bdone < ht->ht_used) { 1985 if (bdone++ == 0) { 1986 hi = ht->ht_array; 1987 } else { 1988 hi++; 1989 } 1990 while (HASHITEM_EMPTY(hi)) { 1991 hi++; 1992 } 1993 return cat_prefix_varname('b', hi->hi_key); 1994 } 1995 1996 // w: variables 1997 ht = &prevwin_curwin()->w_vars->dv_hashtab; 1998 if (wdone < ht->ht_used) { 1999 if (wdone++ == 0) { 2000 hi = ht->ht_array; 2001 } else { 2002 hi++; 2003 } 2004 while (HASHITEM_EMPTY(hi)) { 2005 hi++; 2006 } 2007 return cat_prefix_varname('w', hi->hi_key); 2008 } 2009 2010 // t: variables 2011 ht = &curtab->tp_vars->dv_hashtab; 2012 if (tdone < ht->ht_used) { 2013 if (tdone++ == 0) { 2014 hi = ht->ht_array; 2015 } else { 2016 hi++; 2017 } 2018 while (HASHITEM_EMPTY(hi)) { 2019 hi++; 2020 } 2021 return cat_prefix_varname('t', hi->hi_key); 2022 } 2023 2024 // v: variables 2025 if (vidx < ARRAY_SIZE(vimvars)) { 2026 return cat_prefix_varname('v', get_vim_var_name((VimVarIndex)vidx++)); 2027 } 2028 2029 XFREE_CLEAR(varnamebuf); 2030 varnamebuflen = 0; 2031 return NULL; 2032 } 2033 2034 /// Set type of v: variable to the given type. 2035 /// 2036 /// @param[in] idx Index of variable to set. 2037 /// @param[in] type Type to set to. 2038 void set_vim_var_type(const VimVarIndex idx, const VarType type) 2039 { 2040 typval_T *tv = get_vim_var_tv(idx); 2041 tv->v_type = type; 2042 } 2043 2044 /// Set number v: variable to the given value 2045 /// Note that this does not set the type, use set_vim_var_type() for that. 2046 /// 2047 /// @param[in] idx Index of variable to set. 2048 /// @param[in] val Value to set to. 2049 void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val) 2050 { 2051 typval_T *tv = get_vim_var_tv(idx); 2052 tv_clear(tv); 2053 tv->vval.v_number = val; 2054 } 2055 2056 /// Set boolean v: {true, false} to the given value 2057 /// 2058 /// @param[in] idx Index of variable to set. 2059 /// @param[in] val Value to set to. 2060 void set_vim_var_bool(const VimVarIndex idx, const BoolVarValue val) 2061 { 2062 typval_T *tv = get_vim_var_tv(idx); 2063 tv_clear(tv); 2064 tv->v_type = VAR_BOOL; 2065 tv->vval.v_bool = val; 2066 } 2067 2068 /// Set special v: variable to the given value 2069 /// 2070 /// @param[in] idx Index of variable to set. 2071 /// @param[in] val Value to set to. 2072 void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val) 2073 { 2074 typval_T *tv = get_vim_var_tv(idx); 2075 tv_clear(tv); 2076 tv->v_type = VAR_SPECIAL; 2077 tv->vval.v_special = val; 2078 } 2079 2080 /// Set v:char to character "c". 2081 void set_vim_var_char(int c) 2082 { 2083 char buf[MB_MAXCHAR + 1]; 2084 2085 buf[utf_char2bytes(c, buf)] = NUL; 2086 set_vim_var_string(VV_CHAR, buf, -1); 2087 } 2088 2089 /// Set string v: variable to the given string 2090 /// 2091 /// @param[in] idx Index of variable to set. 2092 /// @param[in] val Value to set to. Will be copied. 2093 /// @param[in] len Length of that value or -1 in which case strlen() will be 2094 /// used. 2095 void set_vim_var_string(const VimVarIndex idx, const char *const val, const ptrdiff_t len) 2096 { 2097 typval_T *tv = get_vim_var_tv(idx); 2098 tv_clear(tv); 2099 tv->v_type = VAR_STRING; 2100 if (val == NULL) { 2101 tv->vval.v_string = NULL; 2102 } else if (len == -1) { 2103 tv->vval.v_string = xstrdup(val); 2104 } else { 2105 tv->vval.v_string = xstrndup(val, (size_t)len); 2106 } 2107 } 2108 2109 /// Set list v: variable to the given list 2110 /// 2111 /// @param[in] idx Index of variable to set. 2112 /// @param[in,out] val Value to set to. Reference count will be incremented. 2113 void set_vim_var_list(const VimVarIndex idx, list_T *const val) 2114 { 2115 typval_T *tv = get_vim_var_tv(idx); 2116 tv_clear(tv); 2117 tv->v_type = VAR_LIST; 2118 tv->vval.v_list = val; 2119 if (val != NULL) { 2120 tv_list_ref(val); 2121 } 2122 } 2123 2124 /// Set Dictionary v: variable to the given dictionary 2125 /// 2126 /// @param[in] idx Index of variable to set. 2127 /// @param[in,out] val Value to set to. Reference count will be incremented. 2128 /// Also keys of the dictionary will be made read-only. 2129 void set_vim_var_dict(const VimVarIndex idx, dict_T *const val) 2130 { 2131 typval_T *tv = get_vim_var_tv(idx); 2132 tv_clear(tv); 2133 tv->v_type = VAR_DICT; 2134 tv->vval.v_dict = val; 2135 if (val == NULL) { 2136 return; 2137 } 2138 2139 val->dv_refcount++; 2140 // Set readonly 2141 tv_dict_set_keys_readonly(val); 2142 } 2143 2144 /// Set partial v: variable to the given value 2145 /// Note that this does not set the type, use set_vim_var_type() for that. 2146 /// 2147 /// @param[in] idx Index of variable to set. 2148 /// @param[in] val Value to set to. 2149 void set_vim_var_partial(const VimVarIndex idx, partial_T *val) 2150 { 2151 typval_T *tv = get_vim_var_tv(idx); 2152 tv->vval.v_partial = val; 2153 } 2154 2155 /// Set v:register if needed. 2156 void set_reg_var(int c) 2157 { 2158 char regname; 2159 2160 if (c == 0 || c == ' ') { 2161 regname = '"'; 2162 } else { 2163 regname = (char)c; 2164 } 2165 // Avoid free/alloc when the value is already right. 2166 typval_T *tv = get_vim_var_tv(VV_REG); 2167 if (tv->vval.v_string == NULL || tv->vval.v_string[0] != c) { 2168 set_vim_var_string(VV_REG, ®name, 1); 2169 } 2170 } 2171 2172 /// Get or set v:exception. If "oldval" == NULL, return the current value. 2173 /// Otherwise, restore the value to "oldval" and return NULL. 2174 /// Must always be called in pairs to save and restore v:exception! Does not 2175 /// take care of memory allocations. 2176 char *v_exception(char *oldval) 2177 { 2178 typval_T *tv = get_vim_var_tv(VV_EXCEPTION); 2179 if (oldval == NULL) { 2180 return tv->vval.v_string; 2181 } 2182 2183 tv->vval.v_string = oldval; 2184 return NULL; 2185 } 2186 2187 /// Set v:cmdarg. 2188 /// If "eap" != NULL, use "eap" to generate the value and return the old value. 2189 /// If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 2190 /// Must always be called in pairs! 2191 char *set_cmdarg(exarg_T *eap, char *oldarg) 2192 { 2193 typval_T *tv = get_vim_var_tv(VV_CMDARG); 2194 char *oldval = tv->vval.v_string; 2195 if (eap == NULL) { 2196 goto error; 2197 } 2198 2199 size_t len = 0; 2200 if (eap->force_bin == FORCE_BIN) { 2201 len += 6; // " ++bin" 2202 } else if (eap->force_bin == FORCE_NOBIN) { 2203 len += 8; // " ++nobin" 2204 } 2205 2206 if (eap->read_edit) { 2207 len += 7; // " ++edit" 2208 } 2209 2210 if (eap->force_ff != 0) { 2211 len += 10; // " ++ff=unix" 2212 } 2213 if (eap->force_enc != 0) { 2214 len += strlen(eap->cmd + eap->force_enc) + 7; 2215 } 2216 if (eap->bad_char != 0) { 2217 len += 7 + 4; // " ++bad=" + "keep" or "drop" 2218 } 2219 if (eap->mkdir_p != 0) { 2220 len += 4; // " ++p" 2221 } 2222 2223 const size_t newval_len = len + 1; 2224 char *newval = xmalloc(newval_len); 2225 size_t xlen = 0; 2226 int rc = 0; 2227 2228 if (eap->force_bin == FORCE_BIN) { 2229 rc = snprintf(newval, newval_len, " ++bin"); 2230 } else if (eap->force_bin == FORCE_NOBIN) { 2231 rc = snprintf(newval, newval_len, " ++nobin"); 2232 } else { 2233 *newval = NUL; 2234 } 2235 if (rc < 0) { 2236 goto error; 2237 } 2238 xlen += (size_t)rc; 2239 2240 if (eap->read_edit) { 2241 rc = snprintf(newval + xlen, newval_len - xlen, " ++edit"); 2242 if (rc < 0) { 2243 goto error; 2244 } 2245 xlen += (size_t)rc; 2246 } 2247 2248 if (eap->force_ff != 0) { 2249 rc = snprintf(newval + xlen, 2250 newval_len - xlen, 2251 " ++ff=%s", 2252 eap->force_ff == 'u' ? "unix" 2253 : eap->force_ff == 'd' ? "dos" : "mac"); 2254 if (rc < 0) { 2255 goto error; 2256 } 2257 xlen += (size_t)rc; 2258 } 2259 if (eap->force_enc != 0) { 2260 rc = snprintf(newval + (xlen), newval_len - xlen, " ++enc=%s", eap->cmd + eap->force_enc); 2261 if (rc < 0) { 2262 goto error; 2263 } 2264 xlen += (size_t)rc; 2265 } 2266 2267 if (eap->bad_char == BAD_KEEP) { 2268 rc = snprintf(newval + xlen, newval_len - xlen, " ++bad=keep"); 2269 if (rc < 0) { 2270 goto error; 2271 } 2272 xlen += (size_t)rc; 2273 } else if (eap->bad_char == BAD_DROP) { 2274 rc = snprintf(newval + xlen, newval_len - xlen, " ++bad=drop"); 2275 if (rc < 0) { 2276 goto error; 2277 } 2278 xlen += (size_t)rc; 2279 } else if (eap->bad_char != 0) { 2280 rc = snprintf(newval + xlen, newval_len - xlen, " ++bad=%c", eap->bad_char); 2281 if (rc < 0) { 2282 goto error; 2283 } 2284 xlen += (size_t)rc; 2285 } 2286 2287 if (eap->mkdir_p != 0) { 2288 rc = snprintf(newval + xlen, newval_len - xlen, " ++p"); 2289 if (rc < 0) { 2290 goto error; 2291 } 2292 xlen += (size_t)rc; 2293 } 2294 assert(xlen <= newval_len); 2295 2296 tv->vval.v_string = newval; 2297 return oldval; 2298 2299 error: 2300 xfree(oldval); 2301 tv->vval.v_string = oldarg; 2302 return NULL; 2303 } 2304 2305 /// Get or set v:throwpoint. If "oldval" == NULL, return the current value. 2306 /// Otherwise, restore the value to "oldval" and return NULL. 2307 /// Must always be called in pairs to save and restore v:throwpoint! Does not 2308 /// take care of memory allocations. 2309 char *v_throwpoint(char *oldval) 2310 { 2311 typval_T *tv = get_vim_var_tv(VV_THROWPOINT); 2312 if (oldval == NULL) { 2313 return tv->vval.v_string; 2314 } 2315 2316 tv->vval.v_string = oldval; 2317 return NULL; 2318 } 2319 2320 /// Set v:count to "count" and v:count1 to "count1". 2321 /// 2322 /// @param set_prevcount if true, first set v:prevcount from v:count. 2323 void set_vcount(int64_t count, int64_t count1, bool set_prevcount) 2324 { 2325 if (set_prevcount) { 2326 get_vim_var_tv(VV_PREVCOUNT)->vval.v_number = get_vim_var_nr(VV_COUNT); 2327 } 2328 get_vim_var_tv(VV_COUNT)->vval.v_number = count; 2329 get_vim_var_tv(VV_COUNT1)->vval.v_number = count1; 2330 } 2331 2332 /// Get the value of internal variable "name". 2333 /// Return OK or FAIL. If OK is returned "rettv" must be cleared. 2334 /// 2335 /// @param len length of "name" 2336 /// @param rettv NULL when only checking existence 2337 /// @param dip non-NULL when typval's dict item is needed 2338 /// @param verbose may give error message 2339 /// @param no_autoload do not use script autoloading 2340 int eval_variable(const char *name, int len, typval_T *rettv, dictitem_T **dip, bool verbose, 2341 bool no_autoload) 2342 { 2343 int ret = OK; 2344 typval_T *tv = NULL; 2345 dictitem_T *v; 2346 2347 v = find_var(name, (size_t)len, NULL, no_autoload); 2348 if (v != NULL) { 2349 tv = &v->di_tv; 2350 if (dip != NULL) { 2351 *dip = v; 2352 } 2353 } 2354 2355 if (tv == NULL) { 2356 if (rettv != NULL && verbose) { 2357 semsg(_("E121: Undefined variable: %.*s"), len, name); 2358 } 2359 ret = FAIL; 2360 } else if (rettv != NULL) { 2361 tv_copy(tv, rettv); 2362 } 2363 2364 return ret; 2365 } 2366 2367 /// Check if variable "name[len]" is a local variable or an argument. 2368 /// If so, "*eval_lavars_used" is set to true. 2369 void check_vars(const char *name, size_t len) 2370 { 2371 if (eval_lavars_used == NULL) { 2372 return; 2373 } 2374 2375 const char *varname; 2376 hashtab_T *ht = find_var_ht(name, len, &varname); 2377 2378 if (ht == get_funccal_local_ht() || ht == get_funccal_args_ht()) { 2379 if (find_var(name, len, NULL, true) != NULL) { 2380 *eval_lavars_used = true; 2381 } 2382 } 2383 } 2384 2385 /// Find variable "name" in the list of variables. 2386 /// Careful: "a:0" variables don't have a name. 2387 /// When "htp" is not NULL we are writing to the variable, set "htp" to the 2388 /// hashtab_T used. 2389 /// 2390 /// @return a pointer to it if found, NULL if not found. 2391 dictitem_T *find_var(const char *const name, const size_t name_len, hashtab_T **htp, 2392 int no_autoload) 2393 { 2394 const char *varname; 2395 hashtab_T *const ht = find_var_ht(name, name_len, &varname); 2396 if (htp != NULL) { 2397 *htp = ht; 2398 } 2399 if (ht == NULL) { 2400 return NULL; 2401 } 2402 dictitem_T *const ret = find_var_in_ht(ht, *name, 2403 varname, 2404 name_len - (size_t)(varname - name), 2405 no_autoload || htp != NULL); 2406 if (ret != NULL) { 2407 return ret; 2408 } 2409 2410 // Search in parent scope for lambda 2411 return find_var_in_scoped_ht(name, name_len, no_autoload || htp != NULL); 2412 } 2413 2414 /// Find variable in hashtab. 2415 /// When "varname" is empty returns curwin/curtab/etc vars dictionary. 2416 /// 2417 /// @param[in] ht Hashtab to find variable in. 2418 /// @param[in] htname Hashtab name (first character). 2419 /// @param[in] varname Variable name. 2420 /// @param[in] varname_len Variable name length. 2421 /// @param[in] no_autoload If true then autoload scripts will not be sourced 2422 /// if autoload variable was not found. 2423 /// 2424 /// @return pointer to the dictionary item with the found variable or NULL if it 2425 /// was not found. 2426 dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const varname, 2427 const size_t varname_len, int no_autoload) 2428 FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL 2429 { 2430 if (varname_len == 0) { 2431 // Must be something like "s:", otherwise "ht" would be NULL. 2432 switch (htname) { 2433 case 's': 2434 return (dictitem_T *)&SCRIPT_SV(current_sctx.sc_sid)->sv_var; 2435 case 'g': 2436 return (dictitem_T *)&globvars_var; 2437 case 'v': 2438 return (dictitem_T *)&vimvars_var; 2439 case 'b': 2440 return (dictitem_T *)&curbuf->b_bufvar; 2441 case 'w': 2442 return (dictitem_T *)&curwin->w_winvar; 2443 case 't': 2444 return (dictitem_T *)&curtab->tp_winvar; 2445 case 'l': 2446 return get_funccal_local_var(); 2447 case 'a': 2448 return get_funccal_args_var(); 2449 } 2450 return NULL; 2451 } 2452 2453 hashitem_T *hi = hash_find_len(ht, varname, varname_len); 2454 if (HASHITEM_EMPTY(hi)) { 2455 // For global variables we may try auto-loading the script. If it 2456 // worked find the variable again. Don't auto-load a script if it was 2457 // loaded already, otherwise it would be loaded every time when 2458 // checking if a function name is a Funcref variable. 2459 if (ht == get_globvar_ht() && !no_autoload) { 2460 // Note: script_autoload() may make "hi" invalid. It must either 2461 // be obtained again or not used. 2462 if (!script_autoload(varname, varname_len, false) || aborting()) { 2463 return NULL; 2464 } 2465 hi = hash_find_len(ht, varname, varname_len); 2466 } 2467 if (HASHITEM_EMPTY(hi)) { 2468 return NULL; 2469 } 2470 } 2471 return TV_DICT_HI2DI(hi); 2472 } 2473 2474 /// Finds the dict (g:, l:, s:, …) and hashtable used for a variable. 2475 /// 2476 /// Assigns SID if s: scope is accessed from Lua or anonymous Vimscript. #15994 2477 /// 2478 /// @param[in] name Variable name, possibly with scope prefix. 2479 /// @param[in] name_len Variable name length. 2480 /// @param[out] varname Will be set to the start of the name without scope 2481 /// prefix. 2482 /// @param[out] d Scope dictionary. 2483 /// 2484 /// @return Scope hashtab, NULL if name is not valid. 2485 static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, const char **varname, 2486 dict_T **d) 2487 { 2488 *d = NULL; 2489 2490 if (name_len == 0) { 2491 return NULL; 2492 } 2493 if (name_len == 1 || name[1] != ':') { 2494 // name has implicit scope 2495 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) { 2496 // The name must not start with a colon or #. 2497 return NULL; 2498 } 2499 *varname = name; 2500 2501 // "version" is "v:version" in all scopes 2502 hashitem_T *hi = hash_find_len(&compat_hashtab, name, name_len); 2503 if (!HASHITEM_EMPTY(hi)) { 2504 return &compat_hashtab; 2505 } 2506 2507 *d = get_funccal_local_dict(); 2508 if (*d != NULL) { // local variable 2509 goto end; 2510 } 2511 2512 *d = get_globvar_dict(); // global variable 2513 goto end; 2514 } 2515 2516 *varname = name + 2; 2517 if (*name == 'g') { // global variable 2518 *d = get_globvar_dict(); 2519 } else if (name_len > 2 2520 && (memchr(name + 2, ':', name_len - 2) != NULL 2521 || memchr(name + 2, AUTOLOAD_CHAR, name_len - 2) != NULL)) { 2522 // There must be no ':' or '#' in the rest of the name if g: was not used 2523 return NULL; 2524 } 2525 2526 if (*name == 'b') { // buffer variable 2527 *d = curbuf->b_vars; 2528 } else if (*name == 'w') { // window variable 2529 *d = curwin->w_vars; 2530 } else if (*name == 't') { // tab page variable 2531 *d = curtab->tp_vars; 2532 } else if (*name == 'v') { // v: variable 2533 *d = get_vimvar_dict(); 2534 } else if (*name == 'a') { // a: function argument 2535 *d = get_funccal_args_dict(); 2536 } else if (*name == 'l') { // l: local variable 2537 *d = get_funccal_local_dict(); 2538 } else if (*name == 's' // script variable 2539 && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR 2540 || current_sctx.sc_sid == SID_LUA) 2541 && current_sctx.sc_sid <= script_items.ga_len) { 2542 // For anonymous scripts without a script item, create one now so script vars can be used 2543 // Try to resolve lua filename & linenr so it can be shown in last-set messages. 2544 nlua_set_sctx(¤t_sctx); 2545 if (current_sctx.sc_sid == SID_STR || current_sctx.sc_sid == SID_LUA) { 2546 // Create SID if s: scope is accessed from Lua or anon Vimscript. #15994 2547 new_script_item(NULL, ¤t_sctx.sc_sid); 2548 } 2549 *d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict; 2550 } 2551 2552 end: 2553 return *d ? &(*d)->dv_hashtab : NULL; 2554 } 2555 2556 /// Find the hashtable used for a variable 2557 /// 2558 /// @param[in] name Variable name, possibly with scope prefix. 2559 /// @param[in] name_len Variable name length. 2560 /// @param[out] varname Will be set to the start of the name without scope 2561 /// prefix. 2562 /// 2563 /// @return Scope hashtab, NULL if name is not valid. 2564 hashtab_T *find_var_ht(const char *name, const size_t name_len, const char **varname) 2565 { 2566 dict_T *d; 2567 return find_var_ht_dict(name, name_len, varname, &d); 2568 } 2569 2570 /// @return the string value of a (global/local) variable or 2571 /// NULL when it doesn't exist. 2572 /// 2573 /// @see tv_get_string() for how long the pointer remains valid. 2574 char *get_var_value(const char *const name) 2575 { 2576 dictitem_T *v; 2577 2578 v = find_var(name, strlen(name), NULL, false); 2579 if (v == NULL) { 2580 return NULL; 2581 } 2582 return (char *)tv_get_string(&v->di_tv); 2583 } 2584 2585 /// Allocate a new hashtab for a sourced script. It will be used while 2586 /// sourcing this script and when executing functions defined in the script. 2587 void new_script_vars(scid_T id) 2588 { 2589 scriptvar_T *sv = xcalloc(1, sizeof(scriptvar_T)); 2590 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); 2591 SCRIPT_ITEM(id)->sn_vars = sv; 2592 } 2593 2594 /// Initialize dictionary "dict" as a scope and set variable "dict_var" to 2595 /// point to it. 2596 void init_var_dict(dict_T *dict, ScopeDictDictItem *dict_var, ScopeType scope) 2597 { 2598 hash_init(&dict->dv_hashtab); 2599 dict->dv_lock = VAR_UNLOCKED; 2600 dict->dv_scope = scope; 2601 dict->dv_refcount = DO_NOT_FREE_CNT; 2602 dict->dv_copyID = 0; 2603 dict_var->di_tv.vval.v_dict = dict; 2604 dict_var->di_tv.v_type = VAR_DICT; 2605 dict_var->di_tv.v_lock = VAR_FIXED; 2606 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 2607 dict_var->di_key[0] = NUL; 2608 QUEUE_INIT(&dict->watchers); 2609 } 2610 2611 /// Unreference a dictionary initialized by init_var_dict(). 2612 void unref_var_dict(dict_T *dict) 2613 { 2614 // Now the dict needs to be freed if no one else is using it, go back to 2615 // normal reference counting. 2616 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; 2617 tv_dict_unref(dict); 2618 } 2619 2620 /// Clean up a list of internal variables. 2621 /// Frees all allocated variables and the value they contain. 2622 /// Clears hashtab "ht", does not free it. 2623 void vars_clear(hashtab_T *ht) 2624 { 2625 vars_clear_ext(ht, true); 2626 } 2627 2628 /// Like vars_clear(), but only free the value if "free_val" is true. 2629 void vars_clear_ext(hashtab_T *ht, bool free_val) 2630 { 2631 int todo; 2632 hashitem_T *hi; 2633 dictitem_T *v; 2634 2635 hash_lock(ht); 2636 todo = (int)ht->ht_used; 2637 for (hi = ht->ht_array; todo > 0; hi++) { 2638 if (!HASHITEM_EMPTY(hi)) { 2639 todo--; 2640 2641 // Free the variable. Don't remove it from the hashtab, 2642 // ht_array might change then. hash_clear() takes care of it 2643 // later. 2644 v = TV_DICT_HI2DI(hi); 2645 if (free_val) { 2646 tv_clear(&v->di_tv); 2647 } 2648 if (v->di_flags & DI_FLAGS_ALLOC) { 2649 xfree(v); 2650 } 2651 } 2652 } 2653 hash_clear(ht); 2654 hash_init(ht); 2655 } 2656 2657 /// Delete a variable from hashtab "ht" at item "hi". 2658 /// Clear the variable value and free the dictitem. 2659 static void delete_var(hashtab_T *ht, hashitem_T *hi) 2660 { 2661 dictitem_T *di = TV_DICT_HI2DI(hi); 2662 2663 hash_remove(ht, hi); 2664 tv_clear(&di->di_tv); 2665 xfree(di); 2666 } 2667 2668 /// List the value of one internal variable. 2669 static void list_one_var(dictitem_T *v, const char *prefix, int *first) 2670 { 2671 char *const s = encode_tv2echo(&v->di_tv, NULL); 2672 list_one_var_a(prefix, v->di_key, (ptrdiff_t)strlen(v->di_key), 2673 v->di_tv.v_type, (s == NULL ? "" : s), first); 2674 xfree(s); 2675 } 2676 2677 /// @param[in] name_len Length of the name. May be -1, in this case strlen() 2678 /// will be used. 2679 /// @param[in,out] first When true clear rest of screen and set to false. 2680 static void list_one_var_a(const char *prefix, const char *name, const ptrdiff_t name_len, 2681 const VarType type, const char *string, int *first) 2682 { 2683 if (*first) { 2684 msg_ext_set_kind("list_cmd"); 2685 msg_start(); 2686 } else { 2687 msg_putchar('\n'); 2688 } 2689 // don't use msg() to avoid overwriting "v:statusmsg" 2690 if (*prefix != NUL) { 2691 msg_puts(prefix); 2692 } 2693 if (name != NULL) { // "a:" vars don't have a name stored 2694 msg_puts_len(name, name_len, 0, false); 2695 } 2696 msg_putchar(' '); 2697 msg_advance(22); 2698 if (type == VAR_NUMBER) { 2699 msg_putchar('#'); 2700 } else if (type == VAR_FUNC || type == VAR_PARTIAL) { 2701 msg_putchar('*'); 2702 } else if (type == VAR_LIST) { 2703 msg_putchar('['); 2704 if (*string == '[') { 2705 string++; 2706 } 2707 } else if (type == VAR_DICT) { 2708 msg_putchar('{'); 2709 if (*string == '{') { 2710 string++; 2711 } 2712 } else { 2713 msg_putchar(' '); 2714 } 2715 2716 msg_outtrans(string, 0, false); 2717 2718 if (type == VAR_FUNC || type == VAR_PARTIAL) { 2719 msg_puts("()"); 2720 } 2721 if (*first) { 2722 msg_clr_eos(); 2723 *first = false; 2724 } 2725 } 2726 2727 /// Additional handling for setting a v: variable. 2728 /// 2729 /// @return true if the variable should be set normally, 2730 /// false if nothing else needs to be done. 2731 bool before_set_vvar(const char *const varname, dictitem_T *const di, typval_T *const tv, 2732 const bool copy, const bool watched, bool *const type_error) 2733 { 2734 if (di->di_tv.v_type == VAR_STRING) { 2735 typval_T oldtv = TV_INITIAL_VALUE; 2736 if (watched) { 2737 tv_copy(&di->di_tv, &oldtv); 2738 } 2739 XFREE_CLEAR(di->di_tv.vval.v_string); 2740 if (copy || tv->v_type != VAR_STRING) { 2741 const char *const val = tv_get_string(tv); 2742 // Careful: when assigning to v:errmsg and tv_get_string() 2743 // causes an error message the variable will already be set. 2744 if (di->di_tv.vval.v_string == NULL) { 2745 di->di_tv.vval.v_string = xstrdup(val); 2746 } 2747 } else { 2748 // Take over the string to avoid an extra alloc/free. 2749 di->di_tv.vval.v_string = tv->vval.v_string; 2750 tv->vval.v_string = NULL; 2751 } 2752 // Notify watchers 2753 if (watched) { 2754 tv_dict_watcher_notify(&vimvardict, varname, &di->di_tv, &oldtv); 2755 tv_clear(&oldtv); 2756 } 2757 return false; 2758 } else if (di->di_tv.v_type == VAR_NUMBER) { 2759 typval_T oldtv = TV_INITIAL_VALUE; 2760 if (watched) { 2761 tv_copy(&di->di_tv, &oldtv); 2762 } 2763 di->di_tv.vval.v_number = tv_get_number(tv); 2764 if (strcmp(varname, "searchforward") == 0) { 2765 set_search_direction(di->di_tv.vval.v_number ? '/' : '?'); 2766 } else if (strcmp(varname, "hlsearch") == 0) { 2767 no_hlsearch = !di->di_tv.vval.v_number; 2768 redraw_all_later(UPD_SOME_VALID); 2769 } 2770 // Notify watchers 2771 if (watched) { 2772 tv_dict_watcher_notify(&vimvardict, varname, &di->di_tv, &oldtv); 2773 tv_clear(&oldtv); 2774 } 2775 return false; 2776 } else if (di->di_tv.v_type != tv->v_type) { 2777 *type_error = true; 2778 return false; 2779 } 2780 return true; 2781 } 2782 2783 /// Set variable to the given value 2784 /// 2785 /// If the variable already exists, the value is updated. Otherwise the variable 2786 /// is created. 2787 /// 2788 /// @param[in] name Variable name to set. 2789 /// @param[in] name_len Length of the variable name. 2790 /// @param tv Variable value. 2791 /// @param[in] copy True if value in tv is to be copied. 2792 void set_var(const char *name, const size_t name_len, typval_T *const tv, const bool copy) 2793 FUNC_ATTR_NONNULL_ALL 2794 { 2795 set_var_const(name, name_len, tv, copy, false); 2796 } 2797 2798 /// Set variable to the given value 2799 /// 2800 /// If the variable already exists, the value is updated. Otherwise the variable 2801 /// is created. 2802 /// 2803 /// @param[in] name Variable name to set. 2804 /// @param[in] name_len Length of the variable name. 2805 /// @param tv Variable value. 2806 /// @param[in] copy True if value in tv is to be copied. 2807 /// @param[in] is_const True if value in tv is to be locked. 2808 void set_var_const(const char *name, const size_t name_len, typval_T *const tv, const bool copy, 2809 const bool is_const) 2810 FUNC_ATTR_NONNULL_ALL 2811 { 2812 const char *varname; 2813 dict_T *dict; 2814 hashtab_T *ht = find_var_ht_dict(name, name_len, &varname, &dict); 2815 const bool watched = tv_dict_is_watched(dict); 2816 2817 if (ht == NULL || *varname == NUL) { 2818 semsg(_(e_illvar), name); 2819 return; 2820 } 2821 const size_t varname_len = name_len - (size_t)(varname - name); 2822 dictitem_T *di = find_var_in_ht(ht, 0, varname, varname_len, true); 2823 2824 // Search in parent scope which is possible to reference from lambda 2825 if (di == NULL) { 2826 di = find_var_in_scoped_ht(name, name_len, true); 2827 } 2828 2829 if (tv_is_func(*tv) && var_wrong_func_name(name, di == NULL)) { 2830 return; 2831 } 2832 2833 typval_T oldtv = TV_INITIAL_VALUE; 2834 if (di != NULL) { 2835 if (is_const) { 2836 emsg(_(e_cannot_mod)); 2837 return; 2838 } 2839 2840 // Check in this order for backwards compatibility: 2841 // - Whether the variable is read-only 2842 // - Whether the variable value is locked 2843 // - Whether the variable is locked 2844 if (var_check_ro(di->di_flags, name, name_len) 2845 || value_check_lock(di->di_tv.v_lock, name, name_len) 2846 || var_check_lock(di->di_flags, name, name_len)) { 2847 return; 2848 } 2849 2850 // existing variable, need to clear the value 2851 2852 // Handle setting internal v: variables separately where needed to 2853 // prevent changing the type. 2854 bool type_error = false; 2855 if (ht == &vimvarht 2856 && !before_set_vvar(varname, di, tv, copy, watched, &type_error)) { 2857 if (type_error) { 2858 semsg(_(e_setting_v_str_to_value_with_wrong_type), varname); 2859 } 2860 return; 2861 } 2862 2863 if (watched) { 2864 tv_copy(&di->di_tv, &oldtv); 2865 } 2866 tv_clear(&di->di_tv); 2867 } else { // Add a new variable. 2868 // Can't add "v:" or "a:" variable. 2869 if (ht == &vimvarht || ht == get_funccal_args_ht()) { 2870 semsg(_(e_illvar), name); 2871 return; 2872 } 2873 2874 // Make sure the variable name is valid. 2875 if (!valid_varname(varname)) { 2876 return; 2877 } 2878 2879 // Make sure dict is valid 2880 assert(dict != NULL); 2881 2882 di = xmalloc(offsetof(dictitem_T, di_key) + varname_len + 1); 2883 memcpy(di->di_key, varname, varname_len + 1); 2884 if (hash_add(ht, di->di_key) == FAIL) { 2885 xfree(di); 2886 return; 2887 } 2888 di->di_flags = DI_FLAGS_ALLOC; 2889 if (is_const) { 2890 di->di_flags |= DI_FLAGS_LOCK; 2891 } 2892 } 2893 2894 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) { 2895 tv_copy(tv, &di->di_tv); 2896 } else { 2897 di->di_tv = *tv; 2898 di->di_tv.v_lock = VAR_UNLOCKED; 2899 tv_init(tv); 2900 } 2901 2902 if (watched) { 2903 tv_dict_watcher_notify(dict, di->di_key, &di->di_tv, &oldtv); 2904 tv_clear(&oldtv); 2905 } 2906 2907 if (is_const) { 2908 // Like :lockvar! name: lock the value and what it contains, but only 2909 // if the reference count is up to one. That locks only literal 2910 // values. 2911 tv_item_lock(&di->di_tv, DICT_MAXNEST, true, true); 2912 } 2913 } 2914 2915 /// Check whether variable is read-only (DI_FLAGS_RO, DI_FLAGS_RO_SBX) 2916 /// 2917 /// Also gives an error message. 2918 /// 2919 /// @param[in] flags di_flags attribute value. 2920 /// @param[in] name Variable name, for use in error message. 2921 /// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate 2922 /// variable name and compute the length. Use #TV_CSTRING 2923 /// to compute the length with strlen() without 2924 /// translating. 2925 /// 2926 /// Both #TV_… values are used for optimization purposes: 2927 /// variable name with its length is needed only in case 2928 /// of error, when no error occurs computing them is 2929 /// a waste of CPU resources. This especially applies to 2930 /// gettext. 2931 /// 2932 /// @return True if variable is read-only: either always or in sandbox when 2933 /// sandbox is enabled, false otherwise. 2934 bool var_check_ro(const int flags, const char *name, size_t name_len) 2935 FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL 2936 { 2937 const char *error_message = NULL; 2938 if (flags & DI_FLAGS_RO) { 2939 error_message = N_(e_cannot_change_readonly_variable_str); 2940 } else if ((flags & DI_FLAGS_RO_SBX) && sandbox) { 2941 error_message = N_(e_cannot_set_variable_in_sandbox_str); 2942 } 2943 2944 if (error_message == NULL) { 2945 return false; 2946 } 2947 if (name_len == TV_TRANSLATE) { 2948 name = _(name); 2949 name_len = strlen(name); 2950 } else if (name_len == TV_CSTRING) { 2951 name_len = strlen(name); 2952 } 2953 2954 semsg(_(error_message), (int)name_len, name); 2955 2956 return true; 2957 } 2958 2959 /// Return true if di_flags "flags" indicates variable "name" is locked. 2960 /// Also give an error message. 2961 bool var_check_lock(const int flags, const char *name, size_t name_len) 2962 { 2963 if (!(flags & DI_FLAGS_LOCK)) { 2964 return false; 2965 } 2966 2967 if (name_len == TV_TRANSLATE) { 2968 name = _(name); 2969 name_len = strlen(name); 2970 } else if (name_len == TV_CSTRING) { 2971 name_len = strlen(name); 2972 } 2973 2974 semsg(_("E1122: Variable is locked: %.*s"), (int)name_len, name); 2975 2976 return true; 2977 } 2978 2979 /// Check whether variable is fixed (DI_FLAGS_FIX) 2980 /// 2981 /// Also gives an error message. 2982 /// 2983 /// @param[in] flags di_flags attribute value. 2984 /// @param[in] name Variable name, for use in error message. 2985 /// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate 2986 /// variable name and compute the length. Use #TV_CSTRING 2987 /// to compute the length with strlen() without 2988 /// translating. 2989 /// 2990 /// Both #TV_… values are used for optimization purposes: 2991 /// variable name with its length is needed only in case 2992 /// of error, when no error occurs computing them is 2993 /// a waste of CPU resources. This especially applies to 2994 /// gettext. 2995 /// 2996 /// @return True if variable is fixed, false otherwise. 2997 bool var_check_fixed(const int flags, const char *name, size_t name_len) 2998 FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL 2999 { 3000 if (flags & DI_FLAGS_FIX) { 3001 if (name_len == TV_TRANSLATE) { 3002 name = _(name); 3003 name_len = strlen(name); 3004 } else if (name_len == TV_CSTRING) { 3005 name_len = strlen(name); 3006 } 3007 semsg(_(e_cannot_delete_variable_str), (int)name_len, name); 3008 return true; 3009 } 3010 return false; 3011 } 3012 3013 /// Check if name is a valid name to assign funcref to 3014 /// 3015 /// @param[in] name Possible function/funcref name. 3016 /// @param[in] new_var True if it is a name for a variable. 3017 /// 3018 /// @return false in case of success, true in case of failure. Also gives an 3019 /// error message if appropriate. 3020 bool var_wrong_func_name(const char *const name, const bool new_var) 3021 FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT 3022 { 3023 // Allow for w: b: s: and t:. 3024 // Allow autoload variable. 3025 if (!(vim_strchr("wbst", (uint8_t)name[0]) != NULL && name[1] == ':') 3026 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') ? name[2] : name[0]) 3027 && vim_strchr(name, '#') == NULL) { 3028 semsg(_("E704: Funcref variable name must start with a capital: %s"), name); 3029 return true; 3030 } 3031 // Don't allow hiding a function. When "v" is not NULL we might be 3032 // assigning another function to the same var, the type is checked 3033 // below. 3034 if (new_var && function_exists(name, false)) { 3035 semsg(_("E705: Variable name conflicts with existing function: %s"), name); 3036 return true; 3037 } 3038 return false; 3039 } 3040 3041 /// Check if a variable name is valid 3042 /// 3043 /// @param[in] varname Variable name to check. 3044 /// 3045 /// @return false when variable name is not valid, true when it is. Also gives 3046 /// an error message if appropriate. 3047 bool valid_varname(const char *varname) 3048 FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT 3049 { 3050 for (const char *p = varname; *p != NUL; p++) { 3051 if (!eval_isnamec1((int)(uint8_t)(*p)) 3052 && (p == varname || !ascii_isdigit(*p)) 3053 && *p != AUTOLOAD_CHAR) { 3054 semsg(_(e_illvar), varname); 3055 return false; 3056 } 3057 } 3058 return true; 3059 } 3060 3061 /// Implements the logic to retrieve local variable and option values. 3062 /// Used by "getwinvar()" "gettabvar()" "gettabwinvar()" "getbufvar()". 3063 /// 3064 /// @param deftv default value if not found 3065 /// @param htname 't'ab, 'w'indow or 'b'uffer local 3066 /// @param tp can be NULL 3067 /// @param buf ignored if htname is not 'b' 3068 static void get_var_from(const char *varname, typval_T *rettv, typval_T *deftv, int htname, 3069 tabpage_T *tp, win_T *win, buf_T *buf) 3070 { 3071 bool done = false; 3072 const bool do_change_curbuf = buf != NULL && htname == 'b'; 3073 3074 emsg_off++; 3075 3076 rettv->v_type = VAR_STRING; 3077 rettv->vval.v_string = NULL; 3078 3079 if (varname != NULL && tp != NULL && win != NULL && (htname != 'b' || buf != NULL)) { 3080 // Set curwin to be our win, temporarily. Also set the tabpage, 3081 // otherwise the window is not valid. Only do this when needed, 3082 // autocommands get blocked. 3083 // If we have a buffer reference avoid the switching, we're saving and 3084 // restoring curbuf directly. 3085 const bool need_switch_win = !(tp == curtab && win == curwin) && !do_change_curbuf; 3086 switchwin_T switchwin; 3087 if (!need_switch_win || switch_win(&switchwin, win, tp, true) == OK) { 3088 if (*varname == '&' && htname != 't') { 3089 buf_T *const save_curbuf = curbuf; 3090 3091 // Change curbuf so the option is read from the correct buffer. 3092 if (do_change_curbuf) { 3093 curbuf = buf; 3094 } 3095 3096 if (varname[1] == NUL) { 3097 // get all window-local or buffer-local options in a dict 3098 dict_T *opts = get_winbuf_options(htname == 'b'); 3099 3100 if (opts != NULL) { 3101 tv_dict_set_ret(rettv, opts); 3102 done = true; 3103 } 3104 } else if (eval_option(&varname, rettv, true) == OK) { 3105 // Local option 3106 done = true; 3107 } 3108 3109 curbuf = save_curbuf; 3110 } else if (*varname == NUL) { 3111 const ScopeDictDictItem *v; 3112 // Empty string: return a dict with all the local variables. 3113 if (htname == 'b') { 3114 v = &buf->b_bufvar; 3115 } else if (htname == 'w') { 3116 v = &win->w_winvar; 3117 } else { 3118 v = &tp->tp_winvar; 3119 } 3120 tv_copy(&v->di_tv, rettv); 3121 done = true; 3122 } else { 3123 hashtab_T *ht; 3124 3125 if (htname == 'b') { 3126 ht = &buf->b_vars->dv_hashtab; 3127 } else if (htname == 'w') { 3128 ht = &win->w_vars->dv_hashtab; 3129 } else { 3130 ht = &tp->tp_vars->dv_hashtab; 3131 } 3132 3133 // Look up the variable. 3134 const dictitem_T *const v = find_var_in_ht(ht, htname, varname, strlen(varname), false); 3135 if (v != NULL) { 3136 tv_copy(&v->di_tv, rettv); 3137 done = true; 3138 } 3139 } 3140 } 3141 3142 if (need_switch_win) { 3143 // restore previous notion of curwin 3144 restore_win(&switchwin, true); 3145 } 3146 } 3147 3148 if (!done && deftv->v_type != VAR_UNKNOWN) { 3149 // use the default value 3150 tv_copy(deftv, rettv); 3151 } 3152 3153 emsg_off--; 3154 } 3155 3156 /// getwinvar() and gettabwinvar() 3157 /// 3158 /// @param off 1 for gettabwinvar() 3159 static void getwinvar(typval_T *argvars, typval_T *rettv, int off) 3160 { 3161 tabpage_T *tp; 3162 3163 if (off == 1) { 3164 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 3165 } else { 3166 tp = curtab; 3167 } 3168 win_T *const win = find_win_by_nr(&argvars[off], tp); 3169 const char *const varname = tv_get_string_chk(&argvars[off + 1]); 3170 3171 get_var_from(varname, rettv, &argvars[off + 2], 'w', tp, win, NULL); 3172 } 3173 3174 /// Convert typval to option value for a particular option. 3175 /// 3176 /// @param[in] tv typval to convert. 3177 /// @param[in] option Option name. 3178 /// @param[in] flags Option flags. 3179 /// @param[out] error Whether an error occurred. 3180 /// 3181 /// @return Typval converted to OptVal. Must be freed by caller. 3182 /// Returns NIL_OPTVAL for invalid option name. 3183 static OptVal tv_to_optval(typval_T *tv, OptIndex opt_idx, const char *option, bool *error) 3184 { 3185 OptVal value = NIL_OPTVAL; 3186 char nbuf[NUMBUFLEN]; 3187 bool err = false; 3188 const bool is_tty_opt = is_tty_option(option); 3189 const bool option_has_bool = !is_tty_opt && option_has_type(opt_idx, kOptValTypeBoolean); 3190 const bool option_has_num = !is_tty_opt && option_has_type(opt_idx, kOptValTypeNumber); 3191 const bool option_has_str = is_tty_opt || option_has_type(opt_idx, kOptValTypeString); 3192 3193 if (!is_tty_opt && (get_option(opt_idx)->flags & kOptFlagFunc) && tv_is_func(*tv)) { 3194 // If the option can be set to a function reference or a lambda 3195 // and the passed value is a function reference, then convert it to 3196 // the name (string) of the function reference. 3197 char *strval = encode_tv2string(tv, NULL); 3198 err = strval == NULL; 3199 value = CSTR_AS_OPTVAL(strval); 3200 } else if (option_has_bool || option_has_num) { 3201 varnumber_T n = option_has_num ? tv_get_number_chk(tv, &err) : tv_get_bool_chk(tv, &err); 3202 // This could be either "0" or a string that's not a number. 3203 // So we need to check if it's actually a number. 3204 if (!err && tv->v_type == VAR_STRING && n == 0) { 3205 unsigned idx; 3206 for (idx = 0; tv->vval.v_string[idx] == '0'; idx++) {} 3207 if (tv->vval.v_string[idx] != NUL || idx == 0) { 3208 // There's another character after zeros or the string is empty. 3209 // In both cases, we are trying to set a num option using a string. 3210 err = true; 3211 semsg(_("E521: Number required: &%s = '%s'"), option, tv->vval.v_string); 3212 } 3213 } 3214 value = option_has_num ? NUMBER_OPTVAL((OptInt)n) : BOOLEAN_OPTVAL(TRISTATE_FROM_INT(n)); 3215 } else if (option_has_str) { 3216 // Avoid setting string option to a boolean or a special value. 3217 if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) { 3218 const char *strval = tv_get_string_buf_chk(tv, nbuf); 3219 err = strval == NULL; 3220 value = CSTR_TO_OPTVAL(strval); 3221 } else if (!is_tty_opt) { 3222 err = true; 3223 emsg(_(e_string_required)); 3224 } 3225 } else { 3226 abort(); // This should never happen. 3227 } 3228 3229 if (error != NULL) { 3230 *error = err; 3231 } 3232 return value; 3233 } 3234 3235 /// Convert an option value to typval. 3236 /// 3237 /// @param[in] value Option value to convert. 3238 /// @param numbool Whether to convert boolean values to number. 3239 /// Used for backwards compatibility. 3240 /// 3241 /// @return OptVal converted to typval. 3242 typval_T optval_as_tv(OptVal value, bool numbool) 3243 { 3244 typval_T rettv = { .v_type = VAR_SPECIAL, .vval = { .v_special = kSpecialVarNull } }; 3245 3246 switch (value.type) { 3247 case kOptValTypeNil: 3248 break; 3249 case kOptValTypeBoolean: 3250 if (numbool) { 3251 rettv.v_type = VAR_NUMBER; 3252 rettv.vval.v_number = value.data.boolean; 3253 } else if (value.data.boolean != kNone) { 3254 rettv.v_type = VAR_BOOL; 3255 rettv.vval.v_bool = value.data.boolean == kTrue; 3256 } 3257 break; // return v:null for None boolean value. 3258 case kOptValTypeNumber: 3259 rettv.v_type = VAR_NUMBER; 3260 rettv.vval.v_number = value.data.number; 3261 break; 3262 case kOptValTypeString: 3263 rettv.v_type = VAR_STRING; 3264 rettv.vval.v_string = value.data.string.data; 3265 break; 3266 } 3267 3268 return rettv; 3269 } 3270 3271 /// Set option "varname" to the value of "varp" for the current buffer/window. 3272 static void set_option_from_tv(const char *varname, typval_T *varp) 3273 { 3274 OptIndex opt_idx = find_option(varname); 3275 if (opt_idx == kOptInvalid) { 3276 semsg(_(e_unknown_option2), varname); 3277 return; 3278 } 3279 3280 bool error = false; 3281 OptVal value = tv_to_optval(varp, opt_idx, varname, &error); 3282 3283 if (!error) { 3284 const char *errmsg = set_option_value_handle_tty(varname, opt_idx, value, OPT_LOCAL); 3285 3286 if (errmsg) { 3287 emsg(errmsg); 3288 } 3289 } 3290 optval_free(value); 3291 } 3292 3293 /// "setwinvar()" and "settabwinvar()" functions 3294 static void setwinvar(typval_T *argvars, int off) 3295 { 3296 if (check_secure()) { 3297 return; 3298 } 3299 3300 tabpage_T *tp = NULL; 3301 if (off == 1) { 3302 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 3303 } else { 3304 tp = curtab; 3305 } 3306 win_T *const win = find_win_by_nr(&argvars[off], tp); 3307 const char *varname = tv_get_string_chk(&argvars[off + 1]); 3308 typval_T *varp = &argvars[off + 2]; 3309 3310 if (win == NULL || varname == NULL) { 3311 return; 3312 } 3313 3314 bool need_switch_win = !(tp == curtab && win == curwin); 3315 switchwin_T switchwin; 3316 if (!need_switch_win || switch_win(&switchwin, win, tp, true) == OK) { 3317 if (*varname == '&') { 3318 set_option_from_tv(varname + 1, varp); 3319 } else { 3320 const size_t varname_len = strlen(varname); 3321 char *const winvarname = xmalloc(varname_len + 3); 3322 memcpy(winvarname, "w:", 2); 3323 memcpy(winvarname + 2, varname, varname_len + 1); 3324 set_var(winvarname, varname_len + 2, varp, true); 3325 xfree(winvarname); 3326 } 3327 } 3328 if (need_switch_win) { 3329 restore_win(&switchwin, true); 3330 } 3331 } 3332 3333 // reset v:option_new, v:option_old, v:option_oldlocal, v:option_oldglobal, 3334 // v:option_type, and v:option_command. 3335 void reset_v_option_vars(void) 3336 { 3337 set_vim_var_string(VV_OPTION_NEW, NULL, -1); 3338 set_vim_var_string(VV_OPTION_OLD, NULL, -1); 3339 set_vim_var_string(VV_OPTION_OLDLOCAL, NULL, -1); 3340 set_vim_var_string(VV_OPTION_OLDGLOBAL, NULL, -1); 3341 set_vim_var_string(VV_OPTION_COMMAND, NULL, -1); 3342 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); 3343 } 3344 3345 /// Add an assert error to v:errors. 3346 void assert_error(garray_T *gap) 3347 { 3348 typval_T *tv = get_vim_var_tv(VV_ERRORS); 3349 3350 if (tv->v_type != VAR_LIST || tv->vval.v_list == NULL) { 3351 // Make sure v:errors is a list. 3352 set_vim_var_list(VV_ERRORS, tv_list_alloc(1)); 3353 } 3354 tv_list_append_string(get_vim_var_list(VV_ERRORS), gap->ga_data, (ptrdiff_t)gap->ga_len); 3355 } 3356 3357 bool var_exists(const char *var) 3358 FUNC_ATTR_NONNULL_ALL 3359 { 3360 char *tofree; 3361 bool n = false; 3362 3363 // get_name_len() takes care of expanding curly braces 3364 const char *name = var; 3365 const int len = get_name_len(&var, &tofree, true, false); 3366 if (len > 0) { 3367 typval_T tv; 3368 3369 if (tofree != NULL) { 3370 name = tofree; 3371 } 3372 n = eval_variable(name, len, &tv, NULL, false, true) == OK; 3373 if (n) { 3374 // Handle d.key, l[idx], f(expr). 3375 n = handle_subscript(&var, &tv, &EVALARG_EVALUATE, false) == OK; 3376 if (n) { 3377 tv_clear(&tv); 3378 } 3379 } 3380 } 3381 if (*var != NUL) { 3382 n = false; 3383 } 3384 3385 xfree(tofree); 3386 return n; 3387 } 3388 3389 static lval_T *redir_lval = NULL; 3390 static garray_T redir_ga; // Only valid when redir_lval is not NULL. 3391 static char *redir_endp = NULL; 3392 static char *redir_varname = NULL; 3393 3394 /// Start recording command output to a variable 3395 /// 3396 /// @param append append to an existing variable 3397 /// 3398 /// @return OK if successfully completed the setup. FAIL otherwise. 3399 int var_redir_start(char *name, bool append) 3400 { 3401 // Catch a bad name early. 3402 if (!eval_isnamec1(*name)) { 3403 emsg(_(e_invarg)); 3404 return FAIL; 3405 } 3406 3407 // Make a copy of the name, it is used in redir_lval until redir ends. 3408 redir_varname = xstrdup(name); 3409 3410 redir_lval = xcalloc(1, sizeof(lval_T)); 3411 3412 // The output is stored in growarray "redir_ga" until redirection ends. 3413 ga_init(&redir_ga, (int)sizeof(char), 500); 3414 3415 // Parse the variable name (can be a dict or list entry). 3416 redir_endp = get_lval(redir_varname, NULL, redir_lval, false, false, 3417 0, FNE_CHECK_START); 3418 if (redir_endp == NULL || redir_lval->ll_name == NULL 3419 || *redir_endp != NUL) { 3420 clear_lval(redir_lval); 3421 if (redir_endp != NULL && *redir_endp != NUL) { 3422 // Trailing characters are present after the variable name 3423 semsg(_(e_trailing_arg), redir_endp); 3424 } else { 3425 semsg(_(e_invarg2), name); 3426 } 3427 redir_endp = NULL; // don't store a value, only cleanup 3428 var_redir_stop(); 3429 return FAIL; 3430 } 3431 3432 // check if we can write to the variable: set it to or append an empty 3433 // string 3434 const int called_emsg_before = called_emsg; 3435 did_emsg = false; 3436 typval_T tv; 3437 tv.v_type = VAR_STRING; 3438 tv.vval.v_string = ""; 3439 if (append) { 3440 set_var_lval(redir_lval, redir_endp, &tv, true, false, "."); 3441 } else { 3442 set_var_lval(redir_lval, redir_endp, &tv, true, false, "="); 3443 } 3444 clear_lval(redir_lval); 3445 if (called_emsg > called_emsg_before) { 3446 redir_endp = NULL; // don't store a value, only cleanup 3447 var_redir_stop(); 3448 return FAIL; 3449 } 3450 3451 return OK; 3452 } 3453 3454 /// Append "value[value_len]" to the variable set by var_redir_start(). 3455 /// The actual appending is postponed until redirection ends, because the value 3456 /// appended may in fact be the string we write to, changing it may cause freed 3457 /// memory to be used: 3458 /// :redir => foo 3459 /// :let foo 3460 /// :redir END 3461 void var_redir_str(const char *value, int value_len) 3462 { 3463 if (redir_lval == NULL) { 3464 return; 3465 } 3466 3467 int len; 3468 if (value_len == -1) { 3469 len = (int)strlen(value); // Append the entire string 3470 } else { 3471 len = value_len; // Append only "value_len" characters 3472 } 3473 3474 ga_grow(&redir_ga, len); 3475 memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, (size_t)len); 3476 redir_ga.ga_len += len; 3477 } 3478 3479 /// Stop redirecting command output to a variable. 3480 /// Frees the allocated memory. 3481 void var_redir_stop(void) 3482 { 3483 if (redir_lval != NULL) { 3484 // If there was no error: assign the text to the variable. 3485 if (redir_endp != NULL) { 3486 ga_append(&redir_ga, NUL); // Append the trailing NUL. 3487 typval_T tv; 3488 tv.v_type = VAR_STRING; 3489 tv.vval.v_string = redir_ga.ga_data; 3490 // Call get_lval() again, if it's inside a Dict or List it may 3491 // have changed. 3492 redir_endp = get_lval(redir_varname, NULL, redir_lval, 3493 false, false, 0, FNE_CHECK_START); 3494 if (redir_endp != NULL && redir_lval->ll_name != NULL) { 3495 set_var_lval(redir_lval, redir_endp, &tv, false, false, "."); 3496 } 3497 clear_lval(redir_lval); 3498 } 3499 3500 // free the collected output 3501 XFREE_CLEAR(redir_ga.ga_data); 3502 3503 XFREE_CLEAR(redir_lval); 3504 } 3505 XFREE_CLEAR(redir_varname); 3506 } 3507 3508 /// "gettabvar()" function 3509 void f_gettabvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3510 { 3511 const char *const varname = tv_get_string_chk(&argvars[1]); 3512 tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 3513 win_T *win = NULL; 3514 3515 if (tp != NULL) { 3516 win = tp == curtab || tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin; 3517 } 3518 3519 get_var_from(varname, rettv, &argvars[2], 't', tp, win, NULL); 3520 } 3521 3522 /// "gettabwinvar()" function 3523 void f_gettabwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3524 { 3525 getwinvar(argvars, rettv, 1); 3526 } 3527 3528 /// "getwinvar()" function 3529 void f_getwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3530 { 3531 getwinvar(argvars, rettv, 0); 3532 } 3533 3534 /// "getbufvar()" function 3535 void f_getbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3536 { 3537 const char *const varname = tv_get_string_chk(&argvars[1]); 3538 buf_T *const buf = tv_get_buf_from_arg(&argvars[0]); 3539 3540 get_var_from(varname, rettv, &argvars[2], 'b', curtab, curwin, buf); 3541 } 3542 3543 /// "settabvar()" function 3544 void f_settabvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3545 { 3546 if (check_secure()) { 3547 return; 3548 } 3549 3550 tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); 3551 const char *const varname = tv_get_string_chk(&argvars[1]); 3552 typval_T *const varp = &argvars[2]; 3553 3554 if (varname == NULL || tp == NULL) { 3555 return; 3556 } 3557 3558 tabpage_T *const save_curtab = curtab; 3559 tabpage_T *const save_lu_tp = lastused_tabpage; 3560 goto_tabpage_tp(tp, false, false); 3561 3562 const size_t varname_len = strlen(varname); 3563 char *const tabvarname = xmalloc(varname_len + 3); 3564 memcpy(tabvarname, "t:", 2); 3565 memcpy(tabvarname + 2, varname, varname_len + 1); 3566 set_var(tabvarname, varname_len + 2, varp, true); 3567 xfree(tabvarname); 3568 3569 // Restore current tabpage and last accessed tabpage. 3570 if (valid_tabpage(save_curtab)) { 3571 goto_tabpage_tp(save_curtab, false, false); 3572 if (valid_tabpage(save_lu_tp)) { 3573 lastused_tabpage = save_lu_tp; 3574 } 3575 } 3576 } 3577 3578 /// "settabwinvar()" function 3579 void f_settabwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3580 { 3581 setwinvar(argvars, 1); 3582 } 3583 3584 /// "setwinvar()" function 3585 void f_setwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3586 { 3587 setwinvar(argvars, 0); 3588 } 3589 3590 /// "setbufvar()" function 3591 void f_setbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 3592 { 3593 if (check_secure() 3594 || !tv_check_str_or_nr(&argvars[0])) { 3595 return; 3596 } 3597 const char *varname = tv_get_string_chk(&argvars[1]); 3598 buf_T *const buf = tv_get_buf(&argvars[0], false); 3599 typval_T *varp = &argvars[2]; 3600 3601 if (buf == NULL || varname == NULL) { 3602 return; 3603 } 3604 3605 if (*varname == '&') { 3606 aco_save_T aco; 3607 3608 // Set curbuf to be our buf, temporarily. 3609 aucmd_prepbuf(&aco, buf); 3610 3611 set_option_from_tv(varname + 1, varp); 3612 3613 // reset notion of buffer 3614 aucmd_restbuf(&aco); 3615 } else { 3616 const size_t varname_len = strlen(varname); 3617 char *const bufvarname = xmalloc(varname_len + 3); 3618 buf_T *const save_curbuf = curbuf; 3619 curbuf = buf; 3620 memcpy(bufvarname, "b:", 2); 3621 memcpy(bufvarname + 2, varname, varname_len + 1); 3622 set_var(bufvarname, varname_len + 2, varp, true); 3623 xfree(bufvarname); 3624 curbuf = save_curbuf; 3625 } 3626 }