1 /* vi:set ts=8 sts=4 sw=4: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * eval.c: Expression evaluation. 12 */ 13 #define USING_FLOAT_STUFF 14 15 #include "vim.h" 16 17 #if defined(FEAT_EVAL) || defined(PROTO) 18 19 #ifdef AMIGA 20 # include <time.h> /* for strftime() */ 21 #endif 22 23 #ifdef VMS 24 # include <float.h> 25 #endif 26 27 #ifdef MACOS 28 # include <time.h> /* for time_t */ 29 #endif 30 31 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 32 33 #define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not 34 be freed. */ 35 36 /* 37 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 38 * This avoids adding a pointer to the hashtab item. 39 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 40 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 41 * HI2DI() converts a hashitem pointer to a dictitem pointer. 42 */ 43 static dictitem_T dumdi; 44 #define DI2HIKEY(di) ((di)->di_key) 45 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 46 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 47 48 /* 49 * Structure returned by get_lval() and used by set_var_lval(). 50 * For a plain name: 51 * "name" points to the variable name. 52 * "exp_name" is NULL. 53 * "tv" is NULL 54 * For a magic braces name: 55 * "name" points to the expanded variable name. 56 * "exp_name" is non-NULL, to be freed later. 57 * "tv" is NULL 58 * For an index in a list: 59 * "name" points to the (expanded) variable name. 60 * "exp_name" NULL or non-NULL, to be freed later. 61 * "tv" points to the (first) list item value 62 * "li" points to the (first) list item 63 * "range", "n1", "n2" and "empty2" indicate what items are used. 64 * For an existing Dict item: 65 * "name" points to the (expanded) variable name. 66 * "exp_name" NULL or non-NULL, to be freed later. 67 * "tv" points to the dict item value 68 * "newkey" is NULL 69 * For a non-existing Dict item: 70 * "name" points to the (expanded) variable name. 71 * "exp_name" NULL or non-NULL, to be freed later. 72 * "tv" points to the Dictionary typval_T 73 * "newkey" is the key for the new item. 74 */ 75 typedef struct lval_S 76 { 77 char_u *ll_name; /* start of variable name (can be NULL) */ 78 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 79 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 80 isn't NULL it's the Dict to which to add 81 the item. */ 82 listitem_T *ll_li; /* The list item or NULL. */ 83 list_T *ll_list; /* The list or NULL. */ 84 int ll_range; /* TRUE when a [i:j] range was used */ 85 long ll_n1; /* First index for list */ 86 long ll_n2; /* Second index for list range */ 87 int ll_empty2; /* Second index is empty: [i:] */ 88 dict_T *ll_dict; /* The Dictionary or NULL */ 89 dictitem_T *ll_di; /* The dictitem or NULL */ 90 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 91 } lval_T; 92 93 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 94 static char *e_listidx = N_("E684: list index out of range: %ld"); 95 static char *e_undefvar = N_("E121: Undefined variable: %s"); 96 static char *e_missbrac = N_("E111: Missing ']'"); 97 static char *e_listarg = N_("E686: Argument of %s must be a List"); 98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 99 static char *e_listreq = N_("E714: List required"); 100 static char *e_dictreq = N_("E715: Dictionary required"); 101 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 102 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 103 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 104 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 105 static char *e_funcref = N_("E718: Funcref required"); 106 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 107 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 108 static char *e_nofunc = N_("E130: Unknown function: %s"); 109 static char *e_illvar = N_("E461: Illegal variable name: %s"); 110 #ifdef FEAT_FLOAT 111 static char *e_float_as_string = N_("E806: using Float as a String"); 112 #endif 113 114 #define NAMESPACE_CHAR (char_u *)"abglstvw" 115 116 static dictitem_T globvars_var; /* variable used for g: */ 117 #define globvarht globvardict.dv_hashtab 118 119 /* 120 * Old Vim variables such as "v:version" are also available without the "v:". 121 * Also in functions. We need a special hashtable for them. 122 */ 123 static hashtab_T compat_hashtab; 124 125 /* 126 * When recursively copying lists and dicts we need to remember which ones we 127 * have done to avoid endless recursiveness. This unique ID is used for that. 128 * The last bit is used for previous_funccal, ignored when comparing. 129 */ 130 static int current_copyID = 0; 131 #define COPYID_INC 2 132 #define COPYID_MASK (~0x1) 133 134 /* Abort conversion to string after a recursion error. */ 135 static int did_echo_string_emsg = FALSE; 136 137 /* 138 * Array to hold the hashtab with variables local to each sourced script. 139 * Each item holds a variable (nameless) that points to the dict_T. 140 */ 141 typedef struct 142 { 143 dictitem_T sv_var; 144 dict_T sv_dict; 145 } scriptvar_T; 146 147 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; 148 #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) 149 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) 150 151 static int echo_attr = 0; /* attributes used for ":echo" */ 152 153 /* Values for trans_function_name() argument: */ 154 #define TFN_INT 1 /* internal function name OK */ 155 #define TFN_QUIET 2 /* no error messages */ 156 #define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */ 157 158 /* Values for get_lval() flags argument: */ 159 #define GLV_QUIET TFN_QUIET /* no error messages */ 160 #define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */ 161 162 /* 163 * Structure to hold info for a user function. 164 */ 165 typedef struct ufunc ufunc_T; 166 167 struct ufunc 168 { 169 int uf_varargs; /* variable nr of arguments */ 170 int uf_flags; 171 int uf_calls; /* nr of active calls */ 172 garray_T uf_args; /* arguments */ 173 garray_T uf_lines; /* function lines */ 174 #ifdef FEAT_PROFILE 175 int uf_profiling; /* TRUE when func is being profiled */ 176 /* profiling the function as a whole */ 177 int uf_tm_count; /* nr of calls */ 178 proftime_T uf_tm_total; /* time spent in function + children */ 179 proftime_T uf_tm_self; /* time spent in function itself */ 180 proftime_T uf_tm_children; /* time spent in children this call */ 181 /* profiling the function per line */ 182 int *uf_tml_count; /* nr of times line was executed */ 183 proftime_T *uf_tml_total; /* time spent in a line + children */ 184 proftime_T *uf_tml_self; /* time spent in a line itself */ 185 proftime_T uf_tml_start; /* start time for current line */ 186 proftime_T uf_tml_children; /* time spent in children for this line */ 187 proftime_T uf_tml_wait; /* start wait time for current line */ 188 int uf_tml_idx; /* index of line being timed; -1 if none */ 189 int uf_tml_execed; /* line being timed was executed */ 190 #endif 191 scid_T uf_script_ID; /* ID of script where function was defined, 192 used for s: variables */ 193 int uf_refcount; /* for numbered function: reference count */ 194 char_u uf_name[1]; /* name of function (actually longer); can 195 start with <SNR>123_ (<SNR> is K_SPECIAL 196 KS_EXTRA KE_SNR) */ 197 }; 198 199 /* function flags */ 200 #define FC_ABORT 1 /* abort function on error */ 201 #define FC_RANGE 2 /* function accepts range */ 202 #define FC_DICT 4 /* Dict function, uses "self" */ 203 204 /* 205 * All user-defined functions are found in this hashtable. 206 */ 207 static hashtab_T func_hashtab; 208 209 /* The names of packages that once were loaded are remembered. */ 210 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 211 212 /* List heads for garbage collection. Although there can be a reference loop 213 * from partial to dict to partial, we don't need to keep track of the partial, 214 * since it will get freed when the dict is unused and gets freed. */ 215 static dict_T *first_dict = NULL; /* list of all dicts */ 216 static list_T *first_list = NULL; /* list of all lists */ 217 218 /* From user function to hashitem and back. */ 219 static ufunc_T dumuf; 220 #define UF2HIKEY(fp) ((fp)->uf_name) 221 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 222 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 223 224 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 225 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 226 227 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 228 #define VAR_SHORT_LEN 20 /* short variable name length */ 229 #define FIXVAR_CNT 12 /* number of fixed variables */ 230 231 /* structure to hold info for a function that is currently being executed. */ 232 typedef struct funccall_S funccall_T; 233 234 struct funccall_S 235 { 236 ufunc_T *func; /* function being called */ 237 int linenr; /* next line to be executed */ 238 int returned; /* ":return" used */ 239 struct /* fixed variables for arguments */ 240 { 241 dictitem_T var; /* variable (without room for name) */ 242 char_u room[VAR_SHORT_LEN]; /* room for the name */ 243 } fixvar[FIXVAR_CNT]; 244 dict_T l_vars; /* l: local function variables */ 245 dictitem_T l_vars_var; /* variable for l: scope */ 246 dict_T l_avars; /* a: argument variables */ 247 dictitem_T l_avars_var; /* variable for a: scope */ 248 list_T l_varlist; /* list for a:000 */ 249 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 250 typval_T *rettv; /* return value */ 251 linenr_T breakpoint; /* next line with breakpoint or zero */ 252 int dbg_tick; /* debug_tick when breakpoint was set */ 253 int level; /* top nesting level of executed function */ 254 #ifdef FEAT_PROFILE 255 proftime_T prof_child; /* time spent in a child */ 256 #endif 257 funccall_T *caller; /* calling function or NULL */ 258 }; 259 260 /* 261 * Info used by a ":for" loop. 262 */ 263 typedef struct 264 { 265 int fi_semicolon; /* TRUE if ending in '; var]' */ 266 int fi_varcount; /* nr of variables in the list */ 267 listwatch_T fi_lw; /* keep an eye on the item used. */ 268 list_T *fi_list; /* list being used */ 269 } forinfo_T; 270 271 /* 272 * Struct used by trans_function_name() 273 */ 274 typedef struct 275 { 276 dict_T *fd_dict; /* Dictionary used */ 277 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 278 dictitem_T *fd_di; /* Dictionary item used */ 279 } funcdict_T; 280 281 282 /* 283 * Array to hold the value of v: variables. 284 * The value is in a dictitem, so that it can also be used in the v: scope. 285 * The reason to use this table anyway is for very quick access to the 286 * variables with the VV_ defines. 287 */ 288 #include "version.h" 289 290 /* values for vv_flags: */ 291 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 292 #define VV_RO 2 /* read-only */ 293 #define VV_RO_SBX 4 /* read-only in the sandbox */ 294 295 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}} 296 297 static struct vimvar 298 { 299 char *vv_name; /* name of variable, without v: */ 300 dictitem16_T vv_di; /* value and name for key (max 16 chars!) */ 301 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 302 } vimvars[VV_LEN] = 303 { 304 /* 305 * The order here must match the VV_ defines in vim.h! 306 * Initializing a union does not work, leave tv.vval empty to get zero's. 307 */ 308 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 309 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 310 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 311 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 312 {VV_NAME("warningmsg", VAR_STRING), 0}, 313 {VV_NAME("statusmsg", VAR_STRING), 0}, 314 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 315 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 316 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 317 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 318 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 319 {VV_NAME("fname", VAR_STRING), VV_RO}, 320 {VV_NAME("lang", VAR_STRING), VV_RO}, 321 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 322 {VV_NAME("ctype", VAR_STRING), VV_RO}, 323 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 324 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 325 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 326 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 327 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 328 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 329 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 330 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 331 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 332 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 333 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 334 {VV_NAME("progname", VAR_STRING), VV_RO}, 335 {VV_NAME("servername", VAR_STRING), VV_RO}, 336 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 337 {VV_NAME("exception", VAR_STRING), VV_RO}, 338 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 339 {VV_NAME("register", VAR_STRING), VV_RO}, 340 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 341 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 342 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 343 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 344 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 345 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 346 {VV_NAME("fcs_choice", VAR_STRING), 0}, 347 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 348 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 349 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 350 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 351 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 352 {VV_NAME("scrollstart", VAR_STRING), 0}, 353 {VV_NAME("swapname", VAR_STRING), VV_RO}, 354 {VV_NAME("swapchoice", VAR_STRING), 0}, 355 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 356 {VV_NAME("char", VAR_STRING), 0}, 357 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 358 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 359 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 360 {VV_NAME("operator", VAR_STRING), VV_RO}, 361 {VV_NAME("searchforward", VAR_NUMBER), 0}, 362 {VV_NAME("hlsearch", VAR_NUMBER), 0}, 363 {VV_NAME("oldfiles", VAR_LIST), 0}, 364 {VV_NAME("windowid", VAR_NUMBER), VV_RO}, 365 {VV_NAME("progpath", VAR_STRING), VV_RO}, 366 {VV_NAME("completed_item", VAR_DICT), VV_RO}, 367 {VV_NAME("option_new", VAR_STRING), VV_RO}, 368 {VV_NAME("option_old", VAR_STRING), VV_RO}, 369 {VV_NAME("option_type", VAR_STRING), VV_RO}, 370 {VV_NAME("errors", VAR_LIST), 0}, 371 {VV_NAME("false", VAR_SPECIAL), VV_RO}, 372 {VV_NAME("true", VAR_SPECIAL), VV_RO}, 373 {VV_NAME("null", VAR_SPECIAL), VV_RO}, 374 {VV_NAME("none", VAR_SPECIAL), VV_RO}, 375 {VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO}, 376 }; 377 378 /* shorthand */ 379 #define vv_type vv_di.di_tv.v_type 380 #define vv_nr vv_di.di_tv.vval.v_number 381 #define vv_float vv_di.di_tv.vval.v_float 382 #define vv_str vv_di.di_tv.vval.v_string 383 #define vv_list vv_di.di_tv.vval.v_list 384 #define vv_dict vv_di.di_tv.vval.v_dict 385 #define vv_tv vv_di.di_tv 386 387 static dictitem_T vimvars_var; /* variable used for v: */ 388 #define vimvarht vimvardict.dv_hashtab 389 390 static void prepare_vimvar(int idx, typval_T *save_tv); 391 static void restore_vimvar(int idx, typval_T *save_tv); 392 static int ex_let_vars(char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars); 393 static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon); 394 static char_u *skip_var_one(char_u *arg); 395 static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first); 396 static void list_glob_vars(int *first); 397 static void list_buf_vars(int *first); 398 static void list_win_vars(int *first); 399 #ifdef FEAT_WINDOWS 400 static void list_tab_vars(int *first); 401 #endif 402 static void list_vim_vars(int *first); 403 static void list_script_vars(int *first); 404 static void list_func_vars(int *first); 405 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); 406 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op); 407 static int check_changedtick(char_u *arg); 408 static char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags); 409 static void clear_lval(lval_T *lp); 410 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op); 411 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); 412 static void list_fix_watch(list_T *l, listitem_T *item); 413 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); 414 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); 415 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); 416 static void item_lock(typval_T *tv, int deep, int lock); 417 static int tv_islocked(typval_T *tv); 418 419 static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate); 420 static int eval1(char_u **arg, typval_T *rettv, int evaluate); 421 static int eval2(char_u **arg, typval_T *rettv, int evaluate); 422 static int eval3(char_u **arg, typval_T *rettv, int evaluate); 423 static int eval4(char_u **arg, typval_T *rettv, int evaluate); 424 static int eval5(char_u **arg, typval_T *rettv, int evaluate); 425 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); 426 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string); 427 428 static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose); 429 static int get_option_tv(char_u **arg, typval_T *rettv, int evaluate); 430 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); 431 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); 432 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate); 433 static long list_len(list_T *l); 434 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive); 435 static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); 436 static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive); 437 static long list_find_nr(list_T *l, long idx, int *errorp); 438 static long list_idx_of_item(list_T *l, listitem_T *item); 439 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); 440 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); 441 static list_T *list_copy(list_T *orig, int deep, int copyID); 442 static char_u *list2string(typval_T *tv, int copyID); 443 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap); 444 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID); 445 static int free_unref_items(int copyID); 446 static dictitem_T *dictitem_copy(dictitem_T *org); 447 static void dictitem_remove(dict_T *dict, dictitem_T *item); 448 static dict_T *dict_copy(dict_T *orig, int deep, int copyID); 449 static long dict_len(dict_T *d); 450 static char_u *dict2string(typval_T *tv, int copyID); 451 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); 452 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); 453 static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); 454 static char_u *string_quote(char_u *str, int function); 455 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); 456 static int find_internal_func(char_u *name); 457 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); 458 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict); 459 static void emsg_funcname(char *ermsg, char_u *name); 460 static int non_zero_arg(typval_T *argvars); 461 462 #ifdef FEAT_FLOAT 463 static void f_abs(typval_T *argvars, typval_T *rettv); 464 static void f_acos(typval_T *argvars, typval_T *rettv); 465 #endif 466 static void f_add(typval_T *argvars, typval_T *rettv); 467 static void f_alloc_fail(typval_T *argvars, typval_T *rettv); 468 static void f_and(typval_T *argvars, typval_T *rettv); 469 static void f_append(typval_T *argvars, typval_T *rettv); 470 static void f_argc(typval_T *argvars, typval_T *rettv); 471 static void f_argidx(typval_T *argvars, typval_T *rettv); 472 static void f_arglistid(typval_T *argvars, typval_T *rettv); 473 static void f_argv(typval_T *argvars, typval_T *rettv); 474 static void f_assert_equal(typval_T *argvars, typval_T *rettv); 475 static void f_assert_exception(typval_T *argvars, typval_T *rettv); 476 static void f_assert_fails(typval_T *argvars, typval_T *rettv); 477 static void f_assert_false(typval_T *argvars, typval_T *rettv); 478 static void f_assert_match(typval_T *argvars, typval_T *rettv); 479 static void f_assert_true(typval_T *argvars, typval_T *rettv); 480 #ifdef FEAT_FLOAT 481 static void f_asin(typval_T *argvars, typval_T *rettv); 482 static void f_atan(typval_T *argvars, typval_T *rettv); 483 static void f_atan2(typval_T *argvars, typval_T *rettv); 484 #endif 485 static void f_browse(typval_T *argvars, typval_T *rettv); 486 static void f_browsedir(typval_T *argvars, typval_T *rettv); 487 static void f_bufexists(typval_T *argvars, typval_T *rettv); 488 static void f_buflisted(typval_T *argvars, typval_T *rettv); 489 static void f_bufloaded(typval_T *argvars, typval_T *rettv); 490 static void f_bufname(typval_T *argvars, typval_T *rettv); 491 static void f_bufnr(typval_T *argvars, typval_T *rettv); 492 static void f_bufwinnr(typval_T *argvars, typval_T *rettv); 493 static void f_byte2line(typval_T *argvars, typval_T *rettv); 494 static void byteidx(typval_T *argvars, typval_T *rettv, int comp); 495 static void f_byteidx(typval_T *argvars, typval_T *rettv); 496 static void f_byteidxcomp(typval_T *argvars, typval_T *rettv); 497 static void f_call(typval_T *argvars, typval_T *rettv); 498 #ifdef FEAT_FLOAT 499 static void f_ceil(typval_T *argvars, typval_T *rettv); 500 #endif 501 #ifdef FEAT_JOB_CHANNEL 502 static void f_ch_close(typval_T *argvars, typval_T *rettv); 503 static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv); 504 static void f_ch_evalraw(typval_T *argvars, typval_T *rettv); 505 static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv); 506 static void f_ch_getjob(typval_T *argvars, typval_T *rettv); 507 static void f_ch_info(typval_T *argvars, typval_T *rettv); 508 static void f_ch_log(typval_T *argvars, typval_T *rettv); 509 static void f_ch_logfile(typval_T *argvars, typval_T *rettv); 510 static void f_ch_open(typval_T *argvars, typval_T *rettv); 511 static void f_ch_read(typval_T *argvars, typval_T *rettv); 512 static void f_ch_readraw(typval_T *argvars, typval_T *rettv); 513 static void f_ch_sendexpr(typval_T *argvars, typval_T *rettv); 514 static void f_ch_sendraw(typval_T *argvars, typval_T *rettv); 515 static void f_ch_setoptions(typval_T *argvars, typval_T *rettv); 516 static void f_ch_status(typval_T *argvars, typval_T *rettv); 517 #endif 518 static void f_changenr(typval_T *argvars, typval_T *rettv); 519 static void f_char2nr(typval_T *argvars, typval_T *rettv); 520 static void f_cindent(typval_T *argvars, typval_T *rettv); 521 static void f_clearmatches(typval_T *argvars, typval_T *rettv); 522 static void f_col(typval_T *argvars, typval_T *rettv); 523 #if defined(FEAT_INS_EXPAND) 524 static void f_complete(typval_T *argvars, typval_T *rettv); 525 static void f_complete_add(typval_T *argvars, typval_T *rettv); 526 static void f_complete_check(typval_T *argvars, typval_T *rettv); 527 #endif 528 static void f_confirm(typval_T *argvars, typval_T *rettv); 529 static void f_copy(typval_T *argvars, typval_T *rettv); 530 #ifdef FEAT_FLOAT 531 static void f_cos(typval_T *argvars, typval_T *rettv); 532 static void f_cosh(typval_T *argvars, typval_T *rettv); 533 #endif 534 static void f_count(typval_T *argvars, typval_T *rettv); 535 static void f_cscope_connection(typval_T *argvars, typval_T *rettv); 536 static void f_cursor(typval_T *argsvars, typval_T *rettv); 537 static void f_deepcopy(typval_T *argvars, typval_T *rettv); 538 static void f_delete(typval_T *argvars, typval_T *rettv); 539 static void f_did_filetype(typval_T *argvars, typval_T *rettv); 540 static void f_diff_filler(typval_T *argvars, typval_T *rettv); 541 static void f_diff_hlID(typval_T *argvars, typval_T *rettv); 542 static void f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv); 543 static void f_empty(typval_T *argvars, typval_T *rettv); 544 static void f_escape(typval_T *argvars, typval_T *rettv); 545 static void f_eval(typval_T *argvars, typval_T *rettv); 546 static void f_eventhandler(typval_T *argvars, typval_T *rettv); 547 static void f_executable(typval_T *argvars, typval_T *rettv); 548 static void f_exepath(typval_T *argvars, typval_T *rettv); 549 static void f_exists(typval_T *argvars, typval_T *rettv); 550 #ifdef FEAT_FLOAT 551 static void f_exp(typval_T *argvars, typval_T *rettv); 552 #endif 553 static void f_expand(typval_T *argvars, typval_T *rettv); 554 static void f_extend(typval_T *argvars, typval_T *rettv); 555 static void f_feedkeys(typval_T *argvars, typval_T *rettv); 556 static void f_filereadable(typval_T *argvars, typval_T *rettv); 557 static void f_filewritable(typval_T *argvars, typval_T *rettv); 558 static void f_filter(typval_T *argvars, typval_T *rettv); 559 static void f_finddir(typval_T *argvars, typval_T *rettv); 560 static void f_findfile(typval_T *argvars, typval_T *rettv); 561 #ifdef FEAT_FLOAT 562 static void f_float2nr(typval_T *argvars, typval_T *rettv); 563 static void f_floor(typval_T *argvars, typval_T *rettv); 564 static void f_fmod(typval_T *argvars, typval_T *rettv); 565 #endif 566 static void f_fnameescape(typval_T *argvars, typval_T *rettv); 567 static void f_fnamemodify(typval_T *argvars, typval_T *rettv); 568 static void f_foldclosed(typval_T *argvars, typval_T *rettv); 569 static void f_foldclosedend(typval_T *argvars, typval_T *rettv); 570 static void f_foldlevel(typval_T *argvars, typval_T *rettv); 571 static void f_foldtext(typval_T *argvars, typval_T *rettv); 572 static void f_foldtextresult(typval_T *argvars, typval_T *rettv); 573 static void f_foreground(typval_T *argvars, typval_T *rettv); 574 static void f_function(typval_T *argvars, typval_T *rettv); 575 static void f_garbagecollect(typval_T *argvars, typval_T *rettv); 576 static void f_get(typval_T *argvars, typval_T *rettv); 577 static void f_getbufline(typval_T *argvars, typval_T *rettv); 578 static void f_getbufvar(typval_T *argvars, typval_T *rettv); 579 static void f_getchar(typval_T *argvars, typval_T *rettv); 580 static void f_getcharmod(typval_T *argvars, typval_T *rettv); 581 static void f_getcharsearch(typval_T *argvars, typval_T *rettv); 582 static void f_getcmdline(typval_T *argvars, typval_T *rettv); 583 static void f_getcmdpos(typval_T *argvars, typval_T *rettv); 584 static void f_getcmdtype(typval_T *argvars, typval_T *rettv); 585 static void f_getcmdwintype(typval_T *argvars, typval_T *rettv); 586 static void f_getcwd(typval_T *argvars, typval_T *rettv); 587 static void f_getfontname(typval_T *argvars, typval_T *rettv); 588 static void f_getfperm(typval_T *argvars, typval_T *rettv); 589 static void f_getfsize(typval_T *argvars, typval_T *rettv); 590 static void f_getftime(typval_T *argvars, typval_T *rettv); 591 static void f_getftype(typval_T *argvars, typval_T *rettv); 592 static void f_getline(typval_T *argvars, typval_T *rettv); 593 static void f_getmatches(typval_T *argvars, typval_T *rettv); 594 static void f_getpid(typval_T *argvars, typval_T *rettv); 595 static void f_getcurpos(typval_T *argvars, typval_T *rettv); 596 static void f_getpos(typval_T *argvars, typval_T *rettv); 597 static void f_getqflist(typval_T *argvars, typval_T *rettv); 598 static void f_getreg(typval_T *argvars, typval_T *rettv); 599 static void f_getregtype(typval_T *argvars, typval_T *rettv); 600 static void f_gettabvar(typval_T *argvars, typval_T *rettv); 601 static void f_gettabwinvar(typval_T *argvars, typval_T *rettv); 602 static void f_getwinposx(typval_T *argvars, typval_T *rettv); 603 static void f_getwinposy(typval_T *argvars, typval_T *rettv); 604 static void f_getwinvar(typval_T *argvars, typval_T *rettv); 605 static void f_glob(typval_T *argvars, typval_T *rettv); 606 static void f_globpath(typval_T *argvars, typval_T *rettv); 607 static void f_glob2regpat(typval_T *argvars, typval_T *rettv); 608 static void f_has(typval_T *argvars, typval_T *rettv); 609 static void f_has_key(typval_T *argvars, typval_T *rettv); 610 static void f_haslocaldir(typval_T *argvars, typval_T *rettv); 611 static void f_hasmapto(typval_T *argvars, typval_T *rettv); 612 static void f_histadd(typval_T *argvars, typval_T *rettv); 613 static void f_histdel(typval_T *argvars, typval_T *rettv); 614 static void f_histget(typval_T *argvars, typval_T *rettv); 615 static void f_histnr(typval_T *argvars, typval_T *rettv); 616 static void f_hlID(typval_T *argvars, typval_T *rettv); 617 static void f_hlexists(typval_T *argvars, typval_T *rettv); 618 static void f_hostname(typval_T *argvars, typval_T *rettv); 619 static void f_iconv(typval_T *argvars, typval_T *rettv); 620 static void f_indent(typval_T *argvars, typval_T *rettv); 621 static void f_index(typval_T *argvars, typval_T *rettv); 622 static void f_input(typval_T *argvars, typval_T *rettv); 623 static void f_inputdialog(typval_T *argvars, typval_T *rettv); 624 static void f_inputlist(typval_T *argvars, typval_T *rettv); 625 static void f_inputrestore(typval_T *argvars, typval_T *rettv); 626 static void f_inputsave(typval_T *argvars, typval_T *rettv); 627 static void f_inputsecret(typval_T *argvars, typval_T *rettv); 628 static void f_insert(typval_T *argvars, typval_T *rettv); 629 static void f_invert(typval_T *argvars, typval_T *rettv); 630 static void f_isdirectory(typval_T *argvars, typval_T *rettv); 631 static void f_islocked(typval_T *argvars, typval_T *rettv); 632 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 633 static void f_isnan(typval_T *argvars, typval_T *rettv); 634 #endif 635 static void f_items(typval_T *argvars, typval_T *rettv); 636 #ifdef FEAT_JOB_CHANNEL 637 static void f_job_getchannel(typval_T *argvars, typval_T *rettv); 638 static void f_job_info(typval_T *argvars, typval_T *rettv); 639 static void f_job_setoptions(typval_T *argvars, typval_T *rettv); 640 static void f_job_start(typval_T *argvars, typval_T *rettv); 641 static void f_job_stop(typval_T *argvars, typval_T *rettv); 642 static void f_job_status(typval_T *argvars, typval_T *rettv); 643 #endif 644 static void f_join(typval_T *argvars, typval_T *rettv); 645 static void f_js_decode(typval_T *argvars, typval_T *rettv); 646 static void f_js_encode(typval_T *argvars, typval_T *rettv); 647 static void f_json_decode(typval_T *argvars, typval_T *rettv); 648 static void f_json_encode(typval_T *argvars, typval_T *rettv); 649 static void f_keys(typval_T *argvars, typval_T *rettv); 650 static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv); 651 static void f_len(typval_T *argvars, typval_T *rettv); 652 static void f_libcall(typval_T *argvars, typval_T *rettv); 653 static void f_libcallnr(typval_T *argvars, typval_T *rettv); 654 static void f_line(typval_T *argvars, typval_T *rettv); 655 static void f_line2byte(typval_T *argvars, typval_T *rettv); 656 static void f_lispindent(typval_T *argvars, typval_T *rettv); 657 static void f_localtime(typval_T *argvars, typval_T *rettv); 658 #ifdef FEAT_FLOAT 659 static void f_log(typval_T *argvars, typval_T *rettv); 660 static void f_log10(typval_T *argvars, typval_T *rettv); 661 #endif 662 #ifdef FEAT_LUA 663 static void f_luaeval(typval_T *argvars, typval_T *rettv); 664 #endif 665 static void f_map(typval_T *argvars, typval_T *rettv); 666 static void f_maparg(typval_T *argvars, typval_T *rettv); 667 static void f_mapcheck(typval_T *argvars, typval_T *rettv); 668 static void f_match(typval_T *argvars, typval_T *rettv); 669 static void f_matchadd(typval_T *argvars, typval_T *rettv); 670 static void f_matchaddpos(typval_T *argvars, typval_T *rettv); 671 static void f_matcharg(typval_T *argvars, typval_T *rettv); 672 static void f_matchdelete(typval_T *argvars, typval_T *rettv); 673 static void f_matchend(typval_T *argvars, typval_T *rettv); 674 static void f_matchlist(typval_T *argvars, typval_T *rettv); 675 static void f_matchstr(typval_T *argvars, typval_T *rettv); 676 static void f_max(typval_T *argvars, typval_T *rettv); 677 static void f_min(typval_T *argvars, typval_T *rettv); 678 #ifdef vim_mkdir 679 static void f_mkdir(typval_T *argvars, typval_T *rettv); 680 #endif 681 static void f_mode(typval_T *argvars, typval_T *rettv); 682 #ifdef FEAT_MZSCHEME 683 static void f_mzeval(typval_T *argvars, typval_T *rettv); 684 #endif 685 static void f_nextnonblank(typval_T *argvars, typval_T *rettv); 686 static void f_nr2char(typval_T *argvars, typval_T *rettv); 687 static void f_or(typval_T *argvars, typval_T *rettv); 688 static void f_pathshorten(typval_T *argvars, typval_T *rettv); 689 #ifdef FEAT_PERL 690 static void f_perleval(typval_T *argvars, typval_T *rettv); 691 #endif 692 #ifdef FEAT_FLOAT 693 static void f_pow(typval_T *argvars, typval_T *rettv); 694 #endif 695 static void f_prevnonblank(typval_T *argvars, typval_T *rettv); 696 static void f_printf(typval_T *argvars, typval_T *rettv); 697 static void f_pumvisible(typval_T *argvars, typval_T *rettv); 698 #ifdef FEAT_PYTHON3 699 static void f_py3eval(typval_T *argvars, typval_T *rettv); 700 #endif 701 #ifdef FEAT_PYTHON 702 static void f_pyeval(typval_T *argvars, typval_T *rettv); 703 #endif 704 static void f_range(typval_T *argvars, typval_T *rettv); 705 static void f_readfile(typval_T *argvars, typval_T *rettv); 706 static void f_reltime(typval_T *argvars, typval_T *rettv); 707 #ifdef FEAT_FLOAT 708 static void f_reltimefloat(typval_T *argvars, typval_T *rettv); 709 #endif 710 static void f_reltimestr(typval_T *argvars, typval_T *rettv); 711 static void f_remote_expr(typval_T *argvars, typval_T *rettv); 712 static void f_remote_foreground(typval_T *argvars, typval_T *rettv); 713 static void f_remote_peek(typval_T *argvars, typval_T *rettv); 714 static void f_remote_read(typval_T *argvars, typval_T *rettv); 715 static void f_remote_send(typval_T *argvars, typval_T *rettv); 716 static void f_remove(typval_T *argvars, typval_T *rettv); 717 static void f_rename(typval_T *argvars, typval_T *rettv); 718 static void f_repeat(typval_T *argvars, typval_T *rettv); 719 static void f_resolve(typval_T *argvars, typval_T *rettv); 720 static void f_reverse(typval_T *argvars, typval_T *rettv); 721 #ifdef FEAT_FLOAT 722 static void f_round(typval_T *argvars, typval_T *rettv); 723 #endif 724 static void f_screenattr(typval_T *argvars, typval_T *rettv); 725 static void f_screenchar(typval_T *argvars, typval_T *rettv); 726 static void f_screencol(typval_T *argvars, typval_T *rettv); 727 static void f_screenrow(typval_T *argvars, typval_T *rettv); 728 static void f_search(typval_T *argvars, typval_T *rettv); 729 static void f_searchdecl(typval_T *argvars, typval_T *rettv); 730 static void f_searchpair(typval_T *argvars, typval_T *rettv); 731 static void f_searchpairpos(typval_T *argvars, typval_T *rettv); 732 static void f_searchpos(typval_T *argvars, typval_T *rettv); 733 static void f_server2client(typval_T *argvars, typval_T *rettv); 734 static void f_serverlist(typval_T *argvars, typval_T *rettv); 735 static void f_setbufvar(typval_T *argvars, typval_T *rettv); 736 static void f_setcharsearch(typval_T *argvars, typval_T *rettv); 737 static void f_setcmdpos(typval_T *argvars, typval_T *rettv); 738 static void f_setfperm(typval_T *argvars, typval_T *rettv); 739 static void f_setline(typval_T *argvars, typval_T *rettv); 740 static void f_setloclist(typval_T *argvars, typval_T *rettv); 741 static void f_setmatches(typval_T *argvars, typval_T *rettv); 742 static void f_setpos(typval_T *argvars, typval_T *rettv); 743 static void f_setqflist(typval_T *argvars, typval_T *rettv); 744 static void f_setreg(typval_T *argvars, typval_T *rettv); 745 static void f_settabvar(typval_T *argvars, typval_T *rettv); 746 static void f_settabwinvar(typval_T *argvars, typval_T *rettv); 747 static void f_setwinvar(typval_T *argvars, typval_T *rettv); 748 #ifdef FEAT_CRYPT 749 static void f_sha256(typval_T *argvars, typval_T *rettv); 750 #endif /* FEAT_CRYPT */ 751 static void f_shellescape(typval_T *argvars, typval_T *rettv); 752 static void f_shiftwidth(typval_T *argvars, typval_T *rettv); 753 static void f_simplify(typval_T *argvars, typval_T *rettv); 754 #ifdef FEAT_FLOAT 755 static void f_sin(typval_T *argvars, typval_T *rettv); 756 static void f_sinh(typval_T *argvars, typval_T *rettv); 757 #endif 758 static void f_sort(typval_T *argvars, typval_T *rettv); 759 static void f_soundfold(typval_T *argvars, typval_T *rettv); 760 static void f_spellbadword(typval_T *argvars, typval_T *rettv); 761 static void f_spellsuggest(typval_T *argvars, typval_T *rettv); 762 static void f_split(typval_T *argvars, typval_T *rettv); 763 #ifdef FEAT_FLOAT 764 static void f_sqrt(typval_T *argvars, typval_T *rettv); 765 static void f_str2float(typval_T *argvars, typval_T *rettv); 766 #endif 767 static void f_str2nr(typval_T *argvars, typval_T *rettv); 768 static void f_strchars(typval_T *argvars, typval_T *rettv); 769 #ifdef HAVE_STRFTIME 770 static void f_strftime(typval_T *argvars, typval_T *rettv); 771 #endif 772 static void f_stridx(typval_T *argvars, typval_T *rettv); 773 static void f_string(typval_T *argvars, typval_T *rettv); 774 static void f_strlen(typval_T *argvars, typval_T *rettv); 775 static void f_strpart(typval_T *argvars, typval_T *rettv); 776 static void f_strridx(typval_T *argvars, typval_T *rettv); 777 static void f_strtrans(typval_T *argvars, typval_T *rettv); 778 static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv); 779 static void f_strwidth(typval_T *argvars, typval_T *rettv); 780 static void f_submatch(typval_T *argvars, typval_T *rettv); 781 static void f_substitute(typval_T *argvars, typval_T *rettv); 782 static void f_synID(typval_T *argvars, typval_T *rettv); 783 static void f_synIDattr(typval_T *argvars, typval_T *rettv); 784 static void f_synIDtrans(typval_T *argvars, typval_T *rettv); 785 static void f_synstack(typval_T *argvars, typval_T *rettv); 786 static void f_synconcealed(typval_T *argvars, typval_T *rettv); 787 static void f_system(typval_T *argvars, typval_T *rettv); 788 static void f_systemlist(typval_T *argvars, typval_T *rettv); 789 static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv); 790 static void f_tabpagenr(typval_T *argvars, typval_T *rettv); 791 static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv); 792 static void f_taglist(typval_T *argvars, typval_T *rettv); 793 static void f_tagfiles(typval_T *argvars, typval_T *rettv); 794 static void f_tempname(typval_T *argvars, typval_T *rettv); 795 static void f_test(typval_T *argvars, typval_T *rettv); 796 #ifdef FEAT_FLOAT 797 static void f_tan(typval_T *argvars, typval_T *rettv); 798 static void f_tanh(typval_T *argvars, typval_T *rettv); 799 #endif 800 #ifdef FEAT_TIMERS 801 static void f_timer_start(typval_T *argvars, typval_T *rettv); 802 static void f_timer_stop(typval_T *argvars, typval_T *rettv); 803 #endif 804 static void f_tolower(typval_T *argvars, typval_T *rettv); 805 static void f_toupper(typval_T *argvars, typval_T *rettv); 806 static void f_tr(typval_T *argvars, typval_T *rettv); 807 #ifdef FEAT_FLOAT 808 static void f_trunc(typval_T *argvars, typval_T *rettv); 809 #endif 810 static void f_type(typval_T *argvars, typval_T *rettv); 811 static void f_undofile(typval_T *argvars, typval_T *rettv); 812 static void f_undotree(typval_T *argvars, typval_T *rettv); 813 static void f_uniq(typval_T *argvars, typval_T *rettv); 814 static void f_values(typval_T *argvars, typval_T *rettv); 815 static void f_virtcol(typval_T *argvars, typval_T *rettv); 816 static void f_visualmode(typval_T *argvars, typval_T *rettv); 817 static void f_wildmenumode(typval_T *argvars, typval_T *rettv); 818 static void f_win_findbuf(typval_T *argvars, typval_T *rettv); 819 static void f_win_getid(typval_T *argvars, typval_T *rettv); 820 static void f_win_gotoid(typval_T *argvars, typval_T *rettv); 821 static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv); 822 static void f_win_id2win(typval_T *argvars, typval_T *rettv); 823 static void f_winbufnr(typval_T *argvars, typval_T *rettv); 824 static void f_wincol(typval_T *argvars, typval_T *rettv); 825 static void f_winheight(typval_T *argvars, typval_T *rettv); 826 static void f_winline(typval_T *argvars, typval_T *rettv); 827 static void f_winnr(typval_T *argvars, typval_T *rettv); 828 static void f_winrestcmd(typval_T *argvars, typval_T *rettv); 829 static void f_winrestview(typval_T *argvars, typval_T *rettv); 830 static void f_winsaveview(typval_T *argvars, typval_T *rettv); 831 static void f_winwidth(typval_T *argvars, typval_T *rettv); 832 static void f_writefile(typval_T *argvars, typval_T *rettv); 833 static void f_wordcount(typval_T *argvars, typval_T *rettv); 834 static void f_xor(typval_T *argvars, typval_T *rettv); 835 836 static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp); 837 static pos_T *var2fpos(typval_T *varp, int dollar_lnum, int *fnum); 838 static int get_env_len(char_u **arg); 839 static int get_id_len(char_u **arg); 840 static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose); 841 static char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags); 842 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 843 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 844 valid character */ 845 static char_u * make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); 846 static int eval_isnamec(int c); 847 static int eval_isnamec1(int c); 848 static int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload); 849 static int handle_subscript(char_u **arg, typval_T *rettv, int evaluate, int verbose); 850 static typval_T *alloc_string_tv(char_u *string); 851 static void init_tv(typval_T *varp); 852 #ifdef FEAT_FLOAT 853 static float_T get_tv_float(typval_T *varp); 854 #endif 855 static linenr_T get_tv_lnum(typval_T *argvars); 856 static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf); 857 static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload); 858 static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload); 859 static hashtab_T *find_var_ht(char_u *name, char_u **varname); 860 static funccall_T *get_funccal(void); 861 static void vars_clear_ext(hashtab_T *ht, int free_val); 862 static void delete_var(hashtab_T *ht, hashitem_T *hi); 863 static void list_one_var(dictitem_T *v, char_u *prefix, int *first); 864 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first); 865 static void set_var(char_u *name, typval_T *varp, int copy); 866 static int var_check_ro(int flags, char_u *name, int use_gettext); 867 static int var_check_fixed(int flags, char_u *name, int use_gettext); 868 static int var_check_func_name(char_u *name, int new_var); 869 static int valid_varname(char_u *varname); 870 static int tv_check_lock(int lock, char_u *name, int use_gettext); 871 static int item_copy(typval_T *from, typval_T *to, int deep, int copyID); 872 static char_u *find_option_end(char_u **arg, int *opt_flags); 873 static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial); 874 static int eval_fname_script(char_u *p); 875 static int eval_fname_sid(char_u *p); 876 static void list_func_head(ufunc_T *fp, int indent); 877 static ufunc_T *find_func(char_u *name); 878 static int function_exists(char_u *name); 879 static int builtin_function(char_u *name, int len); 880 #ifdef FEAT_PROFILE 881 static void func_do_profile(ufunc_T *fp); 882 static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self); 883 static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self); 884 static int 885 # ifdef __BORLANDC__ 886 _RTLENTRYF 887 # endif 888 prof_total_cmp(const void *s1, const void *s2); 889 static int 890 # ifdef __BORLANDC__ 891 _RTLENTRYF 892 # endif 893 prof_self_cmp(const void *s1, const void *s2); 894 #endif 895 static int script_autoload(char_u *name, int reload); 896 static char_u *autoload_name(char_u *name); 897 static void cat_func_name(char_u *buf, ufunc_T *fp); 898 static void func_free(ufunc_T *fp); 899 static void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict); 900 static int can_free_funccal(funccall_T *fc, int copyID) ; 901 static void free_funccal(funccall_T *fc, int free_val); 902 static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr); 903 static win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); 904 static win_T *find_tabwin(typval_T *wvp, typval_T *tvp); 905 static void getwinvar(typval_T *argvars, typval_T *rettv, int off); 906 static int searchpair_cmn(typval_T *argvars, pos_T *match_pos); 907 static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp); 908 static void setwinvar(typval_T *argvars, typval_T *rettv, int off); 909 static int write_list(FILE *fd, list_T *list, int binary); 910 static void get_cmd_output_as_rettv(typval_T *argvars, typval_T *rettv, int retlist); 911 912 913 #ifdef EBCDIC 914 static int compare_func_name(const void *s1, const void *s2); 915 static void sortFunctions(); 916 #endif 917 918 /* 919 * Initialize the global and v: variables. 920 */ 921 void 922 eval_init(void) 923 { 924 int i; 925 struct vimvar *p; 926 927 init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); 928 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); 929 vimvardict.dv_lock = VAR_FIXED; 930 hash_init(&compat_hashtab); 931 hash_init(&func_hashtab); 932 933 for (i = 0; i < VV_LEN; ++i) 934 { 935 p = &vimvars[i]; 936 STRCPY(p->vv_di.di_key, p->vv_name); 937 if (p->vv_flags & VV_RO) 938 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 939 else if (p->vv_flags & VV_RO_SBX) 940 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 941 else 942 p->vv_di.di_flags = DI_FLAGS_FIX; 943 944 /* add to v: scope dict, unless the value is not always available */ 945 if (p->vv_type != VAR_UNKNOWN) 946 hash_add(&vimvarht, p->vv_di.di_key); 947 if (p->vv_flags & VV_COMPAT) 948 /* add to compat scope dict */ 949 hash_add(&compat_hashtab, p->vv_di.di_key); 950 } 951 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 952 953 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 954 set_vim_var_nr(VV_HLSEARCH, 1L); 955 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); 956 set_vim_var_list(VV_ERRORS, list_alloc()); 957 958 set_vim_var_nr(VV_FALSE, VVAL_FALSE); 959 set_vim_var_nr(VV_TRUE, VVAL_TRUE); 960 set_vim_var_nr(VV_NONE, VVAL_NONE); 961 set_vim_var_nr(VV_NULL, VVAL_NULL); 962 963 set_reg_var(0); /* default for v:register is not 0 but '"' */ 964 965 #ifdef EBCDIC 966 /* 967 * Sort the function table, to enable binary search. 968 */ 969 sortFunctions(); 970 #endif 971 } 972 973 #if defined(EXITFREE) || defined(PROTO) 974 void 975 eval_clear(void) 976 { 977 int i; 978 struct vimvar *p; 979 980 for (i = 0; i < VV_LEN; ++i) 981 { 982 p = &vimvars[i]; 983 if (p->vv_di.di_tv.v_type == VAR_STRING) 984 { 985 vim_free(p->vv_str); 986 p->vv_str = NULL; 987 } 988 else if (p->vv_di.di_tv.v_type == VAR_LIST) 989 { 990 list_unref(p->vv_list); 991 p->vv_list = NULL; 992 } 993 } 994 hash_clear(&vimvarht); 995 hash_init(&vimvarht); /* garbage_collect() will access it */ 996 hash_clear(&compat_hashtab); 997 998 free_scriptnames(); 999 # if defined(FEAT_CMDL_COMPL) 1000 free_locales(); 1001 # endif 1002 1003 /* global variables */ 1004 vars_clear(&globvarht); 1005 1006 /* autoloaded script names */ 1007 ga_clear_strings(&ga_loaded); 1008 1009 /* Script-local variables. First clear all the variables and in a second 1010 * loop free the scriptvar_T, because a variable in one script might hold 1011 * a reference to the whole scope of another script. */ 1012 for (i = 1; i <= ga_scripts.ga_len; ++i) 1013 vars_clear(&SCRIPT_VARS(i)); 1014 for (i = 1; i <= ga_scripts.ga_len; ++i) 1015 vim_free(SCRIPT_SV(i)); 1016 ga_clear(&ga_scripts); 1017 1018 /* unreferenced lists and dicts */ 1019 (void)garbage_collect(); 1020 1021 /* functions */ 1022 free_all_functions(); 1023 hash_clear(&func_hashtab); 1024 } 1025 #endif 1026 1027 /* 1028 * Return the name of the executed function. 1029 */ 1030 char_u * 1031 func_name(void *cookie) 1032 { 1033 return ((funccall_T *)cookie)->func->uf_name; 1034 } 1035 1036 /* 1037 * Return the address holding the next breakpoint line for a funccall cookie. 1038 */ 1039 linenr_T * 1040 func_breakpoint(void *cookie) 1041 { 1042 return &((funccall_T *)cookie)->breakpoint; 1043 } 1044 1045 /* 1046 * Return the address holding the debug tick for a funccall cookie. 1047 */ 1048 int * 1049 func_dbg_tick(void *cookie) 1050 { 1051 return &((funccall_T *)cookie)->dbg_tick; 1052 } 1053 1054 /* 1055 * Return the nesting level for a funccall cookie. 1056 */ 1057 int 1058 func_level(void *cookie) 1059 { 1060 return ((funccall_T *)cookie)->level; 1061 } 1062 1063 /* pointer to funccal for currently active function */ 1064 funccall_T *current_funccal = NULL; 1065 1066 /* pointer to list of previously used funccal, still around because some 1067 * item in it is still being used. */ 1068 funccall_T *previous_funccal = NULL; 1069 1070 /* 1071 * Return TRUE when a function was ended by a ":return" command. 1072 */ 1073 int 1074 current_func_returned(void) 1075 { 1076 return current_funccal->returned; 1077 } 1078 1079 1080 /* 1081 * Set an internal variable to a string value. Creates the variable if it does 1082 * not already exist. 1083 */ 1084 void 1085 set_internal_string_var(char_u *name, char_u *value) 1086 { 1087 char_u *val; 1088 typval_T *tvp; 1089 1090 val = vim_strsave(value); 1091 if (val != NULL) 1092 { 1093 tvp = alloc_string_tv(val); 1094 if (tvp != NULL) 1095 { 1096 set_var(name, tvp, FALSE); 1097 free_tv(tvp); 1098 } 1099 } 1100 } 1101 1102 static lval_T *redir_lval = NULL; 1103 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 1104 static char_u *redir_endp = NULL; 1105 static char_u *redir_varname = NULL; 1106 1107 /* 1108 * Start recording command output to a variable 1109 * When "append" is TRUE append to an existing variable. 1110 * Returns OK if successfully completed the setup. FAIL otherwise. 1111 */ 1112 int 1113 var_redir_start(char_u *name, int append) 1114 { 1115 int save_emsg; 1116 int err; 1117 typval_T tv; 1118 1119 /* Catch a bad name early. */ 1120 if (!eval_isnamec1(*name)) 1121 { 1122 EMSG(_(e_invarg)); 1123 return FAIL; 1124 } 1125 1126 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 1127 redir_varname = vim_strsave(name); 1128 if (redir_varname == NULL) 1129 return FAIL; 1130 1131 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1132 if (redir_lval == NULL) 1133 { 1134 var_redir_stop(); 1135 return FAIL; 1136 } 1137 1138 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1139 ga_init2(&redir_ga, (int)sizeof(char), 500); 1140 1141 /* Parse the variable name (can be a dict or list entry). */ 1142 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0, 1143 FNE_CHECK_START); 1144 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1145 { 1146 clear_lval(redir_lval); 1147 if (redir_endp != NULL && *redir_endp != NUL) 1148 /* Trailing characters are present after the variable name */ 1149 EMSG(_(e_trailing)); 1150 else 1151 EMSG(_(e_invarg)); 1152 redir_endp = NULL; /* don't store a value, only cleanup */ 1153 var_redir_stop(); 1154 return FAIL; 1155 } 1156 1157 /* check if we can write to the variable: set it to or append an empty 1158 * string */ 1159 save_emsg = did_emsg; 1160 did_emsg = FALSE; 1161 tv.v_type = VAR_STRING; 1162 tv.vval.v_string = (char_u *)""; 1163 if (append) 1164 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1165 else 1166 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1167 clear_lval(redir_lval); 1168 err = did_emsg; 1169 did_emsg |= save_emsg; 1170 if (err) 1171 { 1172 redir_endp = NULL; /* don't store a value, only cleanup */ 1173 var_redir_stop(); 1174 return FAIL; 1175 } 1176 1177 return OK; 1178 } 1179 1180 /* 1181 * Append "value[value_len]" to the variable set by var_redir_start(). 1182 * The actual appending is postponed until redirection ends, because the value 1183 * appended may in fact be the string we write to, changing it may cause freed 1184 * memory to be used: 1185 * :redir => foo 1186 * :let foo 1187 * :redir END 1188 */ 1189 void 1190 var_redir_str(char_u *value, int value_len) 1191 { 1192 int len; 1193 1194 if (redir_lval == NULL) 1195 return; 1196 1197 if (value_len == -1) 1198 len = (int)STRLEN(value); /* Append the entire string */ 1199 else 1200 len = value_len; /* Append only "value_len" characters */ 1201 1202 if (ga_grow(&redir_ga, len) == OK) 1203 { 1204 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1205 redir_ga.ga_len += len; 1206 } 1207 else 1208 var_redir_stop(); 1209 } 1210 1211 /* 1212 * Stop redirecting command output to a variable. 1213 * Frees the allocated memory. 1214 */ 1215 void 1216 var_redir_stop(void) 1217 { 1218 typval_T tv; 1219 1220 if (redir_lval != NULL) 1221 { 1222 /* If there was no error: assign the text to the variable. */ 1223 if (redir_endp != NULL) 1224 { 1225 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1226 tv.v_type = VAR_STRING; 1227 tv.vval.v_string = redir_ga.ga_data; 1228 /* Call get_lval() again, if it's inside a Dict or List it may 1229 * have changed. */ 1230 redir_endp = get_lval(redir_varname, NULL, redir_lval, 1231 FALSE, FALSE, 0, FNE_CHECK_START); 1232 if (redir_endp != NULL && redir_lval->ll_name != NULL) 1233 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1234 clear_lval(redir_lval); 1235 } 1236 1237 /* free the collected output */ 1238 vim_free(redir_ga.ga_data); 1239 redir_ga.ga_data = NULL; 1240 1241 vim_free(redir_lval); 1242 redir_lval = NULL; 1243 } 1244 vim_free(redir_varname); 1245 redir_varname = NULL; 1246 } 1247 1248 # if defined(FEAT_MBYTE) || defined(PROTO) 1249 int 1250 eval_charconvert( 1251 char_u *enc_from, 1252 char_u *enc_to, 1253 char_u *fname_from, 1254 char_u *fname_to) 1255 { 1256 int err = FALSE; 1257 1258 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1259 set_vim_var_string(VV_CC_TO, enc_to, -1); 1260 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1261 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1262 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1263 err = TRUE; 1264 set_vim_var_string(VV_CC_FROM, NULL, -1); 1265 set_vim_var_string(VV_CC_TO, NULL, -1); 1266 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1267 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1268 1269 if (err) 1270 return FAIL; 1271 return OK; 1272 } 1273 # endif 1274 1275 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1276 int 1277 eval_printexpr(char_u *fname, char_u *args) 1278 { 1279 int err = FALSE; 1280 1281 set_vim_var_string(VV_FNAME_IN, fname, -1); 1282 set_vim_var_string(VV_CMDARG, args, -1); 1283 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1284 err = TRUE; 1285 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1286 set_vim_var_string(VV_CMDARG, NULL, -1); 1287 1288 if (err) 1289 { 1290 mch_remove(fname); 1291 return FAIL; 1292 } 1293 return OK; 1294 } 1295 # endif 1296 1297 # if defined(FEAT_DIFF) || defined(PROTO) 1298 void 1299 eval_diff( 1300 char_u *origfile, 1301 char_u *newfile, 1302 char_u *outfile) 1303 { 1304 int err = FALSE; 1305 1306 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1307 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1308 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1309 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1310 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1311 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1312 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1313 } 1314 1315 void 1316 eval_patch( 1317 char_u *origfile, 1318 char_u *difffile, 1319 char_u *outfile) 1320 { 1321 int err; 1322 1323 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1324 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1325 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1326 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1327 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1328 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1329 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1330 } 1331 # endif 1332 1333 /* 1334 * Top level evaluation function, returning a boolean. 1335 * Sets "error" to TRUE if there was an error. 1336 * Return TRUE or FALSE. 1337 */ 1338 int 1339 eval_to_bool( 1340 char_u *arg, 1341 int *error, 1342 char_u **nextcmd, 1343 int skip) /* only parse, don't execute */ 1344 { 1345 typval_T tv; 1346 int retval = FALSE; 1347 1348 if (skip) 1349 ++emsg_skip; 1350 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1351 *error = TRUE; 1352 else 1353 { 1354 *error = FALSE; 1355 if (!skip) 1356 { 1357 retval = (get_tv_number_chk(&tv, error) != 0); 1358 clear_tv(&tv); 1359 } 1360 } 1361 if (skip) 1362 --emsg_skip; 1363 1364 return retval; 1365 } 1366 1367 /* 1368 * Top level evaluation function, returning a string. If "skip" is TRUE, 1369 * only parsing to "nextcmd" is done, without reporting errors. Return 1370 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1371 */ 1372 char_u * 1373 eval_to_string_skip( 1374 char_u *arg, 1375 char_u **nextcmd, 1376 int skip) /* only parse, don't execute */ 1377 { 1378 typval_T tv; 1379 char_u *retval; 1380 1381 if (skip) 1382 ++emsg_skip; 1383 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1384 retval = NULL; 1385 else 1386 { 1387 retval = vim_strsave(get_tv_string(&tv)); 1388 clear_tv(&tv); 1389 } 1390 if (skip) 1391 --emsg_skip; 1392 1393 return retval; 1394 } 1395 1396 /* 1397 * Skip over an expression at "*pp". 1398 * Return FAIL for an error, OK otherwise. 1399 */ 1400 int 1401 skip_expr(char_u **pp) 1402 { 1403 typval_T rettv; 1404 1405 *pp = skipwhite(*pp); 1406 return eval1(pp, &rettv, FALSE); 1407 } 1408 1409 /* 1410 * Top level evaluation function, returning a string. 1411 * When "convert" is TRUE convert a List into a sequence of lines and convert 1412 * a Float to a String. 1413 * Return pointer to allocated memory, or NULL for failure. 1414 */ 1415 char_u * 1416 eval_to_string( 1417 char_u *arg, 1418 char_u **nextcmd, 1419 int convert) 1420 { 1421 typval_T tv; 1422 char_u *retval; 1423 garray_T ga; 1424 #ifdef FEAT_FLOAT 1425 char_u numbuf[NUMBUFLEN]; 1426 #endif 1427 1428 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1429 retval = NULL; 1430 else 1431 { 1432 if (convert && tv.v_type == VAR_LIST) 1433 { 1434 ga_init2(&ga, (int)sizeof(char), 80); 1435 if (tv.vval.v_list != NULL) 1436 { 1437 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1438 if (tv.vval.v_list->lv_len > 0) 1439 ga_append(&ga, NL); 1440 } 1441 ga_append(&ga, NUL); 1442 retval = (char_u *)ga.ga_data; 1443 } 1444 #ifdef FEAT_FLOAT 1445 else if (convert && tv.v_type == VAR_FLOAT) 1446 { 1447 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1448 retval = vim_strsave(numbuf); 1449 } 1450 #endif 1451 else 1452 retval = vim_strsave(get_tv_string(&tv)); 1453 clear_tv(&tv); 1454 } 1455 1456 return retval; 1457 } 1458 1459 /* 1460 * Call eval_to_string() without using current local variables and using 1461 * textlock. When "use_sandbox" is TRUE use the sandbox. 1462 */ 1463 char_u * 1464 eval_to_string_safe( 1465 char_u *arg, 1466 char_u **nextcmd, 1467 int use_sandbox) 1468 { 1469 char_u *retval; 1470 void *save_funccalp; 1471 1472 save_funccalp = save_funccal(); 1473 if (use_sandbox) 1474 ++sandbox; 1475 ++textlock; 1476 retval = eval_to_string(arg, nextcmd, FALSE); 1477 if (use_sandbox) 1478 --sandbox; 1479 --textlock; 1480 restore_funccal(save_funccalp); 1481 return retval; 1482 } 1483 1484 /* 1485 * Top level evaluation function, returning a number. 1486 * Evaluates "expr" silently. 1487 * Returns -1 for an error. 1488 */ 1489 int 1490 eval_to_number(char_u *expr) 1491 { 1492 typval_T rettv; 1493 int retval; 1494 char_u *p = skipwhite(expr); 1495 1496 ++emsg_off; 1497 1498 if (eval1(&p, &rettv, TRUE) == FAIL) 1499 retval = -1; 1500 else 1501 { 1502 retval = get_tv_number_chk(&rettv, NULL); 1503 clear_tv(&rettv); 1504 } 1505 --emsg_off; 1506 1507 return retval; 1508 } 1509 1510 /* 1511 * Prepare v: variable "idx" to be used. 1512 * Save the current typeval in "save_tv". 1513 * When not used yet add the variable to the v: hashtable. 1514 */ 1515 static void 1516 prepare_vimvar(int idx, typval_T *save_tv) 1517 { 1518 *save_tv = vimvars[idx].vv_tv; 1519 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1520 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1521 } 1522 1523 /* 1524 * Restore v: variable "idx" to typeval "save_tv". 1525 * When no longer defined, remove the variable from the v: hashtable. 1526 */ 1527 static void 1528 restore_vimvar(int idx, typval_T *save_tv) 1529 { 1530 hashitem_T *hi; 1531 1532 vimvars[idx].vv_tv = *save_tv; 1533 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1534 { 1535 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1536 if (HASHITEM_EMPTY(hi)) 1537 EMSG2(_(e_intern2), "restore_vimvar()"); 1538 else 1539 hash_remove(&vimvarht, hi); 1540 } 1541 } 1542 1543 #if defined(FEAT_SPELL) || defined(PROTO) 1544 /* 1545 * Evaluate an expression to a list with suggestions. 1546 * For the "expr:" part of 'spellsuggest'. 1547 * Returns NULL when there is an error. 1548 */ 1549 list_T * 1550 eval_spell_expr(char_u *badword, char_u *expr) 1551 { 1552 typval_T save_val; 1553 typval_T rettv; 1554 list_T *list = NULL; 1555 char_u *p = skipwhite(expr); 1556 1557 /* Set "v:val" to the bad word. */ 1558 prepare_vimvar(VV_VAL, &save_val); 1559 vimvars[VV_VAL].vv_type = VAR_STRING; 1560 vimvars[VV_VAL].vv_str = badword; 1561 if (p_verbose == 0) 1562 ++emsg_off; 1563 1564 if (eval1(&p, &rettv, TRUE) == OK) 1565 { 1566 if (rettv.v_type != VAR_LIST) 1567 clear_tv(&rettv); 1568 else 1569 list = rettv.vval.v_list; 1570 } 1571 1572 if (p_verbose == 0) 1573 --emsg_off; 1574 restore_vimvar(VV_VAL, &save_val); 1575 1576 return list; 1577 } 1578 1579 /* 1580 * "list" is supposed to contain two items: a word and a number. Return the 1581 * word in "pp" and the number as the return value. 1582 * Return -1 if anything isn't right. 1583 * Used to get the good word and score from the eval_spell_expr() result. 1584 */ 1585 int 1586 get_spellword(list_T *list, char_u **pp) 1587 { 1588 listitem_T *li; 1589 1590 li = list->lv_first; 1591 if (li == NULL) 1592 return -1; 1593 *pp = get_tv_string(&li->li_tv); 1594 1595 li = li->li_next; 1596 if (li == NULL) 1597 return -1; 1598 return get_tv_number(&li->li_tv); 1599 } 1600 #endif 1601 1602 /* 1603 * Top level evaluation function. 1604 * Returns an allocated typval_T with the result. 1605 * Returns NULL when there is an error. 1606 */ 1607 typval_T * 1608 eval_expr(char_u *arg, char_u **nextcmd) 1609 { 1610 typval_T *tv; 1611 1612 tv = (typval_T *)alloc(sizeof(typval_T)); 1613 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1614 { 1615 vim_free(tv); 1616 tv = NULL; 1617 } 1618 1619 return tv; 1620 } 1621 1622 1623 /* 1624 * Call some vimL function and return the result in "*rettv". 1625 * Uses argv[argc] for the function arguments. Only Number and String 1626 * arguments are currently supported. 1627 * Returns OK or FAIL. 1628 */ 1629 int 1630 call_vim_function( 1631 char_u *func, 1632 int argc, 1633 char_u **argv, 1634 int safe, /* use the sandbox */ 1635 int str_arg_only, /* all arguments are strings */ 1636 typval_T *rettv) 1637 { 1638 typval_T *argvars; 1639 long n; 1640 int len; 1641 int i; 1642 int doesrange; 1643 void *save_funccalp = NULL; 1644 int ret; 1645 1646 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1647 if (argvars == NULL) 1648 return FAIL; 1649 1650 for (i = 0; i < argc; i++) 1651 { 1652 /* Pass a NULL or empty argument as an empty string */ 1653 if (argv[i] == NULL || *argv[i] == NUL) 1654 { 1655 argvars[i].v_type = VAR_STRING; 1656 argvars[i].vval.v_string = (char_u *)""; 1657 continue; 1658 } 1659 1660 if (str_arg_only) 1661 len = 0; 1662 else 1663 /* Recognize a number argument, the others must be strings. */ 1664 vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0); 1665 if (len != 0 && len == (int)STRLEN(argv[i])) 1666 { 1667 argvars[i].v_type = VAR_NUMBER; 1668 argvars[i].vval.v_number = n; 1669 } 1670 else 1671 { 1672 argvars[i].v_type = VAR_STRING; 1673 argvars[i].vval.v_string = argv[i]; 1674 } 1675 } 1676 1677 if (safe) 1678 { 1679 save_funccalp = save_funccal(); 1680 ++sandbox; 1681 } 1682 1683 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1684 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1685 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1686 &doesrange, TRUE, NULL, NULL); 1687 if (safe) 1688 { 1689 --sandbox; 1690 restore_funccal(save_funccalp); 1691 } 1692 vim_free(argvars); 1693 1694 if (ret == FAIL) 1695 clear_tv(rettv); 1696 1697 return ret; 1698 } 1699 1700 /* 1701 * Call vimL function "func" and return the result as a number. 1702 * Returns -1 when calling the function fails. 1703 * Uses argv[argc] for the function arguments. 1704 */ 1705 long 1706 call_func_retnr( 1707 char_u *func, 1708 int argc, 1709 char_u **argv, 1710 int safe) /* use the sandbox */ 1711 { 1712 typval_T rettv; 1713 long retval; 1714 1715 /* All arguments are passed as strings, no conversion to number. */ 1716 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1717 return -1; 1718 1719 retval = get_tv_number_chk(&rettv, NULL); 1720 clear_tv(&rettv); 1721 return retval; 1722 } 1723 1724 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1725 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1726 1727 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1728 /* 1729 * Call vimL function "func" and return the result as a string. 1730 * Returns NULL when calling the function fails. 1731 * Uses argv[argc] for the function arguments. 1732 */ 1733 void * 1734 call_func_retstr( 1735 char_u *func, 1736 int argc, 1737 char_u **argv, 1738 int safe) /* use the sandbox */ 1739 { 1740 typval_T rettv; 1741 char_u *retval; 1742 1743 /* All arguments are passed as strings, no conversion to number. */ 1744 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1745 return NULL; 1746 1747 retval = vim_strsave(get_tv_string(&rettv)); 1748 clear_tv(&rettv); 1749 return retval; 1750 } 1751 # endif 1752 1753 /* 1754 * Call vimL function "func" and return the result as a List. 1755 * Uses argv[argc] for the function arguments. 1756 * Returns NULL when there is something wrong. 1757 */ 1758 void * 1759 call_func_retlist( 1760 char_u *func, 1761 int argc, 1762 char_u **argv, 1763 int safe) /* use the sandbox */ 1764 { 1765 typval_T rettv; 1766 1767 /* All arguments are passed as strings, no conversion to number. */ 1768 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1769 return NULL; 1770 1771 if (rettv.v_type != VAR_LIST) 1772 { 1773 clear_tv(&rettv); 1774 return NULL; 1775 } 1776 1777 return rettv.vval.v_list; 1778 } 1779 #endif 1780 1781 /* 1782 * Save the current function call pointer, and set it to NULL. 1783 * Used when executing autocommands and for ":source". 1784 */ 1785 void * 1786 save_funccal(void) 1787 { 1788 funccall_T *fc = current_funccal; 1789 1790 current_funccal = NULL; 1791 return (void *)fc; 1792 } 1793 1794 void 1795 restore_funccal(void *vfc) 1796 { 1797 funccall_T *fc = (funccall_T *)vfc; 1798 1799 current_funccal = fc; 1800 } 1801 1802 #if defined(FEAT_PROFILE) || defined(PROTO) 1803 /* 1804 * Prepare profiling for entering a child or something else that is not 1805 * counted for the script/function itself. 1806 * Should always be called in pair with prof_child_exit(). 1807 */ 1808 void 1809 prof_child_enter( 1810 proftime_T *tm) /* place to store waittime */ 1811 { 1812 funccall_T *fc = current_funccal; 1813 1814 if (fc != NULL && fc->func->uf_profiling) 1815 profile_start(&fc->prof_child); 1816 script_prof_save(tm); 1817 } 1818 1819 /* 1820 * Take care of time spent in a child. 1821 * Should always be called after prof_child_enter(). 1822 */ 1823 void 1824 prof_child_exit( 1825 proftime_T *tm) /* where waittime was stored */ 1826 { 1827 funccall_T *fc = current_funccal; 1828 1829 if (fc != NULL && fc->func->uf_profiling) 1830 { 1831 profile_end(&fc->prof_child); 1832 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1833 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1834 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1835 } 1836 script_prof_restore(tm); 1837 } 1838 #endif 1839 1840 1841 #ifdef FEAT_FOLDING 1842 /* 1843 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1844 * it in "*cp". Doesn't give error messages. 1845 */ 1846 int 1847 eval_foldexpr(char_u *arg, int *cp) 1848 { 1849 typval_T tv; 1850 int retval; 1851 char_u *s; 1852 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1853 OPT_LOCAL); 1854 1855 ++emsg_off; 1856 if (use_sandbox) 1857 ++sandbox; 1858 ++textlock; 1859 *cp = NUL; 1860 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1861 retval = 0; 1862 else 1863 { 1864 /* If the result is a number, just return the number. */ 1865 if (tv.v_type == VAR_NUMBER) 1866 retval = tv.vval.v_number; 1867 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1868 retval = 0; 1869 else 1870 { 1871 /* If the result is a string, check if there is a non-digit before 1872 * the number. */ 1873 s = tv.vval.v_string; 1874 if (!VIM_ISDIGIT(*s) && *s != '-') 1875 *cp = *s++; 1876 retval = atol((char *)s); 1877 } 1878 clear_tv(&tv); 1879 } 1880 --emsg_off; 1881 if (use_sandbox) 1882 --sandbox; 1883 --textlock; 1884 1885 return retval; 1886 } 1887 #endif 1888 1889 /* 1890 * ":let" list all variable values 1891 * ":let var1 var2" list variable values 1892 * ":let var = expr" assignment command. 1893 * ":let var += expr" assignment command. 1894 * ":let var -= expr" assignment command. 1895 * ":let var .= expr" assignment command. 1896 * ":let [var1, var2] = expr" unpack list. 1897 */ 1898 void 1899 ex_let(exarg_T *eap) 1900 { 1901 char_u *arg = eap->arg; 1902 char_u *expr = NULL; 1903 typval_T rettv; 1904 int i; 1905 int var_count = 0; 1906 int semicolon = 0; 1907 char_u op[2]; 1908 char_u *argend; 1909 int first = TRUE; 1910 1911 argend = skip_var_list(arg, &var_count, &semicolon); 1912 if (argend == NULL) 1913 return; 1914 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1915 --argend; 1916 expr = skipwhite(argend); 1917 if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL 1918 && expr[1] == '=')) 1919 { 1920 /* 1921 * ":let" without "=": list variables 1922 */ 1923 if (*arg == '[') 1924 EMSG(_(e_invarg)); 1925 else if (!ends_excmd(*arg)) 1926 /* ":let var1 var2" */ 1927 arg = list_arg_vars(eap, arg, &first); 1928 else if (!eap->skip) 1929 { 1930 /* ":let" */ 1931 list_glob_vars(&first); 1932 list_buf_vars(&first); 1933 list_win_vars(&first); 1934 #ifdef FEAT_WINDOWS 1935 list_tab_vars(&first); 1936 #endif 1937 list_script_vars(&first); 1938 list_func_vars(&first); 1939 list_vim_vars(&first); 1940 } 1941 eap->nextcmd = check_nextcmd(arg); 1942 } 1943 else 1944 { 1945 op[0] = '='; 1946 op[1] = NUL; 1947 if (*expr != '=') 1948 { 1949 if (vim_strchr((char_u *)"+-.", *expr) != NULL) 1950 op[0] = *expr; /* +=, -= or .= */ 1951 expr = skipwhite(expr + 2); 1952 } 1953 else 1954 expr = skipwhite(expr + 1); 1955 1956 if (eap->skip) 1957 ++emsg_skip; 1958 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1959 if (eap->skip) 1960 { 1961 if (i != FAIL) 1962 clear_tv(&rettv); 1963 --emsg_skip; 1964 } 1965 else if (i != FAIL) 1966 { 1967 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1968 op); 1969 clear_tv(&rettv); 1970 } 1971 } 1972 } 1973 1974 /* 1975 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1976 * Handles both "var" with any type and "[var, var; var]" with a list type. 1977 * When "nextchars" is not NULL it points to a string with characters that 1978 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1979 * or concatenate. 1980 * Returns OK or FAIL; 1981 */ 1982 static int 1983 ex_let_vars( 1984 char_u *arg_start, 1985 typval_T *tv, 1986 int copy, /* copy values from "tv", don't move */ 1987 int semicolon, /* from skip_var_list() */ 1988 int var_count, /* from skip_var_list() */ 1989 char_u *nextchars) 1990 { 1991 char_u *arg = arg_start; 1992 list_T *l; 1993 int i; 1994 listitem_T *item; 1995 typval_T ltv; 1996 1997 if (*arg != '[') 1998 { 1999 /* 2000 * ":let var = expr" or ":for var in list" 2001 */ 2002 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 2003 return FAIL; 2004 return OK; 2005 } 2006 2007 /* 2008 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 2009 */ 2010 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 2011 { 2012 EMSG(_(e_listreq)); 2013 return FAIL; 2014 } 2015 2016 i = list_len(l); 2017 if (semicolon == 0 && var_count < i) 2018 { 2019 EMSG(_("E687: Less targets than List items")); 2020 return FAIL; 2021 } 2022 if (var_count - semicolon > i) 2023 { 2024 EMSG(_("E688: More targets than List items")); 2025 return FAIL; 2026 } 2027 2028 item = l->lv_first; 2029 while (*arg != ']') 2030 { 2031 arg = skipwhite(arg + 1); 2032 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 2033 item = item->li_next; 2034 if (arg == NULL) 2035 return FAIL; 2036 2037 arg = skipwhite(arg); 2038 if (*arg == ';') 2039 { 2040 /* Put the rest of the list (may be empty) in the var after ';'. 2041 * Create a new list for this. */ 2042 l = list_alloc(); 2043 if (l == NULL) 2044 return FAIL; 2045 while (item != NULL) 2046 { 2047 list_append_tv(l, &item->li_tv); 2048 item = item->li_next; 2049 } 2050 2051 ltv.v_type = VAR_LIST; 2052 ltv.v_lock = 0; 2053 ltv.vval.v_list = l; 2054 l->lv_refcount = 1; 2055 2056 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 2057 (char_u *)"]", nextchars); 2058 clear_tv(<v); 2059 if (arg == NULL) 2060 return FAIL; 2061 break; 2062 } 2063 else if (*arg != ',' && *arg != ']') 2064 { 2065 EMSG2(_(e_intern2), "ex_let_vars()"); 2066 return FAIL; 2067 } 2068 } 2069 2070 return OK; 2071 } 2072 2073 /* 2074 * Skip over assignable variable "var" or list of variables "[var, var]". 2075 * Used for ":let varvar = expr" and ":for varvar in expr". 2076 * For "[var, var]" increment "*var_count" for each variable. 2077 * for "[var, var; var]" set "semicolon". 2078 * Return NULL for an error. 2079 */ 2080 static char_u * 2081 skip_var_list( 2082 char_u *arg, 2083 int *var_count, 2084 int *semicolon) 2085 { 2086 char_u *p, *s; 2087 2088 if (*arg == '[') 2089 { 2090 /* "[var, var]": find the matching ']'. */ 2091 p = arg; 2092 for (;;) 2093 { 2094 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 2095 s = skip_var_one(p); 2096 if (s == p) 2097 { 2098 EMSG2(_(e_invarg2), p); 2099 return NULL; 2100 } 2101 ++*var_count; 2102 2103 p = skipwhite(s); 2104 if (*p == ']') 2105 break; 2106 else if (*p == ';') 2107 { 2108 if (*semicolon == 1) 2109 { 2110 EMSG(_("Double ; in list of variables")); 2111 return NULL; 2112 } 2113 *semicolon = 1; 2114 } 2115 else if (*p != ',') 2116 { 2117 EMSG2(_(e_invarg2), p); 2118 return NULL; 2119 } 2120 } 2121 return p + 1; 2122 } 2123 else 2124 return skip_var_one(arg); 2125 } 2126 2127 /* 2128 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2129 * l[idx]. 2130 */ 2131 static char_u * 2132 skip_var_one(char_u *arg) 2133 { 2134 if (*arg == '@' && arg[1] != NUL) 2135 return arg + 2; 2136 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2137 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2138 } 2139 2140 /* 2141 * List variables for hashtab "ht" with prefix "prefix". 2142 * If "empty" is TRUE also list NULL strings as empty strings. 2143 */ 2144 static void 2145 list_hashtable_vars( 2146 hashtab_T *ht, 2147 char_u *prefix, 2148 int empty, 2149 int *first) 2150 { 2151 hashitem_T *hi; 2152 dictitem_T *di; 2153 int todo; 2154 2155 todo = (int)ht->ht_used; 2156 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2157 { 2158 if (!HASHITEM_EMPTY(hi)) 2159 { 2160 --todo; 2161 di = HI2DI(hi); 2162 if (empty || di->di_tv.v_type != VAR_STRING 2163 || di->di_tv.vval.v_string != NULL) 2164 list_one_var(di, prefix, first); 2165 } 2166 } 2167 } 2168 2169 /* 2170 * List global variables. 2171 */ 2172 static void 2173 list_glob_vars(int *first) 2174 { 2175 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2176 } 2177 2178 /* 2179 * List buffer variables. 2180 */ 2181 static void 2182 list_buf_vars(int *first) 2183 { 2184 char_u numbuf[NUMBUFLEN]; 2185 2186 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:", 2187 TRUE, first); 2188 2189 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2190 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2191 numbuf, first); 2192 } 2193 2194 /* 2195 * List window variables. 2196 */ 2197 static void 2198 list_win_vars(int *first) 2199 { 2200 list_hashtable_vars(&curwin->w_vars->dv_hashtab, 2201 (char_u *)"w:", TRUE, first); 2202 } 2203 2204 #ifdef FEAT_WINDOWS 2205 /* 2206 * List tab page variables. 2207 */ 2208 static void 2209 list_tab_vars(int *first) 2210 { 2211 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, 2212 (char_u *)"t:", TRUE, first); 2213 } 2214 #endif 2215 2216 /* 2217 * List Vim variables. 2218 */ 2219 static void 2220 list_vim_vars(int *first) 2221 { 2222 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2223 } 2224 2225 /* 2226 * List script-local variables, if there is a script. 2227 */ 2228 static void 2229 list_script_vars(int *first) 2230 { 2231 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2232 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2233 (char_u *)"s:", FALSE, first); 2234 } 2235 2236 /* 2237 * List function variables, if there is a function. 2238 */ 2239 static void 2240 list_func_vars(int *first) 2241 { 2242 if (current_funccal != NULL) 2243 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2244 (char_u *)"l:", FALSE, first); 2245 } 2246 2247 /* 2248 * List variables in "arg". 2249 */ 2250 static char_u * 2251 list_arg_vars(exarg_T *eap, char_u *arg, int *first) 2252 { 2253 int error = FALSE; 2254 int len; 2255 char_u *name; 2256 char_u *name_start; 2257 char_u *arg_subsc; 2258 char_u *tofree; 2259 typval_T tv; 2260 2261 while (!ends_excmd(*arg) && !got_int) 2262 { 2263 if (error || eap->skip) 2264 { 2265 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2266 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2267 { 2268 emsg_severe = TRUE; 2269 EMSG(_(e_trailing)); 2270 break; 2271 } 2272 } 2273 else 2274 { 2275 /* get_name_len() takes care of expanding curly braces */ 2276 name_start = name = arg; 2277 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2278 if (len <= 0) 2279 { 2280 /* This is mainly to keep test 49 working: when expanding 2281 * curly braces fails overrule the exception error message. */ 2282 if (len < 0 && !aborting()) 2283 { 2284 emsg_severe = TRUE; 2285 EMSG2(_(e_invarg2), arg); 2286 break; 2287 } 2288 error = TRUE; 2289 } 2290 else 2291 { 2292 if (tofree != NULL) 2293 name = tofree; 2294 if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL) 2295 error = TRUE; 2296 else 2297 { 2298 /* handle d.key, l[idx], f(expr) */ 2299 arg_subsc = arg; 2300 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2301 error = TRUE; 2302 else 2303 { 2304 if (arg == arg_subsc && len == 2 && name[1] == ':') 2305 { 2306 switch (*name) 2307 { 2308 case 'g': list_glob_vars(first); break; 2309 case 'b': list_buf_vars(first); break; 2310 case 'w': list_win_vars(first); break; 2311 #ifdef FEAT_WINDOWS 2312 case 't': list_tab_vars(first); break; 2313 #endif 2314 case 'v': list_vim_vars(first); break; 2315 case 's': list_script_vars(first); break; 2316 case 'l': list_func_vars(first); break; 2317 default: 2318 EMSG2(_("E738: Can't list variables for %s"), name); 2319 } 2320 } 2321 else 2322 { 2323 char_u numbuf[NUMBUFLEN]; 2324 char_u *tf; 2325 int c; 2326 char_u *s; 2327 2328 s = echo_string(&tv, &tf, numbuf, 0); 2329 c = *arg; 2330 *arg = NUL; 2331 list_one_var_a((char_u *)"", 2332 arg == arg_subsc ? name : name_start, 2333 tv.v_type, 2334 s == NULL ? (char_u *)"" : s, 2335 first); 2336 *arg = c; 2337 vim_free(tf); 2338 } 2339 clear_tv(&tv); 2340 } 2341 } 2342 } 2343 2344 vim_free(tofree); 2345 } 2346 2347 arg = skipwhite(arg); 2348 } 2349 2350 return arg; 2351 } 2352 2353 /* 2354 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2355 * Returns a pointer to the char just after the var name. 2356 * Returns NULL if there is an error. 2357 */ 2358 static char_u * 2359 ex_let_one( 2360 char_u *arg, /* points to variable name */ 2361 typval_T *tv, /* value to assign to variable */ 2362 int copy, /* copy value from "tv" */ 2363 char_u *endchars, /* valid chars after variable name or NULL */ 2364 char_u *op) /* "+", "-", "." or NULL*/ 2365 { 2366 int c1; 2367 char_u *name; 2368 char_u *p; 2369 char_u *arg_end = NULL; 2370 int len; 2371 int opt_flags; 2372 char_u *tofree = NULL; 2373 2374 /* 2375 * ":let $VAR = expr": Set environment variable. 2376 */ 2377 if (*arg == '$') 2378 { 2379 /* Find the end of the name. */ 2380 ++arg; 2381 name = arg; 2382 len = get_env_len(&arg); 2383 if (len == 0) 2384 EMSG2(_(e_invarg2), name - 1); 2385 else 2386 { 2387 if (op != NULL && (*op == '+' || *op == '-')) 2388 EMSG2(_(e_letwrong), op); 2389 else if (endchars != NULL 2390 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2391 EMSG(_(e_letunexp)); 2392 else if (!check_secure()) 2393 { 2394 c1 = name[len]; 2395 name[len] = NUL; 2396 p = get_tv_string_chk(tv); 2397 if (p != NULL && op != NULL && *op == '.') 2398 { 2399 int mustfree = FALSE; 2400 char_u *s = vim_getenv(name, &mustfree); 2401 2402 if (s != NULL) 2403 { 2404 p = tofree = concat_str(s, p); 2405 if (mustfree) 2406 vim_free(s); 2407 } 2408 } 2409 if (p != NULL) 2410 { 2411 vim_setenv(name, p); 2412 if (STRICMP(name, "HOME") == 0) 2413 init_homedir(); 2414 else if (didset_vim && STRICMP(name, "VIM") == 0) 2415 didset_vim = FALSE; 2416 else if (didset_vimruntime 2417 && STRICMP(name, "VIMRUNTIME") == 0) 2418 didset_vimruntime = FALSE; 2419 arg_end = arg; 2420 } 2421 name[len] = c1; 2422 vim_free(tofree); 2423 } 2424 } 2425 } 2426 2427 /* 2428 * ":let &option = expr": Set option value. 2429 * ":let &l:option = expr": Set local option value. 2430 * ":let &g:option = expr": Set global option value. 2431 */ 2432 else if (*arg == '&') 2433 { 2434 /* Find the end of the name. */ 2435 p = find_option_end(&arg, &opt_flags); 2436 if (p == NULL || (endchars != NULL 2437 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2438 EMSG(_(e_letunexp)); 2439 else 2440 { 2441 long n; 2442 int opt_type; 2443 long numval; 2444 char_u *stringval = NULL; 2445 char_u *s; 2446 2447 c1 = *p; 2448 *p = NUL; 2449 2450 n = get_tv_number(tv); 2451 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2452 if (s != NULL && op != NULL && *op != '=') 2453 { 2454 opt_type = get_option_value(arg, &numval, 2455 &stringval, opt_flags); 2456 if ((opt_type == 1 && *op == '.') 2457 || (opt_type == 0 && *op != '.')) 2458 EMSG2(_(e_letwrong), op); 2459 else 2460 { 2461 if (opt_type == 1) /* number */ 2462 { 2463 if (*op == '+') 2464 n = numval + n; 2465 else 2466 n = numval - n; 2467 } 2468 else if (opt_type == 0 && stringval != NULL) /* string */ 2469 { 2470 s = concat_str(stringval, s); 2471 vim_free(stringval); 2472 stringval = s; 2473 } 2474 } 2475 } 2476 if (s != NULL) 2477 { 2478 set_option_value(arg, n, s, opt_flags); 2479 arg_end = p; 2480 } 2481 *p = c1; 2482 vim_free(stringval); 2483 } 2484 } 2485 2486 /* 2487 * ":let @r = expr": Set register contents. 2488 */ 2489 else if (*arg == '@') 2490 { 2491 ++arg; 2492 if (op != NULL && (*op == '+' || *op == '-')) 2493 EMSG2(_(e_letwrong), op); 2494 else if (endchars != NULL 2495 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2496 EMSG(_(e_letunexp)); 2497 else 2498 { 2499 char_u *ptofree = NULL; 2500 char_u *s; 2501 2502 p = get_tv_string_chk(tv); 2503 if (p != NULL && op != NULL && *op == '.') 2504 { 2505 s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); 2506 if (s != NULL) 2507 { 2508 p = ptofree = concat_str(s, p); 2509 vim_free(s); 2510 } 2511 } 2512 if (p != NULL) 2513 { 2514 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2515 arg_end = arg + 1; 2516 } 2517 vim_free(ptofree); 2518 } 2519 } 2520 2521 /* 2522 * ":let var = expr": Set internal variable. 2523 * ":let {expr} = expr": Idem, name made with curly braces 2524 */ 2525 else if (eval_isnamec1(*arg) || *arg == '{') 2526 { 2527 lval_T lv; 2528 2529 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); 2530 if (p != NULL && lv.ll_name != NULL) 2531 { 2532 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2533 EMSG(_(e_letunexp)); 2534 else 2535 { 2536 set_var_lval(&lv, p, tv, copy, op); 2537 arg_end = p; 2538 } 2539 } 2540 clear_lval(&lv); 2541 } 2542 2543 else 2544 EMSG2(_(e_invarg2), arg); 2545 2546 return arg_end; 2547 } 2548 2549 /* 2550 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2551 */ 2552 static int 2553 check_changedtick(char_u *arg) 2554 { 2555 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2556 { 2557 EMSG2(_(e_readonlyvar), arg); 2558 return TRUE; 2559 } 2560 return FALSE; 2561 } 2562 2563 /* 2564 * Get an lval: variable, Dict item or List item that can be assigned a value 2565 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2566 * "name.key", "name.key[expr]" etc. 2567 * Indexing only works if "name" is an existing List or Dictionary. 2568 * "name" points to the start of the name. 2569 * If "rettv" is not NULL it points to the value to be assigned. 2570 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2571 * wrong; must end in space or cmd separator. 2572 * 2573 * flags: 2574 * GLV_QUIET: do not give error messages 2575 * GLV_NO_AUTOLOAD: do not use script autoloading 2576 * 2577 * Returns a pointer to just after the name, including indexes. 2578 * When an evaluation error occurs "lp->ll_name" is NULL; 2579 * Returns NULL for a parsing error. Still need to free items in "lp"! 2580 */ 2581 static char_u * 2582 get_lval( 2583 char_u *name, 2584 typval_T *rettv, 2585 lval_T *lp, 2586 int unlet, 2587 int skip, 2588 int flags, /* GLV_ values */ 2589 int fne_flags) /* flags for find_name_end() */ 2590 { 2591 char_u *p; 2592 char_u *expr_start, *expr_end; 2593 int cc; 2594 dictitem_T *v; 2595 typval_T var1; 2596 typval_T var2; 2597 int empty1 = FALSE; 2598 listitem_T *ni; 2599 char_u *key = NULL; 2600 int len; 2601 hashtab_T *ht; 2602 int quiet = flags & GLV_QUIET; 2603 2604 /* Clear everything in "lp". */ 2605 vim_memset(lp, 0, sizeof(lval_T)); 2606 2607 if (skip) 2608 { 2609 /* When skipping just find the end of the name. */ 2610 lp->ll_name = name; 2611 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2612 } 2613 2614 /* Find the end of the name. */ 2615 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2616 if (expr_start != NULL) 2617 { 2618 /* Don't expand the name when we already know there is an error. */ 2619 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2620 && *p != '[' && *p != '.') 2621 { 2622 EMSG(_(e_trailing)); 2623 return NULL; 2624 } 2625 2626 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2627 if (lp->ll_exp_name == NULL) 2628 { 2629 /* Report an invalid expression in braces, unless the 2630 * expression evaluation has been cancelled due to an 2631 * aborting error, an interrupt, or an exception. */ 2632 if (!aborting() && !quiet) 2633 { 2634 emsg_severe = TRUE; 2635 EMSG2(_(e_invarg2), name); 2636 return NULL; 2637 } 2638 } 2639 lp->ll_name = lp->ll_exp_name; 2640 } 2641 else 2642 lp->ll_name = name; 2643 2644 /* Without [idx] or .key we are done. */ 2645 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2646 return p; 2647 2648 cc = *p; 2649 *p = NUL; 2650 v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD); 2651 if (v == NULL && !quiet) 2652 EMSG2(_(e_undefvar), lp->ll_name); 2653 *p = cc; 2654 if (v == NULL) 2655 return NULL; 2656 2657 /* 2658 * Loop until no more [idx] or .key is following. 2659 */ 2660 lp->ll_tv = &v->di_tv; 2661 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2662 { 2663 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2664 && !(lp->ll_tv->v_type == VAR_DICT 2665 && lp->ll_tv->vval.v_dict != NULL)) 2666 { 2667 if (!quiet) 2668 EMSG(_("E689: Can only index a List or Dictionary")); 2669 return NULL; 2670 } 2671 if (lp->ll_range) 2672 { 2673 if (!quiet) 2674 EMSG(_("E708: [:] must come last")); 2675 return NULL; 2676 } 2677 2678 len = -1; 2679 if (*p == '.') 2680 { 2681 key = p + 1; 2682 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2683 ; 2684 if (len == 0) 2685 { 2686 if (!quiet) 2687 EMSG(_(e_emptykey)); 2688 return NULL; 2689 } 2690 p = key + len; 2691 } 2692 else 2693 { 2694 /* Get the index [expr] or the first index [expr: ]. */ 2695 p = skipwhite(p + 1); 2696 if (*p == ':') 2697 empty1 = TRUE; 2698 else 2699 { 2700 empty1 = FALSE; 2701 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2702 return NULL; 2703 if (get_tv_string_chk(&var1) == NULL) 2704 { 2705 /* not a number or string */ 2706 clear_tv(&var1); 2707 return NULL; 2708 } 2709 } 2710 2711 /* Optionally get the second index [ :expr]. */ 2712 if (*p == ':') 2713 { 2714 if (lp->ll_tv->v_type == VAR_DICT) 2715 { 2716 if (!quiet) 2717 EMSG(_(e_dictrange)); 2718 if (!empty1) 2719 clear_tv(&var1); 2720 return NULL; 2721 } 2722 if (rettv != NULL && (rettv->v_type != VAR_LIST 2723 || rettv->vval.v_list == NULL)) 2724 { 2725 if (!quiet) 2726 EMSG(_("E709: [:] requires a List value")); 2727 if (!empty1) 2728 clear_tv(&var1); 2729 return NULL; 2730 } 2731 p = skipwhite(p + 1); 2732 if (*p == ']') 2733 lp->ll_empty2 = TRUE; 2734 else 2735 { 2736 lp->ll_empty2 = FALSE; 2737 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2738 { 2739 if (!empty1) 2740 clear_tv(&var1); 2741 return NULL; 2742 } 2743 if (get_tv_string_chk(&var2) == NULL) 2744 { 2745 /* not a number or string */ 2746 if (!empty1) 2747 clear_tv(&var1); 2748 clear_tv(&var2); 2749 return NULL; 2750 } 2751 } 2752 lp->ll_range = TRUE; 2753 } 2754 else 2755 lp->ll_range = FALSE; 2756 2757 if (*p != ']') 2758 { 2759 if (!quiet) 2760 EMSG(_(e_missbrac)); 2761 if (!empty1) 2762 clear_tv(&var1); 2763 if (lp->ll_range && !lp->ll_empty2) 2764 clear_tv(&var2); 2765 return NULL; 2766 } 2767 2768 /* Skip to past ']'. */ 2769 ++p; 2770 } 2771 2772 if (lp->ll_tv->v_type == VAR_DICT) 2773 { 2774 if (len == -1) 2775 { 2776 /* "[key]": get key from "var1" */ 2777 key = get_tv_string(&var1); /* is number or string */ 2778 if (*key == NUL) 2779 { 2780 if (!quiet) 2781 EMSG(_(e_emptykey)); 2782 clear_tv(&var1); 2783 return NULL; 2784 } 2785 } 2786 lp->ll_list = NULL; 2787 lp->ll_dict = lp->ll_tv->vval.v_dict; 2788 lp->ll_di = dict_find(lp->ll_dict, key, len); 2789 2790 /* When assigning to a scope dictionary check that a function and 2791 * variable name is valid (only variable name unless it is l: or 2792 * g: dictionary). Disallow overwriting a builtin function. */ 2793 if (rettv != NULL && lp->ll_dict->dv_scope != 0) 2794 { 2795 int prevval; 2796 int wrong; 2797 2798 if (len != -1) 2799 { 2800 prevval = key[len]; 2801 key[len] = NUL; 2802 } 2803 else 2804 prevval = 0; /* avoid compiler warning */ 2805 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE 2806 && rettv->v_type == VAR_FUNC 2807 && var_check_func_name(key, lp->ll_di == NULL)) 2808 || !valid_varname(key); 2809 if (len != -1) 2810 key[len] = prevval; 2811 if (wrong) 2812 return NULL; 2813 } 2814 2815 if (lp->ll_di == NULL) 2816 { 2817 /* Can't add "v:" variable. */ 2818 if (lp->ll_dict == &vimvardict) 2819 { 2820 EMSG2(_(e_illvar), name); 2821 return NULL; 2822 } 2823 2824 /* Key does not exist in dict: may need to add it. */ 2825 if (*p == '[' || *p == '.' || unlet) 2826 { 2827 if (!quiet) 2828 EMSG2(_(e_dictkey), key); 2829 if (len == -1) 2830 clear_tv(&var1); 2831 return NULL; 2832 } 2833 if (len == -1) 2834 lp->ll_newkey = vim_strsave(key); 2835 else 2836 lp->ll_newkey = vim_strnsave(key, len); 2837 if (len == -1) 2838 clear_tv(&var1); 2839 if (lp->ll_newkey == NULL) 2840 p = NULL; 2841 break; 2842 } 2843 /* existing variable, need to check if it can be changed */ 2844 else if (var_check_ro(lp->ll_di->di_flags, name, FALSE)) 2845 return NULL; 2846 2847 if (len == -1) 2848 clear_tv(&var1); 2849 lp->ll_tv = &lp->ll_di->di_tv; 2850 } 2851 else 2852 { 2853 /* 2854 * Get the number and item for the only or first index of the List. 2855 */ 2856 if (empty1) 2857 lp->ll_n1 = 0; 2858 else 2859 { 2860 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2861 clear_tv(&var1); 2862 } 2863 lp->ll_dict = NULL; 2864 lp->ll_list = lp->ll_tv->vval.v_list; 2865 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2866 if (lp->ll_li == NULL) 2867 { 2868 if (lp->ll_n1 < 0) 2869 { 2870 lp->ll_n1 = 0; 2871 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2872 } 2873 } 2874 if (lp->ll_li == NULL) 2875 { 2876 if (lp->ll_range && !lp->ll_empty2) 2877 clear_tv(&var2); 2878 if (!quiet) 2879 EMSGN(_(e_listidx), lp->ll_n1); 2880 return NULL; 2881 } 2882 2883 /* 2884 * May need to find the item or absolute index for the second 2885 * index of a range. 2886 * When no index given: "lp->ll_empty2" is TRUE. 2887 * Otherwise "lp->ll_n2" is set to the second index. 2888 */ 2889 if (lp->ll_range && !lp->ll_empty2) 2890 { 2891 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2892 clear_tv(&var2); 2893 if (lp->ll_n2 < 0) 2894 { 2895 ni = list_find(lp->ll_list, lp->ll_n2); 2896 if (ni == NULL) 2897 { 2898 if (!quiet) 2899 EMSGN(_(e_listidx), lp->ll_n2); 2900 return NULL; 2901 } 2902 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2903 } 2904 2905 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2906 if (lp->ll_n1 < 0) 2907 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2908 if (lp->ll_n2 < lp->ll_n1) 2909 { 2910 if (!quiet) 2911 EMSGN(_(e_listidx), lp->ll_n2); 2912 return NULL; 2913 } 2914 } 2915 2916 lp->ll_tv = &lp->ll_li->li_tv; 2917 } 2918 } 2919 2920 return p; 2921 } 2922 2923 /* 2924 * Clear lval "lp" that was filled by get_lval(). 2925 */ 2926 static void 2927 clear_lval(lval_T *lp) 2928 { 2929 vim_free(lp->ll_exp_name); 2930 vim_free(lp->ll_newkey); 2931 } 2932 2933 /* 2934 * Set a variable that was parsed by get_lval() to "rettv". 2935 * "endp" points to just after the parsed name. 2936 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2937 */ 2938 static void 2939 set_var_lval( 2940 lval_T *lp, 2941 char_u *endp, 2942 typval_T *rettv, 2943 int copy, 2944 char_u *op) 2945 { 2946 int cc; 2947 listitem_T *ri; 2948 dictitem_T *di; 2949 2950 if (lp->ll_tv == NULL) 2951 { 2952 if (!check_changedtick(lp->ll_name)) 2953 { 2954 cc = *endp; 2955 *endp = NUL; 2956 if (op != NULL && *op != '=') 2957 { 2958 typval_T tv; 2959 2960 /* handle +=, -= and .= */ 2961 di = NULL; 2962 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2963 &tv, &di, TRUE, FALSE) == OK) 2964 { 2965 if ((di == NULL 2966 || (!var_check_ro(di->di_flags, lp->ll_name, FALSE) 2967 && !tv_check_lock(di->di_tv.v_lock, lp->ll_name, 2968 FALSE))) 2969 && tv_op(&tv, rettv, op) == OK) 2970 set_var(lp->ll_name, &tv, FALSE); 2971 clear_tv(&tv); 2972 } 2973 } 2974 else 2975 set_var(lp->ll_name, rettv, copy); 2976 *endp = cc; 2977 } 2978 } 2979 else if (tv_check_lock(lp->ll_newkey == NULL 2980 ? lp->ll_tv->v_lock 2981 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) 2982 ; 2983 else if (lp->ll_range) 2984 { 2985 listitem_T *ll_li = lp->ll_li; 2986 int ll_n1 = lp->ll_n1; 2987 2988 /* 2989 * Check whether any of the list items is locked 2990 */ 2991 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) 2992 { 2993 if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) 2994 return; 2995 ri = ri->li_next; 2996 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1)) 2997 break; 2998 ll_li = ll_li->li_next; 2999 ++ll_n1; 3000 } 3001 3002 /* 3003 * Assign the List values to the list items. 3004 */ 3005 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 3006 { 3007 if (op != NULL && *op != '=') 3008 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 3009 else 3010 { 3011 clear_tv(&lp->ll_li->li_tv); 3012 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 3013 } 3014 ri = ri->li_next; 3015 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 3016 break; 3017 if (lp->ll_li->li_next == NULL) 3018 { 3019 /* Need to add an empty item. */ 3020 if (list_append_number(lp->ll_list, 0) == FAIL) 3021 { 3022 ri = NULL; 3023 break; 3024 } 3025 } 3026 lp->ll_li = lp->ll_li->li_next; 3027 ++lp->ll_n1; 3028 } 3029 if (ri != NULL) 3030 EMSG(_("E710: List value has more items than target")); 3031 else if (lp->ll_empty2 3032 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 3033 : lp->ll_n1 != lp->ll_n2) 3034 EMSG(_("E711: List value has not enough items")); 3035 } 3036 else 3037 { 3038 /* 3039 * Assign to a List or Dictionary item. 3040 */ 3041 if (lp->ll_newkey != NULL) 3042 { 3043 if (op != NULL && *op != '=') 3044 { 3045 EMSG2(_(e_letwrong), op); 3046 return; 3047 } 3048 3049 /* Need to add an item to the Dictionary. */ 3050 di = dictitem_alloc(lp->ll_newkey); 3051 if (di == NULL) 3052 return; 3053 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 3054 { 3055 vim_free(di); 3056 return; 3057 } 3058 lp->ll_tv = &di->di_tv; 3059 } 3060 else if (op != NULL && *op != '=') 3061 { 3062 tv_op(lp->ll_tv, rettv, op); 3063 return; 3064 } 3065 else 3066 clear_tv(lp->ll_tv); 3067 3068 /* 3069 * Assign the value to the variable or list item. 3070 */ 3071 if (copy) 3072 copy_tv(rettv, lp->ll_tv); 3073 else 3074 { 3075 *lp->ll_tv = *rettv; 3076 lp->ll_tv->v_lock = 0; 3077 init_tv(rettv); 3078 } 3079 } 3080 } 3081 3082 /* 3083 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 3084 * Returns OK or FAIL. 3085 */ 3086 static int 3087 tv_op(typval_T *tv1, typval_T *tv2, char_u *op) 3088 { 3089 long n; 3090 char_u numbuf[NUMBUFLEN]; 3091 char_u *s; 3092 3093 /* Can't do anything with a Funcref, Dict, v:true on the right. */ 3094 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT 3095 && tv2->v_type != VAR_SPECIAL) 3096 { 3097 switch (tv1->v_type) 3098 { 3099 case VAR_UNKNOWN: 3100 case VAR_DICT: 3101 case VAR_FUNC: 3102 case VAR_PARTIAL: 3103 case VAR_SPECIAL: 3104 case VAR_JOB: 3105 case VAR_CHANNEL: 3106 break; 3107 3108 case VAR_LIST: 3109 if (*op != '+' || tv2->v_type != VAR_LIST) 3110 break; 3111 /* List += List */ 3112 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 3113 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 3114 return OK; 3115 3116 case VAR_NUMBER: 3117 case VAR_STRING: 3118 if (tv2->v_type == VAR_LIST) 3119 break; 3120 if (*op == '+' || *op == '-') 3121 { 3122 /* nr += nr or nr -= nr*/ 3123 n = get_tv_number(tv1); 3124 #ifdef FEAT_FLOAT 3125 if (tv2->v_type == VAR_FLOAT) 3126 { 3127 float_T f = n; 3128 3129 if (*op == '+') 3130 f += tv2->vval.v_float; 3131 else 3132 f -= tv2->vval.v_float; 3133 clear_tv(tv1); 3134 tv1->v_type = VAR_FLOAT; 3135 tv1->vval.v_float = f; 3136 } 3137 else 3138 #endif 3139 { 3140 if (*op == '+') 3141 n += get_tv_number(tv2); 3142 else 3143 n -= get_tv_number(tv2); 3144 clear_tv(tv1); 3145 tv1->v_type = VAR_NUMBER; 3146 tv1->vval.v_number = n; 3147 } 3148 } 3149 else 3150 { 3151 if (tv2->v_type == VAR_FLOAT) 3152 break; 3153 3154 /* str .= str */ 3155 s = get_tv_string(tv1); 3156 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 3157 clear_tv(tv1); 3158 tv1->v_type = VAR_STRING; 3159 tv1->vval.v_string = s; 3160 } 3161 return OK; 3162 3163 case VAR_FLOAT: 3164 #ifdef FEAT_FLOAT 3165 { 3166 float_T f; 3167 3168 if (*op == '.' || (tv2->v_type != VAR_FLOAT 3169 && tv2->v_type != VAR_NUMBER 3170 && tv2->v_type != VAR_STRING)) 3171 break; 3172 if (tv2->v_type == VAR_FLOAT) 3173 f = tv2->vval.v_float; 3174 else 3175 f = get_tv_number(tv2); 3176 if (*op == '+') 3177 tv1->vval.v_float += f; 3178 else 3179 tv1->vval.v_float -= f; 3180 } 3181 #endif 3182 return OK; 3183 } 3184 } 3185 3186 EMSG2(_(e_letwrong), op); 3187 return FAIL; 3188 } 3189 3190 /* 3191 * Add a watcher to a list. 3192 */ 3193 void 3194 list_add_watch(list_T *l, listwatch_T *lw) 3195 { 3196 lw->lw_next = l->lv_watch; 3197 l->lv_watch = lw; 3198 } 3199 3200 /* 3201 * Remove a watcher from a list. 3202 * No warning when it isn't found... 3203 */ 3204 void 3205 list_rem_watch(list_T *l, listwatch_T *lwrem) 3206 { 3207 listwatch_T *lw, **lwp; 3208 3209 lwp = &l->lv_watch; 3210 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3211 { 3212 if (lw == lwrem) 3213 { 3214 *lwp = lw->lw_next; 3215 break; 3216 } 3217 lwp = &lw->lw_next; 3218 } 3219 } 3220 3221 /* 3222 * Just before removing an item from a list: advance watchers to the next 3223 * item. 3224 */ 3225 static void 3226 list_fix_watch(list_T *l, listitem_T *item) 3227 { 3228 listwatch_T *lw; 3229 3230 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3231 if (lw->lw_item == item) 3232 lw->lw_item = item->li_next; 3233 } 3234 3235 /* 3236 * Evaluate the expression used in a ":for var in expr" command. 3237 * "arg" points to "var". 3238 * Set "*errp" to TRUE for an error, FALSE otherwise; 3239 * Return a pointer that holds the info. Null when there is an error. 3240 */ 3241 void * 3242 eval_for_line( 3243 char_u *arg, 3244 int *errp, 3245 char_u **nextcmdp, 3246 int skip) 3247 { 3248 forinfo_T *fi; 3249 char_u *expr; 3250 typval_T tv; 3251 list_T *l; 3252 3253 *errp = TRUE; /* default: there is an error */ 3254 3255 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3256 if (fi == NULL) 3257 return NULL; 3258 3259 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3260 if (expr == NULL) 3261 return fi; 3262 3263 expr = skipwhite(expr); 3264 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3265 { 3266 EMSG(_("E690: Missing \"in\" after :for")); 3267 return fi; 3268 } 3269 3270 if (skip) 3271 ++emsg_skip; 3272 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3273 { 3274 *errp = FALSE; 3275 if (!skip) 3276 { 3277 l = tv.vval.v_list; 3278 if (tv.v_type != VAR_LIST || l == NULL) 3279 { 3280 EMSG(_(e_listreq)); 3281 clear_tv(&tv); 3282 } 3283 else 3284 { 3285 /* No need to increment the refcount, it's already set for the 3286 * list being used in "tv". */ 3287 fi->fi_list = l; 3288 list_add_watch(l, &fi->fi_lw); 3289 fi->fi_lw.lw_item = l->lv_first; 3290 } 3291 } 3292 } 3293 if (skip) 3294 --emsg_skip; 3295 3296 return fi; 3297 } 3298 3299 /* 3300 * Use the first item in a ":for" list. Advance to the next. 3301 * Assign the values to the variable (list). "arg" points to the first one. 3302 * Return TRUE when a valid item was found, FALSE when at end of list or 3303 * something wrong. 3304 */ 3305 int 3306 next_for_item(void *fi_void, char_u *arg) 3307 { 3308 forinfo_T *fi = (forinfo_T *)fi_void; 3309 int result; 3310 listitem_T *item; 3311 3312 item = fi->fi_lw.lw_item; 3313 if (item == NULL) 3314 result = FALSE; 3315 else 3316 { 3317 fi->fi_lw.lw_item = item->li_next; 3318 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3319 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3320 } 3321 return result; 3322 } 3323 3324 /* 3325 * Free the structure used to store info used by ":for". 3326 */ 3327 void 3328 free_for_info(void *fi_void) 3329 { 3330 forinfo_T *fi = (forinfo_T *)fi_void; 3331 3332 if (fi != NULL && fi->fi_list != NULL) 3333 { 3334 list_rem_watch(fi->fi_list, &fi->fi_lw); 3335 list_unref(fi->fi_list); 3336 } 3337 vim_free(fi); 3338 } 3339 3340 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3341 3342 void 3343 set_context_for_expression( 3344 expand_T *xp, 3345 char_u *arg, 3346 cmdidx_T cmdidx) 3347 { 3348 int got_eq = FALSE; 3349 int c; 3350 char_u *p; 3351 3352 if (cmdidx == CMD_let) 3353 { 3354 xp->xp_context = EXPAND_USER_VARS; 3355 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3356 { 3357 /* ":let var1 var2 ...": find last space. */ 3358 for (p = arg + STRLEN(arg); p >= arg; ) 3359 { 3360 xp->xp_pattern = p; 3361 mb_ptr_back(arg, p); 3362 if (vim_iswhite(*p)) 3363 break; 3364 } 3365 return; 3366 } 3367 } 3368 else 3369 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3370 : EXPAND_EXPRESSION; 3371 while ((xp->xp_pattern = vim_strpbrk(arg, 3372 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3373 { 3374 c = *xp->xp_pattern; 3375 if (c == '&') 3376 { 3377 c = xp->xp_pattern[1]; 3378 if (c == '&') 3379 { 3380 ++xp->xp_pattern; 3381 xp->xp_context = cmdidx != CMD_let || got_eq 3382 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3383 } 3384 else if (c != ' ') 3385 { 3386 xp->xp_context = EXPAND_SETTINGS; 3387 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3388 xp->xp_pattern += 2; 3389 3390 } 3391 } 3392 else if (c == '$') 3393 { 3394 /* environment variable */ 3395 xp->xp_context = EXPAND_ENV_VARS; 3396 } 3397 else if (c == '=') 3398 { 3399 got_eq = TRUE; 3400 xp->xp_context = EXPAND_EXPRESSION; 3401 } 3402 else if (c == '#' 3403 && xp->xp_context == EXPAND_EXPRESSION) 3404 { 3405 /* Autoload function/variable contains '#'. */ 3406 break; 3407 } 3408 else if ((c == '<' || c == '#') 3409 && xp->xp_context == EXPAND_FUNCTIONS 3410 && vim_strchr(xp->xp_pattern, '(') == NULL) 3411 { 3412 /* Function name can start with "<SNR>" and contain '#'. */ 3413 break; 3414 } 3415 else if (cmdidx != CMD_let || got_eq) 3416 { 3417 if (c == '"') /* string */ 3418 { 3419 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3420 if (c == '\\' && xp->xp_pattern[1] != NUL) 3421 ++xp->xp_pattern; 3422 xp->xp_context = EXPAND_NOTHING; 3423 } 3424 else if (c == '\'') /* literal string */ 3425 { 3426 /* Trick: '' is like stopping and starting a literal string. */ 3427 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3428 /* skip */ ; 3429 xp->xp_context = EXPAND_NOTHING; 3430 } 3431 else if (c == '|') 3432 { 3433 if (xp->xp_pattern[1] == '|') 3434 { 3435 ++xp->xp_pattern; 3436 xp->xp_context = EXPAND_EXPRESSION; 3437 } 3438 else 3439 xp->xp_context = EXPAND_COMMANDS; 3440 } 3441 else 3442 xp->xp_context = EXPAND_EXPRESSION; 3443 } 3444 else 3445 /* Doesn't look like something valid, expand as an expression 3446 * anyway. */ 3447 xp->xp_context = EXPAND_EXPRESSION; 3448 arg = xp->xp_pattern; 3449 if (*arg != NUL) 3450 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3451 /* skip */ ; 3452 } 3453 xp->xp_pattern = arg; 3454 } 3455 3456 #endif /* FEAT_CMDL_COMPL */ 3457 3458 /* 3459 * ":1,25call func(arg1, arg2)" function call. 3460 */ 3461 void 3462 ex_call(exarg_T *eap) 3463 { 3464 char_u *arg = eap->arg; 3465 char_u *startarg; 3466 char_u *name; 3467 char_u *tofree; 3468 int len; 3469 typval_T rettv; 3470 linenr_T lnum; 3471 int doesrange; 3472 int failed = FALSE; 3473 funcdict_T fudi; 3474 partial_T *partial = NULL; 3475 3476 if (eap->skip) 3477 { 3478 /* trans_function_name() doesn't work well when skipping, use eval0() 3479 * instead to skip to any following command, e.g. for: 3480 * :if 0 | call dict.foo().bar() | endif */ 3481 ++emsg_skip; 3482 if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL) 3483 clear_tv(&rettv); 3484 --emsg_skip; 3485 return; 3486 } 3487 3488 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial); 3489 if (fudi.fd_newkey != NULL) 3490 { 3491 /* Still need to give an error message for missing key. */ 3492 EMSG2(_(e_dictkey), fudi.fd_newkey); 3493 vim_free(fudi.fd_newkey); 3494 } 3495 if (tofree == NULL) 3496 return; 3497 3498 /* Increase refcount on dictionary, it could get deleted when evaluating 3499 * the arguments. */ 3500 if (fudi.fd_dict != NULL) 3501 ++fudi.fd_dict->dv_refcount; 3502 3503 /* If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its 3504 * contents. For VAR_PARTIAL get its partial, unless we already have one 3505 * from trans_function_name(). */ 3506 len = (int)STRLEN(tofree); 3507 name = deref_func_name(tofree, &len, 3508 partial != NULL ? NULL : &partial, FALSE); 3509 3510 /* Skip white space to allow ":call func ()". Not good, but required for 3511 * backward compatibility. */ 3512 startarg = skipwhite(arg); 3513 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3514 3515 if (*startarg != '(') 3516 { 3517 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3518 goto end; 3519 } 3520 3521 /* 3522 * When skipping, evaluate the function once, to find the end of the 3523 * arguments. 3524 * When the function takes a range, this is discovered after the first 3525 * call, and the loop is broken. 3526 */ 3527 if (eap->skip) 3528 { 3529 ++emsg_skip; 3530 lnum = eap->line2; /* do it once, also with an invalid range */ 3531 } 3532 else 3533 lnum = eap->line1; 3534 for ( ; lnum <= eap->line2; ++lnum) 3535 { 3536 if (!eap->skip && eap->addr_count > 0) 3537 { 3538 curwin->w_cursor.lnum = lnum; 3539 curwin->w_cursor.col = 0; 3540 #ifdef FEAT_VIRTUALEDIT 3541 curwin->w_cursor.coladd = 0; 3542 #endif 3543 } 3544 arg = startarg; 3545 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3546 eap->line1, eap->line2, &doesrange, 3547 !eap->skip, partial, fudi.fd_dict) == FAIL) 3548 { 3549 failed = TRUE; 3550 break; 3551 } 3552 3553 /* Handle a function returning a Funcref, Dictionary or List. */ 3554 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3555 { 3556 failed = TRUE; 3557 break; 3558 } 3559 3560 clear_tv(&rettv); 3561 if (doesrange || eap->skip) 3562 break; 3563 3564 /* Stop when immediately aborting on error, or when an interrupt 3565 * occurred or an exception was thrown but not caught. 3566 * get_func_tv() returned OK, so that the check for trailing 3567 * characters below is executed. */ 3568 if (aborting()) 3569 break; 3570 } 3571 if (eap->skip) 3572 --emsg_skip; 3573 3574 if (!failed) 3575 { 3576 /* Check for trailing illegal characters and a following command. */ 3577 if (!ends_excmd(*arg)) 3578 { 3579 emsg_severe = TRUE; 3580 EMSG(_(e_trailing)); 3581 } 3582 else 3583 eap->nextcmd = check_nextcmd(arg); 3584 } 3585 3586 end: 3587 dict_unref(fudi.fd_dict); 3588 vim_free(tofree); 3589 } 3590 3591 /* 3592 * ":unlet[!] var1 ... " command. 3593 */ 3594 void 3595 ex_unlet(exarg_T *eap) 3596 { 3597 ex_unletlock(eap, eap->arg, 0); 3598 } 3599 3600 /* 3601 * ":lockvar" and ":unlockvar" commands 3602 */ 3603 void 3604 ex_lockvar(exarg_T *eap) 3605 { 3606 char_u *arg = eap->arg; 3607 int deep = 2; 3608 3609 if (eap->forceit) 3610 deep = -1; 3611 else if (vim_isdigit(*arg)) 3612 { 3613 deep = getdigits(&arg); 3614 arg = skipwhite(arg); 3615 } 3616 3617 ex_unletlock(eap, arg, deep); 3618 } 3619 3620 /* 3621 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3622 */ 3623 static void 3624 ex_unletlock( 3625 exarg_T *eap, 3626 char_u *argstart, 3627 int deep) 3628 { 3629 char_u *arg = argstart; 3630 char_u *name_end; 3631 int error = FALSE; 3632 lval_T lv; 3633 3634 do 3635 { 3636 /* Parse the name and find the end. */ 3637 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, 3638 FNE_CHECK_START); 3639 if (lv.ll_name == NULL) 3640 error = TRUE; /* error but continue parsing */ 3641 if (name_end == NULL || (!vim_iswhite(*name_end) 3642 && !ends_excmd(*name_end))) 3643 { 3644 if (name_end != NULL) 3645 { 3646 emsg_severe = TRUE; 3647 EMSG(_(e_trailing)); 3648 } 3649 if (!(eap->skip || error)) 3650 clear_lval(&lv); 3651 break; 3652 } 3653 3654 if (!error && !eap->skip) 3655 { 3656 if (eap->cmdidx == CMD_unlet) 3657 { 3658 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3659 error = TRUE; 3660 } 3661 else 3662 { 3663 if (do_lock_var(&lv, name_end, deep, 3664 eap->cmdidx == CMD_lockvar) == FAIL) 3665 error = TRUE; 3666 } 3667 } 3668 3669 if (!eap->skip) 3670 clear_lval(&lv); 3671 3672 arg = skipwhite(name_end); 3673 } while (!ends_excmd(*arg)); 3674 3675 eap->nextcmd = check_nextcmd(arg); 3676 } 3677 3678 static int 3679 do_unlet_var( 3680 lval_T *lp, 3681 char_u *name_end, 3682 int forceit) 3683 { 3684 int ret = OK; 3685 int cc; 3686 3687 if (lp->ll_tv == NULL) 3688 { 3689 cc = *name_end; 3690 *name_end = NUL; 3691 3692 /* Normal name or expanded name. */ 3693 if (check_changedtick(lp->ll_name)) 3694 ret = FAIL; 3695 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3696 ret = FAIL; 3697 *name_end = cc; 3698 } 3699 else if ((lp->ll_list != NULL 3700 && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) 3701 || (lp->ll_dict != NULL 3702 && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) 3703 return FAIL; 3704 else if (lp->ll_range) 3705 { 3706 listitem_T *li; 3707 listitem_T *ll_li = lp->ll_li; 3708 int ll_n1 = lp->ll_n1; 3709 3710 while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) 3711 { 3712 li = ll_li->li_next; 3713 if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) 3714 return FAIL; 3715 ll_li = li; 3716 ++ll_n1; 3717 } 3718 3719 /* Delete a range of List items. */ 3720 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3721 { 3722 li = lp->ll_li->li_next; 3723 listitem_remove(lp->ll_list, lp->ll_li); 3724 lp->ll_li = li; 3725 ++lp->ll_n1; 3726 } 3727 } 3728 else 3729 { 3730 if (lp->ll_list != NULL) 3731 /* unlet a List item. */ 3732 listitem_remove(lp->ll_list, lp->ll_li); 3733 else 3734 /* unlet a Dictionary item. */ 3735 dictitem_remove(lp->ll_dict, lp->ll_di); 3736 } 3737 3738 return ret; 3739 } 3740 3741 /* 3742 * "unlet" a variable. Return OK if it existed, FAIL if not. 3743 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3744 */ 3745 int 3746 do_unlet(char_u *name, int forceit) 3747 { 3748 hashtab_T *ht; 3749 hashitem_T *hi; 3750 char_u *varname; 3751 dict_T *d; 3752 dictitem_T *di; 3753 3754 ht = find_var_ht(name, &varname); 3755 if (ht != NULL && *varname != NUL) 3756 { 3757 if (ht == &globvarht) 3758 d = &globvardict; 3759 else if (current_funccal != NULL 3760 && ht == ¤t_funccal->l_vars.dv_hashtab) 3761 d = ¤t_funccal->l_vars; 3762 else if (ht == &compat_hashtab) 3763 d = &vimvardict; 3764 else 3765 { 3766 di = find_var_in_ht(ht, *name, (char_u *)"", FALSE); 3767 d = di == NULL ? NULL : di->di_tv.vval.v_dict; 3768 } 3769 if (d == NULL) 3770 { 3771 EMSG2(_(e_intern2), "do_unlet()"); 3772 return FAIL; 3773 } 3774 hi = hash_find(ht, varname); 3775 if (!HASHITEM_EMPTY(hi)) 3776 { 3777 di = HI2DI(hi); 3778 if (var_check_fixed(di->di_flags, name, FALSE) 3779 || var_check_ro(di->di_flags, name, FALSE) 3780 || tv_check_lock(d->dv_lock, name, FALSE)) 3781 return FAIL; 3782 3783 delete_var(ht, hi); 3784 return OK; 3785 } 3786 } 3787 if (forceit) 3788 return OK; 3789 EMSG2(_("E108: No such variable: \"%s\""), name); 3790 return FAIL; 3791 } 3792 3793 /* 3794 * Lock or unlock variable indicated by "lp". 3795 * "deep" is the levels to go (-1 for unlimited); 3796 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3797 */ 3798 static int 3799 do_lock_var( 3800 lval_T *lp, 3801 char_u *name_end, 3802 int deep, 3803 int lock) 3804 { 3805 int ret = OK; 3806 int cc; 3807 dictitem_T *di; 3808 3809 if (deep == 0) /* nothing to do */ 3810 return OK; 3811 3812 if (lp->ll_tv == NULL) 3813 { 3814 cc = *name_end; 3815 *name_end = NUL; 3816 3817 /* Normal name or expanded name. */ 3818 if (check_changedtick(lp->ll_name)) 3819 ret = FAIL; 3820 else 3821 { 3822 di = find_var(lp->ll_name, NULL, TRUE); 3823 if (di == NULL) 3824 ret = FAIL; 3825 else 3826 { 3827 if (lock) 3828 di->di_flags |= DI_FLAGS_LOCK; 3829 else 3830 di->di_flags &= ~DI_FLAGS_LOCK; 3831 item_lock(&di->di_tv, deep, lock); 3832 } 3833 } 3834 *name_end = cc; 3835 } 3836 else if (lp->ll_range) 3837 { 3838 listitem_T *li = lp->ll_li; 3839 3840 /* (un)lock a range of List items. */ 3841 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3842 { 3843 item_lock(&li->li_tv, deep, lock); 3844 li = li->li_next; 3845 ++lp->ll_n1; 3846 } 3847 } 3848 else if (lp->ll_list != NULL) 3849 /* (un)lock a List item. */ 3850 item_lock(&lp->ll_li->li_tv, deep, lock); 3851 else 3852 /* (un)lock a Dictionary item. */ 3853 item_lock(&lp->ll_di->di_tv, deep, lock); 3854 3855 return ret; 3856 } 3857 3858 /* 3859 * Lock or unlock an item. "deep" is nr of levels to go. 3860 */ 3861 static void 3862 item_lock(typval_T *tv, int deep, int lock) 3863 { 3864 static int recurse = 0; 3865 list_T *l; 3866 listitem_T *li; 3867 dict_T *d; 3868 hashitem_T *hi; 3869 int todo; 3870 3871 if (recurse >= DICT_MAXNEST) 3872 { 3873 EMSG(_("E743: variable nested too deep for (un)lock")); 3874 return; 3875 } 3876 if (deep == 0) 3877 return; 3878 ++recurse; 3879 3880 /* lock/unlock the item itself */ 3881 if (lock) 3882 tv->v_lock |= VAR_LOCKED; 3883 else 3884 tv->v_lock &= ~VAR_LOCKED; 3885 3886 switch (tv->v_type) 3887 { 3888 case VAR_UNKNOWN: 3889 case VAR_NUMBER: 3890 case VAR_STRING: 3891 case VAR_FUNC: 3892 case VAR_PARTIAL: 3893 case VAR_FLOAT: 3894 case VAR_SPECIAL: 3895 case VAR_JOB: 3896 case VAR_CHANNEL: 3897 break; 3898 3899 case VAR_LIST: 3900 if ((l = tv->vval.v_list) != NULL) 3901 { 3902 if (lock) 3903 l->lv_lock |= VAR_LOCKED; 3904 else 3905 l->lv_lock &= ~VAR_LOCKED; 3906 if (deep < 0 || deep > 1) 3907 /* recursive: lock/unlock the items the List contains */ 3908 for (li = l->lv_first; li != NULL; li = li->li_next) 3909 item_lock(&li->li_tv, deep - 1, lock); 3910 } 3911 break; 3912 case VAR_DICT: 3913 if ((d = tv->vval.v_dict) != NULL) 3914 { 3915 if (lock) 3916 d->dv_lock |= VAR_LOCKED; 3917 else 3918 d->dv_lock &= ~VAR_LOCKED; 3919 if (deep < 0 || deep > 1) 3920 { 3921 /* recursive: lock/unlock the items the List contains */ 3922 todo = (int)d->dv_hashtab.ht_used; 3923 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3924 { 3925 if (!HASHITEM_EMPTY(hi)) 3926 { 3927 --todo; 3928 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3929 } 3930 } 3931 } 3932 } 3933 } 3934 --recurse; 3935 } 3936 3937 /* 3938 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3939 * or it refers to a List or Dictionary that is locked. 3940 */ 3941 static int 3942 tv_islocked(typval_T *tv) 3943 { 3944 return (tv->v_lock & VAR_LOCKED) 3945 || (tv->v_type == VAR_LIST 3946 && tv->vval.v_list != NULL 3947 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3948 || (tv->v_type == VAR_DICT 3949 && tv->vval.v_dict != NULL 3950 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3951 } 3952 3953 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3954 /* 3955 * Delete all "menutrans_" variables. 3956 */ 3957 void 3958 del_menutrans_vars(void) 3959 { 3960 hashitem_T *hi; 3961 int todo; 3962 3963 hash_lock(&globvarht); 3964 todo = (int)globvarht.ht_used; 3965 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3966 { 3967 if (!HASHITEM_EMPTY(hi)) 3968 { 3969 --todo; 3970 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3971 delete_var(&globvarht, hi); 3972 } 3973 } 3974 hash_unlock(&globvarht); 3975 } 3976 #endif 3977 3978 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3979 3980 /* 3981 * Local string buffer for the next two functions to store a variable name 3982 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3983 * get_user_var_name(). 3984 */ 3985 3986 static char_u *cat_prefix_varname(int prefix, char_u *name); 3987 3988 static char_u *varnamebuf = NULL; 3989 static int varnamebuflen = 0; 3990 3991 /* 3992 * Function to concatenate a prefix and a variable name. 3993 */ 3994 static char_u * 3995 cat_prefix_varname(int prefix, char_u *name) 3996 { 3997 int len; 3998 3999 len = (int)STRLEN(name) + 3; 4000 if (len > varnamebuflen) 4001 { 4002 vim_free(varnamebuf); 4003 len += 10; /* some additional space */ 4004 varnamebuf = alloc(len); 4005 if (varnamebuf == NULL) 4006 { 4007 varnamebuflen = 0; 4008 return NULL; 4009 } 4010 varnamebuflen = len; 4011 } 4012 *varnamebuf = prefix; 4013 varnamebuf[1] = ':'; 4014 STRCPY(varnamebuf + 2, name); 4015 return varnamebuf; 4016 } 4017 4018 /* 4019 * Function given to ExpandGeneric() to obtain the list of user defined 4020 * (global/buffer/window/built-in) variable names. 4021 */ 4022 char_u * 4023 get_user_var_name(expand_T *xp, int idx) 4024 { 4025 static long_u gdone; 4026 static long_u bdone; 4027 static long_u wdone; 4028 #ifdef FEAT_WINDOWS 4029 static long_u tdone; 4030 #endif 4031 static int vidx; 4032 static hashitem_T *hi; 4033 hashtab_T *ht; 4034 4035 if (idx == 0) 4036 { 4037 gdone = bdone = wdone = vidx = 0; 4038 #ifdef FEAT_WINDOWS 4039 tdone = 0; 4040 #endif 4041 } 4042 4043 /* Global variables */ 4044 if (gdone < globvarht.ht_used) 4045 { 4046 if (gdone++ == 0) 4047 hi = globvarht.ht_array; 4048 else 4049 ++hi; 4050 while (HASHITEM_EMPTY(hi)) 4051 ++hi; 4052 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 4053 return cat_prefix_varname('g', hi->hi_key); 4054 return hi->hi_key; 4055 } 4056 4057 /* b: variables */ 4058 ht = &curbuf->b_vars->dv_hashtab; 4059 if (bdone < ht->ht_used) 4060 { 4061 if (bdone++ == 0) 4062 hi = ht->ht_array; 4063 else 4064 ++hi; 4065 while (HASHITEM_EMPTY(hi)) 4066 ++hi; 4067 return cat_prefix_varname('b', hi->hi_key); 4068 } 4069 if (bdone == ht->ht_used) 4070 { 4071 ++bdone; 4072 return (char_u *)"b:changedtick"; 4073 } 4074 4075 /* w: variables */ 4076 ht = &curwin->w_vars->dv_hashtab; 4077 if (wdone < ht->ht_used) 4078 { 4079 if (wdone++ == 0) 4080 hi = ht->ht_array; 4081 else 4082 ++hi; 4083 while (HASHITEM_EMPTY(hi)) 4084 ++hi; 4085 return cat_prefix_varname('w', hi->hi_key); 4086 } 4087 4088 #ifdef FEAT_WINDOWS 4089 /* t: variables */ 4090 ht = &curtab->tp_vars->dv_hashtab; 4091 if (tdone < ht->ht_used) 4092 { 4093 if (tdone++ == 0) 4094 hi = ht->ht_array; 4095 else 4096 ++hi; 4097 while (HASHITEM_EMPTY(hi)) 4098 ++hi; 4099 return cat_prefix_varname('t', hi->hi_key); 4100 } 4101 #endif 4102 4103 /* v: variables */ 4104 if (vidx < VV_LEN) 4105 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 4106 4107 vim_free(varnamebuf); 4108 varnamebuf = NULL; 4109 varnamebuflen = 0; 4110 return NULL; 4111 } 4112 4113 #endif /* FEAT_CMDL_COMPL */ 4114 4115 /* 4116 * Return TRUE if "pat" matches "text". 4117 * Does not use 'cpo' and always uses 'magic'. 4118 */ 4119 static int 4120 pattern_match(char_u *pat, char_u *text, int ic) 4121 { 4122 int matches = FALSE; 4123 char_u *save_cpo; 4124 regmatch_T regmatch; 4125 4126 /* avoid 'l' flag in 'cpoptions' */ 4127 save_cpo = p_cpo; 4128 p_cpo = (char_u *)""; 4129 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 4130 if (regmatch.regprog != NULL) 4131 { 4132 regmatch.rm_ic = ic; 4133 matches = vim_regexec_nl(®match, text, (colnr_T)0); 4134 vim_regfree(regmatch.regprog); 4135 } 4136 p_cpo = save_cpo; 4137 return matches; 4138 } 4139 4140 /* 4141 * types for expressions. 4142 */ 4143 typedef enum 4144 { 4145 TYPE_UNKNOWN = 0 4146 , TYPE_EQUAL /* == */ 4147 , TYPE_NEQUAL /* != */ 4148 , TYPE_GREATER /* > */ 4149 , TYPE_GEQUAL /* >= */ 4150 , TYPE_SMALLER /* < */ 4151 , TYPE_SEQUAL /* <= */ 4152 , TYPE_MATCH /* =~ */ 4153 , TYPE_NOMATCH /* !~ */ 4154 } exptype_T; 4155 4156 /* 4157 * The "evaluate" argument: When FALSE, the argument is only parsed but not 4158 * executed. The function may return OK, but the rettv will be of type 4159 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 4160 */ 4161 4162 /* 4163 * Handle zero level expression. 4164 * This calls eval1() and handles error message and nextcmd. 4165 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 4166 * Note: "rettv.v_lock" is not set. 4167 * Return OK or FAIL. 4168 */ 4169 static int 4170 eval0( 4171 char_u *arg, 4172 typval_T *rettv, 4173 char_u **nextcmd, 4174 int evaluate) 4175 { 4176 int ret; 4177 char_u *p; 4178 4179 p = skipwhite(arg); 4180 ret = eval1(&p, rettv, evaluate); 4181 if (ret == FAIL || !ends_excmd(*p)) 4182 { 4183 if (ret != FAIL) 4184 clear_tv(rettv); 4185 /* 4186 * Report the invalid expression unless the expression evaluation has 4187 * been cancelled due to an aborting error, an interrupt, or an 4188 * exception. 4189 */ 4190 if (!aborting()) 4191 EMSG2(_(e_invexpr2), arg); 4192 ret = FAIL; 4193 } 4194 if (nextcmd != NULL) 4195 *nextcmd = check_nextcmd(p); 4196 4197 return ret; 4198 } 4199 4200 /* 4201 * Handle top level expression: 4202 * expr2 ? expr1 : expr1 4203 * 4204 * "arg" must point to the first non-white of the expression. 4205 * "arg" is advanced to the next non-white after the recognized expression. 4206 * 4207 * Note: "rettv.v_lock" is not set. 4208 * 4209 * Return OK or FAIL. 4210 */ 4211 static int 4212 eval1(char_u **arg, typval_T *rettv, int evaluate) 4213 { 4214 int result; 4215 typval_T var2; 4216 4217 /* 4218 * Get the first variable. 4219 */ 4220 if (eval2(arg, rettv, evaluate) == FAIL) 4221 return FAIL; 4222 4223 if ((*arg)[0] == '?') 4224 { 4225 result = FALSE; 4226 if (evaluate) 4227 { 4228 int error = FALSE; 4229 4230 if (get_tv_number_chk(rettv, &error) != 0) 4231 result = TRUE; 4232 clear_tv(rettv); 4233 if (error) 4234 return FAIL; 4235 } 4236 4237 /* 4238 * Get the second variable. 4239 */ 4240 *arg = skipwhite(*arg + 1); 4241 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 4242 return FAIL; 4243 4244 /* 4245 * Check for the ":". 4246 */ 4247 if ((*arg)[0] != ':') 4248 { 4249 EMSG(_("E109: Missing ':' after '?'")); 4250 if (evaluate && result) 4251 clear_tv(rettv); 4252 return FAIL; 4253 } 4254 4255 /* 4256 * Get the third variable. 4257 */ 4258 *arg = skipwhite(*arg + 1); 4259 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4260 { 4261 if (evaluate && result) 4262 clear_tv(rettv); 4263 return FAIL; 4264 } 4265 if (evaluate && !result) 4266 *rettv = var2; 4267 } 4268 4269 return OK; 4270 } 4271 4272 /* 4273 * Handle first level expression: 4274 * expr2 || expr2 || expr2 logical OR 4275 * 4276 * "arg" must point to the first non-white of the expression. 4277 * "arg" is advanced to the next non-white after the recognized expression. 4278 * 4279 * Return OK or FAIL. 4280 */ 4281 static int 4282 eval2(char_u **arg, typval_T *rettv, int evaluate) 4283 { 4284 typval_T var2; 4285 long result; 4286 int first; 4287 int error = FALSE; 4288 4289 /* 4290 * Get the first variable. 4291 */ 4292 if (eval3(arg, rettv, evaluate) == FAIL) 4293 return FAIL; 4294 4295 /* 4296 * Repeat until there is no following "||". 4297 */ 4298 first = TRUE; 4299 result = FALSE; 4300 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4301 { 4302 if (evaluate && first) 4303 { 4304 if (get_tv_number_chk(rettv, &error) != 0) 4305 result = TRUE; 4306 clear_tv(rettv); 4307 if (error) 4308 return FAIL; 4309 first = FALSE; 4310 } 4311 4312 /* 4313 * Get the second variable. 4314 */ 4315 *arg = skipwhite(*arg + 2); 4316 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4317 return FAIL; 4318 4319 /* 4320 * Compute the result. 4321 */ 4322 if (evaluate && !result) 4323 { 4324 if (get_tv_number_chk(&var2, &error) != 0) 4325 result = TRUE; 4326 clear_tv(&var2); 4327 if (error) 4328 return FAIL; 4329 } 4330 if (evaluate) 4331 { 4332 rettv->v_type = VAR_NUMBER; 4333 rettv->vval.v_number = result; 4334 } 4335 } 4336 4337 return OK; 4338 } 4339 4340 /* 4341 * Handle second level expression: 4342 * expr3 && expr3 && expr3 logical AND 4343 * 4344 * "arg" must point to the first non-white of the expression. 4345 * "arg" is advanced to the next non-white after the recognized expression. 4346 * 4347 * Return OK or FAIL. 4348 */ 4349 static int 4350 eval3(char_u **arg, typval_T *rettv, int evaluate) 4351 { 4352 typval_T var2; 4353 long result; 4354 int first; 4355 int error = FALSE; 4356 4357 /* 4358 * Get the first variable. 4359 */ 4360 if (eval4(arg, rettv, evaluate) == FAIL) 4361 return FAIL; 4362 4363 /* 4364 * Repeat until there is no following "&&". 4365 */ 4366 first = TRUE; 4367 result = TRUE; 4368 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4369 { 4370 if (evaluate && first) 4371 { 4372 if (get_tv_number_chk(rettv, &error) == 0) 4373 result = FALSE; 4374 clear_tv(rettv); 4375 if (error) 4376 return FAIL; 4377 first = FALSE; 4378 } 4379 4380 /* 4381 * Get the second variable. 4382 */ 4383 *arg = skipwhite(*arg + 2); 4384 if (eval4(arg, &var2, evaluate && result) == FAIL) 4385 return FAIL; 4386 4387 /* 4388 * Compute the result. 4389 */ 4390 if (evaluate && result) 4391 { 4392 if (get_tv_number_chk(&var2, &error) == 0) 4393 result = FALSE; 4394 clear_tv(&var2); 4395 if (error) 4396 return FAIL; 4397 } 4398 if (evaluate) 4399 { 4400 rettv->v_type = VAR_NUMBER; 4401 rettv->vval.v_number = result; 4402 } 4403 } 4404 4405 return OK; 4406 } 4407 4408 /* 4409 * Handle third level expression: 4410 * var1 == var2 4411 * var1 =~ var2 4412 * var1 != var2 4413 * var1 !~ var2 4414 * var1 > var2 4415 * var1 >= var2 4416 * var1 < var2 4417 * var1 <= var2 4418 * var1 is var2 4419 * var1 isnot var2 4420 * 4421 * "arg" must point to the first non-white of the expression. 4422 * "arg" is advanced to the next non-white after the recognized expression. 4423 * 4424 * Return OK or FAIL. 4425 */ 4426 static int 4427 eval4(char_u **arg, typval_T *rettv, int evaluate) 4428 { 4429 typval_T var2; 4430 char_u *p; 4431 int i; 4432 exptype_T type = TYPE_UNKNOWN; 4433 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4434 int len = 2; 4435 long n1, n2; 4436 char_u *s1, *s2; 4437 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4438 int ic; 4439 4440 /* 4441 * Get the first variable. 4442 */ 4443 if (eval5(arg, rettv, evaluate) == FAIL) 4444 return FAIL; 4445 4446 p = *arg; 4447 switch (p[0]) 4448 { 4449 case '=': if (p[1] == '=') 4450 type = TYPE_EQUAL; 4451 else if (p[1] == '~') 4452 type = TYPE_MATCH; 4453 break; 4454 case '!': if (p[1] == '=') 4455 type = TYPE_NEQUAL; 4456 else if (p[1] == '~') 4457 type = TYPE_NOMATCH; 4458 break; 4459 case '>': if (p[1] != '=') 4460 { 4461 type = TYPE_GREATER; 4462 len = 1; 4463 } 4464 else 4465 type = TYPE_GEQUAL; 4466 break; 4467 case '<': if (p[1] != '=') 4468 { 4469 type = TYPE_SMALLER; 4470 len = 1; 4471 } 4472 else 4473 type = TYPE_SEQUAL; 4474 break; 4475 case 'i': if (p[1] == 's') 4476 { 4477 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4478 len = 5; 4479 i = p[len]; 4480 if (!isalnum(i) && i != '_') 4481 { 4482 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4483 type_is = TRUE; 4484 } 4485 } 4486 break; 4487 } 4488 4489 /* 4490 * If there is a comparative operator, use it. 4491 */ 4492 if (type != TYPE_UNKNOWN) 4493 { 4494 /* extra question mark appended: ignore case */ 4495 if (p[len] == '?') 4496 { 4497 ic = TRUE; 4498 ++len; 4499 } 4500 /* extra '#' appended: match case */ 4501 else if (p[len] == '#') 4502 { 4503 ic = FALSE; 4504 ++len; 4505 } 4506 /* nothing appended: use 'ignorecase' */ 4507 else 4508 ic = p_ic; 4509 4510 /* 4511 * Get the second variable. 4512 */ 4513 *arg = skipwhite(p + len); 4514 if (eval5(arg, &var2, evaluate) == FAIL) 4515 { 4516 clear_tv(rettv); 4517 return FAIL; 4518 } 4519 4520 if (evaluate) 4521 { 4522 if (type_is && rettv->v_type != var2.v_type) 4523 { 4524 /* For "is" a different type always means FALSE, for "notis" 4525 * it means TRUE. */ 4526 n1 = (type == TYPE_NEQUAL); 4527 } 4528 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4529 { 4530 if (type_is) 4531 { 4532 n1 = (rettv->v_type == var2.v_type 4533 && rettv->vval.v_list == var2.vval.v_list); 4534 if (type == TYPE_NEQUAL) 4535 n1 = !n1; 4536 } 4537 else if (rettv->v_type != var2.v_type 4538 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4539 { 4540 if (rettv->v_type != var2.v_type) 4541 EMSG(_("E691: Can only compare List with List")); 4542 else 4543 EMSG(_("E692: Invalid operation for List")); 4544 clear_tv(rettv); 4545 clear_tv(&var2); 4546 return FAIL; 4547 } 4548 else 4549 { 4550 /* Compare two Lists for being equal or unequal. */ 4551 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, 4552 ic, FALSE); 4553 if (type == TYPE_NEQUAL) 4554 n1 = !n1; 4555 } 4556 } 4557 4558 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4559 { 4560 if (type_is) 4561 { 4562 n1 = (rettv->v_type == var2.v_type 4563 && rettv->vval.v_dict == var2.vval.v_dict); 4564 if (type == TYPE_NEQUAL) 4565 n1 = !n1; 4566 } 4567 else if (rettv->v_type != var2.v_type 4568 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4569 { 4570 if (rettv->v_type != var2.v_type) 4571 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4572 else 4573 EMSG(_("E736: Invalid operation for Dictionary")); 4574 clear_tv(rettv); 4575 clear_tv(&var2); 4576 return FAIL; 4577 } 4578 else 4579 { 4580 /* Compare two Dictionaries for being equal or unequal. */ 4581 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, 4582 ic, FALSE); 4583 if (type == TYPE_NEQUAL) 4584 n1 = !n1; 4585 } 4586 } 4587 4588 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC 4589 || rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL) 4590 { 4591 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) 4592 { 4593 EMSG(_("E694: Invalid operation for Funcrefs")); 4594 clear_tv(rettv); 4595 clear_tv(&var2); 4596 return FAIL; 4597 } 4598 n1 = tv_equal(rettv, &var2, FALSE, FALSE); 4599 if (type == TYPE_NEQUAL) 4600 n1 = !n1; 4601 } 4602 4603 #ifdef FEAT_FLOAT 4604 /* 4605 * If one of the two variables is a float, compare as a float. 4606 * When using "=~" or "!~", always compare as string. 4607 */ 4608 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4609 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4610 { 4611 float_T f1, f2; 4612 4613 if (rettv->v_type == VAR_FLOAT) 4614 f1 = rettv->vval.v_float; 4615 else 4616 f1 = get_tv_number(rettv); 4617 if (var2.v_type == VAR_FLOAT) 4618 f2 = var2.vval.v_float; 4619 else 4620 f2 = get_tv_number(&var2); 4621 n1 = FALSE; 4622 switch (type) 4623 { 4624 case TYPE_EQUAL: n1 = (f1 == f2); break; 4625 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4626 case TYPE_GREATER: n1 = (f1 > f2); break; 4627 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4628 case TYPE_SMALLER: n1 = (f1 < f2); break; 4629 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4630 case TYPE_UNKNOWN: 4631 case TYPE_MATCH: 4632 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4633 } 4634 } 4635 #endif 4636 4637 /* 4638 * If one of the two variables is a number, compare as a number. 4639 * When using "=~" or "!~", always compare as string. 4640 */ 4641 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4642 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4643 { 4644 n1 = get_tv_number(rettv); 4645 n2 = get_tv_number(&var2); 4646 switch (type) 4647 { 4648 case TYPE_EQUAL: n1 = (n1 == n2); break; 4649 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4650 case TYPE_GREATER: n1 = (n1 > n2); break; 4651 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4652 case TYPE_SMALLER: n1 = (n1 < n2); break; 4653 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4654 case TYPE_UNKNOWN: 4655 case TYPE_MATCH: 4656 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4657 } 4658 } 4659 else 4660 { 4661 s1 = get_tv_string_buf(rettv, buf1); 4662 s2 = get_tv_string_buf(&var2, buf2); 4663 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4664 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4665 else 4666 i = 0; 4667 n1 = FALSE; 4668 switch (type) 4669 { 4670 case TYPE_EQUAL: n1 = (i == 0); break; 4671 case TYPE_NEQUAL: n1 = (i != 0); break; 4672 case TYPE_GREATER: n1 = (i > 0); break; 4673 case TYPE_GEQUAL: n1 = (i >= 0); break; 4674 case TYPE_SMALLER: n1 = (i < 0); break; 4675 case TYPE_SEQUAL: n1 = (i <= 0); break; 4676 4677 case TYPE_MATCH: 4678 case TYPE_NOMATCH: 4679 n1 = pattern_match(s2, s1, ic); 4680 if (type == TYPE_NOMATCH) 4681 n1 = !n1; 4682 break; 4683 4684 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4685 } 4686 } 4687 clear_tv(rettv); 4688 clear_tv(&var2); 4689 rettv->v_type = VAR_NUMBER; 4690 rettv->vval.v_number = n1; 4691 } 4692 } 4693 4694 return OK; 4695 } 4696 4697 /* 4698 * Handle fourth level expression: 4699 * + number addition 4700 * - number subtraction 4701 * . string concatenation 4702 * 4703 * "arg" must point to the first non-white of the expression. 4704 * "arg" is advanced to the next non-white after the recognized expression. 4705 * 4706 * Return OK or FAIL. 4707 */ 4708 static int 4709 eval5(char_u **arg, typval_T *rettv, int evaluate) 4710 { 4711 typval_T var2; 4712 typval_T var3; 4713 int op; 4714 long n1, n2; 4715 #ifdef FEAT_FLOAT 4716 float_T f1 = 0, f2 = 0; 4717 #endif 4718 char_u *s1, *s2; 4719 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4720 char_u *p; 4721 4722 /* 4723 * Get the first variable. 4724 */ 4725 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4726 return FAIL; 4727 4728 /* 4729 * Repeat computing, until no '+', '-' or '.' is following. 4730 */ 4731 for (;;) 4732 { 4733 op = **arg; 4734 if (op != '+' && op != '-' && op != '.') 4735 break; 4736 4737 if ((op != '+' || rettv->v_type != VAR_LIST) 4738 #ifdef FEAT_FLOAT 4739 && (op == '.' || rettv->v_type != VAR_FLOAT) 4740 #endif 4741 ) 4742 { 4743 /* For "list + ...", an illegal use of the first operand as 4744 * a number cannot be determined before evaluating the 2nd 4745 * operand: if this is also a list, all is ok. 4746 * For "something . ...", "something - ..." or "non-list + ...", 4747 * we know that the first operand needs to be a string or number 4748 * without evaluating the 2nd operand. So check before to avoid 4749 * side effects after an error. */ 4750 if (evaluate && get_tv_string_chk(rettv) == NULL) 4751 { 4752 clear_tv(rettv); 4753 return FAIL; 4754 } 4755 } 4756 4757 /* 4758 * Get the second variable. 4759 */ 4760 *arg = skipwhite(*arg + 1); 4761 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4762 { 4763 clear_tv(rettv); 4764 return FAIL; 4765 } 4766 4767 if (evaluate) 4768 { 4769 /* 4770 * Compute the result. 4771 */ 4772 if (op == '.') 4773 { 4774 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4775 s2 = get_tv_string_buf_chk(&var2, buf2); 4776 if (s2 == NULL) /* type error ? */ 4777 { 4778 clear_tv(rettv); 4779 clear_tv(&var2); 4780 return FAIL; 4781 } 4782 p = concat_str(s1, s2); 4783 clear_tv(rettv); 4784 rettv->v_type = VAR_STRING; 4785 rettv->vval.v_string = p; 4786 } 4787 else if (op == '+' && rettv->v_type == VAR_LIST 4788 && var2.v_type == VAR_LIST) 4789 { 4790 /* concatenate Lists */ 4791 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4792 &var3) == FAIL) 4793 { 4794 clear_tv(rettv); 4795 clear_tv(&var2); 4796 return FAIL; 4797 } 4798 clear_tv(rettv); 4799 *rettv = var3; 4800 } 4801 else 4802 { 4803 int error = FALSE; 4804 4805 #ifdef FEAT_FLOAT 4806 if (rettv->v_type == VAR_FLOAT) 4807 { 4808 f1 = rettv->vval.v_float; 4809 n1 = 0; 4810 } 4811 else 4812 #endif 4813 { 4814 n1 = get_tv_number_chk(rettv, &error); 4815 if (error) 4816 { 4817 /* This can only happen for "list + non-list". For 4818 * "non-list + ..." or "something - ...", we returned 4819 * before evaluating the 2nd operand. */ 4820 clear_tv(rettv); 4821 return FAIL; 4822 } 4823 #ifdef FEAT_FLOAT 4824 if (var2.v_type == VAR_FLOAT) 4825 f1 = n1; 4826 #endif 4827 } 4828 #ifdef FEAT_FLOAT 4829 if (var2.v_type == VAR_FLOAT) 4830 { 4831 f2 = var2.vval.v_float; 4832 n2 = 0; 4833 } 4834 else 4835 #endif 4836 { 4837 n2 = get_tv_number_chk(&var2, &error); 4838 if (error) 4839 { 4840 clear_tv(rettv); 4841 clear_tv(&var2); 4842 return FAIL; 4843 } 4844 #ifdef FEAT_FLOAT 4845 if (rettv->v_type == VAR_FLOAT) 4846 f2 = n2; 4847 #endif 4848 } 4849 clear_tv(rettv); 4850 4851 #ifdef FEAT_FLOAT 4852 /* If there is a float on either side the result is a float. */ 4853 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4854 { 4855 if (op == '+') 4856 f1 = f1 + f2; 4857 else 4858 f1 = f1 - f2; 4859 rettv->v_type = VAR_FLOAT; 4860 rettv->vval.v_float = f1; 4861 } 4862 else 4863 #endif 4864 { 4865 if (op == '+') 4866 n1 = n1 + n2; 4867 else 4868 n1 = n1 - n2; 4869 rettv->v_type = VAR_NUMBER; 4870 rettv->vval.v_number = n1; 4871 } 4872 } 4873 clear_tv(&var2); 4874 } 4875 } 4876 return OK; 4877 } 4878 4879 /* 4880 * Handle fifth level expression: 4881 * * number multiplication 4882 * / number division 4883 * % number modulo 4884 * 4885 * "arg" must point to the first non-white of the expression. 4886 * "arg" is advanced to the next non-white after the recognized expression. 4887 * 4888 * Return OK or FAIL. 4889 */ 4890 static int 4891 eval6( 4892 char_u **arg, 4893 typval_T *rettv, 4894 int evaluate, 4895 int want_string) /* after "." operator */ 4896 { 4897 typval_T var2; 4898 int op; 4899 long n1, n2; 4900 #ifdef FEAT_FLOAT 4901 int use_float = FALSE; 4902 float_T f1 = 0, f2; 4903 #endif 4904 int error = FALSE; 4905 4906 /* 4907 * Get the first variable. 4908 */ 4909 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4910 return FAIL; 4911 4912 /* 4913 * Repeat computing, until no '*', '/' or '%' is following. 4914 */ 4915 for (;;) 4916 { 4917 op = **arg; 4918 if (op != '*' && op != '/' && op != '%') 4919 break; 4920 4921 if (evaluate) 4922 { 4923 #ifdef FEAT_FLOAT 4924 if (rettv->v_type == VAR_FLOAT) 4925 { 4926 f1 = rettv->vval.v_float; 4927 use_float = TRUE; 4928 n1 = 0; 4929 } 4930 else 4931 #endif 4932 n1 = get_tv_number_chk(rettv, &error); 4933 clear_tv(rettv); 4934 if (error) 4935 return FAIL; 4936 } 4937 else 4938 n1 = 0; 4939 4940 /* 4941 * Get the second variable. 4942 */ 4943 *arg = skipwhite(*arg + 1); 4944 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4945 return FAIL; 4946 4947 if (evaluate) 4948 { 4949 #ifdef FEAT_FLOAT 4950 if (var2.v_type == VAR_FLOAT) 4951 { 4952 if (!use_float) 4953 { 4954 f1 = n1; 4955 use_float = TRUE; 4956 } 4957 f2 = var2.vval.v_float; 4958 n2 = 0; 4959 } 4960 else 4961 #endif 4962 { 4963 n2 = get_tv_number_chk(&var2, &error); 4964 clear_tv(&var2); 4965 if (error) 4966 return FAIL; 4967 #ifdef FEAT_FLOAT 4968 if (use_float) 4969 f2 = n2; 4970 #endif 4971 } 4972 4973 /* 4974 * Compute the result. 4975 * When either side is a float the result is a float. 4976 */ 4977 #ifdef FEAT_FLOAT 4978 if (use_float) 4979 { 4980 if (op == '*') 4981 f1 = f1 * f2; 4982 else if (op == '/') 4983 { 4984 # ifdef VMS 4985 /* VMS crashes on divide by zero, work around it */ 4986 if (f2 == 0.0) 4987 { 4988 if (f1 == 0) 4989 f1 = -1 * __F_FLT_MAX - 1L; /* similar to NaN */ 4990 else if (f1 < 0) 4991 f1 = -1 * __F_FLT_MAX; 4992 else 4993 f1 = __F_FLT_MAX; 4994 } 4995 else 4996 f1 = f1 / f2; 4997 # else 4998 /* We rely on the floating point library to handle divide 4999 * by zero to result in "inf" and not a crash. */ 5000 f1 = f1 / f2; 5001 # endif 5002 } 5003 else 5004 { 5005 EMSG(_("E804: Cannot use '%' with Float")); 5006 return FAIL; 5007 } 5008 rettv->v_type = VAR_FLOAT; 5009 rettv->vval.v_float = f1; 5010 } 5011 else 5012 #endif 5013 { 5014 if (op == '*') 5015 n1 = n1 * n2; 5016 else if (op == '/') 5017 { 5018 if (n2 == 0) /* give an error message? */ 5019 { 5020 if (n1 == 0) 5021 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 5022 else if (n1 < 0) 5023 n1 = -0x7fffffffL; 5024 else 5025 n1 = 0x7fffffffL; 5026 } 5027 else 5028 n1 = n1 / n2; 5029 } 5030 else 5031 { 5032 if (n2 == 0) /* give an error message? */ 5033 n1 = 0; 5034 else 5035 n1 = n1 % n2; 5036 } 5037 rettv->v_type = VAR_NUMBER; 5038 rettv->vval.v_number = n1; 5039 } 5040 } 5041 } 5042 5043 return OK; 5044 } 5045 5046 /* 5047 * Handle sixth level expression: 5048 * number number constant 5049 * "string" string constant 5050 * 'string' literal string constant 5051 * &option-name option value 5052 * @r register contents 5053 * identifier variable value 5054 * function() function call 5055 * $VAR environment variable 5056 * (expression) nested expression 5057 * [expr, expr] List 5058 * {key: val, key: val} Dictionary 5059 * 5060 * Also handle: 5061 * ! in front logical NOT 5062 * - in front unary minus 5063 * + in front unary plus (ignored) 5064 * trailing [] subscript in String or List 5065 * trailing .name entry in Dictionary 5066 * 5067 * "arg" must point to the first non-white of the expression. 5068 * "arg" is advanced to the next non-white after the recognized expression. 5069 * 5070 * Return OK or FAIL. 5071 */ 5072 static int 5073 eval7( 5074 char_u **arg, 5075 typval_T *rettv, 5076 int evaluate, 5077 int want_string UNUSED) /* after "." operator */ 5078 { 5079 long n; 5080 int len; 5081 char_u *s; 5082 char_u *start_leader, *end_leader; 5083 int ret = OK; 5084 char_u *alias; 5085 5086 /* 5087 * Initialise variable so that clear_tv() can't mistake this for a 5088 * string and free a string that isn't there. 5089 */ 5090 rettv->v_type = VAR_UNKNOWN; 5091 5092 /* 5093 * Skip '!' and '-' characters. They are handled later. 5094 */ 5095 start_leader = *arg; 5096 while (**arg == '!' || **arg == '-' || **arg == '+') 5097 *arg = skipwhite(*arg + 1); 5098 end_leader = *arg; 5099 5100 switch (**arg) 5101 { 5102 /* 5103 * Number constant. 5104 */ 5105 case '0': 5106 case '1': 5107 case '2': 5108 case '3': 5109 case '4': 5110 case '5': 5111 case '6': 5112 case '7': 5113 case '8': 5114 case '9': 5115 { 5116 #ifdef FEAT_FLOAT 5117 char_u *p = skipdigits(*arg + 1); 5118 int get_float = FALSE; 5119 5120 /* We accept a float when the format matches 5121 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 5122 * strict to avoid backwards compatibility problems. 5123 * Don't look for a float after the "." operator, so that 5124 * ":let vers = 1.2.3" doesn't fail. */ 5125 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 5126 { 5127 get_float = TRUE; 5128 p = skipdigits(p + 2); 5129 if (*p == 'e' || *p == 'E') 5130 { 5131 ++p; 5132 if (*p == '-' || *p == '+') 5133 ++p; 5134 if (!vim_isdigit(*p)) 5135 get_float = FALSE; 5136 else 5137 p = skipdigits(p + 1); 5138 } 5139 if (ASCII_ISALPHA(*p) || *p == '.') 5140 get_float = FALSE; 5141 } 5142 if (get_float) 5143 { 5144 float_T f; 5145 5146 *arg += string2float(*arg, &f); 5147 if (evaluate) 5148 { 5149 rettv->v_type = VAR_FLOAT; 5150 rettv->vval.v_float = f; 5151 } 5152 } 5153 else 5154 #endif 5155 { 5156 vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0); 5157 *arg += len; 5158 if (evaluate) 5159 { 5160 rettv->v_type = VAR_NUMBER; 5161 rettv->vval.v_number = n; 5162 } 5163 } 5164 break; 5165 } 5166 5167 /* 5168 * String constant: "string". 5169 */ 5170 case '"': ret = get_string_tv(arg, rettv, evaluate); 5171 break; 5172 5173 /* 5174 * Literal string constant: 'str''ing'. 5175 */ 5176 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 5177 break; 5178 5179 /* 5180 * List: [expr, expr] 5181 */ 5182 case '[': ret = get_list_tv(arg, rettv, evaluate); 5183 break; 5184 5185 /* 5186 * Dictionary: {key: val, key: val} 5187 */ 5188 case '{': ret = get_dict_tv(arg, rettv, evaluate); 5189 break; 5190 5191 /* 5192 * Option value: &name 5193 */ 5194 case '&': ret = get_option_tv(arg, rettv, evaluate); 5195 break; 5196 5197 /* 5198 * Environment variable: $VAR. 5199 */ 5200 case '$': ret = get_env_tv(arg, rettv, evaluate); 5201 break; 5202 5203 /* 5204 * Register contents: @r. 5205 */ 5206 case '@': ++*arg; 5207 if (evaluate) 5208 { 5209 rettv->v_type = VAR_STRING; 5210 rettv->vval.v_string = get_reg_contents(**arg, 5211 GREG_EXPR_SRC); 5212 } 5213 if (**arg != NUL) 5214 ++*arg; 5215 break; 5216 5217 /* 5218 * nested expression: (expression). 5219 */ 5220 case '(': *arg = skipwhite(*arg + 1); 5221 ret = eval1(arg, rettv, evaluate); /* recursive! */ 5222 if (**arg == ')') 5223 ++*arg; 5224 else if (ret == OK) 5225 { 5226 EMSG(_("E110: Missing ')'")); 5227 clear_tv(rettv); 5228 ret = FAIL; 5229 } 5230 break; 5231 5232 default: ret = NOTDONE; 5233 break; 5234 } 5235 5236 if (ret == NOTDONE) 5237 { 5238 /* 5239 * Must be a variable or function name. 5240 * Can also be a curly-braces kind of name: {expr}. 5241 */ 5242 s = *arg; 5243 len = get_name_len(arg, &alias, evaluate, TRUE); 5244 if (alias != NULL) 5245 s = alias; 5246 5247 if (len <= 0) 5248 ret = FAIL; 5249 else 5250 { 5251 if (**arg == '(') /* recursive! */ 5252 { 5253 partial_T *partial; 5254 5255 /* If "s" is the name of a variable of type VAR_FUNC 5256 * use its contents. */ 5257 s = deref_func_name(s, &len, &partial, !evaluate); 5258 5259 /* Invoke the function. */ 5260 ret = get_func_tv(s, len, rettv, arg, 5261 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5262 &len, evaluate, partial, NULL); 5263 5264 /* If evaluate is FALSE rettv->v_type was not set in 5265 * get_func_tv, but it's needed in handle_subscript() to parse 5266 * what follows. So set it here. */ 5267 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') 5268 { 5269 rettv->vval.v_string = vim_strsave((char_u *)""); 5270 rettv->v_type = VAR_FUNC; 5271 } 5272 5273 /* Stop the expression evaluation when immediately 5274 * aborting on error, or when an interrupt occurred or 5275 * an exception was thrown but not caught. */ 5276 if (aborting()) 5277 { 5278 if (ret == OK) 5279 clear_tv(rettv); 5280 ret = FAIL; 5281 } 5282 } 5283 else if (evaluate) 5284 ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE); 5285 else 5286 ret = OK; 5287 } 5288 vim_free(alias); 5289 } 5290 5291 *arg = skipwhite(*arg); 5292 5293 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5294 * expr(expr). */ 5295 if (ret == OK) 5296 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5297 5298 /* 5299 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5300 */ 5301 if (ret == OK && evaluate && end_leader > start_leader) 5302 { 5303 int error = FALSE; 5304 int val = 0; 5305 #ifdef FEAT_FLOAT 5306 float_T f = 0.0; 5307 5308 if (rettv->v_type == VAR_FLOAT) 5309 f = rettv->vval.v_float; 5310 else 5311 #endif 5312 val = get_tv_number_chk(rettv, &error); 5313 if (error) 5314 { 5315 clear_tv(rettv); 5316 ret = FAIL; 5317 } 5318 else 5319 { 5320 while (end_leader > start_leader) 5321 { 5322 --end_leader; 5323 if (*end_leader == '!') 5324 { 5325 #ifdef FEAT_FLOAT 5326 if (rettv->v_type == VAR_FLOAT) 5327 f = !f; 5328 else 5329 #endif 5330 val = !val; 5331 } 5332 else if (*end_leader == '-') 5333 { 5334 #ifdef FEAT_FLOAT 5335 if (rettv->v_type == VAR_FLOAT) 5336 f = -f; 5337 else 5338 #endif 5339 val = -val; 5340 } 5341 } 5342 #ifdef FEAT_FLOAT 5343 if (rettv->v_type == VAR_FLOAT) 5344 { 5345 clear_tv(rettv); 5346 rettv->vval.v_float = f; 5347 } 5348 else 5349 #endif 5350 { 5351 clear_tv(rettv); 5352 rettv->v_type = VAR_NUMBER; 5353 rettv->vval.v_number = val; 5354 } 5355 } 5356 } 5357 5358 return ret; 5359 } 5360 5361 /* 5362 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5363 * "*arg" points to the '[' or '.'. 5364 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5365 */ 5366 static int 5367 eval_index( 5368 char_u **arg, 5369 typval_T *rettv, 5370 int evaluate, 5371 int verbose) /* give error messages */ 5372 { 5373 int empty1 = FALSE, empty2 = FALSE; 5374 typval_T var1, var2; 5375 long n1, n2 = 0; 5376 long len = -1; 5377 int range = FALSE; 5378 char_u *s; 5379 char_u *key = NULL; 5380 5381 switch (rettv->v_type) 5382 { 5383 case VAR_FUNC: 5384 case VAR_PARTIAL: 5385 if (verbose) 5386 EMSG(_("E695: Cannot index a Funcref")); 5387 return FAIL; 5388 case VAR_FLOAT: 5389 #ifdef FEAT_FLOAT 5390 if (verbose) 5391 EMSG(_(e_float_as_string)); 5392 return FAIL; 5393 #endif 5394 case VAR_SPECIAL: 5395 case VAR_JOB: 5396 case VAR_CHANNEL: 5397 if (verbose) 5398 EMSG(_("E909: Cannot index a special variable")); 5399 return FAIL; 5400 case VAR_UNKNOWN: 5401 if (evaluate) 5402 return FAIL; 5403 /* FALLTHROUGH */ 5404 5405 case VAR_STRING: 5406 case VAR_NUMBER: 5407 case VAR_LIST: 5408 case VAR_DICT: 5409 break; 5410 } 5411 5412 init_tv(&var1); 5413 init_tv(&var2); 5414 if (**arg == '.') 5415 { 5416 /* 5417 * dict.name 5418 */ 5419 key = *arg + 1; 5420 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5421 ; 5422 if (len == 0) 5423 return FAIL; 5424 *arg = skipwhite(key + len); 5425 } 5426 else 5427 { 5428 /* 5429 * something[idx] 5430 * 5431 * Get the (first) variable from inside the []. 5432 */ 5433 *arg = skipwhite(*arg + 1); 5434 if (**arg == ':') 5435 empty1 = TRUE; 5436 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5437 return FAIL; 5438 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5439 { 5440 /* not a number or string */ 5441 clear_tv(&var1); 5442 return FAIL; 5443 } 5444 5445 /* 5446 * Get the second variable from inside the [:]. 5447 */ 5448 if (**arg == ':') 5449 { 5450 range = TRUE; 5451 *arg = skipwhite(*arg + 1); 5452 if (**arg == ']') 5453 empty2 = TRUE; 5454 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5455 { 5456 if (!empty1) 5457 clear_tv(&var1); 5458 return FAIL; 5459 } 5460 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5461 { 5462 /* not a number or string */ 5463 if (!empty1) 5464 clear_tv(&var1); 5465 clear_tv(&var2); 5466 return FAIL; 5467 } 5468 } 5469 5470 /* Check for the ']'. */ 5471 if (**arg != ']') 5472 { 5473 if (verbose) 5474 EMSG(_(e_missbrac)); 5475 clear_tv(&var1); 5476 if (range) 5477 clear_tv(&var2); 5478 return FAIL; 5479 } 5480 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5481 } 5482 5483 if (evaluate) 5484 { 5485 n1 = 0; 5486 if (!empty1 && rettv->v_type != VAR_DICT) 5487 { 5488 n1 = get_tv_number(&var1); 5489 clear_tv(&var1); 5490 } 5491 if (range) 5492 { 5493 if (empty2) 5494 n2 = -1; 5495 else 5496 { 5497 n2 = get_tv_number(&var2); 5498 clear_tv(&var2); 5499 } 5500 } 5501 5502 switch (rettv->v_type) 5503 { 5504 case VAR_UNKNOWN: 5505 case VAR_FUNC: 5506 case VAR_PARTIAL: 5507 case VAR_FLOAT: 5508 case VAR_SPECIAL: 5509 case VAR_JOB: 5510 case VAR_CHANNEL: 5511 break; /* not evaluating, skipping over subscript */ 5512 5513 case VAR_NUMBER: 5514 case VAR_STRING: 5515 s = get_tv_string(rettv); 5516 len = (long)STRLEN(s); 5517 if (range) 5518 { 5519 /* The resulting variable is a substring. If the indexes 5520 * are out of range the result is empty. */ 5521 if (n1 < 0) 5522 { 5523 n1 = len + n1; 5524 if (n1 < 0) 5525 n1 = 0; 5526 } 5527 if (n2 < 0) 5528 n2 = len + n2; 5529 else if (n2 >= len) 5530 n2 = len; 5531 if (n1 >= len || n2 < 0 || n1 > n2) 5532 s = NULL; 5533 else 5534 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5535 } 5536 else 5537 { 5538 /* The resulting variable is a string of a single 5539 * character. If the index is too big or negative the 5540 * result is empty. */ 5541 if (n1 >= len || n1 < 0) 5542 s = NULL; 5543 else 5544 s = vim_strnsave(s + n1, 1); 5545 } 5546 clear_tv(rettv); 5547 rettv->v_type = VAR_STRING; 5548 rettv->vval.v_string = s; 5549 break; 5550 5551 case VAR_LIST: 5552 len = list_len(rettv->vval.v_list); 5553 if (n1 < 0) 5554 n1 = len + n1; 5555 if (!empty1 && (n1 < 0 || n1 >= len)) 5556 { 5557 /* For a range we allow invalid values and return an empty 5558 * list. A list index out of range is an error. */ 5559 if (!range) 5560 { 5561 if (verbose) 5562 EMSGN(_(e_listidx), n1); 5563 return FAIL; 5564 } 5565 n1 = len; 5566 } 5567 if (range) 5568 { 5569 list_T *l; 5570 listitem_T *item; 5571 5572 if (n2 < 0) 5573 n2 = len + n2; 5574 else if (n2 >= len) 5575 n2 = len - 1; 5576 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5577 n2 = -1; 5578 l = list_alloc(); 5579 if (l == NULL) 5580 return FAIL; 5581 for (item = list_find(rettv->vval.v_list, n1); 5582 n1 <= n2; ++n1) 5583 { 5584 if (list_append_tv(l, &item->li_tv) == FAIL) 5585 { 5586 list_free(l, TRUE); 5587 return FAIL; 5588 } 5589 item = item->li_next; 5590 } 5591 clear_tv(rettv); 5592 rettv->v_type = VAR_LIST; 5593 rettv->vval.v_list = l; 5594 ++l->lv_refcount; 5595 } 5596 else 5597 { 5598 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5599 clear_tv(rettv); 5600 *rettv = var1; 5601 } 5602 break; 5603 5604 case VAR_DICT: 5605 if (range) 5606 { 5607 if (verbose) 5608 EMSG(_(e_dictrange)); 5609 if (len == -1) 5610 clear_tv(&var1); 5611 return FAIL; 5612 } 5613 { 5614 dictitem_T *item; 5615 5616 if (len == -1) 5617 { 5618 key = get_tv_string(&var1); 5619 if (*key == NUL) 5620 { 5621 if (verbose) 5622 EMSG(_(e_emptykey)); 5623 clear_tv(&var1); 5624 return FAIL; 5625 } 5626 } 5627 5628 item = dict_find(rettv->vval.v_dict, key, (int)len); 5629 5630 if (item == NULL && verbose) 5631 EMSG2(_(e_dictkey), key); 5632 if (len == -1) 5633 clear_tv(&var1); 5634 if (item == NULL) 5635 return FAIL; 5636 5637 copy_tv(&item->di_tv, &var1); 5638 clear_tv(rettv); 5639 *rettv = var1; 5640 } 5641 break; 5642 } 5643 } 5644 5645 return OK; 5646 } 5647 5648 /* 5649 * Get an option value. 5650 * "arg" points to the '&' or '+' before the option name. 5651 * "arg" is advanced to character after the option name. 5652 * Return OK or FAIL. 5653 */ 5654 static int 5655 get_option_tv( 5656 char_u **arg, 5657 typval_T *rettv, /* when NULL, only check if option exists */ 5658 int evaluate) 5659 { 5660 char_u *option_end; 5661 long numval; 5662 char_u *stringval; 5663 int opt_type; 5664 int c; 5665 int working = (**arg == '+'); /* has("+option") */ 5666 int ret = OK; 5667 int opt_flags; 5668 5669 /* 5670 * Isolate the option name and find its value. 5671 */ 5672 option_end = find_option_end(arg, &opt_flags); 5673 if (option_end == NULL) 5674 { 5675 if (rettv != NULL) 5676 EMSG2(_("E112: Option name missing: %s"), *arg); 5677 return FAIL; 5678 } 5679 5680 if (!evaluate) 5681 { 5682 *arg = option_end; 5683 return OK; 5684 } 5685 5686 c = *option_end; 5687 *option_end = NUL; 5688 opt_type = get_option_value(*arg, &numval, 5689 rettv == NULL ? NULL : &stringval, opt_flags); 5690 5691 if (opt_type == -3) /* invalid name */ 5692 { 5693 if (rettv != NULL) 5694 EMSG2(_("E113: Unknown option: %s"), *arg); 5695 ret = FAIL; 5696 } 5697 else if (rettv != NULL) 5698 { 5699 if (opt_type == -2) /* hidden string option */ 5700 { 5701 rettv->v_type = VAR_STRING; 5702 rettv->vval.v_string = NULL; 5703 } 5704 else if (opt_type == -1) /* hidden number option */ 5705 { 5706 rettv->v_type = VAR_NUMBER; 5707 rettv->vval.v_number = 0; 5708 } 5709 else if (opt_type == 1) /* number option */ 5710 { 5711 rettv->v_type = VAR_NUMBER; 5712 rettv->vval.v_number = numval; 5713 } 5714 else /* string option */ 5715 { 5716 rettv->v_type = VAR_STRING; 5717 rettv->vval.v_string = stringval; 5718 } 5719 } 5720 else if (working && (opt_type == -2 || opt_type == -1)) 5721 ret = FAIL; 5722 5723 *option_end = c; /* put back for error messages */ 5724 *arg = option_end; 5725 5726 return ret; 5727 } 5728 5729 /* 5730 * Allocate a variable for a string constant. 5731 * Return OK or FAIL. 5732 */ 5733 static int 5734 get_string_tv(char_u **arg, typval_T *rettv, int evaluate) 5735 { 5736 char_u *p; 5737 char_u *name; 5738 int extra = 0; 5739 5740 /* 5741 * Find the end of the string, skipping backslashed characters. 5742 */ 5743 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5744 { 5745 if (*p == '\\' && p[1] != NUL) 5746 { 5747 ++p; 5748 /* A "\<x>" form occupies at least 4 characters, and produces up 5749 * to 6 characters: reserve space for 2 extra */ 5750 if (*p == '<') 5751 extra += 2; 5752 } 5753 } 5754 5755 if (*p != '"') 5756 { 5757 EMSG2(_("E114: Missing quote: %s"), *arg); 5758 return FAIL; 5759 } 5760 5761 /* If only parsing, set *arg and return here */ 5762 if (!evaluate) 5763 { 5764 *arg = p + 1; 5765 return OK; 5766 } 5767 5768 /* 5769 * Copy the string into allocated memory, handling backslashed 5770 * characters. 5771 */ 5772 name = alloc((unsigned)(p - *arg + extra)); 5773 if (name == NULL) 5774 return FAIL; 5775 rettv->v_type = VAR_STRING; 5776 rettv->vval.v_string = name; 5777 5778 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5779 { 5780 if (*p == '\\') 5781 { 5782 switch (*++p) 5783 { 5784 case 'b': *name++ = BS; ++p; break; 5785 case 'e': *name++ = ESC; ++p; break; 5786 case 'f': *name++ = FF; ++p; break; 5787 case 'n': *name++ = NL; ++p; break; 5788 case 'r': *name++ = CAR; ++p; break; 5789 case 't': *name++ = TAB; ++p; break; 5790 5791 case 'X': /* hex: "\x1", "\x12" */ 5792 case 'x': 5793 case 'u': /* Unicode: "\u0023" */ 5794 case 'U': 5795 if (vim_isxdigit(p[1])) 5796 { 5797 int n, nr; 5798 int c = toupper(*p); 5799 5800 if (c == 'X') 5801 n = 2; 5802 else if (*p == 'u') 5803 n = 4; 5804 else 5805 n = 8; 5806 nr = 0; 5807 while (--n >= 0 && vim_isxdigit(p[1])) 5808 { 5809 ++p; 5810 nr = (nr << 4) + hex2nr(*p); 5811 } 5812 ++p; 5813 #ifdef FEAT_MBYTE 5814 /* For "\u" store the number according to 5815 * 'encoding'. */ 5816 if (c != 'X') 5817 name += (*mb_char2bytes)(nr, name); 5818 else 5819 #endif 5820 *name++ = nr; 5821 } 5822 break; 5823 5824 /* octal: "\1", "\12", "\123" */ 5825 case '0': 5826 case '1': 5827 case '2': 5828 case '3': 5829 case '4': 5830 case '5': 5831 case '6': 5832 case '7': *name = *p++ - '0'; 5833 if (*p >= '0' && *p <= '7') 5834 { 5835 *name = (*name << 3) + *p++ - '0'; 5836 if (*p >= '0' && *p <= '7') 5837 *name = (*name << 3) + *p++ - '0'; 5838 } 5839 ++name; 5840 break; 5841 5842 /* Special key, e.g.: "\<C-W>" */ 5843 case '<': extra = trans_special(&p, name, TRUE); 5844 if (extra != 0) 5845 { 5846 name += extra; 5847 break; 5848 } 5849 /* FALLTHROUGH */ 5850 5851 default: MB_COPY_CHAR(p, name); 5852 break; 5853 } 5854 } 5855 else 5856 MB_COPY_CHAR(p, name); 5857 5858 } 5859 *name = NUL; 5860 *arg = p + 1; 5861 5862 return OK; 5863 } 5864 5865 /* 5866 * Allocate a variable for a 'str''ing' constant. 5867 * Return OK or FAIL. 5868 */ 5869 static int 5870 get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) 5871 { 5872 char_u *p; 5873 char_u *str; 5874 int reduce = 0; 5875 5876 /* 5877 * Find the end of the string, skipping ''. 5878 */ 5879 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5880 { 5881 if (*p == '\'') 5882 { 5883 if (p[1] != '\'') 5884 break; 5885 ++reduce; 5886 ++p; 5887 } 5888 } 5889 5890 if (*p != '\'') 5891 { 5892 EMSG2(_("E115: Missing quote: %s"), *arg); 5893 return FAIL; 5894 } 5895 5896 /* If only parsing return after setting "*arg" */ 5897 if (!evaluate) 5898 { 5899 *arg = p + 1; 5900 return OK; 5901 } 5902 5903 /* 5904 * Copy the string into allocated memory, handling '' to ' reduction. 5905 */ 5906 str = alloc((unsigned)((p - *arg) - reduce)); 5907 if (str == NULL) 5908 return FAIL; 5909 rettv->v_type = VAR_STRING; 5910 rettv->vval.v_string = str; 5911 5912 for (p = *arg + 1; *p != NUL; ) 5913 { 5914 if (*p == '\'') 5915 { 5916 if (p[1] != '\'') 5917 break; 5918 ++p; 5919 } 5920 MB_COPY_CHAR(p, str); 5921 } 5922 *str = NUL; 5923 *arg = p + 1; 5924 5925 return OK; 5926 } 5927 5928 /* 5929 * Allocate a variable for a List and fill it from "*arg". 5930 * Return OK or FAIL. 5931 */ 5932 static int 5933 get_list_tv(char_u **arg, typval_T *rettv, int evaluate) 5934 { 5935 list_T *l = NULL; 5936 typval_T tv; 5937 listitem_T *item; 5938 5939 if (evaluate) 5940 { 5941 l = list_alloc(); 5942 if (l == NULL) 5943 return FAIL; 5944 } 5945 5946 *arg = skipwhite(*arg + 1); 5947 while (**arg != ']' && **arg != NUL) 5948 { 5949 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5950 goto failret; 5951 if (evaluate) 5952 { 5953 item = listitem_alloc(); 5954 if (item != NULL) 5955 { 5956 item->li_tv = tv; 5957 item->li_tv.v_lock = 0; 5958 list_append(l, item); 5959 } 5960 else 5961 clear_tv(&tv); 5962 } 5963 5964 if (**arg == ']') 5965 break; 5966 if (**arg != ',') 5967 { 5968 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5969 goto failret; 5970 } 5971 *arg = skipwhite(*arg + 1); 5972 } 5973 5974 if (**arg != ']') 5975 { 5976 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5977 failret: 5978 if (evaluate) 5979 list_free(l, TRUE); 5980 return FAIL; 5981 } 5982 5983 *arg = skipwhite(*arg + 1); 5984 if (evaluate) 5985 { 5986 rettv->v_type = VAR_LIST; 5987 rettv->vval.v_list = l; 5988 ++l->lv_refcount; 5989 } 5990 5991 return OK; 5992 } 5993 5994 /* 5995 * Allocate an empty header for a list. 5996 * Caller should take care of the reference count. 5997 */ 5998 list_T * 5999 list_alloc(void) 6000 { 6001 list_T *l; 6002 6003 l = (list_T *)alloc_clear(sizeof(list_T)); 6004 if (l != NULL) 6005 { 6006 /* Prepend the list to the list of lists for garbage collection. */ 6007 if (first_list != NULL) 6008 first_list->lv_used_prev = l; 6009 l->lv_used_prev = NULL; 6010 l->lv_used_next = first_list; 6011 first_list = l; 6012 } 6013 return l; 6014 } 6015 6016 /* 6017 * Allocate an empty list for a return value. 6018 * Returns OK or FAIL. 6019 */ 6020 int 6021 rettv_list_alloc(typval_T *rettv) 6022 { 6023 list_T *l = list_alloc(); 6024 6025 if (l == NULL) 6026 return FAIL; 6027 6028 rettv->vval.v_list = l; 6029 rettv->v_type = VAR_LIST; 6030 ++l->lv_refcount; 6031 return OK; 6032 } 6033 6034 /* 6035 * Unreference a list: decrement the reference count and free it when it 6036 * becomes zero. 6037 */ 6038 void 6039 list_unref(list_T *l) 6040 { 6041 if (l != NULL && --l->lv_refcount <= 0) 6042 list_free(l, TRUE); 6043 } 6044 6045 /* 6046 * Free a list, including all non-container items it points to. 6047 * Ignores the reference count. 6048 */ 6049 void 6050 list_free( 6051 list_T *l, 6052 int recurse) /* Free Lists and Dictionaries recursively. */ 6053 { 6054 listitem_T *item; 6055 6056 /* Remove the list from the list of lists for garbage collection. */ 6057 if (l->lv_used_prev == NULL) 6058 first_list = l->lv_used_next; 6059 else 6060 l->lv_used_prev->lv_used_next = l->lv_used_next; 6061 if (l->lv_used_next != NULL) 6062 l->lv_used_next->lv_used_prev = l->lv_used_prev; 6063 6064 for (item = l->lv_first; item != NULL; item = l->lv_first) 6065 { 6066 /* Remove the item before deleting it. */ 6067 l->lv_first = item->li_next; 6068 if (recurse || (item->li_tv.v_type != VAR_LIST 6069 && item->li_tv.v_type != VAR_DICT)) 6070 clear_tv(&item->li_tv); 6071 vim_free(item); 6072 } 6073 vim_free(l); 6074 } 6075 6076 /* 6077 * Allocate a list item. 6078 * It is not initialized, don't forget to set v_lock. 6079 */ 6080 listitem_T * 6081 listitem_alloc(void) 6082 { 6083 return (listitem_T *)alloc(sizeof(listitem_T)); 6084 } 6085 6086 /* 6087 * Free a list item. Also clears the value. Does not notify watchers. 6088 */ 6089 void 6090 listitem_free(listitem_T *item) 6091 { 6092 clear_tv(&item->li_tv); 6093 vim_free(item); 6094 } 6095 6096 /* 6097 * Remove a list item from a List and free it. Also clears the value. 6098 */ 6099 void 6100 listitem_remove(list_T *l, listitem_T *item) 6101 { 6102 vimlist_remove(l, item, item); 6103 listitem_free(item); 6104 } 6105 6106 /* 6107 * Get the number of items in a list. 6108 */ 6109 static long 6110 list_len(list_T *l) 6111 { 6112 if (l == NULL) 6113 return 0L; 6114 return l->lv_len; 6115 } 6116 6117 /* 6118 * Return TRUE when two lists have exactly the same values. 6119 */ 6120 static int 6121 list_equal( 6122 list_T *l1, 6123 list_T *l2, 6124 int ic, /* ignore case for strings */ 6125 int recursive) /* TRUE when used recursively */ 6126 { 6127 listitem_T *item1, *item2; 6128 6129 if (l1 == NULL || l2 == NULL) 6130 return FALSE; 6131 if (l1 == l2) 6132 return TRUE; 6133 if (list_len(l1) != list_len(l2)) 6134 return FALSE; 6135 6136 for (item1 = l1->lv_first, item2 = l2->lv_first; 6137 item1 != NULL && item2 != NULL; 6138 item1 = item1->li_next, item2 = item2->li_next) 6139 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) 6140 return FALSE; 6141 return item1 == NULL && item2 == NULL; 6142 } 6143 6144 /* 6145 * Return the dictitem that an entry in a hashtable points to. 6146 */ 6147 dictitem_T * 6148 dict_lookup(hashitem_T *hi) 6149 { 6150 return HI2DI(hi); 6151 } 6152 6153 /* 6154 * Return TRUE when two dictionaries have exactly the same key/values. 6155 */ 6156 static int 6157 dict_equal( 6158 dict_T *d1, 6159 dict_T *d2, 6160 int ic, /* ignore case for strings */ 6161 int recursive) /* TRUE when used recursively */ 6162 { 6163 hashitem_T *hi; 6164 dictitem_T *item2; 6165 int todo; 6166 6167 if (d1 == NULL || d2 == NULL) 6168 return FALSE; 6169 if (d1 == d2) 6170 return TRUE; 6171 if (dict_len(d1) != dict_len(d2)) 6172 return FALSE; 6173 6174 todo = (int)d1->dv_hashtab.ht_used; 6175 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 6176 { 6177 if (!HASHITEM_EMPTY(hi)) 6178 { 6179 item2 = dict_find(d2, hi->hi_key, -1); 6180 if (item2 == NULL) 6181 return FALSE; 6182 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive)) 6183 return FALSE; 6184 --todo; 6185 } 6186 } 6187 return TRUE; 6188 } 6189 6190 static int tv_equal_recurse_limit; 6191 6192 /* 6193 * Return TRUE if "tv1" and "tv2" have the same value. 6194 * Compares the items just like "==" would compare them, but strings and 6195 * numbers are different. Floats and numbers are also different. 6196 */ 6197 static int 6198 tv_equal( 6199 typval_T *tv1, 6200 typval_T *tv2, 6201 int ic, /* ignore case */ 6202 int recursive) /* TRUE when used recursively */ 6203 { 6204 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 6205 char_u *s1, *s2; 6206 static int recursive_cnt = 0; /* catch recursive loops */ 6207 int r; 6208 6209 /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ 6210 if ((tv1->v_type == VAR_FUNC 6211 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) 6212 && (tv2->v_type == VAR_FUNC 6213 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) 6214 { 6215 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string 6216 : tv1->vval.v_partial->pt_name; 6217 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string 6218 : tv2->vval.v_partial->pt_name; 6219 return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0); 6220 } 6221 6222 if (tv1->v_type != tv2->v_type) 6223 return FALSE; 6224 6225 /* Catch lists and dicts that have an endless loop by limiting 6226 * recursiveness to a limit. We guess they are equal then. 6227 * A fixed limit has the problem of still taking an awful long time. 6228 * Reduce the limit every time running into it. That should work fine for 6229 * deeply linked structures that are not recursively linked and catch 6230 * recursiveness quickly. */ 6231 if (!recursive) 6232 tv_equal_recurse_limit = 1000; 6233 if (recursive_cnt >= tv_equal_recurse_limit) 6234 { 6235 --tv_equal_recurse_limit; 6236 return TRUE; 6237 } 6238 6239 switch (tv1->v_type) 6240 { 6241 case VAR_LIST: 6242 ++recursive_cnt; 6243 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); 6244 --recursive_cnt; 6245 return r; 6246 6247 case VAR_DICT: 6248 ++recursive_cnt; 6249 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE); 6250 --recursive_cnt; 6251 return r; 6252 6253 case VAR_NUMBER: 6254 return tv1->vval.v_number == tv2->vval.v_number; 6255 6256 case VAR_STRING: 6257 s1 = get_tv_string_buf(tv1, buf1); 6258 s2 = get_tv_string_buf(tv2, buf2); 6259 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 6260 6261 case VAR_SPECIAL: 6262 return tv1->vval.v_number == tv2->vval.v_number; 6263 6264 case VAR_FLOAT: 6265 #ifdef FEAT_FLOAT 6266 return tv1->vval.v_float == tv2->vval.v_float; 6267 #endif 6268 case VAR_JOB: 6269 #ifdef FEAT_JOB_CHANNEL 6270 return tv1->vval.v_job == tv2->vval.v_job; 6271 #endif 6272 case VAR_CHANNEL: 6273 #ifdef FEAT_JOB_CHANNEL 6274 return tv1->vval.v_channel == tv2->vval.v_channel; 6275 #endif 6276 case VAR_FUNC: 6277 case VAR_PARTIAL: 6278 case VAR_UNKNOWN: 6279 break; 6280 } 6281 6282 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it 6283 * does not equal anything, not even itself. */ 6284 return FALSE; 6285 } 6286 6287 /* 6288 * Locate item with index "n" in list "l" and return it. 6289 * A negative index is counted from the end; -1 is the last item. 6290 * Returns NULL when "n" is out of range. 6291 */ 6292 listitem_T * 6293 list_find(list_T *l, long n) 6294 { 6295 listitem_T *item; 6296 long idx; 6297 6298 if (l == NULL) 6299 return NULL; 6300 6301 /* Negative index is relative to the end. */ 6302 if (n < 0) 6303 n = l->lv_len + n; 6304 6305 /* Check for index out of range. */ 6306 if (n < 0 || n >= l->lv_len) 6307 return NULL; 6308 6309 /* When there is a cached index may start search from there. */ 6310 if (l->lv_idx_item != NULL) 6311 { 6312 if (n < l->lv_idx / 2) 6313 { 6314 /* closest to the start of the list */ 6315 item = l->lv_first; 6316 idx = 0; 6317 } 6318 else if (n > (l->lv_idx + l->lv_len) / 2) 6319 { 6320 /* closest to the end of the list */ 6321 item = l->lv_last; 6322 idx = l->lv_len - 1; 6323 } 6324 else 6325 { 6326 /* closest to the cached index */ 6327 item = l->lv_idx_item; 6328 idx = l->lv_idx; 6329 } 6330 } 6331 else 6332 { 6333 if (n < l->lv_len / 2) 6334 { 6335 /* closest to the start of the list */ 6336 item = l->lv_first; 6337 idx = 0; 6338 } 6339 else 6340 { 6341 /* closest to the end of the list */ 6342 item = l->lv_last; 6343 idx = l->lv_len - 1; 6344 } 6345 } 6346 6347 while (n > idx) 6348 { 6349 /* search forward */ 6350 item = item->li_next; 6351 ++idx; 6352 } 6353 while (n < idx) 6354 { 6355 /* search backward */ 6356 item = item->li_prev; 6357 --idx; 6358 } 6359 6360 /* cache the used index */ 6361 l->lv_idx = idx; 6362 l->lv_idx_item = item; 6363 6364 return item; 6365 } 6366 6367 /* 6368 * Get list item "l[idx]" as a number. 6369 */ 6370 static long 6371 list_find_nr( 6372 list_T *l, 6373 long idx, 6374 int *errorp) /* set to TRUE when something wrong */ 6375 { 6376 listitem_T *li; 6377 6378 li = list_find(l, idx); 6379 if (li == NULL) 6380 { 6381 if (errorp != NULL) 6382 *errorp = TRUE; 6383 return -1L; 6384 } 6385 return get_tv_number_chk(&li->li_tv, errorp); 6386 } 6387 6388 /* 6389 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6390 */ 6391 char_u * 6392 list_find_str(list_T *l, long idx) 6393 { 6394 listitem_T *li; 6395 6396 li = list_find(l, idx - 1); 6397 if (li == NULL) 6398 { 6399 EMSGN(_(e_listidx), idx); 6400 return NULL; 6401 } 6402 return get_tv_string(&li->li_tv); 6403 } 6404 6405 /* 6406 * Locate "item" list "l" and return its index. 6407 * Returns -1 when "item" is not in the list. 6408 */ 6409 static long 6410 list_idx_of_item(list_T *l, listitem_T *item) 6411 { 6412 long idx = 0; 6413 listitem_T *li; 6414 6415 if (l == NULL) 6416 return -1; 6417 idx = 0; 6418 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6419 ++idx; 6420 if (li == NULL) 6421 return -1; 6422 return idx; 6423 } 6424 6425 /* 6426 * Append item "item" to the end of list "l". 6427 */ 6428 void 6429 list_append(list_T *l, listitem_T *item) 6430 { 6431 if (l->lv_last == NULL) 6432 { 6433 /* empty list */ 6434 l->lv_first = item; 6435 l->lv_last = item; 6436 item->li_prev = NULL; 6437 } 6438 else 6439 { 6440 l->lv_last->li_next = item; 6441 item->li_prev = l->lv_last; 6442 l->lv_last = item; 6443 } 6444 ++l->lv_len; 6445 item->li_next = NULL; 6446 } 6447 6448 /* 6449 * Append typval_T "tv" to the end of list "l". 6450 * Return FAIL when out of memory. 6451 */ 6452 int 6453 list_append_tv(list_T *l, typval_T *tv) 6454 { 6455 listitem_T *li = listitem_alloc(); 6456 6457 if (li == NULL) 6458 return FAIL; 6459 copy_tv(tv, &li->li_tv); 6460 list_append(l, li); 6461 return OK; 6462 } 6463 6464 /* 6465 * Add a dictionary to a list. Used by getqflist(). 6466 * Return FAIL when out of memory. 6467 */ 6468 int 6469 list_append_dict(list_T *list, dict_T *dict) 6470 { 6471 listitem_T *li = listitem_alloc(); 6472 6473 if (li == NULL) 6474 return FAIL; 6475 li->li_tv.v_type = VAR_DICT; 6476 li->li_tv.v_lock = 0; 6477 li->li_tv.vval.v_dict = dict; 6478 list_append(list, li); 6479 ++dict->dv_refcount; 6480 return OK; 6481 } 6482 6483 /* 6484 * Make a copy of "str" and append it as an item to list "l". 6485 * When "len" >= 0 use "str[len]". 6486 * Returns FAIL when out of memory. 6487 */ 6488 int 6489 list_append_string(list_T *l, char_u *str, int len) 6490 { 6491 listitem_T *li = listitem_alloc(); 6492 6493 if (li == NULL) 6494 return FAIL; 6495 list_append(l, li); 6496 li->li_tv.v_type = VAR_STRING; 6497 li->li_tv.v_lock = 0; 6498 if (str == NULL) 6499 li->li_tv.vval.v_string = NULL; 6500 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6501 : vim_strsave(str))) == NULL) 6502 return FAIL; 6503 return OK; 6504 } 6505 6506 /* 6507 * Append "n" to list "l". 6508 * Returns FAIL when out of memory. 6509 */ 6510 int 6511 list_append_number(list_T *l, varnumber_T n) 6512 { 6513 listitem_T *li; 6514 6515 li = listitem_alloc(); 6516 if (li == NULL) 6517 return FAIL; 6518 li->li_tv.v_type = VAR_NUMBER; 6519 li->li_tv.v_lock = 0; 6520 li->li_tv.vval.v_number = n; 6521 list_append(l, li); 6522 return OK; 6523 } 6524 6525 /* 6526 * Insert typval_T "tv" in list "l" before "item". 6527 * If "item" is NULL append at the end. 6528 * Return FAIL when out of memory. 6529 */ 6530 int 6531 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item) 6532 { 6533 listitem_T *ni = listitem_alloc(); 6534 6535 if (ni == NULL) 6536 return FAIL; 6537 copy_tv(tv, &ni->li_tv); 6538 list_insert(l, ni, item); 6539 return OK; 6540 } 6541 6542 void 6543 list_insert(list_T *l, listitem_T *ni, listitem_T *item) 6544 { 6545 if (item == NULL) 6546 /* Append new item at end of list. */ 6547 list_append(l, ni); 6548 else 6549 { 6550 /* Insert new item before existing item. */ 6551 ni->li_prev = item->li_prev; 6552 ni->li_next = item; 6553 if (item->li_prev == NULL) 6554 { 6555 l->lv_first = ni; 6556 ++l->lv_idx; 6557 } 6558 else 6559 { 6560 item->li_prev->li_next = ni; 6561 l->lv_idx_item = NULL; 6562 } 6563 item->li_prev = ni; 6564 ++l->lv_len; 6565 } 6566 } 6567 6568 /* 6569 * Extend "l1" with "l2". 6570 * If "bef" is NULL append at the end, otherwise insert before this item. 6571 * Returns FAIL when out of memory. 6572 */ 6573 static int 6574 list_extend(list_T *l1, list_T *l2, listitem_T *bef) 6575 { 6576 listitem_T *item; 6577 int todo = l2->lv_len; 6578 6579 /* We also quit the loop when we have inserted the original item count of 6580 * the list, avoid a hang when we extend a list with itself. */ 6581 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6582 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6583 return FAIL; 6584 return OK; 6585 } 6586 6587 /* 6588 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6589 * Return FAIL when out of memory. 6590 */ 6591 static int 6592 list_concat(list_T *l1, list_T *l2, typval_T *tv) 6593 { 6594 list_T *l; 6595 6596 if (l1 == NULL || l2 == NULL) 6597 return FAIL; 6598 6599 /* make a copy of the first list. */ 6600 l = list_copy(l1, FALSE, 0); 6601 if (l == NULL) 6602 return FAIL; 6603 tv->v_type = VAR_LIST; 6604 tv->vval.v_list = l; 6605 6606 /* append all items from the second list */ 6607 return list_extend(l, l2, NULL); 6608 } 6609 6610 /* 6611 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6612 * The refcount of the new list is set to 1. 6613 * See item_copy() for "copyID". 6614 * Returns NULL when out of memory. 6615 */ 6616 static list_T * 6617 list_copy(list_T *orig, int deep, int copyID) 6618 { 6619 list_T *copy; 6620 listitem_T *item; 6621 listitem_T *ni; 6622 6623 if (orig == NULL) 6624 return NULL; 6625 6626 copy = list_alloc(); 6627 if (copy != NULL) 6628 { 6629 if (copyID != 0) 6630 { 6631 /* Do this before adding the items, because one of the items may 6632 * refer back to this list. */ 6633 orig->lv_copyID = copyID; 6634 orig->lv_copylist = copy; 6635 } 6636 for (item = orig->lv_first; item != NULL && !got_int; 6637 item = item->li_next) 6638 { 6639 ni = listitem_alloc(); 6640 if (ni == NULL) 6641 break; 6642 if (deep) 6643 { 6644 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6645 { 6646 vim_free(ni); 6647 break; 6648 } 6649 } 6650 else 6651 copy_tv(&item->li_tv, &ni->li_tv); 6652 list_append(copy, ni); 6653 } 6654 ++copy->lv_refcount; 6655 if (item != NULL) 6656 { 6657 list_unref(copy); 6658 copy = NULL; 6659 } 6660 } 6661 6662 return copy; 6663 } 6664 6665 /* 6666 * Remove items "item" to "item2" from list "l". 6667 * Does not free the listitem or the value! 6668 * This used to be called list_remove, but that conflicts with a Sun header 6669 * file. 6670 */ 6671 void 6672 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2) 6673 { 6674 listitem_T *ip; 6675 6676 /* notify watchers */ 6677 for (ip = item; ip != NULL; ip = ip->li_next) 6678 { 6679 --l->lv_len; 6680 list_fix_watch(l, ip); 6681 if (ip == item2) 6682 break; 6683 } 6684 6685 if (item2->li_next == NULL) 6686 l->lv_last = item->li_prev; 6687 else 6688 item2->li_next->li_prev = item->li_prev; 6689 if (item->li_prev == NULL) 6690 l->lv_first = item2->li_next; 6691 else 6692 item->li_prev->li_next = item2->li_next; 6693 l->lv_idx_item = NULL; 6694 } 6695 6696 /* 6697 * Return an allocated string with the string representation of a list. 6698 * May return NULL. 6699 */ 6700 static char_u * 6701 list2string(typval_T *tv, int copyID) 6702 { 6703 garray_T ga; 6704 6705 if (tv->vval.v_list == NULL) 6706 return NULL; 6707 ga_init2(&ga, (int)sizeof(char), 80); 6708 ga_append(&ga, '['); 6709 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6710 { 6711 vim_free(ga.ga_data); 6712 return NULL; 6713 } 6714 ga_append(&ga, ']'); 6715 ga_append(&ga, NUL); 6716 return (char_u *)ga.ga_data; 6717 } 6718 6719 typedef struct join_S { 6720 char_u *s; 6721 char_u *tofree; 6722 } join_T; 6723 6724 static int 6725 list_join_inner( 6726 garray_T *gap, /* to store the result in */ 6727 list_T *l, 6728 char_u *sep, 6729 int echo_style, 6730 int copyID, 6731 garray_T *join_gap) /* to keep each list item string */ 6732 { 6733 int i; 6734 join_T *p; 6735 int len; 6736 int sumlen = 0; 6737 int first = TRUE; 6738 char_u *tofree; 6739 char_u numbuf[NUMBUFLEN]; 6740 listitem_T *item; 6741 char_u *s; 6742 6743 /* Stringify each item in the list. */ 6744 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6745 { 6746 if (echo_style) 6747 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6748 else 6749 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6750 if (s == NULL) 6751 return FAIL; 6752 6753 len = (int)STRLEN(s); 6754 sumlen += len; 6755 6756 (void)ga_grow(join_gap, 1); 6757 p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++); 6758 if (tofree != NULL || s != numbuf) 6759 { 6760 p->s = s; 6761 p->tofree = tofree; 6762 } 6763 else 6764 { 6765 p->s = vim_strnsave(s, len); 6766 p->tofree = p->s; 6767 } 6768 6769 line_breakcheck(); 6770 if (did_echo_string_emsg) /* recursion error, bail out */ 6771 break; 6772 } 6773 6774 /* Allocate result buffer with its total size, avoid re-allocation and 6775 * multiple copy operations. Add 2 for a tailing ']' and NUL. */ 6776 if (join_gap->ga_len >= 2) 6777 sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1); 6778 if (ga_grow(gap, sumlen + 2) == FAIL) 6779 return FAIL; 6780 6781 for (i = 0; i < join_gap->ga_len && !got_int; ++i) 6782 { 6783 if (first) 6784 first = FALSE; 6785 else 6786 ga_concat(gap, sep); 6787 p = ((join_T *)join_gap->ga_data) + i; 6788 6789 if (p->s != NULL) 6790 ga_concat(gap, p->s); 6791 line_breakcheck(); 6792 } 6793 6794 return OK; 6795 } 6796 6797 /* 6798 * Join list "l" into a string in "*gap", using separator "sep". 6799 * When "echo_style" is TRUE use String as echoed, otherwise as inside a List. 6800 * Return FAIL or OK. 6801 */ 6802 static int 6803 list_join( 6804 garray_T *gap, 6805 list_T *l, 6806 char_u *sep, 6807 int echo_style, 6808 int copyID) 6809 { 6810 garray_T join_ga; 6811 int retval; 6812 join_T *p; 6813 int i; 6814 6815 if (l->lv_len < 1) 6816 return OK; /* nothing to do */ 6817 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); 6818 retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga); 6819 6820 /* Dispose each item in join_ga. */ 6821 if (join_ga.ga_data != NULL) 6822 { 6823 p = (join_T *)join_ga.ga_data; 6824 for (i = 0; i < join_ga.ga_len; ++i) 6825 { 6826 vim_free(p->tofree); 6827 ++p; 6828 } 6829 ga_clear(&join_ga); 6830 } 6831 6832 return retval; 6833 } 6834 6835 /* 6836 * Return the next (unique) copy ID. 6837 * Used for serializing nested structures. 6838 */ 6839 int 6840 get_copyID(void) 6841 { 6842 current_copyID += COPYID_INC; 6843 return current_copyID; 6844 } 6845 6846 /* 6847 * Garbage collection for lists and dictionaries. 6848 * 6849 * We use reference counts to be able to free most items right away when they 6850 * are no longer used. But for composite items it's possible that it becomes 6851 * unused while the reference count is > 0: When there is a recursive 6852 * reference. Example: 6853 * :let l = [1, 2, 3] 6854 * :let d = {9: l} 6855 * :let l[1] = d 6856 * 6857 * Since this is quite unusual we handle this with garbage collection: every 6858 * once in a while find out which lists and dicts are not referenced from any 6859 * variable. 6860 * 6861 * Here is a good reference text about garbage collection (refers to Python 6862 * but it applies to all reference-counting mechanisms): 6863 * http://python.ca/nas/python/gc/ 6864 */ 6865 6866 /* 6867 * Do garbage collection for lists and dicts. 6868 * Return TRUE if some memory was freed. 6869 */ 6870 int 6871 garbage_collect(void) 6872 { 6873 int copyID; 6874 int abort = FALSE; 6875 buf_T *buf; 6876 win_T *wp; 6877 int i; 6878 funccall_T *fc, **pfc; 6879 int did_free = FALSE; 6880 int did_free_funccal = FALSE; 6881 #ifdef FEAT_WINDOWS 6882 tabpage_T *tp; 6883 #endif 6884 6885 /* Only do this once. */ 6886 want_garbage_collect = FALSE; 6887 may_garbage_collect = FALSE; 6888 garbage_collect_at_exit = FALSE; 6889 6890 /* We advance by two because we add one for items referenced through 6891 * previous_funccal. */ 6892 copyID = get_copyID(); 6893 6894 /* 6895 * 1. Go through all accessible variables and mark all lists and dicts 6896 * with copyID. 6897 */ 6898 6899 /* Don't free variables in the previous_funccal list unless they are only 6900 * referenced through previous_funccal. This must be first, because if 6901 * the item is referenced elsewhere the funccal must not be freed. */ 6902 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6903 { 6904 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, 6905 NULL); 6906 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, 6907 NULL); 6908 } 6909 6910 /* script-local variables */ 6911 for (i = 1; i <= ga_scripts.ga_len; ++i) 6912 abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); 6913 6914 /* buffer-local variables */ 6915 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6916 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID, 6917 NULL, NULL); 6918 6919 /* window-local variables */ 6920 FOR_ALL_TAB_WINDOWS(tp, wp) 6921 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, 6922 NULL, NULL); 6923 #ifdef FEAT_AUTOCMD 6924 if (aucmd_win != NULL) 6925 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID, 6926 NULL, NULL); 6927 #endif 6928 6929 #ifdef FEAT_WINDOWS 6930 /* tabpage-local variables */ 6931 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6932 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID, 6933 NULL, NULL); 6934 #endif 6935 6936 /* global variables */ 6937 abort = abort || set_ref_in_ht(&globvarht, copyID, NULL); 6938 6939 /* function-local variables */ 6940 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6941 { 6942 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL); 6943 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL); 6944 } 6945 6946 /* v: vars */ 6947 abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL); 6948 6949 #ifdef FEAT_LUA 6950 abort = abort || set_ref_in_lua(copyID); 6951 #endif 6952 6953 #ifdef FEAT_PYTHON 6954 abort = abort || set_ref_in_python(copyID); 6955 #endif 6956 6957 #ifdef FEAT_PYTHON3 6958 abort = abort || set_ref_in_python3(copyID); 6959 #endif 6960 6961 #ifdef FEAT_JOB_CHANNEL 6962 abort = abort || set_ref_in_channel(copyID); 6963 #endif 6964 6965 if (!abort) 6966 { 6967 /* 6968 * 2. Free lists and dictionaries that are not referenced. 6969 */ 6970 did_free = free_unref_items(copyID); 6971 6972 /* 6973 * 3. Check if any funccal can be freed now. 6974 */ 6975 for (pfc = &previous_funccal; *pfc != NULL; ) 6976 { 6977 if (can_free_funccal(*pfc, copyID)) 6978 { 6979 fc = *pfc; 6980 *pfc = fc->caller; 6981 free_funccal(fc, TRUE); 6982 did_free = TRUE; 6983 did_free_funccal = TRUE; 6984 } 6985 else 6986 pfc = &(*pfc)->caller; 6987 } 6988 if (did_free_funccal) 6989 /* When a funccal was freed some more items might be garbage 6990 * collected, so run again. */ 6991 (void)garbage_collect(); 6992 } 6993 else if (p_verbose > 0) 6994 { 6995 verb_msg((char_u *)_("Not enough memory to set references, garbage collection aborted!")); 6996 } 6997 6998 return did_free; 6999 } 7000 7001 /* 7002 * Free lists, dictionaries and jobs that are no longer referenced. 7003 */ 7004 static int 7005 free_unref_items(int copyID) 7006 { 7007 dict_T *dd, *dd_next; 7008 list_T *ll, *ll_next; 7009 int did_free = FALSE; 7010 7011 /* 7012 * Go through the list of dicts and free items without the copyID. 7013 */ 7014 for (dd = first_dict; dd != NULL; ) 7015 { 7016 dd_next = dd->dv_used_next; 7017 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 7018 { 7019 /* Free the Dictionary and ordinary items it contains, but don't 7020 * recurse into Lists and Dictionaries, they will be in the list 7021 * of dicts or list of lists. */ 7022 dict_free(dd, FALSE); 7023 did_free = TRUE; 7024 } 7025 dd = dd_next; 7026 } 7027 7028 /* 7029 * Go through the list of lists and free items without the copyID. 7030 * But don't free a list that has a watcher (used in a for loop), these 7031 * are not referenced anywhere. 7032 */ 7033 for (ll = first_list; ll != NULL; ) 7034 { 7035 ll_next = ll->lv_used_next; 7036 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 7037 && ll->lv_watch == NULL) 7038 { 7039 /* Free the List and ordinary items it contains, but don't recurse 7040 * into Lists and Dictionaries, they will be in the list of dicts 7041 * or list of lists. */ 7042 list_free(ll, FALSE); 7043 did_free = TRUE; 7044 } 7045 ll = ll_next; 7046 } 7047 7048 return did_free; 7049 } 7050 7051 /* 7052 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 7053 * "list_stack" is used to add lists to be marked. Can be NULL. 7054 * 7055 * Returns TRUE if setting references failed somehow. 7056 */ 7057 int 7058 set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack) 7059 { 7060 int todo; 7061 int abort = FALSE; 7062 hashitem_T *hi; 7063 hashtab_T *cur_ht; 7064 ht_stack_T *ht_stack = NULL; 7065 ht_stack_T *tempitem; 7066 7067 cur_ht = ht; 7068 for (;;) 7069 { 7070 if (!abort) 7071 { 7072 /* Mark each item in the hashtab. If the item contains a hashtab 7073 * it is added to ht_stack, if it contains a list it is added to 7074 * list_stack. */ 7075 todo = (int)cur_ht->ht_used; 7076 for (hi = cur_ht->ht_array; todo > 0; ++hi) 7077 if (!HASHITEM_EMPTY(hi)) 7078 { 7079 --todo; 7080 abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID, 7081 &ht_stack, list_stack); 7082 } 7083 } 7084 7085 if (ht_stack == NULL) 7086 break; 7087 7088 /* take an item from the stack */ 7089 cur_ht = ht_stack->ht; 7090 tempitem = ht_stack; 7091 ht_stack = ht_stack->prev; 7092 free(tempitem); 7093 } 7094 7095 return abort; 7096 } 7097 7098 /* 7099 * Mark all lists and dicts referenced through list "l" with "copyID". 7100 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 7101 * 7102 * Returns TRUE if setting references failed somehow. 7103 */ 7104 int 7105 set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack) 7106 { 7107 listitem_T *li; 7108 int abort = FALSE; 7109 list_T *cur_l; 7110 list_stack_T *list_stack = NULL; 7111 list_stack_T *tempitem; 7112 7113 cur_l = l; 7114 for (;;) 7115 { 7116 if (!abort) 7117 /* Mark each item in the list. If the item contains a hashtab 7118 * it is added to ht_stack, if it contains a list it is added to 7119 * list_stack. */ 7120 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next) 7121 abort = abort || set_ref_in_item(&li->li_tv, copyID, 7122 ht_stack, &list_stack); 7123 if (list_stack == NULL) 7124 break; 7125 7126 /* take an item from the stack */ 7127 cur_l = list_stack->list; 7128 tempitem = list_stack; 7129 list_stack = list_stack->prev; 7130 free(tempitem); 7131 } 7132 7133 return abort; 7134 } 7135 7136 /* 7137 * Mark all lists and dicts referenced through typval "tv" with "copyID". 7138 * "list_stack" is used to add lists to be marked. Can be NULL. 7139 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 7140 * 7141 * Returns TRUE if setting references failed somehow. 7142 */ 7143 int 7144 set_ref_in_item( 7145 typval_T *tv, 7146 int copyID, 7147 ht_stack_T **ht_stack, 7148 list_stack_T **list_stack) 7149 { 7150 dict_T *dd; 7151 list_T *ll; 7152 int abort = FALSE; 7153 7154 if (tv->v_type == VAR_DICT || tv->v_type == VAR_PARTIAL) 7155 { 7156 if (tv->v_type == VAR_DICT) 7157 dd = tv->vval.v_dict; 7158 else if (tv->vval.v_partial != NULL) 7159 dd = tv->vval.v_partial->pt_dict; 7160 else 7161 dd = NULL; 7162 if (dd != NULL && dd->dv_copyID != copyID) 7163 { 7164 /* Didn't see this dict yet. */ 7165 dd->dv_copyID = copyID; 7166 if (ht_stack == NULL) 7167 { 7168 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); 7169 } 7170 else 7171 { 7172 ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T)); 7173 if (newitem == NULL) 7174 abort = TRUE; 7175 else 7176 { 7177 newitem->ht = &dd->dv_hashtab; 7178 newitem->prev = *ht_stack; 7179 *ht_stack = newitem; 7180 } 7181 } 7182 } 7183 } 7184 else if (tv->v_type == VAR_LIST) 7185 { 7186 ll = tv->vval.v_list; 7187 if (ll != NULL && ll->lv_copyID != copyID) 7188 { 7189 /* Didn't see this list yet. */ 7190 ll->lv_copyID = copyID; 7191 if (list_stack == NULL) 7192 { 7193 abort = set_ref_in_list(ll, copyID, ht_stack); 7194 } 7195 else 7196 { 7197 list_stack_T *newitem = (list_stack_T*)malloc( 7198 sizeof(list_stack_T)); 7199 if (newitem == NULL) 7200 abort = TRUE; 7201 else 7202 { 7203 newitem->list = ll; 7204 newitem->prev = *list_stack; 7205 *list_stack = newitem; 7206 } 7207 } 7208 } 7209 } 7210 return abort; 7211 } 7212 7213 static void 7214 partial_free(partial_T *pt, int free_dict) 7215 { 7216 int i; 7217 7218 for (i = 0; i < pt->pt_argc; ++i) 7219 clear_tv(&pt->pt_argv[i]); 7220 vim_free(pt->pt_argv); 7221 if (free_dict) 7222 dict_unref(pt->pt_dict); 7223 func_unref(pt->pt_name); 7224 vim_free(pt->pt_name); 7225 vim_free(pt); 7226 } 7227 7228 /* 7229 * Unreference a closure: decrement the reference count and free it when it 7230 * becomes zero. 7231 */ 7232 void 7233 partial_unref(partial_T *pt) 7234 { 7235 if (pt != NULL && --pt->pt_refcount <= 0) 7236 partial_free(pt, TRUE); 7237 } 7238 7239 /* 7240 * Allocate an empty header for a dictionary. 7241 */ 7242 dict_T * 7243 dict_alloc(void) 7244 { 7245 dict_T *d; 7246 7247 d = (dict_T *)alloc(sizeof(dict_T)); 7248 if (d != NULL) 7249 { 7250 /* Add the dict to the list of dicts for garbage collection. */ 7251 if (first_dict != NULL) 7252 first_dict->dv_used_prev = d; 7253 d->dv_used_next = first_dict; 7254 d->dv_used_prev = NULL; 7255 first_dict = d; 7256 7257 hash_init(&d->dv_hashtab); 7258 d->dv_lock = 0; 7259 d->dv_scope = 0; 7260 d->dv_refcount = 0; 7261 d->dv_copyID = 0; 7262 } 7263 return d; 7264 } 7265 7266 /* 7267 * Allocate an empty dict for a return value. 7268 * Returns OK or FAIL. 7269 */ 7270 int 7271 rettv_dict_alloc(typval_T *rettv) 7272 { 7273 dict_T *d = dict_alloc(); 7274 7275 if (d == NULL) 7276 return FAIL; 7277 7278 rettv->vval.v_dict = d; 7279 rettv->v_type = VAR_DICT; 7280 ++d->dv_refcount; 7281 return OK; 7282 } 7283 7284 7285 /* 7286 * Unreference a Dictionary: decrement the reference count and free it when it 7287 * becomes zero. 7288 */ 7289 void 7290 dict_unref(dict_T *d) 7291 { 7292 if (d != NULL && --d->dv_refcount <= 0) 7293 dict_free(d, TRUE); 7294 } 7295 7296 /* 7297 * Free a Dictionary, including all non-container items it contains. 7298 * Ignores the reference count. 7299 */ 7300 void 7301 dict_free( 7302 dict_T *d, 7303 int recurse) /* Free Lists and Dictionaries recursively. */ 7304 { 7305 int todo; 7306 hashitem_T *hi; 7307 dictitem_T *di; 7308 7309 /* Remove the dict from the list of dicts for garbage collection. */ 7310 if (d->dv_used_prev == NULL) 7311 first_dict = d->dv_used_next; 7312 else 7313 d->dv_used_prev->dv_used_next = d->dv_used_next; 7314 if (d->dv_used_next != NULL) 7315 d->dv_used_next->dv_used_prev = d->dv_used_prev; 7316 7317 /* Lock the hashtab, we don't want it to resize while freeing items. */ 7318 hash_lock(&d->dv_hashtab); 7319 todo = (int)d->dv_hashtab.ht_used; 7320 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 7321 { 7322 if (!HASHITEM_EMPTY(hi)) 7323 { 7324 /* Remove the item before deleting it, just in case there is 7325 * something recursive causing trouble. */ 7326 di = HI2DI(hi); 7327 hash_remove(&d->dv_hashtab, hi); 7328 if (recurse || (di->di_tv.v_type != VAR_LIST 7329 && di->di_tv.v_type != VAR_DICT)) 7330 { 7331 if (!recurse && di->di_tv.v_type == VAR_PARTIAL) 7332 { 7333 partial_T *pt = di->di_tv.vval.v_partial; 7334 7335 /* We unref the partial but not the dict it refers to. */ 7336 if (pt != NULL && --pt->pt_refcount == 0) 7337 partial_free(pt, FALSE); 7338 } 7339 else 7340 clear_tv(&di->di_tv); 7341 } 7342 vim_free(di); 7343 --todo; 7344 } 7345 } 7346 hash_clear(&d->dv_hashtab); 7347 vim_free(d); 7348 } 7349 7350 /* 7351 * Allocate a Dictionary item. 7352 * The "key" is copied to the new item. 7353 * Note that the value of the item "di_tv" still needs to be initialized! 7354 * Returns NULL when out of memory. 7355 */ 7356 dictitem_T * 7357 dictitem_alloc(char_u *key) 7358 { 7359 dictitem_T *di; 7360 7361 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 7362 if (di != NULL) 7363 { 7364 STRCPY(di->di_key, key); 7365 di->di_flags = DI_FLAGS_ALLOC; 7366 } 7367 return di; 7368 } 7369 7370 /* 7371 * Make a copy of a Dictionary item. 7372 */ 7373 static dictitem_T * 7374 dictitem_copy(dictitem_T *org) 7375 { 7376 dictitem_T *di; 7377 7378 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 7379 + STRLEN(org->di_key))); 7380 if (di != NULL) 7381 { 7382 STRCPY(di->di_key, org->di_key); 7383 di->di_flags = DI_FLAGS_ALLOC; 7384 copy_tv(&org->di_tv, &di->di_tv); 7385 } 7386 return di; 7387 } 7388 7389 /* 7390 * Remove item "item" from Dictionary "dict" and free it. 7391 */ 7392 static void 7393 dictitem_remove(dict_T *dict, dictitem_T *item) 7394 { 7395 hashitem_T *hi; 7396 7397 hi = hash_find(&dict->dv_hashtab, item->di_key); 7398 if (HASHITEM_EMPTY(hi)) 7399 EMSG2(_(e_intern2), "dictitem_remove()"); 7400 else 7401 hash_remove(&dict->dv_hashtab, hi); 7402 dictitem_free(item); 7403 } 7404 7405 /* 7406 * Free a dict item. Also clears the value. 7407 */ 7408 void 7409 dictitem_free(dictitem_T *item) 7410 { 7411 clear_tv(&item->di_tv); 7412 if (item->di_flags & DI_FLAGS_ALLOC) 7413 vim_free(item); 7414 } 7415 7416 /* 7417 * Make a copy of dict "d". Shallow if "deep" is FALSE. 7418 * The refcount of the new dict is set to 1. 7419 * See item_copy() for "copyID". 7420 * Returns NULL when out of memory. 7421 */ 7422 static dict_T * 7423 dict_copy(dict_T *orig, int deep, int copyID) 7424 { 7425 dict_T *copy; 7426 dictitem_T *di; 7427 int todo; 7428 hashitem_T *hi; 7429 7430 if (orig == NULL) 7431 return NULL; 7432 7433 copy = dict_alloc(); 7434 if (copy != NULL) 7435 { 7436 if (copyID != 0) 7437 { 7438 orig->dv_copyID = copyID; 7439 orig->dv_copydict = copy; 7440 } 7441 todo = (int)orig->dv_hashtab.ht_used; 7442 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7443 { 7444 if (!HASHITEM_EMPTY(hi)) 7445 { 7446 --todo; 7447 7448 di = dictitem_alloc(hi->hi_key); 7449 if (di == NULL) 7450 break; 7451 if (deep) 7452 { 7453 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 7454 copyID) == FAIL) 7455 { 7456 vim_free(di); 7457 break; 7458 } 7459 } 7460 else 7461 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 7462 if (dict_add(copy, di) == FAIL) 7463 { 7464 dictitem_free(di); 7465 break; 7466 } 7467 } 7468 } 7469 7470 ++copy->dv_refcount; 7471 if (todo > 0) 7472 { 7473 dict_unref(copy); 7474 copy = NULL; 7475 } 7476 } 7477 7478 return copy; 7479 } 7480 7481 /* 7482 * Add item "item" to Dictionary "d". 7483 * Returns FAIL when out of memory and when key already exists. 7484 */ 7485 int 7486 dict_add(dict_T *d, dictitem_T *item) 7487 { 7488 return hash_add(&d->dv_hashtab, item->di_key); 7489 } 7490 7491 /* 7492 * Add a number or string entry to dictionary "d". 7493 * When "str" is NULL use number "nr", otherwise use "str". 7494 * Returns FAIL when out of memory and when key already exists. 7495 */ 7496 int 7497 dict_add_nr_str( 7498 dict_T *d, 7499 char *key, 7500 long nr, 7501 char_u *str) 7502 { 7503 dictitem_T *item; 7504 7505 item = dictitem_alloc((char_u *)key); 7506 if (item == NULL) 7507 return FAIL; 7508 item->di_tv.v_lock = 0; 7509 if (str == NULL) 7510 { 7511 item->di_tv.v_type = VAR_NUMBER; 7512 item->di_tv.vval.v_number = nr; 7513 } 7514 else 7515 { 7516 item->di_tv.v_type = VAR_STRING; 7517 item->di_tv.vval.v_string = vim_strsave(str); 7518 } 7519 if (dict_add(d, item) == FAIL) 7520 { 7521 dictitem_free(item); 7522 return FAIL; 7523 } 7524 return OK; 7525 } 7526 7527 /* 7528 * Add a list entry to dictionary "d". 7529 * Returns FAIL when out of memory and when key already exists. 7530 */ 7531 int 7532 dict_add_list(dict_T *d, char *key, list_T *list) 7533 { 7534 dictitem_T *item; 7535 7536 item = dictitem_alloc((char_u *)key); 7537 if (item == NULL) 7538 return FAIL; 7539 item->di_tv.v_lock = 0; 7540 item->di_tv.v_type = VAR_LIST; 7541 item->di_tv.vval.v_list = list; 7542 if (dict_add(d, item) == FAIL) 7543 { 7544 dictitem_free(item); 7545 return FAIL; 7546 } 7547 ++list->lv_refcount; 7548 return OK; 7549 } 7550 7551 /* 7552 * Get the number of items in a Dictionary. 7553 */ 7554 static long 7555 dict_len(dict_T *d) 7556 { 7557 if (d == NULL) 7558 return 0L; 7559 return (long)d->dv_hashtab.ht_used; 7560 } 7561 7562 /* 7563 * Find item "key[len]" in Dictionary "d". 7564 * If "len" is negative use strlen(key). 7565 * Returns NULL when not found. 7566 */ 7567 dictitem_T * 7568 dict_find(dict_T *d, char_u *key, int len) 7569 { 7570 #define AKEYLEN 200 7571 char_u buf[AKEYLEN]; 7572 char_u *akey; 7573 char_u *tofree = NULL; 7574 hashitem_T *hi; 7575 7576 if (len < 0) 7577 akey = key; 7578 else if (len >= AKEYLEN) 7579 { 7580 tofree = akey = vim_strnsave(key, len); 7581 if (akey == NULL) 7582 return NULL; 7583 } 7584 else 7585 { 7586 /* Avoid a malloc/free by using buf[]. */ 7587 vim_strncpy(buf, key, len); 7588 akey = buf; 7589 } 7590 7591 hi = hash_find(&d->dv_hashtab, akey); 7592 vim_free(tofree); 7593 if (HASHITEM_EMPTY(hi)) 7594 return NULL; 7595 return HI2DI(hi); 7596 } 7597 7598 /* 7599 * Get a string item from a dictionary. 7600 * When "save" is TRUE allocate memory for it. 7601 * Returns NULL if the entry doesn't exist or out of memory. 7602 */ 7603 char_u * 7604 get_dict_string(dict_T *d, char_u *key, int save) 7605 { 7606 dictitem_T *di; 7607 char_u *s; 7608 7609 di = dict_find(d, key, -1); 7610 if (di == NULL) 7611 return NULL; 7612 s = get_tv_string(&di->di_tv); 7613 if (save && s != NULL) 7614 s = vim_strsave(s); 7615 return s; 7616 } 7617 7618 /* 7619 * Get a number item from a dictionary. 7620 * Returns 0 if the entry doesn't exist. 7621 */ 7622 long 7623 get_dict_number(dict_T *d, char_u *key) 7624 { 7625 dictitem_T *di; 7626 7627 di = dict_find(d, key, -1); 7628 if (di == NULL) 7629 return 0; 7630 return get_tv_number(&di->di_tv); 7631 } 7632 7633 /* 7634 * Return an allocated string with the string representation of a Dictionary. 7635 * May return NULL. 7636 */ 7637 static char_u * 7638 dict2string(typval_T *tv, int copyID) 7639 { 7640 garray_T ga; 7641 int first = TRUE; 7642 char_u *tofree; 7643 char_u numbuf[NUMBUFLEN]; 7644 hashitem_T *hi; 7645 char_u *s; 7646 dict_T *d; 7647 int todo; 7648 7649 if ((d = tv->vval.v_dict) == NULL) 7650 return NULL; 7651 ga_init2(&ga, (int)sizeof(char), 80); 7652 ga_append(&ga, '{'); 7653 7654 todo = (int)d->dv_hashtab.ht_used; 7655 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7656 { 7657 if (!HASHITEM_EMPTY(hi)) 7658 { 7659 --todo; 7660 7661 if (first) 7662 first = FALSE; 7663 else 7664 ga_concat(&ga, (char_u *)", "); 7665 7666 tofree = string_quote(hi->hi_key, FALSE); 7667 if (tofree != NULL) 7668 { 7669 ga_concat(&ga, tofree); 7670 vim_free(tofree); 7671 } 7672 ga_concat(&ga, (char_u *)": "); 7673 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7674 if (s != NULL) 7675 ga_concat(&ga, s); 7676 vim_free(tofree); 7677 if (s == NULL || did_echo_string_emsg) 7678 break; 7679 line_breakcheck(); 7680 7681 } 7682 } 7683 if (todo > 0) 7684 { 7685 vim_free(ga.ga_data); 7686 return NULL; 7687 } 7688 7689 ga_append(&ga, '}'); 7690 ga_append(&ga, NUL); 7691 return (char_u *)ga.ga_data; 7692 } 7693 7694 /* 7695 * Allocate a variable for a Dictionary and fill it from "*arg". 7696 * Return OK or FAIL. Returns NOTDONE for {expr}. 7697 */ 7698 static int 7699 get_dict_tv(char_u **arg, typval_T *rettv, int evaluate) 7700 { 7701 dict_T *d = NULL; 7702 typval_T tvkey; 7703 typval_T tv; 7704 char_u *key = NULL; 7705 dictitem_T *item; 7706 char_u *start = skipwhite(*arg + 1); 7707 char_u buf[NUMBUFLEN]; 7708 7709 /* 7710 * First check if it's not a curly-braces thing: {expr}. 7711 * Must do this without evaluating, otherwise a function may be called 7712 * twice. Unfortunately this means we need to call eval1() twice for the 7713 * first item. 7714 * But {} is an empty Dictionary. 7715 */ 7716 if (*start != '}') 7717 { 7718 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7719 return FAIL; 7720 if (*start == '}') 7721 return NOTDONE; 7722 } 7723 7724 if (evaluate) 7725 { 7726 d = dict_alloc(); 7727 if (d == NULL) 7728 return FAIL; 7729 } 7730 tvkey.v_type = VAR_UNKNOWN; 7731 tv.v_type = VAR_UNKNOWN; 7732 7733 *arg = skipwhite(*arg + 1); 7734 while (**arg != '}' && **arg != NUL) 7735 { 7736 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7737 goto failret; 7738 if (**arg != ':') 7739 { 7740 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7741 clear_tv(&tvkey); 7742 goto failret; 7743 } 7744 if (evaluate) 7745 { 7746 key = get_tv_string_buf_chk(&tvkey, buf); 7747 if (key == NULL || *key == NUL) 7748 { 7749 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7750 if (key != NULL) 7751 EMSG(_(e_emptykey)); 7752 clear_tv(&tvkey); 7753 goto failret; 7754 } 7755 } 7756 7757 *arg = skipwhite(*arg + 1); 7758 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7759 { 7760 if (evaluate) 7761 clear_tv(&tvkey); 7762 goto failret; 7763 } 7764 if (evaluate) 7765 { 7766 item = dict_find(d, key, -1); 7767 if (item != NULL) 7768 { 7769 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7770 clear_tv(&tvkey); 7771 clear_tv(&tv); 7772 goto failret; 7773 } 7774 item = dictitem_alloc(key); 7775 clear_tv(&tvkey); 7776 if (item != NULL) 7777 { 7778 item->di_tv = tv; 7779 item->di_tv.v_lock = 0; 7780 if (dict_add(d, item) == FAIL) 7781 dictitem_free(item); 7782 } 7783 } 7784 7785 if (**arg == '}') 7786 break; 7787 if (**arg != ',') 7788 { 7789 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7790 goto failret; 7791 } 7792 *arg = skipwhite(*arg + 1); 7793 } 7794 7795 if (**arg != '}') 7796 { 7797 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7798 failret: 7799 if (evaluate) 7800 dict_free(d, TRUE); 7801 return FAIL; 7802 } 7803 7804 *arg = skipwhite(*arg + 1); 7805 if (evaluate) 7806 { 7807 rettv->v_type = VAR_DICT; 7808 rettv->vval.v_dict = d; 7809 ++d->dv_refcount; 7810 } 7811 7812 return OK; 7813 } 7814 7815 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) 7816 #endif 7817 7818 static char * 7819 get_var_special_name(int nr) 7820 { 7821 switch (nr) 7822 { 7823 case VVAL_FALSE: return "v:false"; 7824 case VVAL_TRUE: return "v:true"; 7825 case VVAL_NONE: return "v:none"; 7826 case VVAL_NULL: return "v:null"; 7827 } 7828 EMSG2(_(e_intern2), "get_var_special_name()"); 7829 return "42"; 7830 } 7831 7832 /* 7833 * Return a string with the string representation of a variable. 7834 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7835 * "numbuf" is used for a number. 7836 * Does not put quotes around strings, as ":echo" displays values. 7837 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7838 * May return NULL. 7839 */ 7840 static char_u * 7841 echo_string( 7842 typval_T *tv, 7843 char_u **tofree, 7844 char_u *numbuf, 7845 int copyID) 7846 { 7847 static int recurse = 0; 7848 char_u *r = NULL; 7849 7850 if (recurse >= DICT_MAXNEST) 7851 { 7852 if (!did_echo_string_emsg) 7853 { 7854 /* Only give this message once for a recursive call to avoid 7855 * flooding the user with errors. And stop iterating over lists 7856 * and dicts. */ 7857 did_echo_string_emsg = TRUE; 7858 EMSG(_("E724: variable nested too deep for displaying")); 7859 } 7860 *tofree = NULL; 7861 return (char_u *)"{E724}"; 7862 } 7863 ++recurse; 7864 7865 switch (tv->v_type) 7866 { 7867 case VAR_FUNC: 7868 *tofree = NULL; 7869 r = tv->vval.v_string; 7870 break; 7871 7872 case VAR_PARTIAL: 7873 { 7874 partial_T *pt = tv->vval.v_partial; 7875 char_u *fname = string_quote(pt == NULL ? NULL 7876 : pt->pt_name, FALSE); 7877 garray_T ga; 7878 int i; 7879 char_u *tf; 7880 7881 ga_init2(&ga, 1, 100); 7882 ga_concat(&ga, (char_u *)"function("); 7883 if (fname != NULL) 7884 { 7885 ga_concat(&ga, fname); 7886 vim_free(fname); 7887 } 7888 if (pt != NULL && pt->pt_argc > 0) 7889 { 7890 ga_concat(&ga, (char_u *)", ["); 7891 for (i = 0; i < pt->pt_argc; ++i) 7892 { 7893 if (i > 0) 7894 ga_concat(&ga, (char_u *)", "); 7895 ga_concat(&ga, 7896 tv2string(&pt->pt_argv[i], &tf, numbuf, copyID)); 7897 vim_free(tf); 7898 } 7899 ga_concat(&ga, (char_u *)"]"); 7900 } 7901 if (pt != NULL && pt->pt_dict != NULL) 7902 { 7903 typval_T dtv; 7904 7905 ga_concat(&ga, (char_u *)", "); 7906 dtv.v_type = VAR_DICT; 7907 dtv.vval.v_dict = pt->pt_dict; 7908 ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID)); 7909 vim_free(tf); 7910 } 7911 ga_concat(&ga, (char_u *)")"); 7912 7913 *tofree = ga.ga_data; 7914 r = *tofree; 7915 break; 7916 } 7917 7918 case VAR_LIST: 7919 if (tv->vval.v_list == NULL) 7920 { 7921 *tofree = NULL; 7922 r = NULL; 7923 } 7924 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7925 { 7926 *tofree = NULL; 7927 r = (char_u *)"[...]"; 7928 } 7929 else 7930 { 7931 tv->vval.v_list->lv_copyID = copyID; 7932 *tofree = list2string(tv, copyID); 7933 r = *tofree; 7934 } 7935 break; 7936 7937 case VAR_DICT: 7938 if (tv->vval.v_dict == NULL) 7939 { 7940 *tofree = NULL; 7941 r = NULL; 7942 } 7943 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7944 { 7945 *tofree = NULL; 7946 r = (char_u *)"{...}"; 7947 } 7948 else 7949 { 7950 tv->vval.v_dict->dv_copyID = copyID; 7951 *tofree = dict2string(tv, copyID); 7952 r = *tofree; 7953 } 7954 break; 7955 7956 case VAR_STRING: 7957 case VAR_NUMBER: 7958 case VAR_UNKNOWN: 7959 case VAR_JOB: 7960 case VAR_CHANNEL: 7961 *tofree = NULL; 7962 r = get_tv_string_buf(tv, numbuf); 7963 break; 7964 7965 case VAR_FLOAT: 7966 #ifdef FEAT_FLOAT 7967 *tofree = NULL; 7968 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7969 r = numbuf; 7970 break; 7971 #endif 7972 7973 case VAR_SPECIAL: 7974 *tofree = NULL; 7975 r = (char_u *)get_var_special_name(tv->vval.v_number); 7976 break; 7977 } 7978 7979 if (--recurse == 0) 7980 did_echo_string_emsg = FALSE; 7981 return r; 7982 } 7983 7984 /* 7985 * Return a string with the string representation of a variable. 7986 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7987 * "numbuf" is used for a number. 7988 * Puts quotes around strings, so that they can be parsed back by eval(). 7989 * May return NULL. 7990 */ 7991 static char_u * 7992 tv2string( 7993 typval_T *tv, 7994 char_u **tofree, 7995 char_u *numbuf, 7996 int copyID) 7997 { 7998 switch (tv->v_type) 7999 { 8000 case VAR_FUNC: 8001 *tofree = string_quote(tv->vval.v_string, TRUE); 8002 return *tofree; 8003 case VAR_STRING: 8004 *tofree = string_quote(tv->vval.v_string, FALSE); 8005 return *tofree; 8006 case VAR_FLOAT: 8007 #ifdef FEAT_FLOAT 8008 *tofree = NULL; 8009 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 8010 return numbuf; 8011 #endif 8012 case VAR_NUMBER: 8013 case VAR_LIST: 8014 case VAR_DICT: 8015 case VAR_PARTIAL: 8016 case VAR_SPECIAL: 8017 case VAR_JOB: 8018 case VAR_CHANNEL: 8019 case VAR_UNKNOWN: 8020 break; 8021 } 8022 return echo_string(tv, tofree, numbuf, copyID); 8023 } 8024 8025 /* 8026 * Return string "str" in ' quotes, doubling ' characters. 8027 * If "str" is NULL an empty string is assumed. 8028 * If "function" is TRUE make it function('string'). 8029 */ 8030 static char_u * 8031 string_quote(char_u *str, int function) 8032 { 8033 unsigned len; 8034 char_u *p, *r, *s; 8035 8036 len = (function ? 13 : 3); 8037 if (str != NULL) 8038 { 8039 len += (unsigned)STRLEN(str); 8040 for (p = str; *p != NUL; mb_ptr_adv(p)) 8041 if (*p == '\'') 8042 ++len; 8043 } 8044 s = r = alloc(len); 8045 if (r != NULL) 8046 { 8047 if (function) 8048 { 8049 STRCPY(r, "function('"); 8050 r += 10; 8051 } 8052 else 8053 *r++ = '\''; 8054 if (str != NULL) 8055 for (p = str; *p != NUL; ) 8056 { 8057 if (*p == '\'') 8058 *r++ = '\''; 8059 MB_COPY_CHAR(p, r); 8060 } 8061 *r++ = '\''; 8062 if (function) 8063 *r++ = ')'; 8064 *r++ = NUL; 8065 } 8066 return s; 8067 } 8068 8069 #if defined(FEAT_FLOAT) || defined(PROTO) 8070 /* 8071 * Convert the string "text" to a floating point number. 8072 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 8073 * this always uses a decimal point. 8074 * Returns the length of the text that was consumed. 8075 */ 8076 int 8077 string2float( 8078 char_u *text, 8079 float_T *value) /* result stored here */ 8080 { 8081 char *s = (char *)text; 8082 float_T f; 8083 8084 f = strtod(s, &s); 8085 *value = f; 8086 return (int)((char_u *)s - text); 8087 } 8088 #endif 8089 8090 /* 8091 * Get the value of an environment variable. 8092 * "arg" is pointing to the '$'. It is advanced to after the name. 8093 * If the environment variable was not set, silently assume it is empty. 8094 * Return FAIL if the name is invalid. 8095 */ 8096 static int 8097 get_env_tv(char_u **arg, typval_T *rettv, int evaluate) 8098 { 8099 char_u *string = NULL; 8100 int len; 8101 int cc; 8102 char_u *name; 8103 int mustfree = FALSE; 8104 8105 ++*arg; 8106 name = *arg; 8107 len = get_env_len(arg); 8108 if (evaluate) 8109 { 8110 if (len == 0) 8111 return FAIL; /* invalid empty name */ 8112 8113 cc = name[len]; 8114 name[len] = NUL; 8115 /* first try vim_getenv(), fast for normal environment vars */ 8116 string = vim_getenv(name, &mustfree); 8117 if (string != NULL && *string != NUL) 8118 { 8119 if (!mustfree) 8120 string = vim_strsave(string); 8121 } 8122 else 8123 { 8124 if (mustfree) 8125 vim_free(string); 8126 8127 /* next try expanding things like $VIM and ${HOME} */ 8128 string = expand_env_save(name - 1); 8129 if (string != NULL && *string == '$') 8130 { 8131 vim_free(string); 8132 string = NULL; 8133 } 8134 } 8135 name[len] = cc; 8136 8137 rettv->v_type = VAR_STRING; 8138 rettv->vval.v_string = string; 8139 } 8140 8141 return OK; 8142 } 8143 8144 /* 8145 * Array with names and number of arguments of all internal functions 8146 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 8147 */ 8148 static struct fst 8149 { 8150 char *f_name; /* function name */ 8151 char f_min_argc; /* minimal number of arguments */ 8152 char f_max_argc; /* maximal number of arguments */ 8153 void (*f_func)(typval_T *args, typval_T *rvar); 8154 /* implementation of function */ 8155 } functions[] = 8156 { 8157 #ifdef FEAT_FLOAT 8158 {"abs", 1, 1, f_abs}, 8159 {"acos", 1, 1, f_acos}, /* WJMc */ 8160 #endif 8161 {"add", 2, 2, f_add}, 8162 {"alloc_fail", 3, 3, f_alloc_fail}, 8163 {"and", 2, 2, f_and}, 8164 {"append", 2, 2, f_append}, 8165 {"argc", 0, 0, f_argc}, 8166 {"argidx", 0, 0, f_argidx}, 8167 {"arglistid", 0, 2, f_arglistid}, 8168 {"argv", 0, 1, f_argv}, 8169 #ifdef FEAT_FLOAT 8170 {"asin", 1, 1, f_asin}, /* WJMc */ 8171 #endif 8172 {"assert_equal", 2, 3, f_assert_equal}, 8173 {"assert_exception", 1, 2, f_assert_exception}, 8174 {"assert_fails", 1, 2, f_assert_fails}, 8175 {"assert_false", 1, 2, f_assert_false}, 8176 {"assert_match", 2, 3, f_assert_match}, 8177 {"assert_true", 1, 2, f_assert_true}, 8178 #ifdef FEAT_FLOAT 8179 {"atan", 1, 1, f_atan}, 8180 {"atan2", 2, 2, f_atan2}, 8181 #endif 8182 {"browse", 4, 4, f_browse}, 8183 {"browsedir", 2, 2, f_browsedir}, 8184 {"bufexists", 1, 1, f_bufexists}, 8185 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 8186 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 8187 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 8188 {"buflisted", 1, 1, f_buflisted}, 8189 {"bufloaded", 1, 1, f_bufloaded}, 8190 {"bufname", 1, 1, f_bufname}, 8191 {"bufnr", 1, 2, f_bufnr}, 8192 {"bufwinnr", 1, 1, f_bufwinnr}, 8193 {"byte2line", 1, 1, f_byte2line}, 8194 {"byteidx", 2, 2, f_byteidx}, 8195 {"byteidxcomp", 2, 2, f_byteidxcomp}, 8196 {"call", 2, 3, f_call}, 8197 #ifdef FEAT_FLOAT 8198 {"ceil", 1, 1, f_ceil}, 8199 #endif 8200 #ifdef FEAT_JOB_CHANNEL 8201 {"ch_close", 1, 1, f_ch_close}, 8202 {"ch_evalexpr", 2, 3, f_ch_evalexpr}, 8203 {"ch_evalraw", 2, 3, f_ch_evalraw}, 8204 {"ch_getbufnr", 2, 2, f_ch_getbufnr}, 8205 {"ch_getjob", 1, 1, f_ch_getjob}, 8206 {"ch_info", 1, 1, f_ch_info}, 8207 {"ch_log", 1, 2, f_ch_log}, 8208 {"ch_logfile", 1, 2, f_ch_logfile}, 8209 {"ch_open", 1, 2, f_ch_open}, 8210 {"ch_read", 1, 2, f_ch_read}, 8211 {"ch_readraw", 1, 2, f_ch_readraw}, 8212 {"ch_sendexpr", 2, 3, f_ch_sendexpr}, 8213 {"ch_sendraw", 2, 3, f_ch_sendraw}, 8214 {"ch_setoptions", 2, 2, f_ch_setoptions}, 8215 {"ch_status", 1, 1, f_ch_status}, 8216 #endif 8217 {"changenr", 0, 0, f_changenr}, 8218 {"char2nr", 1, 2, f_char2nr}, 8219 {"cindent", 1, 1, f_cindent}, 8220 {"clearmatches", 0, 0, f_clearmatches}, 8221 {"col", 1, 1, f_col}, 8222 #if defined(FEAT_INS_EXPAND) 8223 {"complete", 2, 2, f_complete}, 8224 {"complete_add", 1, 1, f_complete_add}, 8225 {"complete_check", 0, 0, f_complete_check}, 8226 #endif 8227 {"confirm", 1, 4, f_confirm}, 8228 {"copy", 1, 1, f_copy}, 8229 #ifdef FEAT_FLOAT 8230 {"cos", 1, 1, f_cos}, 8231 {"cosh", 1, 1, f_cosh}, 8232 #endif 8233 {"count", 2, 4, f_count}, 8234 {"cscope_connection",0,3, f_cscope_connection}, 8235 {"cursor", 1, 3, f_cursor}, 8236 {"deepcopy", 1, 2, f_deepcopy}, 8237 {"delete", 1, 2, f_delete}, 8238 {"did_filetype", 0, 0, f_did_filetype}, 8239 {"diff_filler", 1, 1, f_diff_filler}, 8240 {"diff_hlID", 2, 2, f_diff_hlID}, 8241 {"disable_char_avail_for_testing", 1, 1, f_disable_char_avail_for_testing}, 8242 {"empty", 1, 1, f_empty}, 8243 {"escape", 2, 2, f_escape}, 8244 {"eval", 1, 1, f_eval}, 8245 {"eventhandler", 0, 0, f_eventhandler}, 8246 {"executable", 1, 1, f_executable}, 8247 {"exepath", 1, 1, f_exepath}, 8248 {"exists", 1, 1, f_exists}, 8249 #ifdef FEAT_FLOAT 8250 {"exp", 1, 1, f_exp}, 8251 #endif 8252 {"expand", 1, 3, f_expand}, 8253 {"extend", 2, 3, f_extend}, 8254 {"feedkeys", 1, 2, f_feedkeys}, 8255 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 8256 {"filereadable", 1, 1, f_filereadable}, 8257 {"filewritable", 1, 1, f_filewritable}, 8258 {"filter", 2, 2, f_filter}, 8259 {"finddir", 1, 3, f_finddir}, 8260 {"findfile", 1, 3, f_findfile}, 8261 #ifdef FEAT_FLOAT 8262 {"float2nr", 1, 1, f_float2nr}, 8263 {"floor", 1, 1, f_floor}, 8264 {"fmod", 2, 2, f_fmod}, 8265 #endif 8266 {"fnameescape", 1, 1, f_fnameescape}, 8267 {"fnamemodify", 2, 2, f_fnamemodify}, 8268 {"foldclosed", 1, 1, f_foldclosed}, 8269 {"foldclosedend", 1, 1, f_foldclosedend}, 8270 {"foldlevel", 1, 1, f_foldlevel}, 8271 {"foldtext", 0, 0, f_foldtext}, 8272 {"foldtextresult", 1, 1, f_foldtextresult}, 8273 {"foreground", 0, 0, f_foreground}, 8274 {"function", 1, 3, f_function}, 8275 {"garbagecollect", 0, 1, f_garbagecollect}, 8276 {"get", 2, 3, f_get}, 8277 {"getbufline", 2, 3, f_getbufline}, 8278 {"getbufvar", 2, 3, f_getbufvar}, 8279 {"getchar", 0, 1, f_getchar}, 8280 {"getcharmod", 0, 0, f_getcharmod}, 8281 {"getcharsearch", 0, 0, f_getcharsearch}, 8282 {"getcmdline", 0, 0, f_getcmdline}, 8283 {"getcmdpos", 0, 0, f_getcmdpos}, 8284 {"getcmdtype", 0, 0, f_getcmdtype}, 8285 {"getcmdwintype", 0, 0, f_getcmdwintype}, 8286 {"getcurpos", 0, 0, f_getcurpos}, 8287 {"getcwd", 0, 2, f_getcwd}, 8288 {"getfontname", 0, 1, f_getfontname}, 8289 {"getfperm", 1, 1, f_getfperm}, 8290 {"getfsize", 1, 1, f_getfsize}, 8291 {"getftime", 1, 1, f_getftime}, 8292 {"getftype", 1, 1, f_getftype}, 8293 {"getline", 1, 2, f_getline}, 8294 {"getloclist", 1, 1, f_getqflist}, 8295 {"getmatches", 0, 0, f_getmatches}, 8296 {"getpid", 0, 0, f_getpid}, 8297 {"getpos", 1, 1, f_getpos}, 8298 {"getqflist", 0, 0, f_getqflist}, 8299 {"getreg", 0, 3, f_getreg}, 8300 {"getregtype", 0, 1, f_getregtype}, 8301 {"gettabvar", 2, 3, f_gettabvar}, 8302 {"gettabwinvar", 3, 4, f_gettabwinvar}, 8303 {"getwinposx", 0, 0, f_getwinposx}, 8304 {"getwinposy", 0, 0, f_getwinposy}, 8305 {"getwinvar", 2, 3, f_getwinvar}, 8306 {"glob", 1, 4, f_glob}, 8307 {"glob2regpat", 1, 1, f_glob2regpat}, 8308 {"globpath", 2, 5, f_globpath}, 8309 {"has", 1, 1, f_has}, 8310 {"has_key", 2, 2, f_has_key}, 8311 {"haslocaldir", 0, 2, f_haslocaldir}, 8312 {"hasmapto", 1, 3, f_hasmapto}, 8313 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 8314 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 8315 {"histadd", 2, 2, f_histadd}, 8316 {"histdel", 1, 2, f_histdel}, 8317 {"histget", 1, 2, f_histget}, 8318 {"histnr", 1, 1, f_histnr}, 8319 {"hlID", 1, 1, f_hlID}, 8320 {"hlexists", 1, 1, f_hlexists}, 8321 {"hostname", 0, 0, f_hostname}, 8322 {"iconv", 3, 3, f_iconv}, 8323 {"indent", 1, 1, f_indent}, 8324 {"index", 2, 4, f_index}, 8325 {"input", 1, 3, f_input}, 8326 {"inputdialog", 1, 3, f_inputdialog}, 8327 {"inputlist", 1, 1, f_inputlist}, 8328 {"inputrestore", 0, 0, f_inputrestore}, 8329 {"inputsave", 0, 0, f_inputsave}, 8330 {"inputsecret", 1, 2, f_inputsecret}, 8331 {"insert", 2, 3, f_insert}, 8332 {"invert", 1, 1, f_invert}, 8333 {"isdirectory", 1, 1, f_isdirectory}, 8334 {"islocked", 1, 1, f_islocked}, 8335 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 8336 {"isnan", 1, 1, f_isnan}, 8337 #endif 8338 {"items", 1, 1, f_items}, 8339 #ifdef FEAT_JOB_CHANNEL 8340 {"job_getchannel", 1, 1, f_job_getchannel}, 8341 {"job_info", 1, 1, f_job_info}, 8342 {"job_setoptions", 2, 2, f_job_setoptions}, 8343 {"job_start", 1, 2, f_job_start}, 8344 {"job_status", 1, 1, f_job_status}, 8345 {"job_stop", 1, 2, f_job_stop}, 8346 #endif 8347 {"join", 1, 2, f_join}, 8348 {"js_decode", 1, 1, f_js_decode}, 8349 {"js_encode", 1, 1, f_js_encode}, 8350 {"json_decode", 1, 1, f_json_decode}, 8351 {"json_encode", 1, 1, f_json_encode}, 8352 {"keys", 1, 1, f_keys}, 8353 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 8354 {"len", 1, 1, f_len}, 8355 {"libcall", 3, 3, f_libcall}, 8356 {"libcallnr", 3, 3, f_libcallnr}, 8357 {"line", 1, 1, f_line}, 8358 {"line2byte", 1, 1, f_line2byte}, 8359 {"lispindent", 1, 1, f_lispindent}, 8360 {"localtime", 0, 0, f_localtime}, 8361 #ifdef FEAT_FLOAT 8362 {"log", 1, 1, f_log}, 8363 {"log10", 1, 1, f_log10}, 8364 #endif 8365 #ifdef FEAT_LUA 8366 {"luaeval", 1, 2, f_luaeval}, 8367 #endif 8368 {"map", 2, 2, f_map}, 8369 {"maparg", 1, 4, f_maparg}, 8370 {"mapcheck", 1, 3, f_mapcheck}, 8371 {"match", 2, 4, f_match}, 8372 {"matchadd", 2, 5, f_matchadd}, 8373 {"matchaddpos", 2, 5, f_matchaddpos}, 8374 {"matcharg", 1, 1, f_matcharg}, 8375 {"matchdelete", 1, 1, f_matchdelete}, 8376 {"matchend", 2, 4, f_matchend}, 8377 {"matchlist", 2, 4, f_matchlist}, 8378 {"matchstr", 2, 4, f_matchstr}, 8379 {"max", 1, 1, f_max}, 8380 {"min", 1, 1, f_min}, 8381 #ifdef vim_mkdir 8382 {"mkdir", 1, 3, f_mkdir}, 8383 #endif 8384 {"mode", 0, 1, f_mode}, 8385 #ifdef FEAT_MZSCHEME 8386 {"mzeval", 1, 1, f_mzeval}, 8387 #endif 8388 {"nextnonblank", 1, 1, f_nextnonblank}, 8389 {"nr2char", 1, 2, f_nr2char}, 8390 {"or", 2, 2, f_or}, 8391 {"pathshorten", 1, 1, f_pathshorten}, 8392 #ifdef FEAT_PERL 8393 {"perleval", 1, 1, f_perleval}, 8394 #endif 8395 #ifdef FEAT_FLOAT 8396 {"pow", 2, 2, f_pow}, 8397 #endif 8398 {"prevnonblank", 1, 1, f_prevnonblank}, 8399 {"printf", 2, 19, f_printf}, 8400 {"pumvisible", 0, 0, f_pumvisible}, 8401 #ifdef FEAT_PYTHON3 8402 {"py3eval", 1, 1, f_py3eval}, 8403 #endif 8404 #ifdef FEAT_PYTHON 8405 {"pyeval", 1, 1, f_pyeval}, 8406 #endif 8407 {"range", 1, 3, f_range}, 8408 {"readfile", 1, 3, f_readfile}, 8409 {"reltime", 0, 2, f_reltime}, 8410 #ifdef FEAT_FLOAT 8411 {"reltimefloat", 1, 1, f_reltimefloat}, 8412 #endif 8413 {"reltimestr", 1, 1, f_reltimestr}, 8414 {"remote_expr", 2, 3, f_remote_expr}, 8415 {"remote_foreground", 1, 1, f_remote_foreground}, 8416 {"remote_peek", 1, 2, f_remote_peek}, 8417 {"remote_read", 1, 1, f_remote_read}, 8418 {"remote_send", 2, 3, f_remote_send}, 8419 {"remove", 2, 3, f_remove}, 8420 {"rename", 2, 2, f_rename}, 8421 {"repeat", 2, 2, f_repeat}, 8422 {"resolve", 1, 1, f_resolve}, 8423 {"reverse", 1, 1, f_reverse}, 8424 #ifdef FEAT_FLOAT 8425 {"round", 1, 1, f_round}, 8426 #endif 8427 {"screenattr", 2, 2, f_screenattr}, 8428 {"screenchar", 2, 2, f_screenchar}, 8429 {"screencol", 0, 0, f_screencol}, 8430 {"screenrow", 0, 0, f_screenrow}, 8431 {"search", 1, 4, f_search}, 8432 {"searchdecl", 1, 3, f_searchdecl}, 8433 {"searchpair", 3, 7, f_searchpair}, 8434 {"searchpairpos", 3, 7, f_searchpairpos}, 8435 {"searchpos", 1, 4, f_searchpos}, 8436 {"server2client", 2, 2, f_server2client}, 8437 {"serverlist", 0, 0, f_serverlist}, 8438 {"setbufvar", 3, 3, f_setbufvar}, 8439 {"setcharsearch", 1, 1, f_setcharsearch}, 8440 {"setcmdpos", 1, 1, f_setcmdpos}, 8441 {"setfperm", 2, 2, f_setfperm}, 8442 {"setline", 2, 2, f_setline}, 8443 {"setloclist", 2, 3, f_setloclist}, 8444 {"setmatches", 1, 1, f_setmatches}, 8445 {"setpos", 2, 2, f_setpos}, 8446 {"setqflist", 1, 2, f_setqflist}, 8447 {"setreg", 2, 3, f_setreg}, 8448 {"settabvar", 3, 3, f_settabvar}, 8449 {"settabwinvar", 4, 4, f_settabwinvar}, 8450 {"setwinvar", 3, 3, f_setwinvar}, 8451 #ifdef FEAT_CRYPT 8452 {"sha256", 1, 1, f_sha256}, 8453 #endif 8454 {"shellescape", 1, 2, f_shellescape}, 8455 {"shiftwidth", 0, 0, f_shiftwidth}, 8456 {"simplify", 1, 1, f_simplify}, 8457 #ifdef FEAT_FLOAT 8458 {"sin", 1, 1, f_sin}, 8459 {"sinh", 1, 1, f_sinh}, 8460 #endif 8461 {"sort", 1, 3, f_sort}, 8462 {"soundfold", 1, 1, f_soundfold}, 8463 {"spellbadword", 0, 1, f_spellbadword}, 8464 {"spellsuggest", 1, 3, f_spellsuggest}, 8465 {"split", 1, 3, f_split}, 8466 #ifdef FEAT_FLOAT 8467 {"sqrt", 1, 1, f_sqrt}, 8468 {"str2float", 1, 1, f_str2float}, 8469 #endif 8470 {"str2nr", 1, 2, f_str2nr}, 8471 {"strchars", 1, 2, f_strchars}, 8472 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 8473 #ifdef HAVE_STRFTIME 8474 {"strftime", 1, 2, f_strftime}, 8475 #endif 8476 {"stridx", 2, 3, f_stridx}, 8477 {"string", 1, 1, f_string}, 8478 {"strlen", 1, 1, f_strlen}, 8479 {"strpart", 2, 3, f_strpart}, 8480 {"strridx", 2, 3, f_strridx}, 8481 {"strtrans", 1, 1, f_strtrans}, 8482 {"strwidth", 1, 1, f_strwidth}, 8483 {"submatch", 1, 2, f_submatch}, 8484 {"substitute", 4, 4, f_substitute}, 8485 {"synID", 3, 3, f_synID}, 8486 {"synIDattr", 2, 3, f_synIDattr}, 8487 {"synIDtrans", 1, 1, f_synIDtrans}, 8488 {"synconcealed", 2, 2, f_synconcealed}, 8489 {"synstack", 2, 2, f_synstack}, 8490 {"system", 1, 2, f_system}, 8491 {"systemlist", 1, 2, f_systemlist}, 8492 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 8493 {"tabpagenr", 0, 1, f_tabpagenr}, 8494 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 8495 {"tagfiles", 0, 0, f_tagfiles}, 8496 {"taglist", 1, 1, f_taglist}, 8497 #ifdef FEAT_FLOAT 8498 {"tan", 1, 1, f_tan}, 8499 {"tanh", 1, 1, f_tanh}, 8500 #endif 8501 {"tempname", 0, 0, f_tempname}, 8502 {"test", 1, 1, f_test}, 8503 #ifdef FEAT_TIMERS 8504 {"timer_start", 2, 3, f_timer_start}, 8505 {"timer_stop", 1, 1, f_timer_stop}, 8506 #endif 8507 {"tolower", 1, 1, f_tolower}, 8508 {"toupper", 1, 1, f_toupper}, 8509 {"tr", 3, 3, f_tr}, 8510 #ifdef FEAT_FLOAT 8511 {"trunc", 1, 1, f_trunc}, 8512 #endif 8513 {"type", 1, 1, f_type}, 8514 {"undofile", 1, 1, f_undofile}, 8515 {"undotree", 0, 0, f_undotree}, 8516 {"uniq", 1, 3, f_uniq}, 8517 {"values", 1, 1, f_values}, 8518 {"virtcol", 1, 1, f_virtcol}, 8519 {"visualmode", 0, 1, f_visualmode}, 8520 {"wildmenumode", 0, 0, f_wildmenumode}, 8521 {"win_findbuf", 1, 1, f_win_findbuf}, 8522 {"win_getid", 0, 2, f_win_getid}, 8523 {"win_gotoid", 1, 1, f_win_gotoid}, 8524 {"win_id2tabwin", 1, 1, f_win_id2tabwin}, 8525 {"win_id2win", 1, 1, f_win_id2win}, 8526 {"winbufnr", 1, 1, f_winbufnr}, 8527 {"wincol", 0, 0, f_wincol}, 8528 {"winheight", 1, 1, f_winheight}, 8529 {"winline", 0, 0, f_winline}, 8530 {"winnr", 0, 1, f_winnr}, 8531 {"winrestcmd", 0, 0, f_winrestcmd}, 8532 {"winrestview", 1, 1, f_winrestview}, 8533 {"winsaveview", 0, 0, f_winsaveview}, 8534 {"winwidth", 1, 1, f_winwidth}, 8535 {"wordcount", 0, 0, f_wordcount}, 8536 {"writefile", 2, 3, f_writefile}, 8537 {"xor", 2, 2, f_xor}, 8538 }; 8539 8540 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 8541 8542 /* 8543 * Function given to ExpandGeneric() to obtain the list of internal 8544 * or user defined function names. 8545 */ 8546 char_u * 8547 get_function_name(expand_T *xp, int idx) 8548 { 8549 static int intidx = -1; 8550 char_u *name; 8551 8552 if (idx == 0) 8553 intidx = -1; 8554 if (intidx < 0) 8555 { 8556 name = get_user_func_name(xp, idx); 8557 if (name != NULL) 8558 return name; 8559 } 8560 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 8561 { 8562 STRCPY(IObuff, functions[intidx].f_name); 8563 STRCAT(IObuff, "("); 8564 if (functions[intidx].f_max_argc == 0) 8565 STRCAT(IObuff, ")"); 8566 return IObuff; 8567 } 8568 8569 return NULL; 8570 } 8571 8572 /* 8573 * Function given to ExpandGeneric() to obtain the list of internal or 8574 * user defined variable or function names. 8575 */ 8576 char_u * 8577 get_expr_name(expand_T *xp, int idx) 8578 { 8579 static int intidx = -1; 8580 char_u *name; 8581 8582 if (idx == 0) 8583 intidx = -1; 8584 if (intidx < 0) 8585 { 8586 name = get_function_name(xp, idx); 8587 if (name != NULL) 8588 return name; 8589 } 8590 return get_user_var_name(xp, ++intidx); 8591 } 8592 8593 #endif /* FEAT_CMDL_COMPL */ 8594 8595 #if defined(EBCDIC) || defined(PROTO) 8596 /* 8597 * Compare struct fst by function name. 8598 */ 8599 static int 8600 compare_func_name(const void *s1, const void *s2) 8601 { 8602 struct fst *p1 = (struct fst *)s1; 8603 struct fst *p2 = (struct fst *)s2; 8604 8605 return STRCMP(p1->f_name, p2->f_name); 8606 } 8607 8608 /* 8609 * Sort the function table by function name. 8610 * The sorting of the table above is ASCII dependant. 8611 * On machines using EBCDIC we have to sort it. 8612 */ 8613 static void 8614 sortFunctions(void) 8615 { 8616 int funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8617 8618 qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name); 8619 } 8620 #endif 8621 8622 8623 /* 8624 * Find internal function in table above. 8625 * Return index, or -1 if not found 8626 */ 8627 static int 8628 find_internal_func( 8629 char_u *name) /* name of the function */ 8630 { 8631 int first = 0; 8632 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8633 int cmp; 8634 int x; 8635 8636 /* 8637 * Find the function name in the table. Binary search. 8638 */ 8639 while (first <= last) 8640 { 8641 x = first + ((unsigned)(last - first) >> 1); 8642 cmp = STRCMP(name, functions[x].f_name); 8643 if (cmp < 0) 8644 last = x - 1; 8645 else if (cmp > 0) 8646 first = x + 1; 8647 else 8648 return x; 8649 } 8650 return -1; 8651 } 8652 8653 /* 8654 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 8655 * name it contains, otherwise return "name". 8656 * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set 8657 * "partialp". 8658 */ 8659 static char_u * 8660 deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload) 8661 { 8662 dictitem_T *v; 8663 int cc; 8664 8665 if (partialp != NULL) 8666 *partialp = NULL; 8667 8668 cc = name[*lenp]; 8669 name[*lenp] = NUL; 8670 v = find_var(name, NULL, no_autoload); 8671 name[*lenp] = cc; 8672 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 8673 { 8674 if (v->di_tv.vval.v_string == NULL) 8675 { 8676 *lenp = 0; 8677 return (char_u *)""; /* just in case */ 8678 } 8679 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 8680 return v->di_tv.vval.v_string; 8681 } 8682 8683 if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) 8684 { 8685 partial_T *pt = v->di_tv.vval.v_partial; 8686 8687 if (pt == NULL) 8688 { 8689 *lenp = 0; 8690 return (char_u *)""; /* just in case */ 8691 } 8692 if (partialp != NULL) 8693 *partialp = pt; 8694 *lenp = (int)STRLEN(pt->pt_name); 8695 return pt->pt_name; 8696 } 8697 8698 return name; 8699 } 8700 8701 /* 8702 * Allocate a variable for the result of a function. 8703 * Return OK or FAIL. 8704 */ 8705 static int 8706 get_func_tv( 8707 char_u *name, /* name of the function */ 8708 int len, /* length of "name" */ 8709 typval_T *rettv, 8710 char_u **arg, /* argument, pointing to the '(' */ 8711 linenr_T firstline, /* first line of range */ 8712 linenr_T lastline, /* last line of range */ 8713 int *doesrange, /* return: function handled range */ 8714 int evaluate, 8715 partial_T *partial, /* for extra arguments */ 8716 dict_T *selfdict) /* Dictionary for "self" */ 8717 { 8718 char_u *argp; 8719 int ret = OK; 8720 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 8721 int argcount = 0; /* number of arguments found */ 8722 8723 /* 8724 * Get the arguments. 8725 */ 8726 argp = *arg; 8727 while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) 8728 { 8729 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 8730 if (*argp == ')' || *argp == ',' || *argp == NUL) 8731 break; 8732 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 8733 { 8734 ret = FAIL; 8735 break; 8736 } 8737 ++argcount; 8738 if (*argp != ',') 8739 break; 8740 } 8741 if (*argp == ')') 8742 ++argp; 8743 else 8744 ret = FAIL; 8745 8746 if (ret == OK) 8747 ret = call_func(name, len, rettv, argcount, argvars, 8748 firstline, lastline, doesrange, evaluate, partial, selfdict); 8749 else if (!aborting()) 8750 { 8751 if (argcount == MAX_FUNC_ARGS) 8752 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 8753 else 8754 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 8755 } 8756 8757 while (--argcount >= 0) 8758 clear_tv(&argvars[argcount]); 8759 8760 *arg = skipwhite(argp); 8761 return ret; 8762 } 8763 8764 #define ERROR_UNKNOWN 0 8765 #define ERROR_TOOMANY 1 8766 #define ERROR_TOOFEW 2 8767 #define ERROR_SCRIPT 3 8768 #define ERROR_DICT 4 8769 #define ERROR_NONE 5 8770 #define ERROR_OTHER 6 8771 #define FLEN_FIXED 40 8772 8773 /* 8774 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8775 * Change <SNR>123_name() to K_SNR 123_name(). 8776 * Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory 8777 * (slow). 8778 */ 8779 static char_u * 8780 fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) 8781 { 8782 int llen; 8783 char_u *fname; 8784 int i; 8785 8786 llen = eval_fname_script(name); 8787 if (llen > 0) 8788 { 8789 fname_buf[0] = K_SPECIAL; 8790 fname_buf[1] = KS_EXTRA; 8791 fname_buf[2] = (int)KE_SNR; 8792 i = 3; 8793 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8794 { 8795 if (current_SID <= 0) 8796 *error = ERROR_SCRIPT; 8797 else 8798 { 8799 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8800 i = (int)STRLEN(fname_buf); 8801 } 8802 } 8803 if (i + STRLEN(name + llen) < FLEN_FIXED) 8804 { 8805 STRCPY(fname_buf + i, name + llen); 8806 fname = fname_buf; 8807 } 8808 else 8809 { 8810 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8811 if (fname == NULL) 8812 *error = ERROR_OTHER; 8813 else 8814 { 8815 *tofree = fname; 8816 mch_memmove(fname, fname_buf, (size_t)i); 8817 STRCPY(fname + i, name + llen); 8818 } 8819 } 8820 } 8821 else 8822 fname = name; 8823 return fname; 8824 } 8825 8826 /* 8827 * Call a function with its resolved parameters 8828 * Return FAIL when the function can't be called, OK otherwise. 8829 * Also returns OK when an error was encountered while executing the function. 8830 */ 8831 int 8832 call_func( 8833 char_u *funcname, /* name of the function */ 8834 int len, /* length of "name" */ 8835 typval_T *rettv, /* return value goes here */ 8836 int argcount_in, /* number of "argvars" */ 8837 typval_T *argvars_in, /* vars for arguments, must have "argcount" 8838 PLUS ONE elements! */ 8839 linenr_T firstline, /* first line of range */ 8840 linenr_T lastline, /* last line of range */ 8841 int *doesrange, /* return: function handled range */ 8842 int evaluate, 8843 partial_T *partial, /* optional, can be NULL */ 8844 dict_T *selfdict_in) /* Dictionary for "self" */ 8845 { 8846 int ret = FAIL; 8847 int error = ERROR_NONE; 8848 int i; 8849 ufunc_T *fp; 8850 char_u fname_buf[FLEN_FIXED + 1]; 8851 char_u *tofree = NULL; 8852 char_u *fname; 8853 char_u *name; 8854 int argcount = argcount_in; 8855 typval_T *argvars = argvars_in; 8856 dict_T *selfdict = selfdict_in; 8857 typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */ 8858 int argv_clear = 0; 8859 8860 /* Make a copy of the name, if it comes from a funcref variable it could 8861 * be changed or deleted in the called function. */ 8862 name = vim_strnsave(funcname, len); 8863 if (name == NULL) 8864 return ret; 8865 8866 fname = fname_trans_sid(name, fname_buf, &tofree, &error); 8867 8868 *doesrange = FALSE; 8869 8870 if (partial != NULL) 8871 { 8872 if (partial->pt_dict != NULL) 8873 { 8874 /* When the function has a partial with a dict and there is a dict 8875 * argument, use the dict argument. That is backwards compatible. 8876 */ 8877 if (selfdict_in == NULL) 8878 selfdict = partial->pt_dict; 8879 } 8880 if (error == ERROR_NONE && partial->pt_argc > 0) 8881 { 8882 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear) 8883 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]); 8884 for (i = 0; i < argcount_in; ++i) 8885 argv[i + argv_clear] = argvars_in[i]; 8886 argvars = argv; 8887 argcount = partial->pt_argc + argcount_in; 8888 } 8889 } 8890 8891 8892 /* execute the function if no errors detected and executing */ 8893 if (evaluate && error == ERROR_NONE) 8894 { 8895 char_u *rfname = fname; 8896 8897 /* Ignore "g:" before a function name. */ 8898 if (fname[0] == 'g' && fname[1] == ':') 8899 rfname = fname + 2; 8900 8901 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8902 rettv->vval.v_number = 0; 8903 error = ERROR_UNKNOWN; 8904 8905 if (!builtin_function(rfname, -1)) 8906 { 8907 /* 8908 * User defined function. 8909 */ 8910 fp = find_func(rfname); 8911 8912 #ifdef FEAT_AUTOCMD 8913 /* Trigger FuncUndefined event, may load the function. */ 8914 if (fp == NULL 8915 && apply_autocmds(EVENT_FUNCUNDEFINED, 8916 rfname, rfname, TRUE, NULL) 8917 && !aborting()) 8918 { 8919 /* executed an autocommand, search for the function again */ 8920 fp = find_func(rfname); 8921 } 8922 #endif 8923 /* Try loading a package. */ 8924 if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) 8925 { 8926 /* loaded a package, search for the function again */ 8927 fp = find_func(rfname); 8928 } 8929 8930 if (fp != NULL) 8931 { 8932 if (fp->uf_flags & FC_RANGE) 8933 *doesrange = TRUE; 8934 if (argcount < fp->uf_args.ga_len) 8935 error = ERROR_TOOFEW; 8936 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8937 error = ERROR_TOOMANY; 8938 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8939 error = ERROR_DICT; 8940 else 8941 { 8942 int did_save_redo = FALSE; 8943 8944 /* 8945 * Call the user function. 8946 * Save and restore search patterns, script variables and 8947 * redo buffer. 8948 */ 8949 save_search_patterns(); 8950 #ifdef FEAT_INS_EXPAND 8951 if (!ins_compl_active()) 8952 #endif 8953 { 8954 saveRedobuff(); 8955 did_save_redo = TRUE; 8956 } 8957 ++fp->uf_calls; 8958 call_user_func(fp, argcount, argvars, rettv, 8959 firstline, lastline, 8960 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8961 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8962 && fp->uf_refcount <= 0) 8963 /* Function was unreferenced while being used, free it 8964 * now. */ 8965 func_free(fp); 8966 if (did_save_redo) 8967 restoreRedobuff(); 8968 restore_search_patterns(); 8969 error = ERROR_NONE; 8970 } 8971 } 8972 } 8973 else 8974 { 8975 /* 8976 * Find the function name in the table, call its implementation. 8977 */ 8978 i = find_internal_func(fname); 8979 if (i >= 0) 8980 { 8981 if (argcount < functions[i].f_min_argc) 8982 error = ERROR_TOOFEW; 8983 else if (argcount > functions[i].f_max_argc) 8984 error = ERROR_TOOMANY; 8985 else 8986 { 8987 argvars[argcount].v_type = VAR_UNKNOWN; 8988 functions[i].f_func(argvars, rettv); 8989 error = ERROR_NONE; 8990 } 8991 } 8992 } 8993 /* 8994 * The function call (or "FuncUndefined" autocommand sequence) might 8995 * have been aborted by an error, an interrupt, or an explicitly thrown 8996 * exception that has not been caught so far. This situation can be 8997 * tested for by calling aborting(). For an error in an internal 8998 * function or for the "E132" error in call_user_func(), however, the 8999 * throw point at which the "force_abort" flag (temporarily reset by 9000 * emsg()) is normally updated has not been reached yet. We need to 9001 * update that flag first to make aborting() reliable. 9002 */ 9003 update_force_abort(); 9004 } 9005 if (error == ERROR_NONE) 9006 ret = OK; 9007 9008 /* 9009 * Report an error unless the argument evaluation or function call has been 9010 * cancelled due to an aborting error, an interrupt, or an exception. 9011 */ 9012 if (!aborting()) 9013 { 9014 switch (error) 9015 { 9016 case ERROR_UNKNOWN: 9017 emsg_funcname(N_("E117: Unknown function: %s"), name); 9018 break; 9019 case ERROR_TOOMANY: 9020 emsg_funcname(e_toomanyarg, name); 9021 break; 9022 case ERROR_TOOFEW: 9023 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 9024 name); 9025 break; 9026 case ERROR_SCRIPT: 9027 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 9028 name); 9029 break; 9030 case ERROR_DICT: 9031 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 9032 name); 9033 break; 9034 } 9035 } 9036 9037 while (argv_clear > 0) 9038 clear_tv(&argv[--argv_clear]); 9039 vim_free(tofree); 9040 vim_free(name); 9041 9042 return ret; 9043 } 9044 9045 /* 9046 * Give an error message with a function name. Handle <SNR> things. 9047 * "ermsg" is to be passed without translation, use N_() instead of _(). 9048 */ 9049 static void 9050 emsg_funcname(char *ermsg, char_u *name) 9051 { 9052 char_u *p; 9053 9054 if (*name == K_SPECIAL) 9055 p = concat_str((char_u *)"<SNR>", name + 3); 9056 else 9057 p = name; 9058 EMSG2(_(ermsg), p); 9059 if (p != name) 9060 vim_free(p); 9061 } 9062 9063 /* 9064 * Return TRUE for a non-zero Number and a non-empty String. 9065 */ 9066 static int 9067 non_zero_arg(typval_T *argvars) 9068 { 9069 return ((argvars[0].v_type == VAR_NUMBER 9070 && argvars[0].vval.v_number != 0) 9071 || (argvars[0].v_type == VAR_STRING 9072 && argvars[0].vval.v_string != NULL 9073 && *argvars[0].vval.v_string != NUL)); 9074 } 9075 9076 /********************************************* 9077 * Implementation of the built-in functions 9078 */ 9079 9080 #ifdef FEAT_FLOAT 9081 static int get_float_arg(typval_T *argvars, float_T *f); 9082 9083 /* 9084 * Get the float value of "argvars[0]" into "f". 9085 * Returns FAIL when the argument is not a Number or Float. 9086 */ 9087 static int 9088 get_float_arg(typval_T *argvars, float_T *f) 9089 { 9090 if (argvars[0].v_type == VAR_FLOAT) 9091 { 9092 *f = argvars[0].vval.v_float; 9093 return OK; 9094 } 9095 if (argvars[0].v_type == VAR_NUMBER) 9096 { 9097 *f = (float_T)argvars[0].vval.v_number; 9098 return OK; 9099 } 9100 EMSG(_("E808: Number or Float required")); 9101 return FAIL; 9102 } 9103 9104 /* 9105 * "abs(expr)" function 9106 */ 9107 static void 9108 f_abs(typval_T *argvars, typval_T *rettv) 9109 { 9110 if (argvars[0].v_type == VAR_FLOAT) 9111 { 9112 rettv->v_type = VAR_FLOAT; 9113 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 9114 } 9115 else 9116 { 9117 varnumber_T n; 9118 int error = FALSE; 9119 9120 n = get_tv_number_chk(&argvars[0], &error); 9121 if (error) 9122 rettv->vval.v_number = -1; 9123 else if (n > 0) 9124 rettv->vval.v_number = n; 9125 else 9126 rettv->vval.v_number = -n; 9127 } 9128 } 9129 9130 /* 9131 * "acos()" function 9132 */ 9133 static void 9134 f_acos(typval_T *argvars, typval_T *rettv) 9135 { 9136 float_T f = 0.0; 9137 9138 rettv->v_type = VAR_FLOAT; 9139 if (get_float_arg(argvars, &f) == OK) 9140 rettv->vval.v_float = acos(f); 9141 else 9142 rettv->vval.v_float = 0.0; 9143 } 9144 #endif 9145 9146 /* 9147 * "add(list, item)" function 9148 */ 9149 static void 9150 f_add(typval_T *argvars, typval_T *rettv) 9151 { 9152 list_T *l; 9153 9154 rettv->vval.v_number = 1; /* Default: Failed */ 9155 if (argvars[0].v_type == VAR_LIST) 9156 { 9157 if ((l = argvars[0].vval.v_list) != NULL 9158 && !tv_check_lock(l->lv_lock, 9159 (char_u *)N_("add() argument"), TRUE) 9160 && list_append_tv(l, &argvars[1]) == OK) 9161 copy_tv(&argvars[0], rettv); 9162 } 9163 else 9164 EMSG(_(e_listreq)); 9165 } 9166 9167 /* 9168 * "alloc_fail(id, countdown, repeat)" function 9169 */ 9170 static void 9171 f_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED) 9172 { 9173 if (argvars[0].v_type != VAR_NUMBER 9174 || argvars[0].vval.v_number <= 0 9175 || argvars[1].v_type != VAR_NUMBER 9176 || argvars[1].vval.v_number < 0 9177 || argvars[2].v_type != VAR_NUMBER) 9178 EMSG(_(e_invarg)); 9179 else 9180 { 9181 alloc_fail_id = argvars[0].vval.v_number; 9182 if (alloc_fail_id >= aid_last) 9183 EMSG(_(e_invarg)); 9184 alloc_fail_countdown = argvars[1].vval.v_number; 9185 alloc_fail_repeat = argvars[2].vval.v_number; 9186 did_outofmem_msg = FALSE; 9187 } 9188 } 9189 9190 /* 9191 * "and(expr, expr)" function 9192 */ 9193 static void 9194 f_and(typval_T *argvars, typval_T *rettv) 9195 { 9196 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 9197 & get_tv_number_chk(&argvars[1], NULL); 9198 } 9199 9200 /* 9201 * "append(lnum, string/list)" function 9202 */ 9203 static void 9204 f_append(typval_T *argvars, typval_T *rettv) 9205 { 9206 long lnum; 9207 char_u *line; 9208 list_T *l = NULL; 9209 listitem_T *li = NULL; 9210 typval_T *tv; 9211 long added = 0; 9212 9213 /* When coming here from Insert mode, sync undo, so that this can be 9214 * undone separately from what was previously inserted. */ 9215 if (u_sync_once == 2) 9216 { 9217 u_sync_once = 1; /* notify that u_sync() was called */ 9218 u_sync(TRUE); 9219 } 9220 9221 lnum = get_tv_lnum(argvars); 9222 if (lnum >= 0 9223 && lnum <= curbuf->b_ml.ml_line_count 9224 && u_save(lnum, lnum + 1) == OK) 9225 { 9226 if (argvars[1].v_type == VAR_LIST) 9227 { 9228 l = argvars[1].vval.v_list; 9229 if (l == NULL) 9230 return; 9231 li = l->lv_first; 9232 } 9233 for (;;) 9234 { 9235 if (l == NULL) 9236 tv = &argvars[1]; /* append a string */ 9237 else if (li == NULL) 9238 break; /* end of list */ 9239 else 9240 tv = &li->li_tv; /* append item from list */ 9241 line = get_tv_string_chk(tv); 9242 if (line == NULL) /* type error */ 9243 { 9244 rettv->vval.v_number = 1; /* Failed */ 9245 break; 9246 } 9247 ml_append(lnum + added, line, (colnr_T)0, FALSE); 9248 ++added; 9249 if (l == NULL) 9250 break; 9251 li = li->li_next; 9252 } 9253 9254 appended_lines_mark(lnum, added); 9255 if (curwin->w_cursor.lnum > lnum) 9256 curwin->w_cursor.lnum += added; 9257 } 9258 else 9259 rettv->vval.v_number = 1; /* Failed */ 9260 } 9261 9262 /* 9263 * "argc()" function 9264 */ 9265 static void 9266 f_argc(typval_T *argvars UNUSED, typval_T *rettv) 9267 { 9268 rettv->vval.v_number = ARGCOUNT; 9269 } 9270 9271 /* 9272 * "argidx()" function 9273 */ 9274 static void 9275 f_argidx(typval_T *argvars UNUSED, typval_T *rettv) 9276 { 9277 rettv->vval.v_number = curwin->w_arg_idx; 9278 } 9279 9280 /* 9281 * "arglistid()" function 9282 */ 9283 static void 9284 f_arglistid(typval_T *argvars, typval_T *rettv) 9285 { 9286 win_T *wp; 9287 9288 rettv->vval.v_number = -1; 9289 wp = find_tabwin(&argvars[0], &argvars[1]); 9290 if (wp != NULL) 9291 rettv->vval.v_number = wp->w_alist->id; 9292 } 9293 9294 /* 9295 * "argv(nr)" function 9296 */ 9297 static void 9298 f_argv(typval_T *argvars, typval_T *rettv) 9299 { 9300 int idx; 9301 9302 if (argvars[0].v_type != VAR_UNKNOWN) 9303 { 9304 idx = get_tv_number_chk(&argvars[0], NULL); 9305 if (idx >= 0 && idx < ARGCOUNT) 9306 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 9307 else 9308 rettv->vval.v_string = NULL; 9309 rettv->v_type = VAR_STRING; 9310 } 9311 else if (rettv_list_alloc(rettv) == OK) 9312 for (idx = 0; idx < ARGCOUNT; ++idx) 9313 list_append_string(rettv->vval.v_list, 9314 alist_name(&ARGLIST[idx]), -1); 9315 } 9316 9317 static void prepare_assert_error(garray_T*gap); 9318 static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv, int is_match); 9319 static void assert_error(garray_T *gap); 9320 static void assert_bool(typval_T *argvars, int isTrue); 9321 9322 /* 9323 * Prepare "gap" for an assert error and add the sourcing position. 9324 */ 9325 static void 9326 prepare_assert_error(garray_T *gap) 9327 { 9328 char buf[NUMBUFLEN]; 9329 9330 ga_init2(gap, 1, 100); 9331 if (sourcing_name != NULL) 9332 { 9333 ga_concat(gap, sourcing_name); 9334 if (sourcing_lnum > 0) 9335 ga_concat(gap, (char_u *)" "); 9336 } 9337 if (sourcing_lnum > 0) 9338 { 9339 sprintf(buf, "line %ld", (long)sourcing_lnum); 9340 ga_concat(gap, (char_u *)buf); 9341 } 9342 if (sourcing_name != NULL || sourcing_lnum > 0) 9343 ga_concat(gap, (char_u *)": "); 9344 } 9345 9346 /* 9347 * Append "str" to "gap", escaping unprintable characters. 9348 * Changes NL to \n, CR to \r, etc. 9349 */ 9350 static void 9351 ga_concat_esc(garray_T *gap, char_u *str) 9352 { 9353 char_u *p; 9354 char_u buf[NUMBUFLEN]; 9355 9356 if (str == NULL) 9357 { 9358 ga_concat(gap, (char_u *)"NULL"); 9359 return; 9360 } 9361 9362 for (p = str; *p != NUL; ++p) 9363 switch (*p) 9364 { 9365 case BS: ga_concat(gap, (char_u *)"\\b"); break; 9366 case ESC: ga_concat(gap, (char_u *)"\\e"); break; 9367 case FF: ga_concat(gap, (char_u *)"\\f"); break; 9368 case NL: ga_concat(gap, (char_u *)"\\n"); break; 9369 case TAB: ga_concat(gap, (char_u *)"\\t"); break; 9370 case CAR: ga_concat(gap, (char_u *)"\\r"); break; 9371 case '\\': ga_concat(gap, (char_u *)"\\\\"); break; 9372 default: 9373 if (*p < ' ') 9374 { 9375 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); 9376 ga_concat(gap, buf); 9377 } 9378 else 9379 ga_append(gap, *p); 9380 break; 9381 } 9382 } 9383 9384 /* 9385 * Fill "gap" with information about an assert error. 9386 */ 9387 static void 9388 fill_assert_error( 9389 garray_T *gap, 9390 typval_T *opt_msg_tv, 9391 char_u *exp_str, 9392 typval_T *exp_tv, 9393 typval_T *got_tv, 9394 int is_match) 9395 { 9396 char_u numbuf[NUMBUFLEN]; 9397 char_u *tofree; 9398 9399 if (opt_msg_tv->v_type != VAR_UNKNOWN) 9400 { 9401 ga_concat(gap, tv2string(opt_msg_tv, &tofree, numbuf, 0)); 9402 vim_free(tofree); 9403 } 9404 else 9405 { 9406 if (is_match) 9407 ga_concat(gap, (char_u *)"Pattern "); 9408 else 9409 ga_concat(gap, (char_u *)"Expected "); 9410 if (exp_str == NULL) 9411 { 9412 ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); 9413 vim_free(tofree); 9414 } 9415 else 9416 ga_concat_esc(gap, exp_str); 9417 if (is_match) 9418 ga_concat(gap, (char_u *)" does not match "); 9419 else 9420 ga_concat(gap, (char_u *)" but got "); 9421 ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); 9422 vim_free(tofree); 9423 } 9424 } 9425 9426 /* 9427 * Add an assert error to v:errors. 9428 */ 9429 static void 9430 assert_error(garray_T *gap) 9431 { 9432 struct vimvar *vp = &vimvars[VV_ERRORS]; 9433 9434 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) 9435 /* Make sure v:errors is a list. */ 9436 set_vim_var_list(VV_ERRORS, list_alloc()); 9437 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); 9438 } 9439 9440 /* 9441 * "assert_equal(expected, actual[, msg])" function 9442 */ 9443 static void 9444 f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED) 9445 { 9446 garray_T ga; 9447 9448 if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)) 9449 { 9450 prepare_assert_error(&ga); 9451 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], 9452 FALSE); 9453 assert_error(&ga); 9454 ga_clear(&ga); 9455 } 9456 } 9457 9458 /* 9459 * "assert_exception(string[, msg])" function 9460 */ 9461 static void 9462 f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED) 9463 { 9464 garray_T ga; 9465 char *error; 9466 9467 error = (char *)get_tv_string_chk(&argvars[0]); 9468 if (vimvars[VV_EXCEPTION].vv_str == NULL) 9469 { 9470 prepare_assert_error(&ga); 9471 ga_concat(&ga, (char_u *)"v:exception is not set"); 9472 assert_error(&ga); 9473 ga_clear(&ga); 9474 } 9475 else if (error != NULL 9476 && strstr((char *)vimvars[VV_EXCEPTION].vv_str, error) == NULL) 9477 { 9478 prepare_assert_error(&ga); 9479 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], 9480 &vimvars[VV_EXCEPTION].vv_tv, FALSE); 9481 assert_error(&ga); 9482 ga_clear(&ga); 9483 } 9484 } 9485 9486 /* 9487 * "assert_fails(cmd [, error])" function 9488 */ 9489 static void 9490 f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED) 9491 { 9492 char_u *cmd = get_tv_string_chk(&argvars[0]); 9493 garray_T ga; 9494 9495 called_emsg = FALSE; 9496 suppress_errthrow = TRUE; 9497 emsg_silent = TRUE; 9498 do_cmdline_cmd(cmd); 9499 if (!called_emsg) 9500 { 9501 prepare_assert_error(&ga); 9502 ga_concat(&ga, (char_u *)"command did not fail: "); 9503 ga_concat(&ga, cmd); 9504 assert_error(&ga); 9505 ga_clear(&ga); 9506 } 9507 else if (argvars[1].v_type != VAR_UNKNOWN) 9508 { 9509 char_u buf[NUMBUFLEN]; 9510 char *error = (char *)get_tv_string_buf_chk(&argvars[1], buf); 9511 9512 if (error == NULL 9513 || strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL) 9514 { 9515 prepare_assert_error(&ga); 9516 fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], 9517 &vimvars[VV_ERRMSG].vv_tv, FALSE); 9518 assert_error(&ga); 9519 ga_clear(&ga); 9520 } 9521 } 9522 9523 called_emsg = FALSE; 9524 suppress_errthrow = FALSE; 9525 emsg_silent = FALSE; 9526 emsg_on_display = FALSE; 9527 set_vim_var_string(VV_ERRMSG, NULL, 0); 9528 } 9529 9530 /* 9531 * Common for assert_true() and assert_false(). 9532 */ 9533 static void 9534 assert_bool(typval_T *argvars, int isTrue) 9535 { 9536 int error = FALSE; 9537 garray_T ga; 9538 9539 if (argvars[0].v_type == VAR_SPECIAL 9540 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) 9541 return; 9542 if (argvars[0].v_type != VAR_NUMBER 9543 || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue 9544 || error) 9545 { 9546 prepare_assert_error(&ga); 9547 fill_assert_error(&ga, &argvars[1], 9548 (char_u *)(isTrue ? "True" : "False"), 9549 NULL, &argvars[0], FALSE); 9550 assert_error(&ga); 9551 ga_clear(&ga); 9552 } 9553 } 9554 9555 /* 9556 * "assert_false(actual[, msg])" function 9557 */ 9558 static void 9559 f_assert_false(typval_T *argvars, typval_T *rettv UNUSED) 9560 { 9561 assert_bool(argvars, FALSE); 9562 } 9563 9564 /* 9565 * "assert_match(pattern, actual[, msg])" function 9566 */ 9567 static void 9568 f_assert_match(typval_T *argvars, typval_T *rettv UNUSED) 9569 { 9570 garray_T ga; 9571 char_u buf1[NUMBUFLEN]; 9572 char_u buf2[NUMBUFLEN]; 9573 char_u *pat = get_tv_string_buf_chk(&argvars[0], buf1); 9574 char_u *text = get_tv_string_buf_chk(&argvars[1], buf2); 9575 9576 if (!pattern_match(pat, text, FALSE)) 9577 { 9578 prepare_assert_error(&ga); 9579 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], 9580 TRUE); 9581 assert_error(&ga); 9582 ga_clear(&ga); 9583 } 9584 } 9585 9586 /* 9587 * "assert_true(actual[, msg])" function 9588 */ 9589 static void 9590 f_assert_true(typval_T *argvars, typval_T *rettv UNUSED) 9591 { 9592 assert_bool(argvars, TRUE); 9593 } 9594 9595 #ifdef FEAT_FLOAT 9596 /* 9597 * "asin()" function 9598 */ 9599 static void 9600 f_asin(typval_T *argvars, typval_T *rettv) 9601 { 9602 float_T f = 0.0; 9603 9604 rettv->v_type = VAR_FLOAT; 9605 if (get_float_arg(argvars, &f) == OK) 9606 rettv->vval.v_float = asin(f); 9607 else 9608 rettv->vval.v_float = 0.0; 9609 } 9610 9611 /* 9612 * "atan()" function 9613 */ 9614 static void 9615 f_atan(typval_T *argvars, typval_T *rettv) 9616 { 9617 float_T f = 0.0; 9618 9619 rettv->v_type = VAR_FLOAT; 9620 if (get_float_arg(argvars, &f) == OK) 9621 rettv->vval.v_float = atan(f); 9622 else 9623 rettv->vval.v_float = 0.0; 9624 } 9625 9626 /* 9627 * "atan2()" function 9628 */ 9629 static void 9630 f_atan2(typval_T *argvars, typval_T *rettv) 9631 { 9632 float_T fx = 0.0, fy = 0.0; 9633 9634 rettv->v_type = VAR_FLOAT; 9635 if (get_float_arg(argvars, &fx) == OK 9636 && get_float_arg(&argvars[1], &fy) == OK) 9637 rettv->vval.v_float = atan2(fx, fy); 9638 else 9639 rettv->vval.v_float = 0.0; 9640 } 9641 #endif 9642 9643 /* 9644 * "browse(save, title, initdir, default)" function 9645 */ 9646 static void 9647 f_browse(typval_T *argvars UNUSED, typval_T *rettv) 9648 { 9649 #ifdef FEAT_BROWSE 9650 int save; 9651 char_u *title; 9652 char_u *initdir; 9653 char_u *defname; 9654 char_u buf[NUMBUFLEN]; 9655 char_u buf2[NUMBUFLEN]; 9656 int error = FALSE; 9657 9658 save = get_tv_number_chk(&argvars[0], &error); 9659 title = get_tv_string_chk(&argvars[1]); 9660 initdir = get_tv_string_buf_chk(&argvars[2], buf); 9661 defname = get_tv_string_buf_chk(&argvars[3], buf2); 9662 9663 if (error || title == NULL || initdir == NULL || defname == NULL) 9664 rettv->vval.v_string = NULL; 9665 else 9666 rettv->vval.v_string = 9667 do_browse(save ? BROWSE_SAVE : 0, 9668 title, defname, NULL, initdir, NULL, curbuf); 9669 #else 9670 rettv->vval.v_string = NULL; 9671 #endif 9672 rettv->v_type = VAR_STRING; 9673 } 9674 9675 /* 9676 * "browsedir(title, initdir)" function 9677 */ 9678 static void 9679 f_browsedir(typval_T *argvars UNUSED, typval_T *rettv) 9680 { 9681 #ifdef FEAT_BROWSE 9682 char_u *title; 9683 char_u *initdir; 9684 char_u buf[NUMBUFLEN]; 9685 9686 title = get_tv_string_chk(&argvars[0]); 9687 initdir = get_tv_string_buf_chk(&argvars[1], buf); 9688 9689 if (title == NULL || initdir == NULL) 9690 rettv->vval.v_string = NULL; 9691 else 9692 rettv->vval.v_string = do_browse(BROWSE_DIR, 9693 title, NULL, NULL, initdir, NULL, curbuf); 9694 #else 9695 rettv->vval.v_string = NULL; 9696 #endif 9697 rettv->v_type = VAR_STRING; 9698 } 9699 9700 static buf_T *find_buffer(typval_T *avar); 9701 9702 /* 9703 * Find a buffer by number or exact name. 9704 */ 9705 static buf_T * 9706 find_buffer(typval_T *avar) 9707 { 9708 buf_T *buf = NULL; 9709 9710 if (avar->v_type == VAR_NUMBER) 9711 buf = buflist_findnr((int)avar->vval.v_number); 9712 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 9713 { 9714 buf = buflist_findname_exp(avar->vval.v_string); 9715 if (buf == NULL) 9716 { 9717 /* No full path name match, try a match with a URL or a "nofile" 9718 * buffer, these don't use the full path. */ 9719 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 9720 if (buf->b_fname != NULL 9721 && (path_with_url(buf->b_fname) 9722 #ifdef FEAT_QUICKFIX 9723 || bt_nofile(buf) 9724 #endif 9725 ) 9726 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 9727 break; 9728 } 9729 } 9730 return buf; 9731 } 9732 9733 /* 9734 * "bufexists(expr)" function 9735 */ 9736 static void 9737 f_bufexists(typval_T *argvars, typval_T *rettv) 9738 { 9739 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 9740 } 9741 9742 /* 9743 * "buflisted(expr)" function 9744 */ 9745 static void 9746 f_buflisted(typval_T *argvars, typval_T *rettv) 9747 { 9748 buf_T *buf; 9749 9750 buf = find_buffer(&argvars[0]); 9751 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 9752 } 9753 9754 /* 9755 * "bufloaded(expr)" function 9756 */ 9757 static void 9758 f_bufloaded(typval_T *argvars, typval_T *rettv) 9759 { 9760 buf_T *buf; 9761 9762 buf = find_buffer(&argvars[0]); 9763 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 9764 } 9765 9766 buf_T * 9767 buflist_find_by_name(char_u *name, int curtab_only) 9768 { 9769 int save_magic; 9770 char_u *save_cpo; 9771 buf_T *buf; 9772 9773 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 9774 save_magic = p_magic; 9775 p_magic = TRUE; 9776 save_cpo = p_cpo; 9777 p_cpo = (char_u *)""; 9778 9779 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 9780 TRUE, FALSE, curtab_only)); 9781 9782 p_magic = save_magic; 9783 p_cpo = save_cpo; 9784 return buf; 9785 } 9786 9787 /* 9788 * Get buffer by number or pattern. 9789 */ 9790 static buf_T * 9791 get_buf_tv(typval_T *tv, int curtab_only) 9792 { 9793 char_u *name = tv->vval.v_string; 9794 buf_T *buf; 9795 9796 if (tv->v_type == VAR_NUMBER) 9797 return buflist_findnr((int)tv->vval.v_number); 9798 if (tv->v_type != VAR_STRING) 9799 return NULL; 9800 if (name == NULL || *name == NUL) 9801 return curbuf; 9802 if (name[0] == '$' && name[1] == NUL) 9803 return lastbuf; 9804 9805 buf = buflist_find_by_name(name, curtab_only); 9806 9807 /* If not found, try expanding the name, like done for bufexists(). */ 9808 if (buf == NULL) 9809 buf = find_buffer(tv); 9810 9811 return buf; 9812 } 9813 9814 /* 9815 * "bufname(expr)" function 9816 */ 9817 static void 9818 f_bufname(typval_T *argvars, typval_T *rettv) 9819 { 9820 buf_T *buf; 9821 9822 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9823 ++emsg_off; 9824 buf = get_buf_tv(&argvars[0], FALSE); 9825 rettv->v_type = VAR_STRING; 9826 if (buf != NULL && buf->b_fname != NULL) 9827 rettv->vval.v_string = vim_strsave(buf->b_fname); 9828 else 9829 rettv->vval.v_string = NULL; 9830 --emsg_off; 9831 } 9832 9833 /* 9834 * "bufnr(expr)" function 9835 */ 9836 static void 9837 f_bufnr(typval_T *argvars, typval_T *rettv) 9838 { 9839 buf_T *buf; 9840 int error = FALSE; 9841 char_u *name; 9842 9843 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9844 ++emsg_off; 9845 buf = get_buf_tv(&argvars[0], FALSE); 9846 --emsg_off; 9847 9848 /* If the buffer isn't found and the second argument is not zero create a 9849 * new buffer. */ 9850 if (buf == NULL 9851 && argvars[1].v_type != VAR_UNKNOWN 9852 && get_tv_number_chk(&argvars[1], &error) != 0 9853 && !error 9854 && (name = get_tv_string_chk(&argvars[0])) != NULL 9855 && !error) 9856 buf = buflist_new(name, NULL, (linenr_T)1, 0); 9857 9858 if (buf != NULL) 9859 rettv->vval.v_number = buf->b_fnum; 9860 else 9861 rettv->vval.v_number = -1; 9862 } 9863 9864 /* 9865 * "bufwinnr(nr)" function 9866 */ 9867 static void 9868 f_bufwinnr(typval_T *argvars, typval_T *rettv) 9869 { 9870 #ifdef FEAT_WINDOWS 9871 win_T *wp; 9872 int winnr = 0; 9873 #endif 9874 buf_T *buf; 9875 9876 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9877 ++emsg_off; 9878 buf = get_buf_tv(&argvars[0], TRUE); 9879 #ifdef FEAT_WINDOWS 9880 for (wp = firstwin; wp; wp = wp->w_next) 9881 { 9882 ++winnr; 9883 if (wp->w_buffer == buf) 9884 break; 9885 } 9886 rettv->vval.v_number = (wp != NULL ? winnr : -1); 9887 #else 9888 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 9889 #endif 9890 --emsg_off; 9891 } 9892 9893 /* 9894 * "byte2line(byte)" function 9895 */ 9896 static void 9897 f_byte2line(typval_T *argvars UNUSED, typval_T *rettv) 9898 { 9899 #ifndef FEAT_BYTEOFF 9900 rettv->vval.v_number = -1; 9901 #else 9902 long boff = 0; 9903 9904 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 9905 if (boff < 0) 9906 rettv->vval.v_number = -1; 9907 else 9908 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 9909 (linenr_T)0, &boff); 9910 #endif 9911 } 9912 9913 static void 9914 byteidx(typval_T *argvars, typval_T *rettv, int comp UNUSED) 9915 { 9916 #ifdef FEAT_MBYTE 9917 char_u *t; 9918 #endif 9919 char_u *str; 9920 long idx; 9921 9922 str = get_tv_string_chk(&argvars[0]); 9923 idx = get_tv_number_chk(&argvars[1], NULL); 9924 rettv->vval.v_number = -1; 9925 if (str == NULL || idx < 0) 9926 return; 9927 9928 #ifdef FEAT_MBYTE 9929 t = str; 9930 for ( ; idx > 0; idx--) 9931 { 9932 if (*t == NUL) /* EOL reached */ 9933 return; 9934 if (enc_utf8 && comp) 9935 t += utf_ptr2len(t); 9936 else 9937 t += (*mb_ptr2len)(t); 9938 } 9939 rettv->vval.v_number = (varnumber_T)(t - str); 9940 #else 9941 if ((size_t)idx <= STRLEN(str)) 9942 rettv->vval.v_number = idx; 9943 #endif 9944 } 9945 9946 /* 9947 * "byteidx()" function 9948 */ 9949 static void 9950 f_byteidx(typval_T *argvars, typval_T *rettv) 9951 { 9952 byteidx(argvars, rettv, FALSE); 9953 } 9954 9955 /* 9956 * "byteidxcomp()" function 9957 */ 9958 static void 9959 f_byteidxcomp(typval_T *argvars, typval_T *rettv) 9960 { 9961 byteidx(argvars, rettv, TRUE); 9962 } 9963 9964 int 9965 func_call( 9966 char_u *name, 9967 typval_T *args, 9968 partial_T *partial, 9969 dict_T *selfdict, 9970 typval_T *rettv) 9971 { 9972 listitem_T *item; 9973 typval_T argv[MAX_FUNC_ARGS + 1]; 9974 int argc = 0; 9975 int dummy; 9976 int r = 0; 9977 9978 for (item = args->vval.v_list->lv_first; item != NULL; 9979 item = item->li_next) 9980 { 9981 if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) 9982 { 9983 EMSG(_("E699: Too many arguments")); 9984 break; 9985 } 9986 /* Make a copy of each argument. This is needed to be able to set 9987 * v_lock to VAR_FIXED in the copy without changing the original list. 9988 */ 9989 copy_tv(&item->li_tv, &argv[argc++]); 9990 } 9991 9992 if (item == NULL) 9993 r = call_func(name, (int)STRLEN(name), rettv, argc, argv, 9994 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 9995 &dummy, TRUE, partial, selfdict); 9996 9997 /* Free the arguments. */ 9998 while (argc > 0) 9999 clear_tv(&argv[--argc]); 10000 10001 return r; 10002 } 10003 10004 /* 10005 * "call(func, arglist [, dict])" function 10006 */ 10007 static void 10008 f_call(typval_T *argvars, typval_T *rettv) 10009 { 10010 char_u *func; 10011 partial_T *partial = NULL; 10012 dict_T *selfdict = NULL; 10013 10014 if (argvars[1].v_type != VAR_LIST) 10015 { 10016 EMSG(_(e_listreq)); 10017 return; 10018 } 10019 if (argvars[1].vval.v_list == NULL) 10020 return; 10021 10022 if (argvars[0].v_type == VAR_FUNC) 10023 func = argvars[0].vval.v_string; 10024 else if (argvars[0].v_type == VAR_PARTIAL) 10025 { 10026 partial = argvars[0].vval.v_partial; 10027 func = partial->pt_name; 10028 } 10029 else 10030 func = get_tv_string(&argvars[0]); 10031 if (*func == NUL) 10032 return; /* type error or empty name */ 10033 10034 if (argvars[2].v_type != VAR_UNKNOWN) 10035 { 10036 if (argvars[2].v_type != VAR_DICT) 10037 { 10038 EMSG(_(e_dictreq)); 10039 return; 10040 } 10041 selfdict = argvars[2].vval.v_dict; 10042 } 10043 10044 (void)func_call(func, &argvars[1], partial, selfdict, rettv); 10045 } 10046 10047 #ifdef FEAT_FLOAT 10048 /* 10049 * "ceil({float})" function 10050 */ 10051 static void 10052 f_ceil(typval_T *argvars, typval_T *rettv) 10053 { 10054 float_T f = 0.0; 10055 10056 rettv->v_type = VAR_FLOAT; 10057 if (get_float_arg(argvars, &f) == OK) 10058 rettv->vval.v_float = ceil(f); 10059 else 10060 rettv->vval.v_float = 0.0; 10061 } 10062 #endif 10063 10064 #ifdef FEAT_JOB_CHANNEL 10065 /* 10066 * "ch_close()" function 10067 */ 10068 static void 10069 f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) 10070 { 10071 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 10072 10073 if (channel != NULL) 10074 { 10075 channel_close(channel, FALSE); 10076 channel_clear(channel); 10077 } 10078 } 10079 10080 /* 10081 * "ch_getbufnr()" function 10082 */ 10083 static void 10084 f_ch_getbufnr(typval_T *argvars, typval_T *rettv) 10085 { 10086 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 10087 10088 rettv->vval.v_number = -1; 10089 if (channel != NULL) 10090 { 10091 char_u *what = get_tv_string(&argvars[1]); 10092 int part; 10093 10094 if (STRCMP(what, "err") == 0) 10095 part = PART_ERR; 10096 else if (STRCMP(what, "out") == 0) 10097 part = PART_OUT; 10098 else if (STRCMP(what, "in") == 0) 10099 part = PART_IN; 10100 else 10101 part = PART_SOCK; 10102 if (channel->ch_part[part].ch_buffer != NULL) 10103 rettv->vval.v_number = channel->ch_part[part].ch_buffer->b_fnum; 10104 } 10105 } 10106 10107 /* 10108 * "ch_getjob()" function 10109 */ 10110 static void 10111 f_ch_getjob(typval_T *argvars, typval_T *rettv) 10112 { 10113 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 10114 10115 if (channel != NULL) 10116 { 10117 rettv->v_type = VAR_JOB; 10118 rettv->vval.v_job = channel->ch_job; 10119 if (channel->ch_job != NULL) 10120 ++channel->ch_job->jv_refcount; 10121 } 10122 } 10123 10124 /* 10125 * "ch_info()" function 10126 */ 10127 static void 10128 f_ch_info(typval_T *argvars, typval_T *rettv UNUSED) 10129 { 10130 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 10131 10132 if (channel != NULL && rettv_dict_alloc(rettv) != FAIL) 10133 channel_info(channel, rettv->vval.v_dict); 10134 } 10135 10136 /* 10137 * "ch_log()" function 10138 */ 10139 static void 10140 f_ch_log(typval_T *argvars, typval_T *rettv UNUSED) 10141 { 10142 char_u *msg = get_tv_string(&argvars[0]); 10143 channel_T *channel = NULL; 10144 10145 if (argvars[1].v_type != VAR_UNKNOWN) 10146 channel = get_channel_arg(&argvars[1], TRUE); 10147 10148 ch_log(channel, (char *)msg); 10149 } 10150 10151 /* 10152 * "ch_logfile()" function 10153 */ 10154 static void 10155 f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) 10156 { 10157 char_u *fname; 10158 char_u *opt = (char_u *)""; 10159 char_u buf[NUMBUFLEN]; 10160 10161 fname = get_tv_string(&argvars[0]); 10162 if (argvars[1].v_type == VAR_STRING) 10163 opt = get_tv_string_buf(&argvars[1], buf); 10164 ch_logfile(fname, opt); 10165 } 10166 10167 /* 10168 * "ch_open()" function 10169 */ 10170 static void 10171 f_ch_open(typval_T *argvars, typval_T *rettv) 10172 { 10173 rettv->v_type = VAR_CHANNEL; 10174 rettv->vval.v_channel = channel_open_func(argvars); 10175 } 10176 10177 /* 10178 * "ch_read()" function 10179 */ 10180 static void 10181 f_ch_read(typval_T *argvars, typval_T *rettv) 10182 { 10183 common_channel_read(argvars, rettv, FALSE); 10184 } 10185 10186 /* 10187 * "ch_readraw()" function 10188 */ 10189 static void 10190 f_ch_readraw(typval_T *argvars, typval_T *rettv) 10191 { 10192 common_channel_read(argvars, rettv, TRUE); 10193 } 10194 10195 /* 10196 * "ch_evalexpr()" function 10197 */ 10198 static void 10199 f_ch_evalexpr(typval_T *argvars, typval_T *rettv) 10200 { 10201 ch_expr_common(argvars, rettv, TRUE); 10202 } 10203 10204 /* 10205 * "ch_sendexpr()" function 10206 */ 10207 static void 10208 f_ch_sendexpr(typval_T *argvars, typval_T *rettv) 10209 { 10210 ch_expr_common(argvars, rettv, FALSE); 10211 } 10212 10213 /* 10214 * "ch_evalraw()" function 10215 */ 10216 static void 10217 f_ch_evalraw(typval_T *argvars, typval_T *rettv) 10218 { 10219 ch_raw_common(argvars, rettv, TRUE); 10220 } 10221 10222 /* 10223 * "ch_sendraw()" function 10224 */ 10225 static void 10226 f_ch_sendraw(typval_T *argvars, typval_T *rettv) 10227 { 10228 ch_raw_common(argvars, rettv, FALSE); 10229 } 10230 10231 /* 10232 * "ch_setoptions()" function 10233 */ 10234 static void 10235 f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED) 10236 { 10237 channel_T *channel; 10238 jobopt_T opt; 10239 10240 channel = get_channel_arg(&argvars[0], TRUE); 10241 if (channel == NULL) 10242 return; 10243 clear_job_options(&opt); 10244 if (get_job_options(&argvars[1], &opt, 10245 JO_CB_ALL + JO_TIMEOUT_ALL + JO_MODE_ALL) == FAIL) 10246 return; 10247 channel_set_options(channel, &opt); 10248 } 10249 10250 /* 10251 * "ch_status()" function 10252 */ 10253 static void 10254 f_ch_status(typval_T *argvars, typval_T *rettv) 10255 { 10256 channel_T *channel; 10257 10258 /* return an empty string by default */ 10259 rettv->v_type = VAR_STRING; 10260 rettv->vval.v_string = NULL; 10261 10262 channel = get_channel_arg(&argvars[0], FALSE); 10263 rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel)); 10264 } 10265 #endif 10266 10267 /* 10268 * "changenr()" function 10269 */ 10270 static void 10271 f_changenr(typval_T *argvars UNUSED, typval_T *rettv) 10272 { 10273 rettv->vval.v_number = curbuf->b_u_seq_cur; 10274 } 10275 10276 /* 10277 * "char2nr(string)" function 10278 */ 10279 static void 10280 f_char2nr(typval_T *argvars, typval_T *rettv) 10281 { 10282 #ifdef FEAT_MBYTE 10283 if (has_mbyte) 10284 { 10285 int utf8 = 0; 10286 10287 if (argvars[1].v_type != VAR_UNKNOWN) 10288 utf8 = get_tv_number_chk(&argvars[1], NULL); 10289 10290 if (utf8) 10291 rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0])); 10292 else 10293 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 10294 } 10295 else 10296 #endif 10297 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 10298 } 10299 10300 /* 10301 * "cindent(lnum)" function 10302 */ 10303 static void 10304 f_cindent(typval_T *argvars UNUSED, typval_T *rettv) 10305 { 10306 #ifdef FEAT_CINDENT 10307 pos_T pos; 10308 linenr_T lnum; 10309 10310 pos = curwin->w_cursor; 10311 lnum = get_tv_lnum(argvars); 10312 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10313 { 10314 curwin->w_cursor.lnum = lnum; 10315 rettv->vval.v_number = get_c_indent(); 10316 curwin->w_cursor = pos; 10317 } 10318 else 10319 #endif 10320 rettv->vval.v_number = -1; 10321 } 10322 10323 /* 10324 * "clearmatches()" function 10325 */ 10326 static void 10327 f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10328 { 10329 #ifdef FEAT_SEARCH_EXTRA 10330 clear_matches(curwin); 10331 #endif 10332 } 10333 10334 /* 10335 * "col(string)" function 10336 */ 10337 static void 10338 f_col(typval_T *argvars, typval_T *rettv) 10339 { 10340 colnr_T col = 0; 10341 pos_T *fp; 10342 int fnum = curbuf->b_fnum; 10343 10344 fp = var2fpos(&argvars[0], FALSE, &fnum); 10345 if (fp != NULL && fnum == curbuf->b_fnum) 10346 { 10347 if (fp->col == MAXCOL) 10348 { 10349 /* '> can be MAXCOL, get the length of the line then */ 10350 if (fp->lnum <= curbuf->b_ml.ml_line_count) 10351 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 10352 else 10353 col = MAXCOL; 10354 } 10355 else 10356 { 10357 col = fp->col + 1; 10358 #ifdef FEAT_VIRTUALEDIT 10359 /* col(".") when the cursor is on the NUL at the end of the line 10360 * because of "coladd" can be seen as an extra column. */ 10361 if (virtual_active() && fp == &curwin->w_cursor) 10362 { 10363 char_u *p = ml_get_cursor(); 10364 10365 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 10366 curwin->w_virtcol - curwin->w_cursor.coladd)) 10367 { 10368 # ifdef FEAT_MBYTE 10369 int l; 10370 10371 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 10372 col += l; 10373 # else 10374 if (*p != NUL && p[1] == NUL) 10375 ++col; 10376 # endif 10377 } 10378 } 10379 #endif 10380 } 10381 } 10382 rettv->vval.v_number = col; 10383 } 10384 10385 #if defined(FEAT_INS_EXPAND) 10386 /* 10387 * "complete()" function 10388 */ 10389 static void 10390 f_complete(typval_T *argvars, typval_T *rettv UNUSED) 10391 { 10392 int startcol; 10393 10394 if ((State & INSERT) == 0) 10395 { 10396 EMSG(_("E785: complete() can only be used in Insert mode")); 10397 return; 10398 } 10399 10400 /* Check for undo allowed here, because if something was already inserted 10401 * the line was already saved for undo and this check isn't done. */ 10402 if (!undo_allowed()) 10403 return; 10404 10405 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 10406 { 10407 EMSG(_(e_invarg)); 10408 return; 10409 } 10410 10411 startcol = get_tv_number_chk(&argvars[0], NULL); 10412 if (startcol <= 0) 10413 return; 10414 10415 set_completion(startcol - 1, argvars[1].vval.v_list); 10416 } 10417 10418 /* 10419 * "complete_add()" function 10420 */ 10421 static void 10422 f_complete_add(typval_T *argvars, typval_T *rettv) 10423 { 10424 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 10425 } 10426 10427 /* 10428 * "complete_check()" function 10429 */ 10430 static void 10431 f_complete_check(typval_T *argvars UNUSED, typval_T *rettv) 10432 { 10433 int saved = RedrawingDisabled; 10434 10435 RedrawingDisabled = 0; 10436 ins_compl_check_keys(0); 10437 rettv->vval.v_number = compl_interrupted; 10438 RedrawingDisabled = saved; 10439 } 10440 #endif 10441 10442 /* 10443 * "confirm(message, buttons[, default [, type]])" function 10444 */ 10445 static void 10446 f_confirm(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10447 { 10448 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 10449 char_u *message; 10450 char_u *buttons = NULL; 10451 char_u buf[NUMBUFLEN]; 10452 char_u buf2[NUMBUFLEN]; 10453 int def = 1; 10454 int type = VIM_GENERIC; 10455 char_u *typestr; 10456 int error = FALSE; 10457 10458 message = get_tv_string_chk(&argvars[0]); 10459 if (message == NULL) 10460 error = TRUE; 10461 if (argvars[1].v_type != VAR_UNKNOWN) 10462 { 10463 buttons = get_tv_string_buf_chk(&argvars[1], buf); 10464 if (buttons == NULL) 10465 error = TRUE; 10466 if (argvars[2].v_type != VAR_UNKNOWN) 10467 { 10468 def = get_tv_number_chk(&argvars[2], &error); 10469 if (argvars[3].v_type != VAR_UNKNOWN) 10470 { 10471 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 10472 if (typestr == NULL) 10473 error = TRUE; 10474 else 10475 { 10476 switch (TOUPPER_ASC(*typestr)) 10477 { 10478 case 'E': type = VIM_ERROR; break; 10479 case 'Q': type = VIM_QUESTION; break; 10480 case 'I': type = VIM_INFO; break; 10481 case 'W': type = VIM_WARNING; break; 10482 case 'G': type = VIM_GENERIC; break; 10483 } 10484 } 10485 } 10486 } 10487 } 10488 10489 if (buttons == NULL || *buttons == NUL) 10490 buttons = (char_u *)_("&Ok"); 10491 10492 if (!error) 10493 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 10494 def, NULL, FALSE); 10495 #endif 10496 } 10497 10498 /* 10499 * "copy()" function 10500 */ 10501 static void 10502 f_copy(typval_T *argvars, typval_T *rettv) 10503 { 10504 item_copy(&argvars[0], rettv, FALSE, 0); 10505 } 10506 10507 #ifdef FEAT_FLOAT 10508 /* 10509 * "cos()" function 10510 */ 10511 static void 10512 f_cos(typval_T *argvars, typval_T *rettv) 10513 { 10514 float_T f = 0.0; 10515 10516 rettv->v_type = VAR_FLOAT; 10517 if (get_float_arg(argvars, &f) == OK) 10518 rettv->vval.v_float = cos(f); 10519 else 10520 rettv->vval.v_float = 0.0; 10521 } 10522 10523 /* 10524 * "cosh()" function 10525 */ 10526 static void 10527 f_cosh(typval_T *argvars, typval_T *rettv) 10528 { 10529 float_T f = 0.0; 10530 10531 rettv->v_type = VAR_FLOAT; 10532 if (get_float_arg(argvars, &f) == OK) 10533 rettv->vval.v_float = cosh(f); 10534 else 10535 rettv->vval.v_float = 0.0; 10536 } 10537 #endif 10538 10539 /* 10540 * "count()" function 10541 */ 10542 static void 10543 f_count(typval_T *argvars, typval_T *rettv) 10544 { 10545 long n = 0; 10546 int ic = FALSE; 10547 10548 if (argvars[0].v_type == VAR_LIST) 10549 { 10550 listitem_T *li; 10551 list_T *l; 10552 long idx; 10553 10554 if ((l = argvars[0].vval.v_list) != NULL) 10555 { 10556 li = l->lv_first; 10557 if (argvars[2].v_type != VAR_UNKNOWN) 10558 { 10559 int error = FALSE; 10560 10561 ic = get_tv_number_chk(&argvars[2], &error); 10562 if (argvars[3].v_type != VAR_UNKNOWN) 10563 { 10564 idx = get_tv_number_chk(&argvars[3], &error); 10565 if (!error) 10566 { 10567 li = list_find(l, idx); 10568 if (li == NULL) 10569 EMSGN(_(e_listidx), idx); 10570 } 10571 } 10572 if (error) 10573 li = NULL; 10574 } 10575 10576 for ( ; li != NULL; li = li->li_next) 10577 if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE)) 10578 ++n; 10579 } 10580 } 10581 else if (argvars[0].v_type == VAR_DICT) 10582 { 10583 int todo; 10584 dict_T *d; 10585 hashitem_T *hi; 10586 10587 if ((d = argvars[0].vval.v_dict) != NULL) 10588 { 10589 int error = FALSE; 10590 10591 if (argvars[2].v_type != VAR_UNKNOWN) 10592 { 10593 ic = get_tv_number_chk(&argvars[2], &error); 10594 if (argvars[3].v_type != VAR_UNKNOWN) 10595 EMSG(_(e_invarg)); 10596 } 10597 10598 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 10599 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 10600 { 10601 if (!HASHITEM_EMPTY(hi)) 10602 { 10603 --todo; 10604 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE)) 10605 ++n; 10606 } 10607 } 10608 } 10609 } 10610 else 10611 EMSG2(_(e_listdictarg), "count()"); 10612 rettv->vval.v_number = n; 10613 } 10614 10615 /* 10616 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 10617 * 10618 * Checks the existence of a cscope connection. 10619 */ 10620 static void 10621 f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10622 { 10623 #ifdef FEAT_CSCOPE 10624 int num = 0; 10625 char_u *dbpath = NULL; 10626 char_u *prepend = NULL; 10627 char_u buf[NUMBUFLEN]; 10628 10629 if (argvars[0].v_type != VAR_UNKNOWN 10630 && argvars[1].v_type != VAR_UNKNOWN) 10631 { 10632 num = (int)get_tv_number(&argvars[0]); 10633 dbpath = get_tv_string(&argvars[1]); 10634 if (argvars[2].v_type != VAR_UNKNOWN) 10635 prepend = get_tv_string_buf(&argvars[2], buf); 10636 } 10637 10638 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 10639 #endif 10640 } 10641 10642 /* 10643 * "cursor(lnum, col)" function, or 10644 * "cursor(list)" 10645 * 10646 * Moves the cursor to the specified line and column. 10647 * Returns 0 when the position could be set, -1 otherwise. 10648 */ 10649 static void 10650 f_cursor(typval_T *argvars, typval_T *rettv) 10651 { 10652 long line, col; 10653 #ifdef FEAT_VIRTUALEDIT 10654 long coladd = 0; 10655 #endif 10656 int set_curswant = TRUE; 10657 10658 rettv->vval.v_number = -1; 10659 if (argvars[1].v_type == VAR_UNKNOWN) 10660 { 10661 pos_T pos; 10662 colnr_T curswant = -1; 10663 10664 if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL) 10665 { 10666 EMSG(_(e_invarg)); 10667 return; 10668 } 10669 line = pos.lnum; 10670 col = pos.col; 10671 #ifdef FEAT_VIRTUALEDIT 10672 coladd = pos.coladd; 10673 #endif 10674 if (curswant >= 0) 10675 { 10676 curwin->w_curswant = curswant - 1; 10677 set_curswant = FALSE; 10678 } 10679 } 10680 else 10681 { 10682 line = get_tv_lnum(argvars); 10683 col = get_tv_number_chk(&argvars[1], NULL); 10684 #ifdef FEAT_VIRTUALEDIT 10685 if (argvars[2].v_type != VAR_UNKNOWN) 10686 coladd = get_tv_number_chk(&argvars[2], NULL); 10687 #endif 10688 } 10689 if (line < 0 || col < 0 10690 #ifdef FEAT_VIRTUALEDIT 10691 || coladd < 0 10692 #endif 10693 ) 10694 return; /* type error; errmsg already given */ 10695 if (line > 0) 10696 curwin->w_cursor.lnum = line; 10697 if (col > 0) 10698 curwin->w_cursor.col = col - 1; 10699 #ifdef FEAT_VIRTUALEDIT 10700 curwin->w_cursor.coladd = coladd; 10701 #endif 10702 10703 /* Make sure the cursor is in a valid position. */ 10704 check_cursor(); 10705 #ifdef FEAT_MBYTE 10706 /* Correct cursor for multi-byte character. */ 10707 if (has_mbyte) 10708 mb_adjust_cursor(); 10709 #endif 10710 10711 curwin->w_set_curswant = set_curswant; 10712 rettv->vval.v_number = 0; 10713 } 10714 10715 /* 10716 * "deepcopy()" function 10717 */ 10718 static void 10719 f_deepcopy(typval_T *argvars, typval_T *rettv) 10720 { 10721 int noref = 0; 10722 10723 if (argvars[1].v_type != VAR_UNKNOWN) 10724 noref = get_tv_number_chk(&argvars[1], NULL); 10725 if (noref < 0 || noref > 1) 10726 EMSG(_(e_invarg)); 10727 else 10728 { 10729 current_copyID += COPYID_INC; 10730 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 10731 } 10732 } 10733 10734 /* 10735 * "delete()" function 10736 */ 10737 static void 10738 f_delete(typval_T *argvars, typval_T *rettv) 10739 { 10740 char_u nbuf[NUMBUFLEN]; 10741 char_u *name; 10742 char_u *flags; 10743 10744 rettv->vval.v_number = -1; 10745 if (check_restricted() || check_secure()) 10746 return; 10747 10748 name = get_tv_string(&argvars[0]); 10749 if (name == NULL || *name == NUL) 10750 { 10751 EMSG(_(e_invarg)); 10752 return; 10753 } 10754 10755 if (argvars[1].v_type != VAR_UNKNOWN) 10756 flags = get_tv_string_buf(&argvars[1], nbuf); 10757 else 10758 flags = (char_u *)""; 10759 10760 if (*flags == NUL) 10761 /* delete a file */ 10762 rettv->vval.v_number = mch_remove(name) == 0 ? 0 : -1; 10763 else if (STRCMP(flags, "d") == 0) 10764 /* delete an empty directory */ 10765 rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1; 10766 else if (STRCMP(flags, "rf") == 0) 10767 /* delete a directory recursively */ 10768 rettv->vval.v_number = delete_recursive(name); 10769 else 10770 EMSG2(_(e_invexpr2), flags); 10771 } 10772 10773 /* 10774 * "did_filetype()" function 10775 */ 10776 static void 10777 f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10778 { 10779 #ifdef FEAT_AUTOCMD 10780 rettv->vval.v_number = did_filetype; 10781 #endif 10782 } 10783 10784 /* 10785 * "diff_filler()" function 10786 */ 10787 static void 10788 f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10789 { 10790 #ifdef FEAT_DIFF 10791 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 10792 #endif 10793 } 10794 10795 /* 10796 * "diff_hlID()" function 10797 */ 10798 static void 10799 f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10800 { 10801 #ifdef FEAT_DIFF 10802 linenr_T lnum = get_tv_lnum(argvars); 10803 static linenr_T prev_lnum = 0; 10804 static int changedtick = 0; 10805 static int fnum = 0; 10806 static int change_start = 0; 10807 static int change_end = 0; 10808 static hlf_T hlID = (hlf_T)0; 10809 int filler_lines; 10810 int col; 10811 10812 if (lnum < 0) /* ignore type error in {lnum} arg */ 10813 lnum = 0; 10814 if (lnum != prev_lnum 10815 || changedtick != curbuf->b_changedtick 10816 || fnum != curbuf->b_fnum) 10817 { 10818 /* New line, buffer, change: need to get the values. */ 10819 filler_lines = diff_check(curwin, lnum); 10820 if (filler_lines < 0) 10821 { 10822 if (filler_lines == -1) 10823 { 10824 change_start = MAXCOL; 10825 change_end = -1; 10826 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 10827 hlID = HLF_ADD; /* added line */ 10828 else 10829 hlID = HLF_CHD; /* changed line */ 10830 } 10831 else 10832 hlID = HLF_ADD; /* added line */ 10833 } 10834 else 10835 hlID = (hlf_T)0; 10836 prev_lnum = lnum; 10837 changedtick = curbuf->b_changedtick; 10838 fnum = curbuf->b_fnum; 10839 } 10840 10841 if (hlID == HLF_CHD || hlID == HLF_TXD) 10842 { 10843 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 10844 if (col >= change_start && col <= change_end) 10845 hlID = HLF_TXD; /* changed text */ 10846 else 10847 hlID = HLF_CHD; /* changed line */ 10848 } 10849 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 10850 #endif 10851 } 10852 10853 /* 10854 * "disable_char_avail_for_testing({expr})" function 10855 */ 10856 static void 10857 f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv UNUSED) 10858 { 10859 disable_char_avail_for_testing = get_tv_number(&argvars[0]); 10860 } 10861 10862 /* 10863 * "empty({expr})" function 10864 */ 10865 static void 10866 f_empty(typval_T *argvars, typval_T *rettv) 10867 { 10868 int n = FALSE; 10869 10870 switch (argvars[0].v_type) 10871 { 10872 case VAR_STRING: 10873 case VAR_FUNC: 10874 n = argvars[0].vval.v_string == NULL 10875 || *argvars[0].vval.v_string == NUL; 10876 break; 10877 case VAR_PARTIAL: 10878 n = FALSE; 10879 break; 10880 case VAR_NUMBER: 10881 n = argvars[0].vval.v_number == 0; 10882 break; 10883 case VAR_FLOAT: 10884 #ifdef FEAT_FLOAT 10885 n = argvars[0].vval.v_float == 0.0; 10886 break; 10887 #endif 10888 case VAR_LIST: 10889 n = argvars[0].vval.v_list == NULL 10890 || argvars[0].vval.v_list->lv_first == NULL; 10891 break; 10892 case VAR_DICT: 10893 n = argvars[0].vval.v_dict == NULL 10894 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 10895 break; 10896 case VAR_SPECIAL: 10897 n = argvars[0].vval.v_number != VVAL_TRUE; 10898 break; 10899 10900 case VAR_JOB: 10901 #ifdef FEAT_JOB_CHANNEL 10902 n = argvars[0].vval.v_job == NULL 10903 || argvars[0].vval.v_job->jv_status != JOB_STARTED; 10904 break; 10905 #endif 10906 case VAR_CHANNEL: 10907 #ifdef FEAT_JOB_CHANNEL 10908 n = argvars[0].vval.v_channel == NULL 10909 || !channel_is_open(argvars[0].vval.v_channel); 10910 break; 10911 #endif 10912 case VAR_UNKNOWN: 10913 EMSG2(_(e_intern2), "f_empty(UNKNOWN)"); 10914 n = TRUE; 10915 break; 10916 } 10917 10918 rettv->vval.v_number = n; 10919 } 10920 10921 /* 10922 * "escape({string}, {chars})" function 10923 */ 10924 static void 10925 f_escape(typval_T *argvars, typval_T *rettv) 10926 { 10927 char_u buf[NUMBUFLEN]; 10928 10929 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 10930 get_tv_string_buf(&argvars[1], buf)); 10931 rettv->v_type = VAR_STRING; 10932 } 10933 10934 /* 10935 * "eval()" function 10936 */ 10937 static void 10938 f_eval(typval_T *argvars, typval_T *rettv) 10939 { 10940 char_u *s, *p; 10941 10942 s = get_tv_string_chk(&argvars[0]); 10943 if (s != NULL) 10944 s = skipwhite(s); 10945 10946 p = s; 10947 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 10948 { 10949 if (p != NULL && !aborting()) 10950 EMSG2(_(e_invexpr2), p); 10951 need_clr_eos = FALSE; 10952 rettv->v_type = VAR_NUMBER; 10953 rettv->vval.v_number = 0; 10954 } 10955 else if (*s != NUL) 10956 EMSG(_(e_trailing)); 10957 } 10958 10959 /* 10960 * "eventhandler()" function 10961 */ 10962 static void 10963 f_eventhandler(typval_T *argvars UNUSED, typval_T *rettv) 10964 { 10965 rettv->vval.v_number = vgetc_busy; 10966 } 10967 10968 /* 10969 * "executable()" function 10970 */ 10971 static void 10972 f_executable(typval_T *argvars, typval_T *rettv) 10973 { 10974 char_u *name = get_tv_string(&argvars[0]); 10975 10976 /* Check in $PATH and also check directly if there is a directory name. */ 10977 rettv->vval.v_number = mch_can_exe(name, NULL, TRUE) 10978 || (gettail(name) != name && mch_can_exe(name, NULL, FALSE)); 10979 } 10980 10981 /* 10982 * "exepath()" function 10983 */ 10984 static void 10985 f_exepath(typval_T *argvars, typval_T *rettv) 10986 { 10987 char_u *p = NULL; 10988 10989 (void)mch_can_exe(get_tv_string(&argvars[0]), &p, TRUE); 10990 rettv->v_type = VAR_STRING; 10991 rettv->vval.v_string = p; 10992 } 10993 10994 /* 10995 * "exists()" function 10996 */ 10997 static void 10998 f_exists(typval_T *argvars, typval_T *rettv) 10999 { 11000 char_u *p; 11001 char_u *name; 11002 int n = FALSE; 11003 int len = 0; 11004 11005 p = get_tv_string(&argvars[0]); 11006 if (*p == '$') /* environment variable */ 11007 { 11008 /* first try "normal" environment variables (fast) */ 11009 if (mch_getenv(p + 1) != NULL) 11010 n = TRUE; 11011 else 11012 { 11013 /* try expanding things like $VIM and ${HOME} */ 11014 p = expand_env_save(p); 11015 if (p != NULL && *p != '$') 11016 n = TRUE; 11017 vim_free(p); 11018 } 11019 } 11020 else if (*p == '&' || *p == '+') /* option */ 11021 { 11022 n = (get_option_tv(&p, NULL, TRUE) == OK); 11023 if (*skipwhite(p) != NUL) 11024 n = FALSE; /* trailing garbage */ 11025 } 11026 else if (*p == '*') /* internal or user defined function */ 11027 { 11028 n = function_exists(p + 1); 11029 } 11030 else if (*p == ':') 11031 { 11032 n = cmd_exists(p + 1); 11033 } 11034 else if (*p == '#') 11035 { 11036 #ifdef FEAT_AUTOCMD 11037 if (p[1] == '#') 11038 n = autocmd_supported(p + 2); 11039 else 11040 n = au_exists(p + 1); 11041 #endif 11042 } 11043 else /* internal variable */ 11044 { 11045 char_u *tofree; 11046 typval_T tv; 11047 11048 /* get_name_len() takes care of expanding curly braces */ 11049 name = p; 11050 len = get_name_len(&p, &tofree, TRUE, FALSE); 11051 if (len > 0) 11052 { 11053 if (tofree != NULL) 11054 name = tofree; 11055 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK); 11056 if (n) 11057 { 11058 /* handle d.key, l[idx], f(expr) */ 11059 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 11060 if (n) 11061 clear_tv(&tv); 11062 } 11063 } 11064 if (*p != NUL) 11065 n = FALSE; 11066 11067 vim_free(tofree); 11068 } 11069 11070 rettv->vval.v_number = n; 11071 } 11072 11073 #ifdef FEAT_FLOAT 11074 /* 11075 * "exp()" function 11076 */ 11077 static void 11078 f_exp(typval_T *argvars, typval_T *rettv) 11079 { 11080 float_T f = 0.0; 11081 11082 rettv->v_type = VAR_FLOAT; 11083 if (get_float_arg(argvars, &f) == OK) 11084 rettv->vval.v_float = exp(f); 11085 else 11086 rettv->vval.v_float = 0.0; 11087 } 11088 #endif 11089 11090 /* 11091 * "expand()" function 11092 */ 11093 static void 11094 f_expand(typval_T *argvars, typval_T *rettv) 11095 { 11096 char_u *s; 11097 int len; 11098 char_u *errormsg; 11099 int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 11100 expand_T xpc; 11101 int error = FALSE; 11102 char_u *result; 11103 11104 rettv->v_type = VAR_STRING; 11105 if (argvars[1].v_type != VAR_UNKNOWN 11106 && argvars[2].v_type != VAR_UNKNOWN 11107 && get_tv_number_chk(&argvars[2], &error) 11108 && !error) 11109 { 11110 rettv->v_type = VAR_LIST; 11111 rettv->vval.v_list = NULL; 11112 } 11113 11114 s = get_tv_string(&argvars[0]); 11115 if (*s == '%' || *s == '#' || *s == '<') 11116 { 11117 ++emsg_off; 11118 result = eval_vars(s, s, &len, NULL, &errormsg, NULL); 11119 --emsg_off; 11120 if (rettv->v_type == VAR_LIST) 11121 { 11122 if (rettv_list_alloc(rettv) != FAIL && result != NULL) 11123 list_append_string(rettv->vval.v_list, result, -1); 11124 else 11125 vim_free(result); 11126 } 11127 else 11128 rettv->vval.v_string = result; 11129 } 11130 else 11131 { 11132 /* When the optional second argument is non-zero, don't remove matches 11133 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11134 if (argvars[1].v_type != VAR_UNKNOWN 11135 && get_tv_number_chk(&argvars[1], &error)) 11136 options |= WILD_KEEP_ALL; 11137 if (!error) 11138 { 11139 ExpandInit(&xpc); 11140 xpc.xp_context = EXPAND_FILES; 11141 if (p_wic) 11142 options += WILD_ICASE; 11143 if (rettv->v_type == VAR_STRING) 11144 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, 11145 options, WILD_ALL); 11146 else if (rettv_list_alloc(rettv) != FAIL) 11147 { 11148 int i; 11149 11150 ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP); 11151 for (i = 0; i < xpc.xp_numfiles; i++) 11152 list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); 11153 ExpandCleanup(&xpc); 11154 } 11155 } 11156 else 11157 rettv->vval.v_string = NULL; 11158 } 11159 } 11160 11161 /* 11162 * Go over all entries in "d2" and add them to "d1". 11163 * When "action" is "error" then a duplicate key is an error. 11164 * When "action" is "force" then a duplicate key is overwritten. 11165 * Otherwise duplicate keys are ignored ("action" is "keep"). 11166 */ 11167 void 11168 dict_extend(dict_T *d1, dict_T *d2, char_u *action) 11169 { 11170 dictitem_T *di1; 11171 hashitem_T *hi2; 11172 int todo; 11173 char_u *arg_errmsg = (char_u *)N_("extend() argument"); 11174 11175 todo = (int)d2->dv_hashtab.ht_used; 11176 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 11177 { 11178 if (!HASHITEM_EMPTY(hi2)) 11179 { 11180 --todo; 11181 di1 = dict_find(d1, hi2->hi_key, -1); 11182 if (d1->dv_scope != 0) 11183 { 11184 /* Disallow replacing a builtin function in l: and g:. 11185 * Check the key to be valid when adding to any 11186 * scope. */ 11187 if (d1->dv_scope == VAR_DEF_SCOPE 11188 && HI2DI(hi2)->di_tv.v_type == VAR_FUNC 11189 && var_check_func_name(hi2->hi_key, 11190 di1 == NULL)) 11191 break; 11192 if (!valid_varname(hi2->hi_key)) 11193 break; 11194 } 11195 if (di1 == NULL) 11196 { 11197 di1 = dictitem_copy(HI2DI(hi2)); 11198 if (di1 != NULL && dict_add(d1, di1) == FAIL) 11199 dictitem_free(di1); 11200 } 11201 else if (*action == 'e') 11202 { 11203 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 11204 break; 11205 } 11206 else if (*action == 'f' && HI2DI(hi2) != di1) 11207 { 11208 if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE) 11209 || var_check_ro(di1->di_flags, arg_errmsg, TRUE)) 11210 break; 11211 clear_tv(&di1->di_tv); 11212 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 11213 } 11214 } 11215 } 11216 } 11217 11218 /* 11219 * "extend(list, list [, idx])" function 11220 * "extend(dict, dict [, action])" function 11221 */ 11222 static void 11223 f_extend(typval_T *argvars, typval_T *rettv) 11224 { 11225 char_u *arg_errmsg = (char_u *)N_("extend() argument"); 11226 11227 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 11228 { 11229 list_T *l1, *l2; 11230 listitem_T *item; 11231 long before; 11232 int error = FALSE; 11233 11234 l1 = argvars[0].vval.v_list; 11235 l2 = argvars[1].vval.v_list; 11236 if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, TRUE) 11237 && l2 != NULL) 11238 { 11239 if (argvars[2].v_type != VAR_UNKNOWN) 11240 { 11241 before = get_tv_number_chk(&argvars[2], &error); 11242 if (error) 11243 return; /* type error; errmsg already given */ 11244 11245 if (before == l1->lv_len) 11246 item = NULL; 11247 else 11248 { 11249 item = list_find(l1, before); 11250 if (item == NULL) 11251 { 11252 EMSGN(_(e_listidx), before); 11253 return; 11254 } 11255 } 11256 } 11257 else 11258 item = NULL; 11259 list_extend(l1, l2, item); 11260 11261 copy_tv(&argvars[0], rettv); 11262 } 11263 } 11264 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 11265 { 11266 dict_T *d1, *d2; 11267 char_u *action; 11268 int i; 11269 11270 d1 = argvars[0].vval.v_dict; 11271 d2 = argvars[1].vval.v_dict; 11272 if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE) 11273 && d2 != NULL) 11274 { 11275 /* Check the third argument. */ 11276 if (argvars[2].v_type != VAR_UNKNOWN) 11277 { 11278 static char *(av[]) = {"keep", "force", "error"}; 11279 11280 action = get_tv_string_chk(&argvars[2]); 11281 if (action == NULL) 11282 return; /* type error; errmsg already given */ 11283 for (i = 0; i < 3; ++i) 11284 if (STRCMP(action, av[i]) == 0) 11285 break; 11286 if (i == 3) 11287 { 11288 EMSG2(_(e_invarg2), action); 11289 return; 11290 } 11291 } 11292 else 11293 action = (char_u *)"force"; 11294 11295 dict_extend(d1, d2, action); 11296 11297 copy_tv(&argvars[0], rettv); 11298 } 11299 } 11300 else 11301 EMSG2(_(e_listdictarg), "extend()"); 11302 } 11303 11304 /* 11305 * "feedkeys()" function 11306 */ 11307 static void 11308 f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED) 11309 { 11310 int remap = TRUE; 11311 int insert = FALSE; 11312 char_u *keys, *flags; 11313 char_u nbuf[NUMBUFLEN]; 11314 int typed = FALSE; 11315 int execute = FALSE; 11316 char_u *keys_esc; 11317 11318 /* This is not allowed in the sandbox. If the commands would still be 11319 * executed in the sandbox it would be OK, but it probably happens later, 11320 * when "sandbox" is no longer set. */ 11321 if (check_secure()) 11322 return; 11323 11324 keys = get_tv_string(&argvars[0]); 11325 11326 if (argvars[1].v_type != VAR_UNKNOWN) 11327 { 11328 flags = get_tv_string_buf(&argvars[1], nbuf); 11329 for ( ; *flags != NUL; ++flags) 11330 { 11331 switch (*flags) 11332 { 11333 case 'n': remap = FALSE; break; 11334 case 'm': remap = TRUE; break; 11335 case 't': typed = TRUE; break; 11336 case 'i': insert = TRUE; break; 11337 case 'x': execute = TRUE; break; 11338 } 11339 } 11340 } 11341 11342 if (*keys != NUL || execute) 11343 { 11344 /* Need to escape K_SPECIAL and CSI before putting the string in the 11345 * typeahead buffer. */ 11346 keys_esc = vim_strsave_escape_csi(keys); 11347 if (keys_esc != NULL) 11348 { 11349 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 11350 insert ? 0 : typebuf.tb_len, !typed, FALSE); 11351 vim_free(keys_esc); 11352 if (vgetc_busy) 11353 typebuf_was_filled = TRUE; 11354 if (execute) 11355 { 11356 int save_msg_scroll = msg_scroll; 11357 11358 /* Avoid a 1 second delay when the keys start Insert mode. */ 11359 msg_scroll = FALSE; 11360 exec_normal(TRUE); 11361 msg_scroll |= save_msg_scroll; 11362 } 11363 } 11364 } 11365 } 11366 11367 /* 11368 * "filereadable()" function 11369 */ 11370 static void 11371 f_filereadable(typval_T *argvars, typval_T *rettv) 11372 { 11373 int fd; 11374 char_u *p; 11375 int n; 11376 11377 #ifndef O_NONBLOCK 11378 # define O_NONBLOCK 0 11379 #endif 11380 p = get_tv_string(&argvars[0]); 11381 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 11382 O_RDONLY | O_NONBLOCK, 0)) >= 0) 11383 { 11384 n = TRUE; 11385 close(fd); 11386 } 11387 else 11388 n = FALSE; 11389 11390 rettv->vval.v_number = n; 11391 } 11392 11393 /* 11394 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 11395 * rights to write into. 11396 */ 11397 static void 11398 f_filewritable(typval_T *argvars, typval_T *rettv) 11399 { 11400 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 11401 } 11402 11403 static void 11404 findfilendir( 11405 typval_T *argvars UNUSED, 11406 typval_T *rettv, 11407 int find_what UNUSED) 11408 { 11409 #ifdef FEAT_SEARCHPATH 11410 char_u *fname; 11411 char_u *fresult = NULL; 11412 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 11413 char_u *p; 11414 char_u pathbuf[NUMBUFLEN]; 11415 int count = 1; 11416 int first = TRUE; 11417 int error = FALSE; 11418 #endif 11419 11420 rettv->vval.v_string = NULL; 11421 rettv->v_type = VAR_STRING; 11422 11423 #ifdef FEAT_SEARCHPATH 11424 fname = get_tv_string(&argvars[0]); 11425 11426 if (argvars[1].v_type != VAR_UNKNOWN) 11427 { 11428 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 11429 if (p == NULL) 11430 error = TRUE; 11431 else 11432 { 11433 if (*p != NUL) 11434 path = p; 11435 11436 if (argvars[2].v_type != VAR_UNKNOWN) 11437 count = get_tv_number_chk(&argvars[2], &error); 11438 } 11439 } 11440 11441 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 11442 error = TRUE; 11443 11444 if (*fname != NUL && !error) 11445 { 11446 do 11447 { 11448 if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) 11449 vim_free(fresult); 11450 fresult = find_file_in_path_option(first ? fname : NULL, 11451 first ? (int)STRLEN(fname) : 0, 11452 0, first, path, 11453 find_what, 11454 curbuf->b_ffname, 11455 find_what == FINDFILE_DIR 11456 ? (char_u *)"" : curbuf->b_p_sua); 11457 first = FALSE; 11458 11459 if (fresult != NULL && rettv->v_type == VAR_LIST) 11460 list_append_string(rettv->vval.v_list, fresult, -1); 11461 11462 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 11463 } 11464 11465 if (rettv->v_type == VAR_STRING) 11466 rettv->vval.v_string = fresult; 11467 #endif 11468 } 11469 11470 static void filter_map(typval_T *argvars, typval_T *rettv, int map); 11471 static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp); 11472 11473 /* 11474 * Implementation of map() and filter(). 11475 */ 11476 static void 11477 filter_map(typval_T *argvars, typval_T *rettv, int map) 11478 { 11479 char_u buf[NUMBUFLEN]; 11480 char_u *expr; 11481 listitem_T *li, *nli; 11482 list_T *l = NULL; 11483 dictitem_T *di; 11484 hashtab_T *ht; 11485 hashitem_T *hi; 11486 dict_T *d = NULL; 11487 typval_T save_val; 11488 typval_T save_key; 11489 int rem; 11490 int todo; 11491 char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); 11492 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument") 11493 : N_("filter() argument")); 11494 int save_did_emsg; 11495 int idx = 0; 11496 11497 if (argvars[0].v_type == VAR_LIST) 11498 { 11499 if ((l = argvars[0].vval.v_list) == NULL 11500 || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE))) 11501 return; 11502 } 11503 else if (argvars[0].v_type == VAR_DICT) 11504 { 11505 if ((d = argvars[0].vval.v_dict) == NULL 11506 || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TRUE))) 11507 return; 11508 } 11509 else 11510 { 11511 EMSG2(_(e_listdictarg), ermsg); 11512 return; 11513 } 11514 11515 expr = get_tv_string_buf_chk(&argvars[1], buf); 11516 /* On type errors, the preceding call has already displayed an error 11517 * message. Avoid a misleading error message for an empty string that 11518 * was not passed as argument. */ 11519 if (expr != NULL) 11520 { 11521 prepare_vimvar(VV_VAL, &save_val); 11522 expr = skipwhite(expr); 11523 11524 /* We reset "did_emsg" to be able to detect whether an error 11525 * occurred during evaluation of the expression. */ 11526 save_did_emsg = did_emsg; 11527 did_emsg = FALSE; 11528 11529 prepare_vimvar(VV_KEY, &save_key); 11530 if (argvars[0].v_type == VAR_DICT) 11531 { 11532 vimvars[VV_KEY].vv_type = VAR_STRING; 11533 11534 ht = &d->dv_hashtab; 11535 hash_lock(ht); 11536 todo = (int)ht->ht_used; 11537 for (hi = ht->ht_array; todo > 0; ++hi) 11538 { 11539 if (!HASHITEM_EMPTY(hi)) 11540 { 11541 int r; 11542 11543 --todo; 11544 di = HI2DI(hi); 11545 if (map && 11546 (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TRUE) 11547 || var_check_ro(di->di_flags, arg_errmsg, TRUE))) 11548 break; 11549 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 11550 r = filter_map_one(&di->di_tv, expr, map, &rem); 11551 clear_tv(&vimvars[VV_KEY].vv_tv); 11552 if (r == FAIL || did_emsg) 11553 break; 11554 if (!map && rem) 11555 { 11556 if (var_check_fixed(di->di_flags, arg_errmsg, TRUE) 11557 || var_check_ro(di->di_flags, arg_errmsg, TRUE)) 11558 break; 11559 dictitem_remove(d, di); 11560 } 11561 } 11562 } 11563 hash_unlock(ht); 11564 } 11565 else 11566 { 11567 vimvars[VV_KEY].vv_type = VAR_NUMBER; 11568 11569 for (li = l->lv_first; li != NULL; li = nli) 11570 { 11571 if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) 11572 break; 11573 nli = li->li_next; 11574 vimvars[VV_KEY].vv_nr = idx; 11575 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 11576 || did_emsg) 11577 break; 11578 if (!map && rem) 11579 listitem_remove(l, li); 11580 ++idx; 11581 } 11582 } 11583 11584 restore_vimvar(VV_KEY, &save_key); 11585 restore_vimvar(VV_VAL, &save_val); 11586 11587 did_emsg |= save_did_emsg; 11588 } 11589 11590 copy_tv(&argvars[0], rettv); 11591 } 11592 11593 static int 11594 filter_map_one(typval_T *tv, char_u *expr, int map, int *remp) 11595 { 11596 typval_T rettv; 11597 char_u *s; 11598 int retval = FAIL; 11599 11600 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 11601 s = expr; 11602 if (eval1(&s, &rettv, TRUE) == FAIL) 11603 goto theend; 11604 if (*s != NUL) /* check for trailing chars after expr */ 11605 { 11606 EMSG2(_(e_invexpr2), s); 11607 clear_tv(&rettv); 11608 goto theend; 11609 } 11610 if (map) 11611 { 11612 /* map(): replace the list item value */ 11613 clear_tv(tv); 11614 rettv.v_lock = 0; 11615 *tv = rettv; 11616 } 11617 else 11618 { 11619 int error = FALSE; 11620 11621 /* filter(): when expr is zero remove the item */ 11622 *remp = (get_tv_number_chk(&rettv, &error) == 0); 11623 clear_tv(&rettv); 11624 /* On type error, nothing has been removed; return FAIL to stop the 11625 * loop. The error message was given by get_tv_number_chk(). */ 11626 if (error) 11627 goto theend; 11628 } 11629 retval = OK; 11630 theend: 11631 clear_tv(&vimvars[VV_VAL].vv_tv); 11632 return retval; 11633 } 11634 11635 /* 11636 * "filter()" function 11637 */ 11638 static void 11639 f_filter(typval_T *argvars, typval_T *rettv) 11640 { 11641 filter_map(argvars, rettv, FALSE); 11642 } 11643 11644 /* 11645 * "finddir({fname}[, {path}[, {count}]])" function 11646 */ 11647 static void 11648 f_finddir(typval_T *argvars, typval_T *rettv) 11649 { 11650 findfilendir(argvars, rettv, FINDFILE_DIR); 11651 } 11652 11653 /* 11654 * "findfile({fname}[, {path}[, {count}]])" function 11655 */ 11656 static void 11657 f_findfile(typval_T *argvars, typval_T *rettv) 11658 { 11659 findfilendir(argvars, rettv, FINDFILE_FILE); 11660 } 11661 11662 #ifdef FEAT_FLOAT 11663 /* 11664 * "float2nr({float})" function 11665 */ 11666 static void 11667 f_float2nr(typval_T *argvars, typval_T *rettv) 11668 { 11669 float_T f = 0.0; 11670 11671 if (get_float_arg(argvars, &f) == OK) 11672 { 11673 if (f < -0x7fffffff) 11674 rettv->vval.v_number = -0x7fffffff; 11675 else if (f > 0x7fffffff) 11676 rettv->vval.v_number = 0x7fffffff; 11677 else 11678 rettv->vval.v_number = (varnumber_T)f; 11679 } 11680 } 11681 11682 /* 11683 * "floor({float})" function 11684 */ 11685 static void 11686 f_floor(typval_T *argvars, typval_T *rettv) 11687 { 11688 float_T f = 0.0; 11689 11690 rettv->v_type = VAR_FLOAT; 11691 if (get_float_arg(argvars, &f) == OK) 11692 rettv->vval.v_float = floor(f); 11693 else 11694 rettv->vval.v_float = 0.0; 11695 } 11696 11697 /* 11698 * "fmod()" function 11699 */ 11700 static void 11701 f_fmod(typval_T *argvars, typval_T *rettv) 11702 { 11703 float_T fx = 0.0, fy = 0.0; 11704 11705 rettv->v_type = VAR_FLOAT; 11706 if (get_float_arg(argvars, &fx) == OK 11707 && get_float_arg(&argvars[1], &fy) == OK) 11708 rettv->vval.v_float = fmod(fx, fy); 11709 else 11710 rettv->vval.v_float = 0.0; 11711 } 11712 #endif 11713 11714 /* 11715 * "fnameescape({string})" function 11716 */ 11717 static void 11718 f_fnameescape(typval_T *argvars, typval_T *rettv) 11719 { 11720 rettv->vval.v_string = vim_strsave_fnameescape( 11721 get_tv_string(&argvars[0]), FALSE); 11722 rettv->v_type = VAR_STRING; 11723 } 11724 11725 /* 11726 * "fnamemodify({fname}, {mods})" function 11727 */ 11728 static void 11729 f_fnamemodify(typval_T *argvars, typval_T *rettv) 11730 { 11731 char_u *fname; 11732 char_u *mods; 11733 int usedlen = 0; 11734 int len; 11735 char_u *fbuf = NULL; 11736 char_u buf[NUMBUFLEN]; 11737 11738 fname = get_tv_string_chk(&argvars[0]); 11739 mods = get_tv_string_buf_chk(&argvars[1], buf); 11740 if (fname == NULL || mods == NULL) 11741 fname = NULL; 11742 else 11743 { 11744 len = (int)STRLEN(fname); 11745 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 11746 } 11747 11748 rettv->v_type = VAR_STRING; 11749 if (fname == NULL) 11750 rettv->vval.v_string = NULL; 11751 else 11752 rettv->vval.v_string = vim_strnsave(fname, len); 11753 vim_free(fbuf); 11754 } 11755 11756 static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end); 11757 11758 /* 11759 * "foldclosed()" function 11760 */ 11761 static void 11762 foldclosed_both( 11763 typval_T *argvars UNUSED, 11764 typval_T *rettv, 11765 int end UNUSED) 11766 { 11767 #ifdef FEAT_FOLDING 11768 linenr_T lnum; 11769 linenr_T first, last; 11770 11771 lnum = get_tv_lnum(argvars); 11772 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11773 { 11774 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 11775 { 11776 if (end) 11777 rettv->vval.v_number = (varnumber_T)last; 11778 else 11779 rettv->vval.v_number = (varnumber_T)first; 11780 return; 11781 } 11782 } 11783 #endif 11784 rettv->vval.v_number = -1; 11785 } 11786 11787 /* 11788 * "foldclosed()" function 11789 */ 11790 static void 11791 f_foldclosed(typval_T *argvars, typval_T *rettv) 11792 { 11793 foldclosed_both(argvars, rettv, FALSE); 11794 } 11795 11796 /* 11797 * "foldclosedend()" function 11798 */ 11799 static void 11800 f_foldclosedend(typval_T *argvars, typval_T *rettv) 11801 { 11802 foldclosed_both(argvars, rettv, TRUE); 11803 } 11804 11805 /* 11806 * "foldlevel()" function 11807 */ 11808 static void 11809 f_foldlevel(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 11810 { 11811 #ifdef FEAT_FOLDING 11812 linenr_T lnum; 11813 11814 lnum = get_tv_lnum(argvars); 11815 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11816 rettv->vval.v_number = foldLevel(lnum); 11817 #endif 11818 } 11819 11820 /* 11821 * "foldtext()" function 11822 */ 11823 static void 11824 f_foldtext(typval_T *argvars UNUSED, typval_T *rettv) 11825 { 11826 #ifdef FEAT_FOLDING 11827 linenr_T lnum; 11828 char_u *s; 11829 char_u *r; 11830 int len; 11831 char *txt; 11832 #endif 11833 11834 rettv->v_type = VAR_STRING; 11835 rettv->vval.v_string = NULL; 11836 #ifdef FEAT_FOLDING 11837 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 11838 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 11839 <= curbuf->b_ml.ml_line_count 11840 && vimvars[VV_FOLDDASHES].vv_str != NULL) 11841 { 11842 /* Find first non-empty line in the fold. */ 11843 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 11844 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 11845 { 11846 if (!linewhite(lnum)) 11847 break; 11848 ++lnum; 11849 } 11850 11851 /* Find interesting text in this line. */ 11852 s = skipwhite(ml_get(lnum)); 11853 /* skip C comment-start */ 11854 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 11855 { 11856 s = skipwhite(s + 2); 11857 if (*skipwhite(s) == NUL 11858 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 11859 { 11860 s = skipwhite(ml_get(lnum + 1)); 11861 if (*s == '*') 11862 s = skipwhite(s + 1); 11863 } 11864 } 11865 txt = _("+-%s%3ld lines: "); 11866 r = alloc((unsigned)(STRLEN(txt) 11867 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 11868 + 20 /* for %3ld */ 11869 + STRLEN(s))); /* concatenated */ 11870 if (r != NULL) 11871 { 11872 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 11873 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 11874 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 11875 len = (int)STRLEN(r); 11876 STRCAT(r, s); 11877 /* remove 'foldmarker' and 'commentstring' */ 11878 foldtext_cleanup(r + len); 11879 rettv->vval.v_string = r; 11880 } 11881 } 11882 #endif 11883 } 11884 11885 /* 11886 * "foldtextresult(lnum)" function 11887 */ 11888 static void 11889 f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv) 11890 { 11891 #ifdef FEAT_FOLDING 11892 linenr_T lnum; 11893 char_u *text; 11894 char_u buf[51]; 11895 foldinfo_T foldinfo; 11896 int fold_count; 11897 #endif 11898 11899 rettv->v_type = VAR_STRING; 11900 rettv->vval.v_string = NULL; 11901 #ifdef FEAT_FOLDING 11902 lnum = get_tv_lnum(argvars); 11903 /* treat illegal types and illegal string values for {lnum} the same */ 11904 if (lnum < 0) 11905 lnum = 0; 11906 fold_count = foldedCount(curwin, lnum, &foldinfo); 11907 if (fold_count > 0) 11908 { 11909 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 11910 &foldinfo, buf); 11911 if (text == buf) 11912 text = vim_strsave(text); 11913 rettv->vval.v_string = text; 11914 } 11915 #endif 11916 } 11917 11918 /* 11919 * "foreground()" function 11920 */ 11921 static void 11922 f_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 11923 { 11924 #ifdef FEAT_GUI 11925 if (gui.in_use) 11926 gui_mch_set_foreground(); 11927 #else 11928 # ifdef WIN32 11929 win32_set_foreground(); 11930 # endif 11931 #endif 11932 } 11933 11934 /* 11935 * "function()" function 11936 */ 11937 static void 11938 f_function(typval_T *argvars, typval_T *rettv) 11939 { 11940 char_u *s; 11941 char_u *name; 11942 int use_string = FALSE; 11943 partial_T *arg_pt = NULL; 11944 11945 if (argvars[0].v_type == VAR_FUNC) 11946 { 11947 /* function(MyFunc, [arg], dict) */ 11948 s = argvars[0].vval.v_string; 11949 } 11950 else if (argvars[0].v_type == VAR_PARTIAL 11951 && argvars[0].vval.v_partial != NULL) 11952 { 11953 /* function(dict.MyFunc, [arg]) */ 11954 arg_pt = argvars[0].vval.v_partial; 11955 s = arg_pt->pt_name; 11956 } 11957 else 11958 { 11959 /* function('MyFunc', [arg], dict) */ 11960 s = get_tv_string(&argvars[0]); 11961 use_string = TRUE; 11962 } 11963 11964 if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s))) 11965 EMSG2(_(e_invarg2), s); 11966 /* Don't check an autoload name for existence here. */ 11967 else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL 11968 && !function_exists(s)) 11969 EMSG2(_("E700: Unknown function: %s"), s); 11970 else 11971 { 11972 int dict_idx = 0; 11973 int arg_idx = 0; 11974 list_T *list = NULL; 11975 11976 if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0) 11977 { 11978 char sid_buf[25]; 11979 int off = *s == 's' ? 2 : 5; 11980 11981 /* Expand s: and <SID> into <SNR>nr_, so that the function can 11982 * also be called from another script. Using trans_function_name() 11983 * would also work, but some plugins depend on the name being 11984 * printable text. */ 11985 sprintf(sid_buf, "<SNR>%ld_", (long)current_SID); 11986 name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); 11987 if (name != NULL) 11988 { 11989 STRCPY(name, sid_buf); 11990 STRCAT(name, s + off); 11991 } 11992 } 11993 else 11994 name = vim_strsave(s); 11995 11996 if (argvars[1].v_type != VAR_UNKNOWN) 11997 { 11998 if (argvars[2].v_type != VAR_UNKNOWN) 11999 { 12000 /* function(name, [args], dict) */ 12001 arg_idx = 1; 12002 dict_idx = 2; 12003 } 12004 else if (argvars[1].v_type == VAR_DICT) 12005 /* function(name, dict) */ 12006 dict_idx = 1; 12007 else 12008 /* function(name, [args]) */ 12009 arg_idx = 1; 12010 if (dict_idx > 0) 12011 { 12012 if (argvars[dict_idx].v_type != VAR_DICT) 12013 { 12014 EMSG(_("E922: expected a dict")); 12015 vim_free(name); 12016 return; 12017 } 12018 if (argvars[dict_idx].vval.v_dict == NULL) 12019 dict_idx = 0; 12020 } 12021 if (arg_idx > 0) 12022 { 12023 if (argvars[arg_idx].v_type != VAR_LIST) 12024 { 12025 EMSG(_("E923: Second argument of function() must be a list or a dict")); 12026 vim_free(name); 12027 return; 12028 } 12029 list = argvars[arg_idx].vval.v_list; 12030 if (list == NULL || list->lv_len == 0) 12031 arg_idx = 0; 12032 } 12033 } 12034 if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL) 12035 { 12036 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); 12037 12038 /* result is a VAR_PARTIAL */ 12039 if (pt == NULL) 12040 vim_free(name); 12041 else 12042 { 12043 if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0)) 12044 { 12045 listitem_T *li; 12046 int i = 0; 12047 int arg_len = 0; 12048 int lv_len = 0; 12049 12050 if (arg_pt != NULL) 12051 arg_len = arg_pt->pt_argc; 12052 if (list != NULL) 12053 lv_len = list->lv_len; 12054 pt->pt_argc = arg_len + lv_len; 12055 pt->pt_argv = (typval_T *)alloc( 12056 sizeof(typval_T) * pt->pt_argc); 12057 if (pt->pt_argv == NULL) 12058 { 12059 vim_free(pt); 12060 vim_free(name); 12061 return; 12062 } 12063 else 12064 { 12065 for (i = 0; i < arg_len; i++) 12066 copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]); 12067 if (lv_len > 0) 12068 for (li = list->lv_first; li != NULL; 12069 li = li->li_next) 12070 copy_tv(&li->li_tv, &pt->pt_argv[i++]); 12071 } 12072 } 12073 12074 /* For "function(dict.func, [], dict)" and "func" is a partial 12075 * use "dict". That is backwards compatible. */ 12076 if (dict_idx > 0) 12077 { 12078 pt->pt_dict = argvars[dict_idx].vval.v_dict; 12079 ++pt->pt_dict->dv_refcount; 12080 } 12081 else if (arg_pt != NULL) 12082 { 12083 pt->pt_dict = arg_pt->pt_dict; 12084 if (pt->pt_dict != NULL) 12085 ++pt->pt_dict->dv_refcount; 12086 } 12087 12088 pt->pt_refcount = 1; 12089 pt->pt_name = name; 12090 func_ref(pt->pt_name); 12091 } 12092 rettv->v_type = VAR_PARTIAL; 12093 rettv->vval.v_partial = pt; 12094 } 12095 else 12096 { 12097 /* result is a VAR_FUNC */ 12098 rettv->v_type = VAR_FUNC; 12099 rettv->vval.v_string = name; 12100 func_ref(name); 12101 } 12102 } 12103 } 12104 12105 /* 12106 * "garbagecollect()" function 12107 */ 12108 static void 12109 f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED) 12110 { 12111 /* This is postponed until we are back at the toplevel, because we may be 12112 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 12113 want_garbage_collect = TRUE; 12114 12115 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 12116 garbage_collect_at_exit = TRUE; 12117 } 12118 12119 /* 12120 * "get()" function 12121 */ 12122 static void 12123 f_get(typval_T *argvars, typval_T *rettv) 12124 { 12125 listitem_T *li; 12126 list_T *l; 12127 dictitem_T *di; 12128 dict_T *d; 12129 typval_T *tv = NULL; 12130 12131 if (argvars[0].v_type == VAR_LIST) 12132 { 12133 if ((l = argvars[0].vval.v_list) != NULL) 12134 { 12135 int error = FALSE; 12136 12137 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 12138 if (!error && li != NULL) 12139 tv = &li->li_tv; 12140 } 12141 } 12142 else if (argvars[0].v_type == VAR_DICT) 12143 { 12144 if ((d = argvars[0].vval.v_dict) != NULL) 12145 { 12146 di = dict_find(d, get_tv_string(&argvars[1]), -1); 12147 if (di != NULL) 12148 tv = &di->di_tv; 12149 } 12150 } 12151 else 12152 EMSG2(_(e_listdictarg), "get()"); 12153 12154 if (tv == NULL) 12155 { 12156 if (argvars[2].v_type != VAR_UNKNOWN) 12157 copy_tv(&argvars[2], rettv); 12158 } 12159 else 12160 copy_tv(tv, rettv); 12161 } 12162 12163 static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv); 12164 12165 /* 12166 * Get line or list of lines from buffer "buf" into "rettv". 12167 * Return a range (from start to end) of lines in rettv from the specified 12168 * buffer. 12169 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 12170 */ 12171 static void 12172 get_buffer_lines( 12173 buf_T *buf, 12174 linenr_T start, 12175 linenr_T end, 12176 int retlist, 12177 typval_T *rettv) 12178 { 12179 char_u *p; 12180 12181 rettv->v_type = VAR_STRING; 12182 rettv->vval.v_string = NULL; 12183 if (retlist && rettv_list_alloc(rettv) == FAIL) 12184 return; 12185 12186 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 12187 return; 12188 12189 if (!retlist) 12190 { 12191 if (start >= 1 && start <= buf->b_ml.ml_line_count) 12192 p = ml_get_buf(buf, start, FALSE); 12193 else 12194 p = (char_u *)""; 12195 rettv->vval.v_string = vim_strsave(p); 12196 } 12197 else 12198 { 12199 if (end < start) 12200 return; 12201 12202 if (start < 1) 12203 start = 1; 12204 if (end > buf->b_ml.ml_line_count) 12205 end = buf->b_ml.ml_line_count; 12206 while (start <= end) 12207 if (list_append_string(rettv->vval.v_list, 12208 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 12209 break; 12210 } 12211 } 12212 12213 /* 12214 * "getbufline()" function 12215 */ 12216 static void 12217 f_getbufline(typval_T *argvars, typval_T *rettv) 12218 { 12219 linenr_T lnum; 12220 linenr_T end; 12221 buf_T *buf; 12222 12223 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 12224 ++emsg_off; 12225 buf = get_buf_tv(&argvars[0], FALSE); 12226 --emsg_off; 12227 12228 lnum = get_tv_lnum_buf(&argvars[1], buf); 12229 if (argvars[2].v_type == VAR_UNKNOWN) 12230 end = lnum; 12231 else 12232 end = get_tv_lnum_buf(&argvars[2], buf); 12233 12234 get_buffer_lines(buf, lnum, end, TRUE, rettv); 12235 } 12236 12237 /* 12238 * "getbufvar()" function 12239 */ 12240 static void 12241 f_getbufvar(typval_T *argvars, typval_T *rettv) 12242 { 12243 buf_T *buf; 12244 buf_T *save_curbuf; 12245 char_u *varname; 12246 dictitem_T *v; 12247 int done = FALSE; 12248 12249 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 12250 varname = get_tv_string_chk(&argvars[1]); 12251 ++emsg_off; 12252 buf = get_buf_tv(&argvars[0], FALSE); 12253 12254 rettv->v_type = VAR_STRING; 12255 rettv->vval.v_string = NULL; 12256 12257 if (buf != NULL && varname != NULL) 12258 { 12259 /* set curbuf to be our buf, temporarily */ 12260 save_curbuf = curbuf; 12261 curbuf = buf; 12262 12263 if (*varname == '&') /* buffer-local-option */ 12264 { 12265 if (get_option_tv(&varname, rettv, TRUE) == OK) 12266 done = TRUE; 12267 } 12268 else if (STRCMP(varname, "changedtick") == 0) 12269 { 12270 rettv->v_type = VAR_NUMBER; 12271 rettv->vval.v_number = curbuf->b_changedtick; 12272 done = TRUE; 12273 } 12274 else 12275 { 12276 /* Look up the variable. */ 12277 /* Let getbufvar({nr}, "") return the "b:" dictionary. */ 12278 v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 12279 'b', varname, FALSE); 12280 if (v != NULL) 12281 { 12282 copy_tv(&v->di_tv, rettv); 12283 done = TRUE; 12284 } 12285 } 12286 12287 /* restore previous notion of curbuf */ 12288 curbuf = save_curbuf; 12289 } 12290 12291 if (!done && argvars[2].v_type != VAR_UNKNOWN) 12292 /* use the default value */ 12293 copy_tv(&argvars[2], rettv); 12294 12295 --emsg_off; 12296 } 12297 12298 /* 12299 * "getchar()" function 12300 */ 12301 static void 12302 f_getchar(typval_T *argvars, typval_T *rettv) 12303 { 12304 varnumber_T n; 12305 int error = FALSE; 12306 12307 /* Position the cursor. Needed after a message that ends in a space. */ 12308 windgoto(msg_row, msg_col); 12309 12310 ++no_mapping; 12311 ++allow_keys; 12312 for (;;) 12313 { 12314 if (argvars[0].v_type == VAR_UNKNOWN) 12315 /* getchar(): blocking wait. */ 12316 n = safe_vgetc(); 12317 else if (get_tv_number_chk(&argvars[0], &error) == 1) 12318 /* getchar(1): only check if char avail */ 12319 n = vpeekc_any(); 12320 else if (error || vpeekc_any() == NUL) 12321 /* illegal argument or getchar(0) and no char avail: return zero */ 12322 n = 0; 12323 else 12324 /* getchar(0) and char avail: return char */ 12325 n = safe_vgetc(); 12326 12327 if (n == K_IGNORE) 12328 continue; 12329 break; 12330 } 12331 --no_mapping; 12332 --allow_keys; 12333 12334 vimvars[VV_MOUSE_WIN].vv_nr = 0; 12335 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 12336 vimvars[VV_MOUSE_COL].vv_nr = 0; 12337 12338 rettv->vval.v_number = n; 12339 if (IS_SPECIAL(n) || mod_mask != 0) 12340 { 12341 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 12342 int i = 0; 12343 12344 /* Turn a special key into three bytes, plus modifier. */ 12345 if (mod_mask != 0) 12346 { 12347 temp[i++] = K_SPECIAL; 12348 temp[i++] = KS_MODIFIER; 12349 temp[i++] = mod_mask; 12350 } 12351 if (IS_SPECIAL(n)) 12352 { 12353 temp[i++] = K_SPECIAL; 12354 temp[i++] = K_SECOND(n); 12355 temp[i++] = K_THIRD(n); 12356 } 12357 #ifdef FEAT_MBYTE 12358 else if (has_mbyte) 12359 i += (*mb_char2bytes)(n, temp + i); 12360 #endif 12361 else 12362 temp[i++] = n; 12363 temp[i++] = NUL; 12364 rettv->v_type = VAR_STRING; 12365 rettv->vval.v_string = vim_strsave(temp); 12366 12367 #ifdef FEAT_MOUSE 12368 if (is_mouse_key(n)) 12369 { 12370 int row = mouse_row; 12371 int col = mouse_col; 12372 win_T *win; 12373 linenr_T lnum; 12374 # ifdef FEAT_WINDOWS 12375 win_T *wp; 12376 # endif 12377 int winnr = 1; 12378 12379 if (row >= 0 && col >= 0) 12380 { 12381 /* Find the window at the mouse coordinates and compute the 12382 * text position. */ 12383 win = mouse_find_win(&row, &col); 12384 (void)mouse_comp_pos(win, &row, &col, &lnum); 12385 # ifdef FEAT_WINDOWS 12386 for (wp = firstwin; wp != win; wp = wp->w_next) 12387 ++winnr; 12388 # endif 12389 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 12390 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 12391 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 12392 } 12393 } 12394 #endif 12395 } 12396 } 12397 12398 /* 12399 * "getcharmod()" function 12400 */ 12401 static void 12402 f_getcharmod(typval_T *argvars UNUSED, typval_T *rettv) 12403 { 12404 rettv->vval.v_number = mod_mask; 12405 } 12406 12407 /* 12408 * "getcharsearch()" function 12409 */ 12410 static void 12411 f_getcharsearch(typval_T *argvars UNUSED, typval_T *rettv) 12412 { 12413 if (rettv_dict_alloc(rettv) != FAIL) 12414 { 12415 dict_T *dict = rettv->vval.v_dict; 12416 12417 dict_add_nr_str(dict, "char", 0L, last_csearch()); 12418 dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL); 12419 dict_add_nr_str(dict, "until", last_csearch_until(), NULL); 12420 } 12421 } 12422 12423 /* 12424 * "getcmdline()" function 12425 */ 12426 static void 12427 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv) 12428 { 12429 rettv->v_type = VAR_STRING; 12430 rettv->vval.v_string = get_cmdline_str(); 12431 } 12432 12433 /* 12434 * "getcmdpos()" function 12435 */ 12436 static void 12437 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv) 12438 { 12439 rettv->vval.v_number = get_cmdline_pos() + 1; 12440 } 12441 12442 /* 12443 * "getcmdtype()" function 12444 */ 12445 static void 12446 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv) 12447 { 12448 rettv->v_type = VAR_STRING; 12449 rettv->vval.v_string = alloc(2); 12450 if (rettv->vval.v_string != NULL) 12451 { 12452 rettv->vval.v_string[0] = get_cmdline_type(); 12453 rettv->vval.v_string[1] = NUL; 12454 } 12455 } 12456 12457 /* 12458 * "getcmdwintype()" function 12459 */ 12460 static void 12461 f_getcmdwintype(typval_T *argvars UNUSED, typval_T *rettv) 12462 { 12463 rettv->v_type = VAR_STRING; 12464 rettv->vval.v_string = NULL; 12465 #ifdef FEAT_CMDWIN 12466 rettv->vval.v_string = alloc(2); 12467 if (rettv->vval.v_string != NULL) 12468 { 12469 rettv->vval.v_string[0] = cmdwin_type; 12470 rettv->vval.v_string[1] = NUL; 12471 } 12472 #endif 12473 } 12474 12475 /* 12476 * "getcwd()" function 12477 */ 12478 static void 12479 f_getcwd(typval_T *argvars, typval_T *rettv) 12480 { 12481 win_T *wp = NULL; 12482 char_u *cwd; 12483 12484 rettv->v_type = VAR_STRING; 12485 rettv->vval.v_string = NULL; 12486 12487 wp = find_tabwin(&argvars[0], &argvars[1]); 12488 if (wp != NULL) 12489 { 12490 if (wp->w_localdir != NULL) 12491 rettv->vval.v_string = vim_strsave(wp->w_localdir); 12492 else if(globaldir != NULL) 12493 rettv->vval.v_string = vim_strsave(globaldir); 12494 else 12495 { 12496 cwd = alloc(MAXPATHL); 12497 if (cwd != NULL) 12498 { 12499 if (mch_dirname(cwd, MAXPATHL) != FAIL) 12500 rettv->vval.v_string = vim_strsave(cwd); 12501 vim_free(cwd); 12502 } 12503 } 12504 #ifdef BACKSLASH_IN_FILENAME 12505 if (rettv->vval.v_string != NULL) 12506 slash_adjust(rettv->vval.v_string); 12507 #endif 12508 } 12509 } 12510 12511 /* 12512 * "getfontname()" function 12513 */ 12514 static void 12515 f_getfontname(typval_T *argvars UNUSED, typval_T *rettv) 12516 { 12517 rettv->v_type = VAR_STRING; 12518 rettv->vval.v_string = NULL; 12519 #ifdef FEAT_GUI 12520 if (gui.in_use) 12521 { 12522 GuiFont font; 12523 char_u *name = NULL; 12524 12525 if (argvars[0].v_type == VAR_UNKNOWN) 12526 { 12527 /* Get the "Normal" font. Either the name saved by 12528 * hl_set_font_name() or from the font ID. */ 12529 font = gui.norm_font; 12530 name = hl_get_font_name(); 12531 } 12532 else 12533 { 12534 name = get_tv_string(&argvars[0]); 12535 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 12536 return; 12537 font = gui_mch_get_font(name, FALSE); 12538 if (font == NOFONT) 12539 return; /* Invalid font name, return empty string. */ 12540 } 12541 rettv->vval.v_string = gui_mch_get_fontname(font, name); 12542 if (argvars[0].v_type != VAR_UNKNOWN) 12543 gui_mch_free_font(font); 12544 } 12545 #endif 12546 } 12547 12548 /* 12549 * "getfperm({fname})" function 12550 */ 12551 static void 12552 f_getfperm(typval_T *argvars, typval_T *rettv) 12553 { 12554 char_u *fname; 12555 struct stat st; 12556 char_u *perm = NULL; 12557 char_u flags[] = "rwx"; 12558 int i; 12559 12560 fname = get_tv_string(&argvars[0]); 12561 12562 rettv->v_type = VAR_STRING; 12563 if (mch_stat((char *)fname, &st) >= 0) 12564 { 12565 perm = vim_strsave((char_u *)"---------"); 12566 if (perm != NULL) 12567 { 12568 for (i = 0; i < 9; i++) 12569 { 12570 if (st.st_mode & (1 << (8 - i))) 12571 perm[i] = flags[i % 3]; 12572 } 12573 } 12574 } 12575 rettv->vval.v_string = perm; 12576 } 12577 12578 /* 12579 * "getfsize({fname})" function 12580 */ 12581 static void 12582 f_getfsize(typval_T *argvars, typval_T *rettv) 12583 { 12584 char_u *fname; 12585 struct stat st; 12586 12587 fname = get_tv_string(&argvars[0]); 12588 12589 rettv->v_type = VAR_NUMBER; 12590 12591 if (mch_stat((char *)fname, &st) >= 0) 12592 { 12593 if (mch_isdir(fname)) 12594 rettv->vval.v_number = 0; 12595 else 12596 { 12597 rettv->vval.v_number = (varnumber_T)st.st_size; 12598 12599 /* non-perfect check for overflow */ 12600 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 12601 rettv->vval.v_number = -2; 12602 } 12603 } 12604 else 12605 rettv->vval.v_number = -1; 12606 } 12607 12608 /* 12609 * "getftime({fname})" function 12610 */ 12611 static void 12612 f_getftime(typval_T *argvars, typval_T *rettv) 12613 { 12614 char_u *fname; 12615 struct stat st; 12616 12617 fname = get_tv_string(&argvars[0]); 12618 12619 if (mch_stat((char *)fname, &st) >= 0) 12620 rettv->vval.v_number = (varnumber_T)st.st_mtime; 12621 else 12622 rettv->vval.v_number = -1; 12623 } 12624 12625 /* 12626 * "getftype({fname})" function 12627 */ 12628 static void 12629 f_getftype(typval_T *argvars, typval_T *rettv) 12630 { 12631 char_u *fname; 12632 struct stat st; 12633 char_u *type = NULL; 12634 char *t; 12635 12636 fname = get_tv_string(&argvars[0]); 12637 12638 rettv->v_type = VAR_STRING; 12639 if (mch_lstat((char *)fname, &st) >= 0) 12640 { 12641 #ifdef S_ISREG 12642 if (S_ISREG(st.st_mode)) 12643 t = "file"; 12644 else if (S_ISDIR(st.st_mode)) 12645 t = "dir"; 12646 # ifdef S_ISLNK 12647 else if (S_ISLNK(st.st_mode)) 12648 t = "link"; 12649 # endif 12650 # ifdef S_ISBLK 12651 else if (S_ISBLK(st.st_mode)) 12652 t = "bdev"; 12653 # endif 12654 # ifdef S_ISCHR 12655 else if (S_ISCHR(st.st_mode)) 12656 t = "cdev"; 12657 # endif 12658 # ifdef S_ISFIFO 12659 else if (S_ISFIFO(st.st_mode)) 12660 t = "fifo"; 12661 # endif 12662 # ifdef S_ISSOCK 12663 else if (S_ISSOCK(st.st_mode)) 12664 t = "fifo"; 12665 # endif 12666 else 12667 t = "other"; 12668 #else 12669 # ifdef S_IFMT 12670 switch (st.st_mode & S_IFMT) 12671 { 12672 case S_IFREG: t = "file"; break; 12673 case S_IFDIR: t = "dir"; break; 12674 # ifdef S_IFLNK 12675 case S_IFLNK: t = "link"; break; 12676 # endif 12677 # ifdef S_IFBLK 12678 case S_IFBLK: t = "bdev"; break; 12679 # endif 12680 # ifdef S_IFCHR 12681 case S_IFCHR: t = "cdev"; break; 12682 # endif 12683 # ifdef S_IFIFO 12684 case S_IFIFO: t = "fifo"; break; 12685 # endif 12686 # ifdef S_IFSOCK 12687 case S_IFSOCK: t = "socket"; break; 12688 # endif 12689 default: t = "other"; 12690 } 12691 # else 12692 if (mch_isdir(fname)) 12693 t = "dir"; 12694 else 12695 t = "file"; 12696 # endif 12697 #endif 12698 type = vim_strsave((char_u *)t); 12699 } 12700 rettv->vval.v_string = type; 12701 } 12702 12703 /* 12704 * "getline(lnum, [end])" function 12705 */ 12706 static void 12707 f_getline(typval_T *argvars, typval_T *rettv) 12708 { 12709 linenr_T lnum; 12710 linenr_T end; 12711 int retlist; 12712 12713 lnum = get_tv_lnum(argvars); 12714 if (argvars[1].v_type == VAR_UNKNOWN) 12715 { 12716 end = 0; 12717 retlist = FALSE; 12718 } 12719 else 12720 { 12721 end = get_tv_lnum(&argvars[1]); 12722 retlist = TRUE; 12723 } 12724 12725 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 12726 } 12727 12728 /* 12729 * "getmatches()" function 12730 */ 12731 static void 12732 f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 12733 { 12734 #ifdef FEAT_SEARCH_EXTRA 12735 dict_T *dict; 12736 matchitem_T *cur = curwin->w_match_head; 12737 int i; 12738 12739 if (rettv_list_alloc(rettv) == OK) 12740 { 12741 while (cur != NULL) 12742 { 12743 dict = dict_alloc(); 12744 if (dict == NULL) 12745 return; 12746 if (cur->match.regprog == NULL) 12747 { 12748 /* match added with matchaddpos() */ 12749 for (i = 0; i < MAXPOSMATCH; ++i) 12750 { 12751 llpos_T *llpos; 12752 char buf[6]; 12753 list_T *l; 12754 12755 llpos = &cur->pos.pos[i]; 12756 if (llpos->lnum == 0) 12757 break; 12758 l = list_alloc(); 12759 if (l == NULL) 12760 break; 12761 list_append_number(l, (varnumber_T)llpos->lnum); 12762 if (llpos->col > 0) 12763 { 12764 list_append_number(l, (varnumber_T)llpos->col); 12765 list_append_number(l, (varnumber_T)llpos->len); 12766 } 12767 sprintf(buf, "pos%d", i + 1); 12768 dict_add_list(dict, buf, l); 12769 } 12770 } 12771 else 12772 { 12773 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 12774 } 12775 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 12776 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 12777 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 12778 # ifdef FEAT_CONCEAL 12779 if (cur->conceal_char) 12780 { 12781 char_u buf[MB_MAXBYTES + 1]; 12782 12783 buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL; 12784 dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf); 12785 } 12786 # endif 12787 list_append_dict(rettv->vval.v_list, dict); 12788 cur = cur->next; 12789 } 12790 } 12791 #endif 12792 } 12793 12794 /* 12795 * "getpid()" function 12796 */ 12797 static void 12798 f_getpid(typval_T *argvars UNUSED, typval_T *rettv) 12799 { 12800 rettv->vval.v_number = mch_get_pid(); 12801 } 12802 12803 static void getpos_both(typval_T *argvars, typval_T *rettv, int getcurpos); 12804 12805 /* 12806 * "getcurpos()" function 12807 */ 12808 static void 12809 f_getcurpos(typval_T *argvars, typval_T *rettv) 12810 { 12811 getpos_both(argvars, rettv, TRUE); 12812 } 12813 12814 /* 12815 * "getpos(string)" function 12816 */ 12817 static void 12818 f_getpos(typval_T *argvars, typval_T *rettv) 12819 { 12820 getpos_both(argvars, rettv, FALSE); 12821 } 12822 12823 static void 12824 getpos_both( 12825 typval_T *argvars, 12826 typval_T *rettv, 12827 int getcurpos) 12828 { 12829 pos_T *fp; 12830 list_T *l; 12831 int fnum = -1; 12832 12833 if (rettv_list_alloc(rettv) == OK) 12834 { 12835 l = rettv->vval.v_list; 12836 if (getcurpos) 12837 fp = &curwin->w_cursor; 12838 else 12839 fp = var2fpos(&argvars[0], TRUE, &fnum); 12840 if (fnum != -1) 12841 list_append_number(l, (varnumber_T)fnum); 12842 else 12843 list_append_number(l, (varnumber_T)0); 12844 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 12845 : (varnumber_T)0); 12846 list_append_number(l, (fp != NULL) 12847 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 12848 : (varnumber_T)0); 12849 list_append_number(l, 12850 #ifdef FEAT_VIRTUALEDIT 12851 (fp != NULL) ? (varnumber_T)fp->coladd : 12852 #endif 12853 (varnumber_T)0); 12854 if (getcurpos) 12855 { 12856 update_curswant(); 12857 list_append_number(l, curwin->w_curswant == MAXCOL ? 12858 (varnumber_T)MAXCOL : (varnumber_T)curwin->w_curswant + 1); 12859 } 12860 } 12861 else 12862 rettv->vval.v_number = FALSE; 12863 } 12864 12865 /* 12866 * "getqflist()" and "getloclist()" functions 12867 */ 12868 static void 12869 f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 12870 { 12871 #ifdef FEAT_QUICKFIX 12872 win_T *wp; 12873 #endif 12874 12875 #ifdef FEAT_QUICKFIX 12876 if (rettv_list_alloc(rettv) == OK) 12877 { 12878 wp = NULL; 12879 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 12880 { 12881 wp = find_win_by_nr(&argvars[0], NULL); 12882 if (wp == NULL) 12883 return; 12884 } 12885 12886 (void)get_errorlist(wp, rettv->vval.v_list); 12887 } 12888 #endif 12889 } 12890 12891 /* 12892 * "getreg()" function 12893 */ 12894 static void 12895 f_getreg(typval_T *argvars, typval_T *rettv) 12896 { 12897 char_u *strregname; 12898 int regname; 12899 int arg2 = FALSE; 12900 int return_list = FALSE; 12901 int error = FALSE; 12902 12903 if (argvars[0].v_type != VAR_UNKNOWN) 12904 { 12905 strregname = get_tv_string_chk(&argvars[0]); 12906 error = strregname == NULL; 12907 if (argvars[1].v_type != VAR_UNKNOWN) 12908 { 12909 arg2 = get_tv_number_chk(&argvars[1], &error); 12910 if (!error && argvars[2].v_type != VAR_UNKNOWN) 12911 return_list = get_tv_number_chk(&argvars[2], &error); 12912 } 12913 } 12914 else 12915 strregname = vimvars[VV_REG].vv_str; 12916 12917 if (error) 12918 return; 12919 12920 regname = (strregname == NULL ? '"' : *strregname); 12921 if (regname == 0) 12922 regname = '"'; 12923 12924 if (return_list) 12925 { 12926 rettv->v_type = VAR_LIST; 12927 rettv->vval.v_list = (list_T *)get_reg_contents(regname, 12928 (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST); 12929 if (rettv->vval.v_list != NULL) 12930 ++rettv->vval.v_list->lv_refcount; 12931 } 12932 else 12933 { 12934 rettv->v_type = VAR_STRING; 12935 rettv->vval.v_string = get_reg_contents(regname, 12936 arg2 ? GREG_EXPR_SRC : 0); 12937 } 12938 } 12939 12940 /* 12941 * "getregtype()" function 12942 */ 12943 static void 12944 f_getregtype(typval_T *argvars, typval_T *rettv) 12945 { 12946 char_u *strregname; 12947 int regname; 12948 char_u buf[NUMBUFLEN + 2]; 12949 long reglen = 0; 12950 12951 if (argvars[0].v_type != VAR_UNKNOWN) 12952 { 12953 strregname = get_tv_string_chk(&argvars[0]); 12954 if (strregname == NULL) /* type error; errmsg already given */ 12955 { 12956 rettv->v_type = VAR_STRING; 12957 rettv->vval.v_string = NULL; 12958 return; 12959 } 12960 } 12961 else 12962 /* Default to v:register */ 12963 strregname = vimvars[VV_REG].vv_str; 12964 12965 regname = (strregname == NULL ? '"' : *strregname); 12966 if (regname == 0) 12967 regname = '"'; 12968 12969 buf[0] = NUL; 12970 buf[1] = NUL; 12971 switch (get_reg_type(regname, ®len)) 12972 { 12973 case MLINE: buf[0] = 'V'; break; 12974 case MCHAR: buf[0] = 'v'; break; 12975 case MBLOCK: 12976 buf[0] = Ctrl_V; 12977 sprintf((char *)buf + 1, "%ld", reglen + 1); 12978 break; 12979 } 12980 rettv->v_type = VAR_STRING; 12981 rettv->vval.v_string = vim_strsave(buf); 12982 } 12983 12984 /* 12985 * "gettabvar()" function 12986 */ 12987 static void 12988 f_gettabvar(typval_T *argvars, typval_T *rettv) 12989 { 12990 win_T *oldcurwin; 12991 tabpage_T *tp, *oldtabpage; 12992 dictitem_T *v; 12993 char_u *varname; 12994 int done = FALSE; 12995 12996 rettv->v_type = VAR_STRING; 12997 rettv->vval.v_string = NULL; 12998 12999 varname = get_tv_string_chk(&argvars[1]); 13000 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 13001 if (tp != NULL && varname != NULL) 13002 { 13003 /* Set tp to be our tabpage, temporarily. Also set the window to the 13004 * first window in the tabpage, otherwise the window is not valid. */ 13005 if (switch_win(&oldcurwin, &oldtabpage, 13006 tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE) 13007 == OK) 13008 { 13009 /* look up the variable */ 13010 /* Let gettabvar({nr}, "") return the "t:" dictionary. */ 13011 v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); 13012 if (v != NULL) 13013 { 13014 copy_tv(&v->di_tv, rettv); 13015 done = TRUE; 13016 } 13017 } 13018 13019 /* restore previous notion of curwin */ 13020 restore_win(oldcurwin, oldtabpage, TRUE); 13021 } 13022 13023 if (!done && argvars[2].v_type != VAR_UNKNOWN) 13024 copy_tv(&argvars[2], rettv); 13025 } 13026 13027 /* 13028 * "gettabwinvar()" function 13029 */ 13030 static void 13031 f_gettabwinvar(typval_T *argvars, typval_T *rettv) 13032 { 13033 getwinvar(argvars, rettv, 1); 13034 } 13035 13036 /* 13037 * "getwinposx()" function 13038 */ 13039 static void 13040 f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv) 13041 { 13042 rettv->vval.v_number = -1; 13043 #ifdef FEAT_GUI 13044 if (gui.in_use) 13045 { 13046 int x, y; 13047 13048 if (gui_mch_get_winpos(&x, &y) == OK) 13049 rettv->vval.v_number = x; 13050 } 13051 #endif 13052 } 13053 13054 /* 13055 * "win_findbuf()" function 13056 */ 13057 static void 13058 f_win_findbuf(typval_T *argvars, typval_T *rettv) 13059 { 13060 if (rettv_list_alloc(rettv) != FAIL) 13061 win_findbuf(argvars, rettv->vval.v_list); 13062 } 13063 13064 /* 13065 * "win_getid()" function 13066 */ 13067 static void 13068 f_win_getid(typval_T *argvars, typval_T *rettv) 13069 { 13070 rettv->vval.v_number = win_getid(argvars); 13071 } 13072 13073 /* 13074 * "win_gotoid()" function 13075 */ 13076 static void 13077 f_win_gotoid(typval_T *argvars, typval_T *rettv) 13078 { 13079 rettv->vval.v_number = win_gotoid(argvars); 13080 } 13081 13082 /* 13083 * "win_id2tabwin()" function 13084 */ 13085 static void 13086 f_win_id2tabwin(typval_T *argvars, typval_T *rettv) 13087 { 13088 if (rettv_list_alloc(rettv) != FAIL) 13089 win_id2tabwin(argvars, rettv->vval.v_list); 13090 } 13091 13092 /* 13093 * "win_id2win()" function 13094 */ 13095 static void 13096 f_win_id2win(typval_T *argvars, typval_T *rettv) 13097 { 13098 rettv->vval.v_number = win_id2win(argvars); 13099 } 13100 13101 /* 13102 * "getwinposy()" function 13103 */ 13104 static void 13105 f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv) 13106 { 13107 rettv->vval.v_number = -1; 13108 #ifdef FEAT_GUI 13109 if (gui.in_use) 13110 { 13111 int x, y; 13112 13113 if (gui_mch_get_winpos(&x, &y) == OK) 13114 rettv->vval.v_number = y; 13115 } 13116 #endif 13117 } 13118 13119 /* 13120 * Find window specified by "vp" in tabpage "tp". 13121 */ 13122 static win_T * 13123 find_win_by_nr( 13124 typval_T *vp, 13125 tabpage_T *tp UNUSED) /* NULL for current tab page */ 13126 { 13127 #ifdef FEAT_WINDOWS 13128 win_T *wp; 13129 #endif 13130 int nr; 13131 13132 nr = get_tv_number_chk(vp, NULL); 13133 13134 #ifdef FEAT_WINDOWS 13135 if (nr < 0) 13136 return NULL; 13137 if (nr == 0) 13138 return curwin; 13139 13140 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 13141 wp != NULL; wp = wp->w_next) 13142 if (--nr <= 0) 13143 break; 13144 return wp; 13145 #else 13146 if (nr == 0 || nr == 1) 13147 return curwin; 13148 return NULL; 13149 #endif 13150 } 13151 13152 /* 13153 * Find window specified by "wvp" in tabpage "tvp". 13154 */ 13155 static win_T * 13156 find_tabwin( 13157 typval_T *wvp, /* VAR_UNKNOWN for current window */ 13158 typval_T *tvp) /* VAR_UNKNOWN for current tab page */ 13159 { 13160 win_T *wp = NULL; 13161 tabpage_T *tp = NULL; 13162 long n; 13163 13164 if (wvp->v_type != VAR_UNKNOWN) 13165 { 13166 if (tvp->v_type != VAR_UNKNOWN) 13167 { 13168 n = get_tv_number(tvp); 13169 if (n >= 0) 13170 tp = find_tabpage(n); 13171 } 13172 else 13173 tp = curtab; 13174 13175 if (tp != NULL) 13176 wp = find_win_by_nr(wvp, tp); 13177 } 13178 else 13179 wp = curwin; 13180 13181 return wp; 13182 } 13183 13184 /* 13185 * "getwinvar()" function 13186 */ 13187 static void 13188 f_getwinvar(typval_T *argvars, typval_T *rettv) 13189 { 13190 getwinvar(argvars, rettv, 0); 13191 } 13192 13193 /* 13194 * getwinvar() and gettabwinvar() 13195 */ 13196 static void 13197 getwinvar( 13198 typval_T *argvars, 13199 typval_T *rettv, 13200 int off) /* 1 for gettabwinvar() */ 13201 { 13202 win_T *win; 13203 char_u *varname; 13204 dictitem_T *v; 13205 tabpage_T *tp = NULL; 13206 int done = FALSE; 13207 #ifdef FEAT_WINDOWS 13208 win_T *oldcurwin; 13209 tabpage_T *oldtabpage; 13210 int need_switch_win; 13211 #endif 13212 13213 #ifdef FEAT_WINDOWS 13214 if (off == 1) 13215 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 13216 else 13217 tp = curtab; 13218 #endif 13219 win = find_win_by_nr(&argvars[off], tp); 13220 varname = get_tv_string_chk(&argvars[off + 1]); 13221 ++emsg_off; 13222 13223 rettv->v_type = VAR_STRING; 13224 rettv->vval.v_string = NULL; 13225 13226 if (win != NULL && varname != NULL) 13227 { 13228 #ifdef FEAT_WINDOWS 13229 /* Set curwin to be our win, temporarily. Also set the tabpage, 13230 * otherwise the window is not valid. Only do this when needed, 13231 * autocommands get blocked. */ 13232 need_switch_win = !(tp == curtab && win == curwin); 13233 if (!need_switch_win 13234 || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) 13235 #endif 13236 { 13237 if (*varname == '&') /* window-local-option */ 13238 { 13239 if (get_option_tv(&varname, rettv, 1) == OK) 13240 done = TRUE; 13241 } 13242 else 13243 { 13244 /* Look up the variable. */ 13245 /* Let getwinvar({nr}, "") return the "w:" dictionary. */ 13246 v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', 13247 varname, FALSE); 13248 if (v != NULL) 13249 { 13250 copy_tv(&v->di_tv, rettv); 13251 done = TRUE; 13252 } 13253 } 13254 } 13255 13256 #ifdef FEAT_WINDOWS 13257 if (need_switch_win) 13258 /* restore previous notion of curwin */ 13259 restore_win(oldcurwin, oldtabpage, TRUE); 13260 #endif 13261 } 13262 13263 if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) 13264 /* use the default return value */ 13265 copy_tv(&argvars[off + 2], rettv); 13266 13267 --emsg_off; 13268 } 13269 13270 /* 13271 * "glob()" function 13272 */ 13273 static void 13274 f_glob(typval_T *argvars, typval_T *rettv) 13275 { 13276 int options = WILD_SILENT|WILD_USE_NL; 13277 expand_T xpc; 13278 int error = FALSE; 13279 13280 /* When the optional second argument is non-zero, don't remove matches 13281 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 13282 rettv->v_type = VAR_STRING; 13283 if (argvars[1].v_type != VAR_UNKNOWN) 13284 { 13285 if (get_tv_number_chk(&argvars[1], &error)) 13286 options |= WILD_KEEP_ALL; 13287 if (argvars[2].v_type != VAR_UNKNOWN) 13288 { 13289 if (get_tv_number_chk(&argvars[2], &error)) 13290 { 13291 rettv->v_type = VAR_LIST; 13292 rettv->vval.v_list = NULL; 13293 } 13294 if (argvars[3].v_type != VAR_UNKNOWN 13295 && get_tv_number_chk(&argvars[3], &error)) 13296 options |= WILD_ALLLINKS; 13297 } 13298 } 13299 if (!error) 13300 { 13301 ExpandInit(&xpc); 13302 xpc.xp_context = EXPAND_FILES; 13303 if (p_wic) 13304 options += WILD_ICASE; 13305 if (rettv->v_type == VAR_STRING) 13306 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 13307 NULL, options, WILD_ALL); 13308 else if (rettv_list_alloc(rettv) != FAIL) 13309 { 13310 int i; 13311 13312 ExpandOne(&xpc, get_tv_string(&argvars[0]), 13313 NULL, options, WILD_ALL_KEEP); 13314 for (i = 0; i < xpc.xp_numfiles; i++) 13315 list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); 13316 13317 ExpandCleanup(&xpc); 13318 } 13319 } 13320 else 13321 rettv->vval.v_string = NULL; 13322 } 13323 13324 /* 13325 * "globpath()" function 13326 */ 13327 static void 13328 f_globpath(typval_T *argvars, typval_T *rettv) 13329 { 13330 int flags = 0; 13331 char_u buf1[NUMBUFLEN]; 13332 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 13333 int error = FALSE; 13334 garray_T ga; 13335 int i; 13336 13337 /* When the optional second argument is non-zero, don't remove matches 13338 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 13339 rettv->v_type = VAR_STRING; 13340 if (argvars[2].v_type != VAR_UNKNOWN) 13341 { 13342 if (get_tv_number_chk(&argvars[2], &error)) 13343 flags |= WILD_KEEP_ALL; 13344 if (argvars[3].v_type != VAR_UNKNOWN) 13345 { 13346 if (get_tv_number_chk(&argvars[3], &error)) 13347 { 13348 rettv->v_type = VAR_LIST; 13349 rettv->vval.v_list = NULL; 13350 } 13351 if (argvars[4].v_type != VAR_UNKNOWN 13352 && get_tv_number_chk(&argvars[4], &error)) 13353 flags |= WILD_ALLLINKS; 13354 } 13355 } 13356 if (file != NULL && !error) 13357 { 13358 ga_init2(&ga, (int)sizeof(char_u *), 10); 13359 globpath(get_tv_string(&argvars[0]), file, &ga, flags); 13360 if (rettv->v_type == VAR_STRING) 13361 rettv->vval.v_string = ga_concat_strings(&ga, "\n"); 13362 else if (rettv_list_alloc(rettv) != FAIL) 13363 for (i = 0; i < ga.ga_len; ++i) 13364 list_append_string(rettv->vval.v_list, 13365 ((char_u **)(ga.ga_data))[i], -1); 13366 ga_clear_strings(&ga); 13367 } 13368 else 13369 rettv->vval.v_string = NULL; 13370 } 13371 13372 /* 13373 * "glob2regpat()" function 13374 */ 13375 static void 13376 f_glob2regpat(typval_T *argvars, typval_T *rettv) 13377 { 13378 char_u *pat = get_tv_string_chk(&argvars[0]); 13379 13380 rettv->v_type = VAR_STRING; 13381 rettv->vval.v_string = (pat == NULL) 13382 ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, FALSE); 13383 } 13384 13385 /* 13386 * "has()" function 13387 */ 13388 static void 13389 f_has(typval_T *argvars, typval_T *rettv) 13390 { 13391 int i; 13392 char_u *name; 13393 int n = FALSE; 13394 static char *(has_list[]) = 13395 { 13396 #ifdef AMIGA 13397 "amiga", 13398 # ifdef FEAT_ARP 13399 "arp", 13400 # endif 13401 #endif 13402 #ifdef __BEOS__ 13403 "beos", 13404 #endif 13405 #ifdef MACOS 13406 "mac", 13407 #endif 13408 #if defined(MACOS_X_UNIX) 13409 "macunix", /* built with 'darwin' enabled */ 13410 #endif 13411 #if defined(__APPLE__) && __APPLE__ == 1 13412 "osx", /* built with or without 'darwin' enabled */ 13413 #endif 13414 #ifdef __QNX__ 13415 "qnx", 13416 #endif 13417 #ifdef UNIX 13418 "unix", 13419 #endif 13420 #ifdef VMS 13421 "vms", 13422 #endif 13423 #ifdef WIN32 13424 "win32", 13425 #endif 13426 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 13427 "win32unix", 13428 #endif 13429 #if defined(WIN64) || defined(_WIN64) 13430 "win64", 13431 #endif 13432 #ifdef EBCDIC 13433 "ebcdic", 13434 #endif 13435 #ifndef CASE_INSENSITIVE_FILENAME 13436 "fname_case", 13437 #endif 13438 #ifdef HAVE_ACL 13439 "acl", 13440 #endif 13441 #ifdef FEAT_ARABIC 13442 "arabic", 13443 #endif 13444 #ifdef FEAT_AUTOCMD 13445 "autocmd", 13446 #endif 13447 #ifdef FEAT_BEVAL 13448 "balloon_eval", 13449 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 13450 "balloon_multiline", 13451 # endif 13452 #endif 13453 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 13454 "builtin_terms", 13455 # ifdef ALL_BUILTIN_TCAPS 13456 "all_builtin_terms", 13457 # endif 13458 #endif 13459 #if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \ 13460 || defined(FEAT_GUI_W32) \ 13461 || defined(FEAT_GUI_MOTIF)) 13462 "browsefilter", 13463 #endif 13464 #ifdef FEAT_BYTEOFF 13465 "byte_offset", 13466 #endif 13467 #ifdef FEAT_JOB_CHANNEL 13468 "channel", 13469 #endif 13470 #ifdef FEAT_CINDENT 13471 "cindent", 13472 #endif 13473 #ifdef FEAT_CLIENTSERVER 13474 "clientserver", 13475 #endif 13476 #ifdef FEAT_CLIPBOARD 13477 "clipboard", 13478 #endif 13479 #ifdef FEAT_CMDL_COMPL 13480 "cmdline_compl", 13481 #endif 13482 #ifdef FEAT_CMDHIST 13483 "cmdline_hist", 13484 #endif 13485 #ifdef FEAT_COMMENTS 13486 "comments", 13487 #endif 13488 #ifdef FEAT_CONCEAL 13489 "conceal", 13490 #endif 13491 #ifdef FEAT_CRYPT 13492 "cryptv", 13493 "crypt-blowfish", 13494 "crypt-blowfish2", 13495 #endif 13496 #ifdef FEAT_CSCOPE 13497 "cscope", 13498 #endif 13499 #ifdef FEAT_CURSORBIND 13500 "cursorbind", 13501 #endif 13502 #ifdef CURSOR_SHAPE 13503 "cursorshape", 13504 #endif 13505 #ifdef DEBUG 13506 "debug", 13507 #endif 13508 #ifdef FEAT_CON_DIALOG 13509 "dialog_con", 13510 #endif 13511 #ifdef FEAT_GUI_DIALOG 13512 "dialog_gui", 13513 #endif 13514 #ifdef FEAT_DIFF 13515 "diff", 13516 #endif 13517 #ifdef FEAT_DIGRAPHS 13518 "digraphs", 13519 #endif 13520 #ifdef FEAT_DIRECTX 13521 "directx", 13522 #endif 13523 #ifdef FEAT_DND 13524 "dnd", 13525 #endif 13526 #ifdef FEAT_EMACS_TAGS 13527 "emacs_tags", 13528 #endif 13529 "eval", /* always present, of course! */ 13530 "ex_extra", /* graduated feature */ 13531 #ifdef FEAT_SEARCH_EXTRA 13532 "extra_search", 13533 #endif 13534 #ifdef FEAT_FKMAP 13535 "farsi", 13536 #endif 13537 #ifdef FEAT_SEARCHPATH 13538 "file_in_path", 13539 #endif 13540 #ifdef FEAT_FILTERPIPE 13541 "filterpipe", 13542 #endif 13543 #ifdef FEAT_FIND_ID 13544 "find_in_path", 13545 #endif 13546 #ifdef FEAT_FLOAT 13547 "float", 13548 #endif 13549 #ifdef FEAT_FOLDING 13550 "folding", 13551 #endif 13552 #ifdef FEAT_FOOTER 13553 "footer", 13554 #endif 13555 #if !defined(USE_SYSTEM) && defined(UNIX) 13556 "fork", 13557 #endif 13558 #ifdef FEAT_GETTEXT 13559 "gettext", 13560 #endif 13561 #ifdef FEAT_GUI 13562 "gui", 13563 #endif 13564 #ifdef FEAT_GUI_ATHENA 13565 # ifdef FEAT_GUI_NEXTAW 13566 "gui_neXtaw", 13567 # else 13568 "gui_athena", 13569 # endif 13570 #endif 13571 #ifdef FEAT_GUI_GTK 13572 "gui_gtk", 13573 # ifdef USE_GTK3 13574 "gui_gtk3", 13575 # else 13576 "gui_gtk2", 13577 # endif 13578 #endif 13579 #ifdef FEAT_GUI_GNOME 13580 "gui_gnome", 13581 #endif 13582 #ifdef FEAT_GUI_MAC 13583 "gui_mac", 13584 #endif 13585 #ifdef FEAT_GUI_MOTIF 13586 "gui_motif", 13587 #endif 13588 #ifdef FEAT_GUI_PHOTON 13589 "gui_photon", 13590 #endif 13591 #ifdef FEAT_GUI_W32 13592 "gui_win32", 13593 #endif 13594 #ifdef FEAT_HANGULIN 13595 "hangul_input", 13596 #endif 13597 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 13598 "iconv", 13599 #endif 13600 #ifdef FEAT_INS_EXPAND 13601 "insert_expand", 13602 #endif 13603 #ifdef FEAT_JOB_CHANNEL 13604 "job", 13605 #endif 13606 #ifdef FEAT_JUMPLIST 13607 "jumplist", 13608 #endif 13609 #ifdef FEAT_KEYMAP 13610 "keymap", 13611 #endif 13612 #ifdef FEAT_LANGMAP 13613 "langmap", 13614 #endif 13615 #ifdef FEAT_LIBCALL 13616 "libcall", 13617 #endif 13618 #ifdef FEAT_LINEBREAK 13619 "linebreak", 13620 #endif 13621 #ifdef FEAT_LISP 13622 "lispindent", 13623 #endif 13624 #ifdef FEAT_LISTCMDS 13625 "listcmds", 13626 #endif 13627 #ifdef FEAT_LOCALMAP 13628 "localmap", 13629 #endif 13630 #ifdef FEAT_LUA 13631 # ifndef DYNAMIC_LUA 13632 "lua", 13633 # endif 13634 #endif 13635 #ifdef FEAT_MENU 13636 "menu", 13637 #endif 13638 #ifdef FEAT_SESSION 13639 "mksession", 13640 #endif 13641 #ifdef FEAT_MODIFY_FNAME 13642 "modify_fname", 13643 #endif 13644 #ifdef FEAT_MOUSE 13645 "mouse", 13646 #endif 13647 #ifdef FEAT_MOUSESHAPE 13648 "mouseshape", 13649 #endif 13650 #if defined(UNIX) || defined(VMS) 13651 # ifdef FEAT_MOUSE_DEC 13652 "mouse_dec", 13653 # endif 13654 # ifdef FEAT_MOUSE_GPM 13655 "mouse_gpm", 13656 # endif 13657 # ifdef FEAT_MOUSE_JSB 13658 "mouse_jsbterm", 13659 # endif 13660 # ifdef FEAT_MOUSE_NET 13661 "mouse_netterm", 13662 # endif 13663 # ifdef FEAT_MOUSE_PTERM 13664 "mouse_pterm", 13665 # endif 13666 # ifdef FEAT_MOUSE_SGR 13667 "mouse_sgr", 13668 # endif 13669 # ifdef FEAT_SYSMOUSE 13670 "mouse_sysmouse", 13671 # endif 13672 # ifdef FEAT_MOUSE_URXVT 13673 "mouse_urxvt", 13674 # endif 13675 # ifdef FEAT_MOUSE_XTERM 13676 "mouse_xterm", 13677 # endif 13678 #endif 13679 #ifdef FEAT_MBYTE 13680 "multi_byte", 13681 #endif 13682 #ifdef FEAT_MBYTE_IME 13683 "multi_byte_ime", 13684 #endif 13685 #ifdef FEAT_MULTI_LANG 13686 "multi_lang", 13687 #endif 13688 #ifdef FEAT_MZSCHEME 13689 #ifndef DYNAMIC_MZSCHEME 13690 "mzscheme", 13691 #endif 13692 #endif 13693 #ifdef FEAT_OLE 13694 "ole", 13695 #endif 13696 "packages", 13697 #ifdef FEAT_PATH_EXTRA 13698 "path_extra", 13699 #endif 13700 #ifdef FEAT_PERL 13701 #ifndef DYNAMIC_PERL 13702 "perl", 13703 #endif 13704 #endif 13705 #ifdef FEAT_PERSISTENT_UNDO 13706 "persistent_undo", 13707 #endif 13708 #ifdef FEAT_PYTHON 13709 #ifndef DYNAMIC_PYTHON 13710 "python", 13711 #endif 13712 #endif 13713 #ifdef FEAT_PYTHON3 13714 #ifndef DYNAMIC_PYTHON3 13715 "python3", 13716 #endif 13717 #endif 13718 #ifdef FEAT_POSTSCRIPT 13719 "postscript", 13720 #endif 13721 #ifdef FEAT_PRINTER 13722 "printer", 13723 #endif 13724 #ifdef FEAT_PROFILE 13725 "profile", 13726 #endif 13727 #ifdef FEAT_RELTIME 13728 "reltime", 13729 #endif 13730 #ifdef FEAT_QUICKFIX 13731 "quickfix", 13732 #endif 13733 #ifdef FEAT_RIGHTLEFT 13734 "rightleft", 13735 #endif 13736 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 13737 "ruby", 13738 #endif 13739 #ifdef FEAT_SCROLLBIND 13740 "scrollbind", 13741 #endif 13742 #ifdef FEAT_CMDL_INFO 13743 "showcmd", 13744 "cmdline_info", 13745 #endif 13746 #ifdef FEAT_SIGNS 13747 "signs", 13748 #endif 13749 #ifdef FEAT_SMARTINDENT 13750 "smartindent", 13751 #endif 13752 #ifdef STARTUPTIME 13753 "startuptime", 13754 #endif 13755 #ifdef FEAT_STL_OPT 13756 "statusline", 13757 #endif 13758 #ifdef FEAT_SUN_WORKSHOP 13759 "sun_workshop", 13760 #endif 13761 #ifdef FEAT_NETBEANS_INTG 13762 "netbeans_intg", 13763 #endif 13764 #ifdef FEAT_SPELL 13765 "spell", 13766 #endif 13767 #ifdef FEAT_SYN_HL 13768 "syntax", 13769 #endif 13770 #if defined(USE_SYSTEM) || !defined(UNIX) 13771 "system", 13772 #endif 13773 #ifdef FEAT_TAG_BINS 13774 "tag_binary", 13775 #endif 13776 #ifdef FEAT_TAG_OLDSTATIC 13777 "tag_old_static", 13778 #endif 13779 #ifdef FEAT_TAG_ANYWHITE 13780 "tag_any_white", 13781 #endif 13782 #ifdef FEAT_TCL 13783 # ifndef DYNAMIC_TCL 13784 "tcl", 13785 # endif 13786 #endif 13787 #ifdef TERMINFO 13788 "terminfo", 13789 #endif 13790 #ifdef FEAT_TERMRESPONSE 13791 "termresponse", 13792 #endif 13793 #ifdef FEAT_TEXTOBJ 13794 "textobjects", 13795 #endif 13796 #ifdef HAVE_TGETENT 13797 "tgetent", 13798 #endif 13799 #ifdef FEAT_TIMERS 13800 "timers", 13801 #endif 13802 #ifdef FEAT_TITLE 13803 "title", 13804 #endif 13805 #ifdef FEAT_TOOLBAR 13806 "toolbar", 13807 #endif 13808 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) 13809 "unnamedplus", 13810 #endif 13811 #ifdef FEAT_USR_CMDS 13812 "user-commands", /* was accidentally included in 5.4 */ 13813 "user_commands", 13814 #endif 13815 #ifdef FEAT_VIMINFO 13816 "viminfo", 13817 #endif 13818 #ifdef FEAT_WINDOWS 13819 "vertsplit", 13820 #endif 13821 #ifdef FEAT_VIRTUALEDIT 13822 "virtualedit", 13823 #endif 13824 "visual", 13825 #ifdef FEAT_VISUALEXTRA 13826 "visualextra", 13827 #endif 13828 #ifdef FEAT_VREPLACE 13829 "vreplace", 13830 #endif 13831 #ifdef FEAT_WILDIGN 13832 "wildignore", 13833 #endif 13834 #ifdef FEAT_WILDMENU 13835 "wildmenu", 13836 #endif 13837 #ifdef FEAT_WINDOWS 13838 "windows", 13839 #endif 13840 #ifdef FEAT_WAK 13841 "winaltkeys", 13842 #endif 13843 #ifdef FEAT_WRITEBACKUP 13844 "writebackup", 13845 #endif 13846 #ifdef FEAT_XIM 13847 "xim", 13848 #endif 13849 #ifdef FEAT_XFONTSET 13850 "xfontset", 13851 #endif 13852 #ifdef FEAT_XPM_W32 13853 "xpm", 13854 "xpm_w32", /* for backward compatibility */ 13855 #else 13856 # if defined(HAVE_XPM) 13857 "xpm", 13858 # endif 13859 #endif 13860 #ifdef USE_XSMP 13861 "xsmp", 13862 #endif 13863 #ifdef USE_XSMP_INTERACT 13864 "xsmp_interact", 13865 #endif 13866 #ifdef FEAT_XCLIPBOARD 13867 "xterm_clipboard", 13868 #endif 13869 #ifdef FEAT_XTERM_SAVE 13870 "xterm_save", 13871 #endif 13872 #if defined(UNIX) && defined(FEAT_X11) 13873 "X11", 13874 #endif 13875 NULL 13876 }; 13877 13878 name = get_tv_string(&argvars[0]); 13879 for (i = 0; has_list[i] != NULL; ++i) 13880 if (STRICMP(name, has_list[i]) == 0) 13881 { 13882 n = TRUE; 13883 break; 13884 } 13885 13886 if (n == FALSE) 13887 { 13888 if (STRNICMP(name, "patch", 5) == 0) 13889 { 13890 if (name[5] == '-' 13891 && STRLEN(name) >= 11 13892 && vim_isdigit(name[6]) 13893 && vim_isdigit(name[8]) 13894 && vim_isdigit(name[10])) 13895 { 13896 int major = atoi((char *)name + 6); 13897 int minor = atoi((char *)name + 8); 13898 13899 /* Expect "patch-9.9.01234". */ 13900 n = (major < VIM_VERSION_MAJOR 13901 || (major == VIM_VERSION_MAJOR 13902 && (minor < VIM_VERSION_MINOR 13903 || (minor == VIM_VERSION_MINOR 13904 && has_patch(atoi((char *)name + 10)))))); 13905 } 13906 else 13907 n = has_patch(atoi((char *)name + 5)); 13908 } 13909 else if (STRICMP(name, "vim_starting") == 0) 13910 n = (starting != 0); 13911 #ifdef FEAT_MBYTE 13912 else if (STRICMP(name, "multi_byte_encoding") == 0) 13913 n = has_mbyte; 13914 #endif 13915 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 13916 else if (STRICMP(name, "balloon_multiline") == 0) 13917 n = multiline_balloon_available(); 13918 #endif 13919 #ifdef DYNAMIC_TCL 13920 else if (STRICMP(name, "tcl") == 0) 13921 n = tcl_enabled(FALSE); 13922 #endif 13923 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 13924 else if (STRICMP(name, "iconv") == 0) 13925 n = iconv_enabled(FALSE); 13926 #endif 13927 #ifdef DYNAMIC_LUA 13928 else if (STRICMP(name, "lua") == 0) 13929 n = lua_enabled(FALSE); 13930 #endif 13931 #ifdef DYNAMIC_MZSCHEME 13932 else if (STRICMP(name, "mzscheme") == 0) 13933 n = mzscheme_enabled(FALSE); 13934 #endif 13935 #ifdef DYNAMIC_RUBY 13936 else if (STRICMP(name, "ruby") == 0) 13937 n = ruby_enabled(FALSE); 13938 #endif 13939 #ifdef FEAT_PYTHON 13940 #ifdef DYNAMIC_PYTHON 13941 else if (STRICMP(name, "python") == 0) 13942 n = python_enabled(FALSE); 13943 #endif 13944 #endif 13945 #ifdef FEAT_PYTHON3 13946 #ifdef DYNAMIC_PYTHON3 13947 else if (STRICMP(name, "python3") == 0) 13948 n = python3_enabled(FALSE); 13949 #endif 13950 #endif 13951 #ifdef DYNAMIC_PERL 13952 else if (STRICMP(name, "perl") == 0) 13953 n = perl_enabled(FALSE); 13954 #endif 13955 #ifdef FEAT_GUI 13956 else if (STRICMP(name, "gui_running") == 0) 13957 n = (gui.in_use || gui.starting); 13958 # ifdef FEAT_GUI_W32 13959 else if (STRICMP(name, "gui_win32s") == 0) 13960 n = gui_is_win32s(); 13961 # endif 13962 # ifdef FEAT_BROWSE 13963 else if (STRICMP(name, "browse") == 0) 13964 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 13965 # endif 13966 #endif 13967 #ifdef FEAT_SYN_HL 13968 else if (STRICMP(name, "syntax_items") == 0) 13969 n = syntax_present(curwin); 13970 #endif 13971 #if defined(WIN3264) 13972 else if (STRICMP(name, "win95") == 0) 13973 n = mch_windows95(); 13974 #endif 13975 #ifdef FEAT_NETBEANS_INTG 13976 else if (STRICMP(name, "netbeans_enabled") == 0) 13977 n = netbeans_active(); 13978 #endif 13979 } 13980 13981 rettv->vval.v_number = n; 13982 } 13983 13984 /* 13985 * "has_key()" function 13986 */ 13987 static void 13988 f_has_key(typval_T *argvars, typval_T *rettv) 13989 { 13990 if (argvars[0].v_type != VAR_DICT) 13991 { 13992 EMSG(_(e_dictreq)); 13993 return; 13994 } 13995 if (argvars[0].vval.v_dict == NULL) 13996 return; 13997 13998 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 13999 get_tv_string(&argvars[1]), -1) != NULL; 14000 } 14001 14002 /* 14003 * "haslocaldir()" function 14004 */ 14005 static void 14006 f_haslocaldir(typval_T *argvars, typval_T *rettv) 14007 { 14008 win_T *wp = NULL; 14009 14010 wp = find_tabwin(&argvars[0], &argvars[1]); 14011 rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL); 14012 } 14013 14014 /* 14015 * "hasmapto()" function 14016 */ 14017 static void 14018 f_hasmapto(typval_T *argvars, typval_T *rettv) 14019 { 14020 char_u *name; 14021 char_u *mode; 14022 char_u buf[NUMBUFLEN]; 14023 int abbr = FALSE; 14024 14025 name = get_tv_string(&argvars[0]); 14026 if (argvars[1].v_type == VAR_UNKNOWN) 14027 mode = (char_u *)"nvo"; 14028 else 14029 { 14030 mode = get_tv_string_buf(&argvars[1], buf); 14031 if (argvars[2].v_type != VAR_UNKNOWN) 14032 abbr = get_tv_number(&argvars[2]); 14033 } 14034 14035 if (map_to_exists(name, mode, abbr)) 14036 rettv->vval.v_number = TRUE; 14037 else 14038 rettv->vval.v_number = FALSE; 14039 } 14040 14041 /* 14042 * "histadd()" function 14043 */ 14044 static void 14045 f_histadd(typval_T *argvars UNUSED, typval_T *rettv) 14046 { 14047 #ifdef FEAT_CMDHIST 14048 int histype; 14049 char_u *str; 14050 char_u buf[NUMBUFLEN]; 14051 #endif 14052 14053 rettv->vval.v_number = FALSE; 14054 if (check_restricted() || check_secure()) 14055 return; 14056 #ifdef FEAT_CMDHIST 14057 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 14058 histype = str != NULL ? get_histtype(str) : -1; 14059 if (histype >= 0) 14060 { 14061 str = get_tv_string_buf(&argvars[1], buf); 14062 if (*str != NUL) 14063 { 14064 init_history(); 14065 add_to_history(histype, str, FALSE, NUL); 14066 rettv->vval.v_number = TRUE; 14067 return; 14068 } 14069 } 14070 #endif 14071 } 14072 14073 /* 14074 * "histdel()" function 14075 */ 14076 static void 14077 f_histdel(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 14078 { 14079 #ifdef FEAT_CMDHIST 14080 int n; 14081 char_u buf[NUMBUFLEN]; 14082 char_u *str; 14083 14084 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 14085 if (str == NULL) 14086 n = 0; 14087 else if (argvars[1].v_type == VAR_UNKNOWN) 14088 /* only one argument: clear entire history */ 14089 n = clr_history(get_histtype(str)); 14090 else if (argvars[1].v_type == VAR_NUMBER) 14091 /* index given: remove that entry */ 14092 n = del_history_idx(get_histtype(str), 14093 (int)get_tv_number(&argvars[1])); 14094 else 14095 /* string given: remove all matching entries */ 14096 n = del_history_entry(get_histtype(str), 14097 get_tv_string_buf(&argvars[1], buf)); 14098 rettv->vval.v_number = n; 14099 #endif 14100 } 14101 14102 /* 14103 * "histget()" function 14104 */ 14105 static void 14106 f_histget(typval_T *argvars UNUSED, typval_T *rettv) 14107 { 14108 #ifdef FEAT_CMDHIST 14109 int type; 14110 int idx; 14111 char_u *str; 14112 14113 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 14114 if (str == NULL) 14115 rettv->vval.v_string = NULL; 14116 else 14117 { 14118 type = get_histtype(str); 14119 if (argvars[1].v_type == VAR_UNKNOWN) 14120 idx = get_history_idx(type); 14121 else 14122 idx = (int)get_tv_number_chk(&argvars[1], NULL); 14123 /* -1 on type error */ 14124 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 14125 } 14126 #else 14127 rettv->vval.v_string = NULL; 14128 #endif 14129 rettv->v_type = VAR_STRING; 14130 } 14131 14132 /* 14133 * "histnr()" function 14134 */ 14135 static void 14136 f_histnr(typval_T *argvars UNUSED, typval_T *rettv) 14137 { 14138 int i; 14139 14140 #ifdef FEAT_CMDHIST 14141 char_u *history = get_tv_string_chk(&argvars[0]); 14142 14143 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 14144 if (i >= HIST_CMD && i < HIST_COUNT) 14145 i = get_history_idx(i); 14146 else 14147 #endif 14148 i = -1; 14149 rettv->vval.v_number = i; 14150 } 14151 14152 /* 14153 * "highlightID(name)" function 14154 */ 14155 static void 14156 f_hlID(typval_T *argvars, typval_T *rettv) 14157 { 14158 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 14159 } 14160 14161 /* 14162 * "highlight_exists()" function 14163 */ 14164 static void 14165 f_hlexists(typval_T *argvars, typval_T *rettv) 14166 { 14167 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 14168 } 14169 14170 /* 14171 * "hostname()" function 14172 */ 14173 static void 14174 f_hostname(typval_T *argvars UNUSED, typval_T *rettv) 14175 { 14176 char_u hostname[256]; 14177 14178 mch_get_host_name(hostname, 256); 14179 rettv->v_type = VAR_STRING; 14180 rettv->vval.v_string = vim_strsave(hostname); 14181 } 14182 14183 /* 14184 * iconv() function 14185 */ 14186 static void 14187 f_iconv(typval_T *argvars UNUSED, typval_T *rettv) 14188 { 14189 #ifdef FEAT_MBYTE 14190 char_u buf1[NUMBUFLEN]; 14191 char_u buf2[NUMBUFLEN]; 14192 char_u *from, *to, *str; 14193 vimconv_T vimconv; 14194 #endif 14195 14196 rettv->v_type = VAR_STRING; 14197 rettv->vval.v_string = NULL; 14198 14199 #ifdef FEAT_MBYTE 14200 str = get_tv_string(&argvars[0]); 14201 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 14202 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 14203 vimconv.vc_type = CONV_NONE; 14204 convert_setup(&vimconv, from, to); 14205 14206 /* If the encodings are equal, no conversion needed. */ 14207 if (vimconv.vc_type == CONV_NONE) 14208 rettv->vval.v_string = vim_strsave(str); 14209 else 14210 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 14211 14212 convert_setup(&vimconv, NULL, NULL); 14213 vim_free(from); 14214 vim_free(to); 14215 #endif 14216 } 14217 14218 /* 14219 * "indent()" function 14220 */ 14221 static void 14222 f_indent(typval_T *argvars, typval_T *rettv) 14223 { 14224 linenr_T lnum; 14225 14226 lnum = get_tv_lnum(argvars); 14227 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 14228 rettv->vval.v_number = get_indent_lnum(lnum); 14229 else 14230 rettv->vval.v_number = -1; 14231 } 14232 14233 /* 14234 * "index()" function 14235 */ 14236 static void 14237 f_index(typval_T *argvars, typval_T *rettv) 14238 { 14239 list_T *l; 14240 listitem_T *item; 14241 long idx = 0; 14242 int ic = FALSE; 14243 14244 rettv->vval.v_number = -1; 14245 if (argvars[0].v_type != VAR_LIST) 14246 { 14247 EMSG(_(e_listreq)); 14248 return; 14249 } 14250 l = argvars[0].vval.v_list; 14251 if (l != NULL) 14252 { 14253 item = l->lv_first; 14254 if (argvars[2].v_type != VAR_UNKNOWN) 14255 { 14256 int error = FALSE; 14257 14258 /* Start at specified item. Use the cached index that list_find() 14259 * sets, so that a negative number also works. */ 14260 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 14261 idx = l->lv_idx; 14262 if (argvars[3].v_type != VAR_UNKNOWN) 14263 ic = get_tv_number_chk(&argvars[3], &error); 14264 if (error) 14265 item = NULL; 14266 } 14267 14268 for ( ; item != NULL; item = item->li_next, ++idx) 14269 if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) 14270 { 14271 rettv->vval.v_number = idx; 14272 break; 14273 } 14274 } 14275 } 14276 14277 static int inputsecret_flag = 0; 14278 14279 static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog); 14280 14281 /* 14282 * This function is used by f_input() and f_inputdialog() functions. The third 14283 * argument to f_input() specifies the type of completion to use at the 14284 * prompt. The third argument to f_inputdialog() specifies the value to return 14285 * when the user cancels the prompt. 14286 */ 14287 static void 14288 get_user_input( 14289 typval_T *argvars, 14290 typval_T *rettv, 14291 int inputdialog) 14292 { 14293 char_u *prompt = get_tv_string_chk(&argvars[0]); 14294 char_u *p = NULL; 14295 int c; 14296 char_u buf[NUMBUFLEN]; 14297 int cmd_silent_save = cmd_silent; 14298 char_u *defstr = (char_u *)""; 14299 int xp_type = EXPAND_NOTHING; 14300 char_u *xp_arg = NULL; 14301 14302 rettv->v_type = VAR_STRING; 14303 rettv->vval.v_string = NULL; 14304 14305 #ifdef NO_CONSOLE_INPUT 14306 /* While starting up, there is no place to enter text. */ 14307 if (no_console_input()) 14308 return; 14309 #endif 14310 14311 cmd_silent = FALSE; /* Want to see the prompt. */ 14312 if (prompt != NULL) 14313 { 14314 /* Only the part of the message after the last NL is considered as 14315 * prompt for the command line */ 14316 p = vim_strrchr(prompt, '\n'); 14317 if (p == NULL) 14318 p = prompt; 14319 else 14320 { 14321 ++p; 14322 c = *p; 14323 *p = NUL; 14324 msg_start(); 14325 msg_clr_eos(); 14326 msg_puts_attr(prompt, echo_attr); 14327 msg_didout = FALSE; 14328 msg_starthere(); 14329 *p = c; 14330 } 14331 cmdline_row = msg_row; 14332 14333 if (argvars[1].v_type != VAR_UNKNOWN) 14334 { 14335 defstr = get_tv_string_buf_chk(&argvars[1], buf); 14336 if (defstr != NULL) 14337 stuffReadbuffSpec(defstr); 14338 14339 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 14340 { 14341 char_u *xp_name; 14342 int xp_namelen; 14343 long argt; 14344 14345 /* input() with a third argument: completion */ 14346 rettv->vval.v_string = NULL; 14347 14348 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 14349 if (xp_name == NULL) 14350 return; 14351 14352 xp_namelen = (int)STRLEN(xp_name); 14353 14354 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 14355 &xp_arg) == FAIL) 14356 return; 14357 } 14358 } 14359 14360 if (defstr != NULL) 14361 { 14362 int save_ex_normal_busy = ex_normal_busy; 14363 ex_normal_busy = 0; 14364 rettv->vval.v_string = 14365 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 14366 xp_type, xp_arg); 14367 ex_normal_busy = save_ex_normal_busy; 14368 } 14369 if (inputdialog && rettv->vval.v_string == NULL 14370 && argvars[1].v_type != VAR_UNKNOWN 14371 && argvars[2].v_type != VAR_UNKNOWN) 14372 rettv->vval.v_string = vim_strsave(get_tv_string_buf( 14373 &argvars[2], buf)); 14374 14375 vim_free(xp_arg); 14376 14377 /* since the user typed this, no need to wait for return */ 14378 need_wait_return = FALSE; 14379 msg_didout = FALSE; 14380 } 14381 cmd_silent = cmd_silent_save; 14382 } 14383 14384 /* 14385 * "input()" function 14386 * Also handles inputsecret() when inputsecret is set. 14387 */ 14388 static void 14389 f_input(typval_T *argvars, typval_T *rettv) 14390 { 14391 get_user_input(argvars, rettv, FALSE); 14392 } 14393 14394 /* 14395 * "inputdialog()" function 14396 */ 14397 static void 14398 f_inputdialog(typval_T *argvars, typval_T *rettv) 14399 { 14400 #if defined(FEAT_GUI_TEXTDIALOG) 14401 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 14402 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 14403 { 14404 char_u *message; 14405 char_u buf[NUMBUFLEN]; 14406 char_u *defstr = (char_u *)""; 14407 14408 message = get_tv_string_chk(&argvars[0]); 14409 if (argvars[1].v_type != VAR_UNKNOWN 14410 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 14411 vim_strncpy(IObuff, defstr, IOSIZE - 1); 14412 else 14413 IObuff[0] = NUL; 14414 if (message != NULL && defstr != NULL 14415 && do_dialog(VIM_QUESTION, NULL, message, 14416 (char_u *)_("&OK\n&Cancel"), 1, IObuff, FALSE) == 1) 14417 rettv->vval.v_string = vim_strsave(IObuff); 14418 else 14419 { 14420 if (message != NULL && defstr != NULL 14421 && argvars[1].v_type != VAR_UNKNOWN 14422 && argvars[2].v_type != VAR_UNKNOWN) 14423 rettv->vval.v_string = vim_strsave( 14424 get_tv_string_buf(&argvars[2], buf)); 14425 else 14426 rettv->vval.v_string = NULL; 14427 } 14428 rettv->v_type = VAR_STRING; 14429 } 14430 else 14431 #endif 14432 get_user_input(argvars, rettv, TRUE); 14433 } 14434 14435 /* 14436 * "inputlist()" function 14437 */ 14438 static void 14439 f_inputlist(typval_T *argvars, typval_T *rettv) 14440 { 14441 listitem_T *li; 14442 int selected; 14443 int mouse_used; 14444 14445 #ifdef NO_CONSOLE_INPUT 14446 /* While starting up, there is no place to enter text. */ 14447 if (no_console_input()) 14448 return; 14449 #endif 14450 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 14451 { 14452 EMSG2(_(e_listarg), "inputlist()"); 14453 return; 14454 } 14455 14456 msg_start(); 14457 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 14458 lines_left = Rows; /* avoid more prompt */ 14459 msg_scroll = TRUE; 14460 msg_clr_eos(); 14461 14462 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 14463 { 14464 msg_puts(get_tv_string(&li->li_tv)); 14465 msg_putchar('\n'); 14466 } 14467 14468 /* Ask for choice. */ 14469 selected = prompt_for_number(&mouse_used); 14470 if (mouse_used) 14471 selected -= lines_left; 14472 14473 rettv->vval.v_number = selected; 14474 } 14475 14476 14477 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 14478 14479 /* 14480 * "inputrestore()" function 14481 */ 14482 static void 14483 f_inputrestore(typval_T *argvars UNUSED, typval_T *rettv) 14484 { 14485 if (ga_userinput.ga_len > 0) 14486 { 14487 --ga_userinput.ga_len; 14488 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 14489 + ga_userinput.ga_len); 14490 /* default return is zero == OK */ 14491 } 14492 else if (p_verbose > 1) 14493 { 14494 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 14495 rettv->vval.v_number = 1; /* Failed */ 14496 } 14497 } 14498 14499 /* 14500 * "inputsave()" function 14501 */ 14502 static void 14503 f_inputsave(typval_T *argvars UNUSED, typval_T *rettv) 14504 { 14505 /* Add an entry to the stack of typeahead storage. */ 14506 if (ga_grow(&ga_userinput, 1) == OK) 14507 { 14508 save_typeahead((tasave_T *)(ga_userinput.ga_data) 14509 + ga_userinput.ga_len); 14510 ++ga_userinput.ga_len; 14511 /* default return is zero == OK */ 14512 } 14513 else 14514 rettv->vval.v_number = 1; /* Failed */ 14515 } 14516 14517 /* 14518 * "inputsecret()" function 14519 */ 14520 static void 14521 f_inputsecret(typval_T *argvars, typval_T *rettv) 14522 { 14523 ++cmdline_star; 14524 ++inputsecret_flag; 14525 f_input(argvars, rettv); 14526 --cmdline_star; 14527 --inputsecret_flag; 14528 } 14529 14530 /* 14531 * "insert()" function 14532 */ 14533 static void 14534 f_insert(typval_T *argvars, typval_T *rettv) 14535 { 14536 long before = 0; 14537 listitem_T *item; 14538 list_T *l; 14539 int error = FALSE; 14540 14541 if (argvars[0].v_type != VAR_LIST) 14542 EMSG2(_(e_listarg), "insert()"); 14543 else if ((l = argvars[0].vval.v_list) != NULL 14544 && !tv_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE)) 14545 { 14546 if (argvars[2].v_type != VAR_UNKNOWN) 14547 before = get_tv_number_chk(&argvars[2], &error); 14548 if (error) 14549 return; /* type error; errmsg already given */ 14550 14551 if (before == l->lv_len) 14552 item = NULL; 14553 else 14554 { 14555 item = list_find(l, before); 14556 if (item == NULL) 14557 { 14558 EMSGN(_(e_listidx), before); 14559 l = NULL; 14560 } 14561 } 14562 if (l != NULL) 14563 { 14564 list_insert_tv(l, &argvars[1], item); 14565 copy_tv(&argvars[0], rettv); 14566 } 14567 } 14568 } 14569 14570 /* 14571 * "invert(expr)" function 14572 */ 14573 static void 14574 f_invert(typval_T *argvars, typval_T *rettv) 14575 { 14576 rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL); 14577 } 14578 14579 /* 14580 * "isdirectory()" function 14581 */ 14582 static void 14583 f_isdirectory(typval_T *argvars, typval_T *rettv) 14584 { 14585 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 14586 } 14587 14588 /* 14589 * "islocked()" function 14590 */ 14591 static void 14592 f_islocked(typval_T *argvars, typval_T *rettv) 14593 { 14594 lval_T lv; 14595 char_u *end; 14596 dictitem_T *di; 14597 14598 rettv->vval.v_number = -1; 14599 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, 14600 GLV_NO_AUTOLOAD, FNE_CHECK_START); 14601 if (end != NULL && lv.ll_name != NULL) 14602 { 14603 if (*end != NUL) 14604 EMSG(_(e_trailing)); 14605 else 14606 { 14607 if (lv.ll_tv == NULL) 14608 { 14609 if (check_changedtick(lv.ll_name)) 14610 rettv->vval.v_number = 1; /* always locked */ 14611 else 14612 { 14613 di = find_var(lv.ll_name, NULL, TRUE); 14614 if (di != NULL) 14615 { 14616 /* Consider a variable locked when: 14617 * 1. the variable itself is locked 14618 * 2. the value of the variable is locked. 14619 * 3. the List or Dict value is locked. 14620 */ 14621 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 14622 || tv_islocked(&di->di_tv)); 14623 } 14624 } 14625 } 14626 else if (lv.ll_range) 14627 EMSG(_("E786: Range not allowed")); 14628 else if (lv.ll_newkey != NULL) 14629 EMSG2(_(e_dictkey), lv.ll_newkey); 14630 else if (lv.ll_list != NULL) 14631 /* List item. */ 14632 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 14633 else 14634 /* Dictionary item. */ 14635 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 14636 } 14637 } 14638 14639 clear_lval(&lv); 14640 } 14641 14642 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 14643 /* 14644 * "isnan()" function 14645 */ 14646 static void 14647 f_isnan(typval_T *argvars, typval_T *rettv) 14648 { 14649 rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT 14650 && isnan(argvars[0].vval.v_float); 14651 } 14652 #endif 14653 14654 static void dict_list(typval_T *argvars, typval_T *rettv, int what); 14655 14656 /* 14657 * Turn a dict into a list: 14658 * "what" == 0: list of keys 14659 * "what" == 1: list of values 14660 * "what" == 2: list of items 14661 */ 14662 static void 14663 dict_list(typval_T *argvars, typval_T *rettv, int what) 14664 { 14665 list_T *l2; 14666 dictitem_T *di; 14667 hashitem_T *hi; 14668 listitem_T *li; 14669 listitem_T *li2; 14670 dict_T *d; 14671 int todo; 14672 14673 if (argvars[0].v_type != VAR_DICT) 14674 { 14675 EMSG(_(e_dictreq)); 14676 return; 14677 } 14678 if ((d = argvars[0].vval.v_dict) == NULL) 14679 return; 14680 14681 if (rettv_list_alloc(rettv) == FAIL) 14682 return; 14683 14684 todo = (int)d->dv_hashtab.ht_used; 14685 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 14686 { 14687 if (!HASHITEM_EMPTY(hi)) 14688 { 14689 --todo; 14690 di = HI2DI(hi); 14691 14692 li = listitem_alloc(); 14693 if (li == NULL) 14694 break; 14695 list_append(rettv->vval.v_list, li); 14696 14697 if (what == 0) 14698 { 14699 /* keys() */ 14700 li->li_tv.v_type = VAR_STRING; 14701 li->li_tv.v_lock = 0; 14702 li->li_tv.vval.v_string = vim_strsave(di->di_key); 14703 } 14704 else if (what == 1) 14705 { 14706 /* values() */ 14707 copy_tv(&di->di_tv, &li->li_tv); 14708 } 14709 else 14710 { 14711 /* items() */ 14712 l2 = list_alloc(); 14713 li->li_tv.v_type = VAR_LIST; 14714 li->li_tv.v_lock = 0; 14715 li->li_tv.vval.v_list = l2; 14716 if (l2 == NULL) 14717 break; 14718 ++l2->lv_refcount; 14719 14720 li2 = listitem_alloc(); 14721 if (li2 == NULL) 14722 break; 14723 list_append(l2, li2); 14724 li2->li_tv.v_type = VAR_STRING; 14725 li2->li_tv.v_lock = 0; 14726 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 14727 14728 li2 = listitem_alloc(); 14729 if (li2 == NULL) 14730 break; 14731 list_append(l2, li2); 14732 copy_tv(&di->di_tv, &li2->li_tv); 14733 } 14734 } 14735 } 14736 } 14737 14738 /* 14739 * "items(dict)" function 14740 */ 14741 static void 14742 f_items(typval_T *argvars, typval_T *rettv) 14743 { 14744 dict_list(argvars, rettv, 2); 14745 } 14746 14747 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) 14748 /* 14749 * Get the job from the argument. 14750 * Returns NULL if the job is invalid. 14751 */ 14752 static job_T * 14753 get_job_arg(typval_T *tv) 14754 { 14755 job_T *job; 14756 14757 if (tv->v_type != VAR_JOB) 14758 { 14759 EMSG2(_(e_invarg2), get_tv_string(tv)); 14760 return NULL; 14761 } 14762 job = tv->vval.v_job; 14763 14764 if (job == NULL) 14765 EMSG(_("E916: not a valid job")); 14766 return job; 14767 } 14768 14769 /* 14770 * "job_getchannel()" function 14771 */ 14772 static void 14773 f_job_getchannel(typval_T *argvars, typval_T *rettv) 14774 { 14775 job_T *job = get_job_arg(&argvars[0]); 14776 14777 if (job != NULL) 14778 { 14779 rettv->v_type = VAR_CHANNEL; 14780 rettv->vval.v_channel = job->jv_channel; 14781 if (job->jv_channel != NULL) 14782 ++job->jv_channel->ch_refcount; 14783 } 14784 } 14785 14786 /* 14787 * "job_info()" function 14788 */ 14789 static void 14790 f_job_info(typval_T *argvars, typval_T *rettv) 14791 { 14792 job_T *job = get_job_arg(&argvars[0]); 14793 14794 if (job != NULL && rettv_dict_alloc(rettv) != FAIL) 14795 job_info(job, rettv->vval.v_dict); 14796 } 14797 14798 /* 14799 * "job_setoptions()" function 14800 */ 14801 static void 14802 f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED) 14803 { 14804 job_T *job = get_job_arg(&argvars[0]); 14805 jobopt_T opt; 14806 14807 if (job == NULL) 14808 return; 14809 clear_job_options(&opt); 14810 if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB) == FAIL) 14811 return; 14812 job_set_options(job, &opt); 14813 } 14814 14815 /* 14816 * "job_start()" function 14817 */ 14818 static void 14819 f_job_start(typval_T *argvars, typval_T *rettv) 14820 { 14821 rettv->v_type = VAR_JOB; 14822 rettv->vval.v_job = job_start(argvars); 14823 } 14824 14825 /* 14826 * "job_status()" function 14827 */ 14828 static void 14829 f_job_status(typval_T *argvars, typval_T *rettv) 14830 { 14831 job_T *job = get_job_arg(&argvars[0]); 14832 14833 if (job != NULL) 14834 { 14835 rettv->v_type = VAR_STRING; 14836 rettv->vval.v_string = vim_strsave((char_u *)job_status(job)); 14837 } 14838 } 14839 14840 /* 14841 * "job_stop()" function 14842 */ 14843 static void 14844 f_job_stop(typval_T *argvars, typval_T *rettv) 14845 { 14846 job_T *job = get_job_arg(&argvars[0]); 14847 14848 if (job != NULL) 14849 rettv->vval.v_number = job_stop(job, argvars); 14850 } 14851 #endif 14852 14853 /* 14854 * "join()" function 14855 */ 14856 static void 14857 f_join(typval_T *argvars, typval_T *rettv) 14858 { 14859 garray_T ga; 14860 char_u *sep; 14861 14862 if (argvars[0].v_type != VAR_LIST) 14863 { 14864 EMSG(_(e_listreq)); 14865 return; 14866 } 14867 if (argvars[0].vval.v_list == NULL) 14868 return; 14869 if (argvars[1].v_type == VAR_UNKNOWN) 14870 sep = (char_u *)" "; 14871 else 14872 sep = get_tv_string_chk(&argvars[1]); 14873 14874 rettv->v_type = VAR_STRING; 14875 14876 if (sep != NULL) 14877 { 14878 ga_init2(&ga, (int)sizeof(char), 80); 14879 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 14880 ga_append(&ga, NUL); 14881 rettv->vval.v_string = (char_u *)ga.ga_data; 14882 } 14883 else 14884 rettv->vval.v_string = NULL; 14885 } 14886 14887 /* 14888 * "js_decode()" function 14889 */ 14890 static void 14891 f_js_decode(typval_T *argvars, typval_T *rettv) 14892 { 14893 js_read_T reader; 14894 14895 reader.js_buf = get_tv_string(&argvars[0]); 14896 reader.js_fill = NULL; 14897 reader.js_used = 0; 14898 if (json_decode_all(&reader, rettv, JSON_JS) != OK) 14899 EMSG(_(e_invarg)); 14900 } 14901 14902 /* 14903 * "js_encode()" function 14904 */ 14905 static void 14906 f_js_encode(typval_T *argvars, typval_T *rettv) 14907 { 14908 rettv->v_type = VAR_STRING; 14909 rettv->vval.v_string = json_encode(&argvars[0], JSON_JS); 14910 } 14911 14912 /* 14913 * "json_decode()" function 14914 */ 14915 static void 14916 f_json_decode(typval_T *argvars, typval_T *rettv) 14917 { 14918 js_read_T reader; 14919 14920 reader.js_buf = get_tv_string(&argvars[0]); 14921 reader.js_fill = NULL; 14922 reader.js_used = 0; 14923 if (json_decode_all(&reader, rettv, 0) != OK) 14924 EMSG(_(e_invarg)); 14925 } 14926 14927 /* 14928 * "json_encode()" function 14929 */ 14930 static void 14931 f_json_encode(typval_T *argvars, typval_T *rettv) 14932 { 14933 rettv->v_type = VAR_STRING; 14934 rettv->vval.v_string = json_encode(&argvars[0], 0); 14935 } 14936 14937 /* 14938 * "keys()" function 14939 */ 14940 static void 14941 f_keys(typval_T *argvars, typval_T *rettv) 14942 { 14943 dict_list(argvars, rettv, 0); 14944 } 14945 14946 /* 14947 * "last_buffer_nr()" function. 14948 */ 14949 static void 14950 f_last_buffer_nr(typval_T *argvars UNUSED, typval_T *rettv) 14951 { 14952 int n = 0; 14953 buf_T *buf; 14954 14955 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 14956 if (n < buf->b_fnum) 14957 n = buf->b_fnum; 14958 14959 rettv->vval.v_number = n; 14960 } 14961 14962 /* 14963 * "len()" function 14964 */ 14965 static void 14966 f_len(typval_T *argvars, typval_T *rettv) 14967 { 14968 switch (argvars[0].v_type) 14969 { 14970 case VAR_STRING: 14971 case VAR_NUMBER: 14972 rettv->vval.v_number = (varnumber_T)STRLEN( 14973 get_tv_string(&argvars[0])); 14974 break; 14975 case VAR_LIST: 14976 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 14977 break; 14978 case VAR_DICT: 14979 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 14980 break; 14981 case VAR_UNKNOWN: 14982 case VAR_SPECIAL: 14983 case VAR_FLOAT: 14984 case VAR_FUNC: 14985 case VAR_PARTIAL: 14986 case VAR_JOB: 14987 case VAR_CHANNEL: 14988 EMSG(_("E701: Invalid type for len()")); 14989 break; 14990 } 14991 } 14992 14993 static void libcall_common(typval_T *argvars, typval_T *rettv, int type); 14994 14995 static void 14996 libcall_common(typval_T *argvars, typval_T *rettv, int type) 14997 { 14998 #ifdef FEAT_LIBCALL 14999 char_u *string_in; 15000 char_u **string_result; 15001 int nr_result; 15002 #endif 15003 15004 rettv->v_type = type; 15005 if (type != VAR_NUMBER) 15006 rettv->vval.v_string = NULL; 15007 15008 if (check_restricted() || check_secure()) 15009 return; 15010 15011 #ifdef FEAT_LIBCALL 15012 /* The first two args must be strings, otherwise its meaningless */ 15013 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 15014 { 15015 string_in = NULL; 15016 if (argvars[2].v_type == VAR_STRING) 15017 string_in = argvars[2].vval.v_string; 15018 if (type == VAR_NUMBER) 15019 string_result = NULL; 15020 else 15021 string_result = &rettv->vval.v_string; 15022 if (mch_libcall(argvars[0].vval.v_string, 15023 argvars[1].vval.v_string, 15024 string_in, 15025 argvars[2].vval.v_number, 15026 string_result, 15027 &nr_result) == OK 15028 && type == VAR_NUMBER) 15029 rettv->vval.v_number = nr_result; 15030 } 15031 #endif 15032 } 15033 15034 /* 15035 * "libcall()" function 15036 */ 15037 static void 15038 f_libcall(typval_T *argvars, typval_T *rettv) 15039 { 15040 libcall_common(argvars, rettv, VAR_STRING); 15041 } 15042 15043 /* 15044 * "libcallnr()" function 15045 */ 15046 static void 15047 f_libcallnr(typval_T *argvars, typval_T *rettv) 15048 { 15049 libcall_common(argvars, rettv, VAR_NUMBER); 15050 } 15051 15052 /* 15053 * "line(string)" function 15054 */ 15055 static void 15056 f_line(typval_T *argvars, typval_T *rettv) 15057 { 15058 linenr_T lnum = 0; 15059 pos_T *fp; 15060 int fnum; 15061 15062 fp = var2fpos(&argvars[0], TRUE, &fnum); 15063 if (fp != NULL) 15064 lnum = fp->lnum; 15065 rettv->vval.v_number = lnum; 15066 } 15067 15068 /* 15069 * "line2byte(lnum)" function 15070 */ 15071 static void 15072 f_line2byte(typval_T *argvars UNUSED, typval_T *rettv) 15073 { 15074 #ifndef FEAT_BYTEOFF 15075 rettv->vval.v_number = -1; 15076 #else 15077 linenr_T lnum; 15078 15079 lnum = get_tv_lnum(argvars); 15080 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 15081 rettv->vval.v_number = -1; 15082 else 15083 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 15084 if (rettv->vval.v_number >= 0) 15085 ++rettv->vval.v_number; 15086 #endif 15087 } 15088 15089 /* 15090 * "lispindent(lnum)" function 15091 */ 15092 static void 15093 f_lispindent(typval_T *argvars UNUSED, typval_T *rettv) 15094 { 15095 #ifdef FEAT_LISP 15096 pos_T pos; 15097 linenr_T lnum; 15098 15099 pos = curwin->w_cursor; 15100 lnum = get_tv_lnum(argvars); 15101 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 15102 { 15103 curwin->w_cursor.lnum = lnum; 15104 rettv->vval.v_number = get_lisp_indent(); 15105 curwin->w_cursor = pos; 15106 } 15107 else 15108 #endif 15109 rettv->vval.v_number = -1; 15110 } 15111 15112 /* 15113 * "localtime()" function 15114 */ 15115 static void 15116 f_localtime(typval_T *argvars UNUSED, typval_T *rettv) 15117 { 15118 rettv->vval.v_number = (varnumber_T)time(NULL); 15119 } 15120 15121 static void get_maparg(typval_T *argvars, typval_T *rettv, int exact); 15122 15123 static void 15124 get_maparg(typval_T *argvars, typval_T *rettv, int exact) 15125 { 15126 char_u *keys; 15127 char_u *which; 15128 char_u buf[NUMBUFLEN]; 15129 char_u *keys_buf = NULL; 15130 char_u *rhs; 15131 int mode; 15132 int abbr = FALSE; 15133 int get_dict = FALSE; 15134 mapblock_T *mp; 15135 int buffer_local; 15136 15137 /* return empty string for failure */ 15138 rettv->v_type = VAR_STRING; 15139 rettv->vval.v_string = NULL; 15140 15141 keys = get_tv_string(&argvars[0]); 15142 if (*keys == NUL) 15143 return; 15144 15145 if (argvars[1].v_type != VAR_UNKNOWN) 15146 { 15147 which = get_tv_string_buf_chk(&argvars[1], buf); 15148 if (argvars[2].v_type != VAR_UNKNOWN) 15149 { 15150 abbr = get_tv_number(&argvars[2]); 15151 if (argvars[3].v_type != VAR_UNKNOWN) 15152 get_dict = get_tv_number(&argvars[3]); 15153 } 15154 } 15155 else 15156 which = (char_u *)""; 15157 if (which == NULL) 15158 return; 15159 15160 mode = get_map_mode(&which, 0); 15161 15162 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 15163 rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); 15164 vim_free(keys_buf); 15165 15166 if (!get_dict) 15167 { 15168 /* Return a string. */ 15169 if (rhs != NULL) 15170 rettv->vval.v_string = str2special_save(rhs, FALSE); 15171 15172 } 15173 else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL) 15174 { 15175 /* Return a dictionary. */ 15176 char_u *lhs = str2special_save(mp->m_keys, TRUE); 15177 char_u *mapmode = map_mode_to_chars(mp->m_mode); 15178 dict_T *dict = rettv->vval.v_dict; 15179 15180 dict_add_nr_str(dict, "lhs", 0L, lhs); 15181 dict_add_nr_str(dict, "rhs", 0L, mp->m_orig_str); 15182 dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL); 15183 dict_add_nr_str(dict, "expr", mp->m_expr ? 1L : 0L, NULL); 15184 dict_add_nr_str(dict, "silent", mp->m_silent ? 1L : 0L, NULL); 15185 dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL); 15186 dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL); 15187 dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL); 15188 dict_add_nr_str(dict, "mode", 0L, mapmode); 15189 15190 vim_free(lhs); 15191 vim_free(mapmode); 15192 } 15193 } 15194 15195 #ifdef FEAT_FLOAT 15196 /* 15197 * "log()" function 15198 */ 15199 static void 15200 f_log(typval_T *argvars, typval_T *rettv) 15201 { 15202 float_T f = 0.0; 15203 15204 rettv->v_type = VAR_FLOAT; 15205 if (get_float_arg(argvars, &f) == OK) 15206 rettv->vval.v_float = log(f); 15207 else 15208 rettv->vval.v_float = 0.0; 15209 } 15210 15211 /* 15212 * "log10()" function 15213 */ 15214 static void 15215 f_log10(typval_T *argvars, typval_T *rettv) 15216 { 15217 float_T f = 0.0; 15218 15219 rettv->v_type = VAR_FLOAT; 15220 if (get_float_arg(argvars, &f) == OK) 15221 rettv->vval.v_float = log10(f); 15222 else 15223 rettv->vval.v_float = 0.0; 15224 } 15225 #endif 15226 15227 #ifdef FEAT_LUA 15228 /* 15229 * "luaeval()" function 15230 */ 15231 static void 15232 f_luaeval(typval_T *argvars, typval_T *rettv) 15233 { 15234 char_u *str; 15235 char_u buf[NUMBUFLEN]; 15236 15237 str = get_tv_string_buf(&argvars[0], buf); 15238 do_luaeval(str, argvars + 1, rettv); 15239 } 15240 #endif 15241 15242 /* 15243 * "map()" function 15244 */ 15245 static void 15246 f_map(typval_T *argvars, typval_T *rettv) 15247 { 15248 filter_map(argvars, rettv, TRUE); 15249 } 15250 15251 /* 15252 * "maparg()" function 15253 */ 15254 static void 15255 f_maparg(typval_T *argvars, typval_T *rettv) 15256 { 15257 get_maparg(argvars, rettv, TRUE); 15258 } 15259 15260 /* 15261 * "mapcheck()" function 15262 */ 15263 static void 15264 f_mapcheck(typval_T *argvars, typval_T *rettv) 15265 { 15266 get_maparg(argvars, rettv, FALSE); 15267 } 15268 15269 static void find_some_match(typval_T *argvars, typval_T *rettv, int start); 15270 15271 static void 15272 find_some_match(typval_T *argvars, typval_T *rettv, int type) 15273 { 15274 char_u *str = NULL; 15275 long len = 0; 15276 char_u *expr = NULL; 15277 char_u *pat; 15278 regmatch_T regmatch; 15279 char_u patbuf[NUMBUFLEN]; 15280 char_u strbuf[NUMBUFLEN]; 15281 char_u *save_cpo; 15282 long start = 0; 15283 long nth = 1; 15284 colnr_T startcol = 0; 15285 int match = 0; 15286 list_T *l = NULL; 15287 listitem_T *li = NULL; 15288 long idx = 0; 15289 char_u *tofree = NULL; 15290 15291 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15292 save_cpo = p_cpo; 15293 p_cpo = (char_u *)""; 15294 15295 rettv->vval.v_number = -1; 15296 if (type == 3) 15297 { 15298 /* return empty list when there are no matches */ 15299 if (rettv_list_alloc(rettv) == FAIL) 15300 goto theend; 15301 } 15302 else if (type == 2) 15303 { 15304 rettv->v_type = VAR_STRING; 15305 rettv->vval.v_string = NULL; 15306 } 15307 15308 if (argvars[0].v_type == VAR_LIST) 15309 { 15310 if ((l = argvars[0].vval.v_list) == NULL) 15311 goto theend; 15312 li = l->lv_first; 15313 } 15314 else 15315 { 15316 expr = str = get_tv_string(&argvars[0]); 15317 len = (long)STRLEN(str); 15318 } 15319 15320 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 15321 if (pat == NULL) 15322 goto theend; 15323 15324 if (argvars[2].v_type != VAR_UNKNOWN) 15325 { 15326 int error = FALSE; 15327 15328 start = get_tv_number_chk(&argvars[2], &error); 15329 if (error) 15330 goto theend; 15331 if (l != NULL) 15332 { 15333 li = list_find(l, start); 15334 if (li == NULL) 15335 goto theend; 15336 idx = l->lv_idx; /* use the cached index */ 15337 } 15338 else 15339 { 15340 if (start < 0) 15341 start = 0; 15342 if (start > len) 15343 goto theend; 15344 /* When "count" argument is there ignore matches before "start", 15345 * otherwise skip part of the string. Differs when pattern is "^" 15346 * or "\<". */ 15347 if (argvars[3].v_type != VAR_UNKNOWN) 15348 startcol = start; 15349 else 15350 { 15351 str += start; 15352 len -= start; 15353 } 15354 } 15355 15356 if (argvars[3].v_type != VAR_UNKNOWN) 15357 nth = get_tv_number_chk(&argvars[3], &error); 15358 if (error) 15359 goto theend; 15360 } 15361 15362 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 15363 if (regmatch.regprog != NULL) 15364 { 15365 regmatch.rm_ic = p_ic; 15366 15367 for (;;) 15368 { 15369 if (l != NULL) 15370 { 15371 if (li == NULL) 15372 { 15373 match = FALSE; 15374 break; 15375 } 15376 vim_free(tofree); 15377 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 15378 if (str == NULL) 15379 break; 15380 } 15381 15382 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 15383 15384 if (match && --nth <= 0) 15385 break; 15386 if (l == NULL && !match) 15387 break; 15388 15389 /* Advance to just after the match. */ 15390 if (l != NULL) 15391 { 15392 li = li->li_next; 15393 ++idx; 15394 } 15395 else 15396 { 15397 #ifdef FEAT_MBYTE 15398 startcol = (colnr_T)(regmatch.startp[0] 15399 + (*mb_ptr2len)(regmatch.startp[0]) - str); 15400 #else 15401 startcol = (colnr_T)(regmatch.startp[0] + 1 - str); 15402 #endif 15403 if (startcol > (colnr_T)len 15404 || str + startcol <= regmatch.startp[0]) 15405 { 15406 match = FALSE; 15407 break; 15408 } 15409 } 15410 } 15411 15412 if (match) 15413 { 15414 if (type == 3) 15415 { 15416 int i; 15417 15418 /* return list with matched string and submatches */ 15419 for (i = 0; i < NSUBEXP; ++i) 15420 { 15421 if (regmatch.endp[i] == NULL) 15422 { 15423 if (list_append_string(rettv->vval.v_list, 15424 (char_u *)"", 0) == FAIL) 15425 break; 15426 } 15427 else if (list_append_string(rettv->vval.v_list, 15428 regmatch.startp[i], 15429 (int)(regmatch.endp[i] - regmatch.startp[i])) 15430 == FAIL) 15431 break; 15432 } 15433 } 15434 else if (type == 2) 15435 { 15436 /* return matched string */ 15437 if (l != NULL) 15438 copy_tv(&li->li_tv, rettv); 15439 else 15440 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 15441 (int)(regmatch.endp[0] - regmatch.startp[0])); 15442 } 15443 else if (l != NULL) 15444 rettv->vval.v_number = idx; 15445 else 15446 { 15447 if (type != 0) 15448 rettv->vval.v_number = 15449 (varnumber_T)(regmatch.startp[0] - str); 15450 else 15451 rettv->vval.v_number = 15452 (varnumber_T)(regmatch.endp[0] - str); 15453 rettv->vval.v_number += (varnumber_T)(str - expr); 15454 } 15455 } 15456 vim_regfree(regmatch.regprog); 15457 } 15458 15459 theend: 15460 vim_free(tofree); 15461 p_cpo = save_cpo; 15462 } 15463 15464 /* 15465 * "match()" function 15466 */ 15467 static void 15468 f_match(typval_T *argvars, typval_T *rettv) 15469 { 15470 find_some_match(argvars, rettv, 1); 15471 } 15472 15473 /* 15474 * "matchadd()" function 15475 */ 15476 static void 15477 f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 15478 { 15479 #ifdef FEAT_SEARCH_EXTRA 15480 char_u buf[NUMBUFLEN]; 15481 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 15482 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 15483 int prio = 10; /* default priority */ 15484 int id = -1; 15485 int error = FALSE; 15486 char_u *conceal_char = NULL; 15487 15488 rettv->vval.v_number = -1; 15489 15490 if (grp == NULL || pat == NULL) 15491 return; 15492 if (argvars[2].v_type != VAR_UNKNOWN) 15493 { 15494 prio = get_tv_number_chk(&argvars[2], &error); 15495 if (argvars[3].v_type != VAR_UNKNOWN) 15496 { 15497 id = get_tv_number_chk(&argvars[3], &error); 15498 if (argvars[4].v_type != VAR_UNKNOWN) 15499 { 15500 if (argvars[4].v_type != VAR_DICT) 15501 { 15502 EMSG(_(e_dictreq)); 15503 return; 15504 } 15505 if (dict_find(argvars[4].vval.v_dict, 15506 (char_u *)"conceal", -1) != NULL) 15507 conceal_char = get_dict_string(argvars[4].vval.v_dict, 15508 (char_u *)"conceal", FALSE); 15509 } 15510 } 15511 } 15512 if (error == TRUE) 15513 return; 15514 if (id >= 1 && id <= 3) 15515 { 15516 EMSGN("E798: ID is reserved for \":match\": %ld", id); 15517 return; 15518 } 15519 15520 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL, 15521 conceal_char); 15522 #endif 15523 } 15524 15525 /* 15526 * "matchaddpos()" function 15527 */ 15528 static void 15529 f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 15530 { 15531 #ifdef FEAT_SEARCH_EXTRA 15532 char_u buf[NUMBUFLEN]; 15533 char_u *group; 15534 int prio = 10; 15535 int id = -1; 15536 int error = FALSE; 15537 list_T *l; 15538 char_u *conceal_char = NULL; 15539 15540 rettv->vval.v_number = -1; 15541 15542 group = get_tv_string_buf_chk(&argvars[0], buf); 15543 if (group == NULL) 15544 return; 15545 15546 if (argvars[1].v_type != VAR_LIST) 15547 { 15548 EMSG2(_(e_listarg), "matchaddpos()"); 15549 return; 15550 } 15551 l = argvars[1].vval.v_list; 15552 if (l == NULL) 15553 return; 15554 15555 if (argvars[2].v_type != VAR_UNKNOWN) 15556 { 15557 prio = get_tv_number_chk(&argvars[2], &error); 15558 if (argvars[3].v_type != VAR_UNKNOWN) 15559 { 15560 id = get_tv_number_chk(&argvars[3], &error); 15561 if (argvars[4].v_type != VAR_UNKNOWN) 15562 { 15563 if (argvars[4].v_type != VAR_DICT) 15564 { 15565 EMSG(_(e_dictreq)); 15566 return; 15567 } 15568 if (dict_find(argvars[4].vval.v_dict, 15569 (char_u *)"conceal", -1) != NULL) 15570 conceal_char = get_dict_string(argvars[4].vval.v_dict, 15571 (char_u *)"conceal", FALSE); 15572 } 15573 } 15574 } 15575 if (error == TRUE) 15576 return; 15577 15578 /* id == 3 is ok because matchaddpos() is supposed to substitute :3match */ 15579 if (id == 1 || id == 2) 15580 { 15581 EMSGN("E798: ID is reserved for \":match\": %ld", id); 15582 return; 15583 } 15584 15585 rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l, 15586 conceal_char); 15587 #endif 15588 } 15589 15590 /* 15591 * "matcharg()" function 15592 */ 15593 static void 15594 f_matcharg(typval_T *argvars UNUSED, typval_T *rettv) 15595 { 15596 if (rettv_list_alloc(rettv) == OK) 15597 { 15598 #ifdef FEAT_SEARCH_EXTRA 15599 int id = get_tv_number(&argvars[0]); 15600 matchitem_T *m; 15601 15602 if (id >= 1 && id <= 3) 15603 { 15604 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 15605 { 15606 list_append_string(rettv->vval.v_list, 15607 syn_id2name(m->hlg_id), -1); 15608 list_append_string(rettv->vval.v_list, m->pattern, -1); 15609 } 15610 else 15611 { 15612 list_append_string(rettv->vval.v_list, NULL, -1); 15613 list_append_string(rettv->vval.v_list, NULL, -1); 15614 } 15615 } 15616 #endif 15617 } 15618 } 15619 15620 /* 15621 * "matchdelete()" function 15622 */ 15623 static void 15624 f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 15625 { 15626 #ifdef FEAT_SEARCH_EXTRA 15627 rettv->vval.v_number = match_delete(curwin, 15628 (int)get_tv_number(&argvars[0]), TRUE); 15629 #endif 15630 } 15631 15632 /* 15633 * "matchend()" function 15634 */ 15635 static void 15636 f_matchend(typval_T *argvars, typval_T *rettv) 15637 { 15638 find_some_match(argvars, rettv, 0); 15639 } 15640 15641 /* 15642 * "matchlist()" function 15643 */ 15644 static void 15645 f_matchlist(typval_T *argvars, typval_T *rettv) 15646 { 15647 find_some_match(argvars, rettv, 3); 15648 } 15649 15650 /* 15651 * "matchstr()" function 15652 */ 15653 static void 15654 f_matchstr(typval_T *argvars, typval_T *rettv) 15655 { 15656 find_some_match(argvars, rettv, 2); 15657 } 15658 15659 static void max_min(typval_T *argvars, typval_T *rettv, int domax); 15660 15661 static void 15662 max_min(typval_T *argvars, typval_T *rettv, int domax) 15663 { 15664 long n = 0; 15665 long i; 15666 int error = FALSE; 15667 15668 if (argvars[0].v_type == VAR_LIST) 15669 { 15670 list_T *l; 15671 listitem_T *li; 15672 15673 l = argvars[0].vval.v_list; 15674 if (l != NULL) 15675 { 15676 li = l->lv_first; 15677 if (li != NULL) 15678 { 15679 n = get_tv_number_chk(&li->li_tv, &error); 15680 for (;;) 15681 { 15682 li = li->li_next; 15683 if (li == NULL) 15684 break; 15685 i = get_tv_number_chk(&li->li_tv, &error); 15686 if (domax ? i > n : i < n) 15687 n = i; 15688 } 15689 } 15690 } 15691 } 15692 else if (argvars[0].v_type == VAR_DICT) 15693 { 15694 dict_T *d; 15695 int first = TRUE; 15696 hashitem_T *hi; 15697 int todo; 15698 15699 d = argvars[0].vval.v_dict; 15700 if (d != NULL) 15701 { 15702 todo = (int)d->dv_hashtab.ht_used; 15703 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 15704 { 15705 if (!HASHITEM_EMPTY(hi)) 15706 { 15707 --todo; 15708 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 15709 if (first) 15710 { 15711 n = i; 15712 first = FALSE; 15713 } 15714 else if (domax ? i > n : i < n) 15715 n = i; 15716 } 15717 } 15718 } 15719 } 15720 else 15721 EMSG(_(e_listdictarg)); 15722 rettv->vval.v_number = error ? 0 : n; 15723 } 15724 15725 /* 15726 * "max()" function 15727 */ 15728 static void 15729 f_max(typval_T *argvars, typval_T *rettv) 15730 { 15731 max_min(argvars, rettv, TRUE); 15732 } 15733 15734 /* 15735 * "min()" function 15736 */ 15737 static void 15738 f_min(typval_T *argvars, typval_T *rettv) 15739 { 15740 max_min(argvars, rettv, FALSE); 15741 } 15742 15743 static int mkdir_recurse(char_u *dir, int prot); 15744 15745 /* 15746 * Create the directory in which "dir" is located, and higher levels when 15747 * needed. 15748 */ 15749 static int 15750 mkdir_recurse(char_u *dir, int prot) 15751 { 15752 char_u *p; 15753 char_u *updir; 15754 int r = FAIL; 15755 15756 /* Get end of directory name in "dir". 15757 * We're done when it's "/" or "c:/". */ 15758 p = gettail_sep(dir); 15759 if (p <= get_past_head(dir)) 15760 return OK; 15761 15762 /* If the directory exists we're done. Otherwise: create it.*/ 15763 updir = vim_strnsave(dir, (int)(p - dir)); 15764 if (updir == NULL) 15765 return FAIL; 15766 if (mch_isdir(updir)) 15767 r = OK; 15768 else if (mkdir_recurse(updir, prot) == OK) 15769 r = vim_mkdir_emsg(updir, prot); 15770 vim_free(updir); 15771 return r; 15772 } 15773 15774 #ifdef vim_mkdir 15775 /* 15776 * "mkdir()" function 15777 */ 15778 static void 15779 f_mkdir(typval_T *argvars, typval_T *rettv) 15780 { 15781 char_u *dir; 15782 char_u buf[NUMBUFLEN]; 15783 int prot = 0755; 15784 15785 rettv->vval.v_number = FAIL; 15786 if (check_restricted() || check_secure()) 15787 return; 15788 15789 dir = get_tv_string_buf(&argvars[0], buf); 15790 if (*dir == NUL) 15791 rettv->vval.v_number = FAIL; 15792 else 15793 { 15794 if (*gettail(dir) == NUL) 15795 /* remove trailing slashes */ 15796 *gettail_sep(dir) = NUL; 15797 15798 if (argvars[1].v_type != VAR_UNKNOWN) 15799 { 15800 if (argvars[2].v_type != VAR_UNKNOWN) 15801 prot = get_tv_number_chk(&argvars[2], NULL); 15802 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 15803 mkdir_recurse(dir, prot); 15804 } 15805 rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); 15806 } 15807 } 15808 #endif 15809 15810 /* 15811 * "mode()" function 15812 */ 15813 static void 15814 f_mode(typval_T *argvars, typval_T *rettv) 15815 { 15816 char_u buf[3]; 15817 15818 buf[1] = NUL; 15819 buf[2] = NUL; 15820 15821 if (VIsual_active) 15822 { 15823 if (VIsual_select) 15824 buf[0] = VIsual_mode + 's' - 'v'; 15825 else 15826 buf[0] = VIsual_mode; 15827 } 15828 else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 15829 || State == CONFIRM) 15830 { 15831 buf[0] = 'r'; 15832 if (State == ASKMORE) 15833 buf[1] = 'm'; 15834 else if (State == CONFIRM) 15835 buf[1] = '?'; 15836 } 15837 else if (State == EXTERNCMD) 15838 buf[0] = '!'; 15839 else if (State & INSERT) 15840 { 15841 #ifdef FEAT_VREPLACE 15842 if (State & VREPLACE_FLAG) 15843 { 15844 buf[0] = 'R'; 15845 buf[1] = 'v'; 15846 } 15847 else 15848 #endif 15849 if (State & REPLACE_FLAG) 15850 buf[0] = 'R'; 15851 else 15852 buf[0] = 'i'; 15853 } 15854 else if (State & CMDLINE) 15855 { 15856 buf[0] = 'c'; 15857 if (exmode_active) 15858 buf[1] = 'v'; 15859 } 15860 else if (exmode_active) 15861 { 15862 buf[0] = 'c'; 15863 buf[1] = 'e'; 15864 } 15865 else 15866 { 15867 buf[0] = 'n'; 15868 if (finish_op) 15869 buf[1] = 'o'; 15870 } 15871 15872 /* Clear out the minor mode when the argument is not a non-zero number or 15873 * non-empty string. */ 15874 if (!non_zero_arg(&argvars[0])) 15875 buf[1] = NUL; 15876 15877 rettv->vval.v_string = vim_strsave(buf); 15878 rettv->v_type = VAR_STRING; 15879 } 15880 15881 #if defined(FEAT_MZSCHEME) || defined(PROTO) 15882 /* 15883 * "mzeval()" function 15884 */ 15885 static void 15886 f_mzeval(typval_T *argvars, typval_T *rettv) 15887 { 15888 char_u *str; 15889 char_u buf[NUMBUFLEN]; 15890 15891 str = get_tv_string_buf(&argvars[0], buf); 15892 do_mzeval(str, rettv); 15893 } 15894 15895 void 15896 mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv) 15897 { 15898 typval_T argvars[3]; 15899 15900 argvars[0].v_type = VAR_STRING; 15901 argvars[0].vval.v_string = name; 15902 copy_tv(args, &argvars[1]); 15903 argvars[2].v_type = VAR_UNKNOWN; 15904 f_call(argvars, rettv); 15905 clear_tv(&argvars[1]); 15906 } 15907 #endif 15908 15909 /* 15910 * "nextnonblank()" function 15911 */ 15912 static void 15913 f_nextnonblank(typval_T *argvars, typval_T *rettv) 15914 { 15915 linenr_T lnum; 15916 15917 for (lnum = get_tv_lnum(argvars); ; ++lnum) 15918 { 15919 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 15920 { 15921 lnum = 0; 15922 break; 15923 } 15924 if (*skipwhite(ml_get(lnum)) != NUL) 15925 break; 15926 } 15927 rettv->vval.v_number = lnum; 15928 } 15929 15930 /* 15931 * "nr2char()" function 15932 */ 15933 static void 15934 f_nr2char(typval_T *argvars, typval_T *rettv) 15935 { 15936 char_u buf[NUMBUFLEN]; 15937 15938 #ifdef FEAT_MBYTE 15939 if (has_mbyte) 15940 { 15941 int utf8 = 0; 15942 15943 if (argvars[1].v_type != VAR_UNKNOWN) 15944 utf8 = get_tv_number_chk(&argvars[1], NULL); 15945 if (utf8) 15946 buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 15947 else 15948 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 15949 } 15950 else 15951 #endif 15952 { 15953 buf[0] = (char_u)get_tv_number(&argvars[0]); 15954 buf[1] = NUL; 15955 } 15956 rettv->v_type = VAR_STRING; 15957 rettv->vval.v_string = vim_strsave(buf); 15958 } 15959 15960 /* 15961 * "or(expr, expr)" function 15962 */ 15963 static void 15964 f_or(typval_T *argvars, typval_T *rettv) 15965 { 15966 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 15967 | get_tv_number_chk(&argvars[1], NULL); 15968 } 15969 15970 /* 15971 * "pathshorten()" function 15972 */ 15973 static void 15974 f_pathshorten(typval_T *argvars, typval_T *rettv) 15975 { 15976 char_u *p; 15977 15978 rettv->v_type = VAR_STRING; 15979 p = get_tv_string_chk(&argvars[0]); 15980 if (p == NULL) 15981 rettv->vval.v_string = NULL; 15982 else 15983 { 15984 p = vim_strsave(p); 15985 rettv->vval.v_string = p; 15986 if (p != NULL) 15987 shorten_dir(p); 15988 } 15989 } 15990 15991 #ifdef FEAT_PERL 15992 /* 15993 * "perleval()" function 15994 */ 15995 static void 15996 f_perleval(typval_T *argvars, typval_T *rettv) 15997 { 15998 char_u *str; 15999 char_u buf[NUMBUFLEN]; 16000 16001 str = get_tv_string_buf(&argvars[0], buf); 16002 do_perleval(str, rettv); 16003 } 16004 #endif 16005 16006 #ifdef FEAT_FLOAT 16007 /* 16008 * "pow()" function 16009 */ 16010 static void 16011 f_pow(typval_T *argvars, typval_T *rettv) 16012 { 16013 float_T fx = 0.0, fy = 0.0; 16014 16015 rettv->v_type = VAR_FLOAT; 16016 if (get_float_arg(argvars, &fx) == OK 16017 && get_float_arg(&argvars[1], &fy) == OK) 16018 rettv->vval.v_float = pow(fx, fy); 16019 else 16020 rettv->vval.v_float = 0.0; 16021 } 16022 #endif 16023 16024 /* 16025 * "prevnonblank()" function 16026 */ 16027 static void 16028 f_prevnonblank(typval_T *argvars, typval_T *rettv) 16029 { 16030 linenr_T lnum; 16031 16032 lnum = get_tv_lnum(argvars); 16033 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 16034 lnum = 0; 16035 else 16036 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 16037 --lnum; 16038 rettv->vval.v_number = lnum; 16039 } 16040 16041 /* This dummy va_list is here because: 16042 * - passing a NULL pointer doesn't work when va_list isn't a pointer 16043 * - locally in the function results in a "used before set" warning 16044 * - using va_start() to initialize it gives "function with fixed args" error */ 16045 static va_list ap; 16046 16047 /* 16048 * "printf()" function 16049 */ 16050 static void 16051 f_printf(typval_T *argvars, typval_T *rettv) 16052 { 16053 char_u buf[NUMBUFLEN]; 16054 int len; 16055 char_u *s; 16056 int saved_did_emsg = did_emsg; 16057 char *fmt; 16058 16059 rettv->v_type = VAR_STRING; 16060 rettv->vval.v_string = NULL; 16061 16062 /* Get the required length, allocate the buffer and do it for real. */ 16063 did_emsg = FALSE; 16064 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 16065 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 16066 if (!did_emsg) 16067 { 16068 s = alloc(len + 1); 16069 if (s != NULL) 16070 { 16071 rettv->vval.v_string = s; 16072 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 16073 } 16074 } 16075 did_emsg |= saved_did_emsg; 16076 } 16077 16078 /* 16079 * "pumvisible()" function 16080 */ 16081 static void 16082 f_pumvisible(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 16083 { 16084 #ifdef FEAT_INS_EXPAND 16085 if (pum_visible()) 16086 rettv->vval.v_number = 1; 16087 #endif 16088 } 16089 16090 #ifdef FEAT_PYTHON3 16091 /* 16092 * "py3eval()" function 16093 */ 16094 static void 16095 f_py3eval(typval_T *argvars, typval_T *rettv) 16096 { 16097 char_u *str; 16098 char_u buf[NUMBUFLEN]; 16099 16100 str = get_tv_string_buf(&argvars[0], buf); 16101 do_py3eval(str, rettv); 16102 } 16103 #endif 16104 16105 #ifdef FEAT_PYTHON 16106 /* 16107 * "pyeval()" function 16108 */ 16109 static void 16110 f_pyeval(typval_T *argvars, typval_T *rettv) 16111 { 16112 char_u *str; 16113 char_u buf[NUMBUFLEN]; 16114 16115 str = get_tv_string_buf(&argvars[0], buf); 16116 do_pyeval(str, rettv); 16117 } 16118 #endif 16119 16120 /* 16121 * "range()" function 16122 */ 16123 static void 16124 f_range(typval_T *argvars, typval_T *rettv) 16125 { 16126 long start; 16127 long end; 16128 long stride = 1; 16129 long i; 16130 int error = FALSE; 16131 16132 start = get_tv_number_chk(&argvars[0], &error); 16133 if (argvars[1].v_type == VAR_UNKNOWN) 16134 { 16135 end = start - 1; 16136 start = 0; 16137 } 16138 else 16139 { 16140 end = get_tv_number_chk(&argvars[1], &error); 16141 if (argvars[2].v_type != VAR_UNKNOWN) 16142 stride = get_tv_number_chk(&argvars[2], &error); 16143 } 16144 16145 if (error) 16146 return; /* type error; errmsg already given */ 16147 if (stride == 0) 16148 EMSG(_("E726: Stride is zero")); 16149 else if (stride > 0 ? end + 1 < start : end - 1 > start) 16150 EMSG(_("E727: Start past end")); 16151 else 16152 { 16153 if (rettv_list_alloc(rettv) == OK) 16154 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 16155 if (list_append_number(rettv->vval.v_list, 16156 (varnumber_T)i) == FAIL) 16157 break; 16158 } 16159 } 16160 16161 /* 16162 * "readfile()" function 16163 */ 16164 static void 16165 f_readfile(typval_T *argvars, typval_T *rettv) 16166 { 16167 int binary = FALSE; 16168 int failed = FALSE; 16169 char_u *fname; 16170 FILE *fd; 16171 char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */ 16172 int io_size = sizeof(buf); 16173 int readlen; /* size of last fread() */ 16174 char_u *prev = NULL; /* previously read bytes, if any */ 16175 long prevlen = 0; /* length of data in prev */ 16176 long prevsize = 0; /* size of prev buffer */ 16177 long maxline = MAXLNUM; 16178 long cnt = 0; 16179 char_u *p; /* position in buf */ 16180 char_u *start; /* start of current line */ 16181 16182 if (argvars[1].v_type != VAR_UNKNOWN) 16183 { 16184 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 16185 binary = TRUE; 16186 if (argvars[2].v_type != VAR_UNKNOWN) 16187 maxline = get_tv_number(&argvars[2]); 16188 } 16189 16190 if (rettv_list_alloc(rettv) == FAIL) 16191 return; 16192 16193 /* Always open the file in binary mode, library functions have a mind of 16194 * their own about CR-LF conversion. */ 16195 fname = get_tv_string(&argvars[0]); 16196 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 16197 { 16198 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 16199 return; 16200 } 16201 16202 while (cnt < maxline || maxline < 0) 16203 { 16204 readlen = (int)fread(buf, 1, io_size, fd); 16205 16206 /* This for loop processes what was read, but is also entered at end 16207 * of file so that either: 16208 * - an incomplete line gets written 16209 * - a "binary" file gets an empty line at the end if it ends in a 16210 * newline. */ 16211 for (p = buf, start = buf; 16212 p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary)); 16213 ++p) 16214 { 16215 if (*p == '\n' || readlen <= 0) 16216 { 16217 listitem_T *li; 16218 char_u *s = NULL; 16219 long_u len = p - start; 16220 16221 /* Finished a line. Remove CRs before NL. */ 16222 if (readlen > 0 && !binary) 16223 { 16224 while (len > 0 && start[len - 1] == '\r') 16225 --len; 16226 /* removal may cross back to the "prev" string */ 16227 if (len == 0) 16228 while (prevlen > 0 && prev[prevlen - 1] == '\r') 16229 --prevlen; 16230 } 16231 if (prevlen == 0) 16232 s = vim_strnsave(start, (int)len); 16233 else 16234 { 16235 /* Change "prev" buffer to be the right size. This way 16236 * the bytes are only copied once, and very long lines are 16237 * allocated only once. */ 16238 if ((s = vim_realloc(prev, prevlen + len + 1)) != NULL) 16239 { 16240 mch_memmove(s + prevlen, start, len); 16241 s[prevlen + len] = NUL; 16242 prev = NULL; /* the list will own the string */ 16243 prevlen = prevsize = 0; 16244 } 16245 } 16246 if (s == NULL) 16247 { 16248 do_outofmem_msg((long_u) prevlen + len + 1); 16249 failed = TRUE; 16250 break; 16251 } 16252 16253 if ((li = listitem_alloc()) == NULL) 16254 { 16255 vim_free(s); 16256 failed = TRUE; 16257 break; 16258 } 16259 li->li_tv.v_type = VAR_STRING; 16260 li->li_tv.v_lock = 0; 16261 li->li_tv.vval.v_string = s; 16262 list_append(rettv->vval.v_list, li); 16263 16264 start = p + 1; /* step over newline */ 16265 if ((++cnt >= maxline && maxline >= 0) || readlen <= 0) 16266 break; 16267 } 16268 else if (*p == NUL) 16269 *p = '\n'; 16270 #ifdef FEAT_MBYTE 16271 /* Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this 16272 * when finding the BF and check the previous two bytes. */ 16273 else if (*p == 0xbf && enc_utf8 && !binary) 16274 { 16275 /* Find the two bytes before the 0xbf. If p is at buf, or buf 16276 * + 1, these may be in the "prev" string. */ 16277 char_u back1 = p >= buf + 1 ? p[-1] 16278 : prevlen >= 1 ? prev[prevlen - 1] : NUL; 16279 char_u back2 = p >= buf + 2 ? p[-2] 16280 : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1] 16281 : prevlen >= 2 ? prev[prevlen - 2] : NUL; 16282 16283 if (back2 == 0xef && back1 == 0xbb) 16284 { 16285 char_u *dest = p - 2; 16286 16287 /* Usually a BOM is at the beginning of a file, and so at 16288 * the beginning of a line; then we can just step over it. 16289 */ 16290 if (start == dest) 16291 start = p + 1; 16292 else 16293 { 16294 /* have to shuffle buf to close gap */ 16295 int adjust_prevlen = 0; 16296 16297 if (dest < buf) 16298 { 16299 adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */ 16300 dest = buf; 16301 } 16302 if (readlen > p - buf + 1) 16303 mch_memmove(dest, p + 1, readlen - (p - buf) - 1); 16304 readlen -= 3 - adjust_prevlen; 16305 prevlen -= adjust_prevlen; 16306 p = dest - 1; 16307 } 16308 } 16309 } 16310 #endif 16311 } /* for */ 16312 16313 if (failed || (cnt >= maxline && maxline >= 0) || readlen <= 0) 16314 break; 16315 if (start < p) 16316 { 16317 /* There's part of a line in buf, store it in "prev". */ 16318 if (p - start + prevlen >= prevsize) 16319 { 16320 /* need bigger "prev" buffer */ 16321 char_u *newprev; 16322 16323 /* A common use case is ordinary text files and "prev" gets a 16324 * fragment of a line, so the first allocation is made 16325 * small, to avoid repeatedly 'allocing' large and 16326 * 'reallocing' small. */ 16327 if (prevsize == 0) 16328 prevsize = (long)(p - start); 16329 else 16330 { 16331 long grow50pc = (prevsize * 3) / 2; 16332 long growmin = (long)((p - start) * 2 + prevlen); 16333 prevsize = grow50pc > growmin ? grow50pc : growmin; 16334 } 16335 newprev = prev == NULL ? alloc(prevsize) 16336 : vim_realloc(prev, prevsize); 16337 if (newprev == NULL) 16338 { 16339 do_outofmem_msg((long_u)prevsize); 16340 failed = TRUE; 16341 break; 16342 } 16343 prev = newprev; 16344 } 16345 /* Add the line part to end of "prev". */ 16346 mch_memmove(prev + prevlen, start, p - start); 16347 prevlen += (long)(p - start); 16348 } 16349 } /* while */ 16350 16351 /* 16352 * For a negative line count use only the lines at the end of the file, 16353 * free the rest. 16354 */ 16355 if (!failed && maxline < 0) 16356 while (cnt > -maxline) 16357 { 16358 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 16359 --cnt; 16360 } 16361 16362 if (failed) 16363 { 16364 list_free(rettv->vval.v_list, TRUE); 16365 /* readfile doc says an empty list is returned on error */ 16366 rettv->vval.v_list = list_alloc(); 16367 } 16368 16369 vim_free(prev); 16370 fclose(fd); 16371 } 16372 16373 #if defined(FEAT_RELTIME) 16374 static int list2proftime(typval_T *arg, proftime_T *tm); 16375 16376 /* 16377 * Convert a List to proftime_T. 16378 * Return FAIL when there is something wrong. 16379 */ 16380 static int 16381 list2proftime(typval_T *arg, proftime_T *tm) 16382 { 16383 long n1, n2; 16384 int error = FALSE; 16385 16386 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 16387 || arg->vval.v_list->lv_len != 2) 16388 return FAIL; 16389 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 16390 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 16391 # ifdef WIN3264 16392 tm->HighPart = n1; 16393 tm->LowPart = n2; 16394 # else 16395 tm->tv_sec = n1; 16396 tm->tv_usec = n2; 16397 # endif 16398 return error ? FAIL : OK; 16399 } 16400 #endif /* FEAT_RELTIME */ 16401 16402 /* 16403 * "reltime()" function 16404 */ 16405 static void 16406 f_reltime(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 16407 { 16408 #ifdef FEAT_RELTIME 16409 proftime_T res; 16410 proftime_T start; 16411 16412 if (argvars[0].v_type == VAR_UNKNOWN) 16413 { 16414 /* No arguments: get current time. */ 16415 profile_start(&res); 16416 } 16417 else if (argvars[1].v_type == VAR_UNKNOWN) 16418 { 16419 if (list2proftime(&argvars[0], &res) == FAIL) 16420 return; 16421 profile_end(&res); 16422 } 16423 else 16424 { 16425 /* Two arguments: compute the difference. */ 16426 if (list2proftime(&argvars[0], &start) == FAIL 16427 || list2proftime(&argvars[1], &res) == FAIL) 16428 return; 16429 profile_sub(&res, &start); 16430 } 16431 16432 if (rettv_list_alloc(rettv) == OK) 16433 { 16434 long n1, n2; 16435 16436 # ifdef WIN3264 16437 n1 = res.HighPart; 16438 n2 = res.LowPart; 16439 # else 16440 n1 = res.tv_sec; 16441 n2 = res.tv_usec; 16442 # endif 16443 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 16444 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 16445 } 16446 #endif 16447 } 16448 16449 #ifdef FEAT_FLOAT 16450 /* 16451 * "reltimefloat()" function 16452 */ 16453 static void 16454 f_reltimefloat(typval_T *argvars UNUSED, typval_T *rettv) 16455 { 16456 # ifdef FEAT_RELTIME 16457 proftime_T tm; 16458 # endif 16459 16460 rettv->v_type = VAR_FLOAT; 16461 rettv->vval.v_float = 0; 16462 # ifdef FEAT_RELTIME 16463 if (list2proftime(&argvars[0], &tm) == OK) 16464 rettv->vval.v_float = profile_float(&tm); 16465 # endif 16466 } 16467 #endif 16468 16469 /* 16470 * "reltimestr()" function 16471 */ 16472 static void 16473 f_reltimestr(typval_T *argvars UNUSED, typval_T *rettv) 16474 { 16475 #ifdef FEAT_RELTIME 16476 proftime_T tm; 16477 #endif 16478 16479 rettv->v_type = VAR_STRING; 16480 rettv->vval.v_string = NULL; 16481 #ifdef FEAT_RELTIME 16482 if (list2proftime(&argvars[0], &tm) == OK) 16483 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 16484 #endif 16485 } 16486 16487 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 16488 static void make_connection(void); 16489 static int check_connection(void); 16490 16491 static void 16492 make_connection(void) 16493 { 16494 if (X_DISPLAY == NULL 16495 # ifdef FEAT_GUI 16496 && !gui.in_use 16497 # endif 16498 ) 16499 { 16500 x_force_connect = TRUE; 16501 setup_term_clip(); 16502 x_force_connect = FALSE; 16503 } 16504 } 16505 16506 static int 16507 check_connection(void) 16508 { 16509 make_connection(); 16510 if (X_DISPLAY == NULL) 16511 { 16512 EMSG(_("E240: No connection to Vim server")); 16513 return FAIL; 16514 } 16515 return OK; 16516 } 16517 #endif 16518 16519 #ifdef FEAT_CLIENTSERVER 16520 static void remote_common(typval_T *argvars, typval_T *rettv, int expr); 16521 16522 static void 16523 remote_common(typval_T *argvars, typval_T *rettv, int expr) 16524 { 16525 char_u *server_name; 16526 char_u *keys; 16527 char_u *r = NULL; 16528 char_u buf[NUMBUFLEN]; 16529 # ifdef WIN32 16530 HWND w; 16531 # else 16532 Window w; 16533 # endif 16534 16535 if (check_restricted() || check_secure()) 16536 return; 16537 16538 # ifdef FEAT_X11 16539 if (check_connection() == FAIL) 16540 return; 16541 # endif 16542 16543 server_name = get_tv_string_chk(&argvars[0]); 16544 if (server_name == NULL) 16545 return; /* type error; errmsg already given */ 16546 keys = get_tv_string_buf(&argvars[1], buf); 16547 # ifdef WIN32 16548 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 16549 # else 16550 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 16551 < 0) 16552 # endif 16553 { 16554 if (r != NULL) 16555 EMSG(r); /* sending worked but evaluation failed */ 16556 else 16557 EMSG2(_("E241: Unable to send to %s"), server_name); 16558 return; 16559 } 16560 16561 rettv->vval.v_string = r; 16562 16563 if (argvars[2].v_type != VAR_UNKNOWN) 16564 { 16565 dictitem_T v; 16566 char_u str[30]; 16567 char_u *idvar; 16568 16569 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 16570 v.di_tv.v_type = VAR_STRING; 16571 v.di_tv.vval.v_string = vim_strsave(str); 16572 idvar = get_tv_string_chk(&argvars[2]); 16573 if (idvar != NULL) 16574 set_var(idvar, &v.di_tv, FALSE); 16575 vim_free(v.di_tv.vval.v_string); 16576 } 16577 } 16578 #endif 16579 16580 /* 16581 * "remote_expr()" function 16582 */ 16583 static void 16584 f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv) 16585 { 16586 rettv->v_type = VAR_STRING; 16587 rettv->vval.v_string = NULL; 16588 #ifdef FEAT_CLIENTSERVER 16589 remote_common(argvars, rettv, TRUE); 16590 #endif 16591 } 16592 16593 /* 16594 * "remote_foreground()" function 16595 */ 16596 static void 16597 f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 16598 { 16599 #ifdef FEAT_CLIENTSERVER 16600 # ifdef WIN32 16601 /* On Win32 it's done in this application. */ 16602 { 16603 char_u *server_name = get_tv_string_chk(&argvars[0]); 16604 16605 if (server_name != NULL) 16606 serverForeground(server_name); 16607 } 16608 # else 16609 /* Send a foreground() expression to the server. */ 16610 argvars[1].v_type = VAR_STRING; 16611 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 16612 argvars[2].v_type = VAR_UNKNOWN; 16613 remote_common(argvars, rettv, TRUE); 16614 vim_free(argvars[1].vval.v_string); 16615 # endif 16616 #endif 16617 } 16618 16619 static void 16620 f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) 16621 { 16622 #ifdef FEAT_CLIENTSERVER 16623 dictitem_T v; 16624 char_u *s = NULL; 16625 # ifdef WIN32 16626 long_u n = 0; 16627 # endif 16628 char_u *serverid; 16629 16630 if (check_restricted() || check_secure()) 16631 { 16632 rettv->vval.v_number = -1; 16633 return; 16634 } 16635 serverid = get_tv_string_chk(&argvars[0]); 16636 if (serverid == NULL) 16637 { 16638 rettv->vval.v_number = -1; 16639 return; /* type error; errmsg already given */ 16640 } 16641 # ifdef WIN32 16642 sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); 16643 if (n == 0) 16644 rettv->vval.v_number = -1; 16645 else 16646 { 16647 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 16648 rettv->vval.v_number = (s != NULL); 16649 } 16650 # else 16651 if (check_connection() == FAIL) 16652 return; 16653 16654 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 16655 serverStrToWin(serverid), &s); 16656 # endif 16657 16658 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 16659 { 16660 char_u *retvar; 16661 16662 v.di_tv.v_type = VAR_STRING; 16663 v.di_tv.vval.v_string = vim_strsave(s); 16664 retvar = get_tv_string_chk(&argvars[1]); 16665 if (retvar != NULL) 16666 set_var(retvar, &v.di_tv, FALSE); 16667 vim_free(v.di_tv.vval.v_string); 16668 } 16669 #else 16670 rettv->vval.v_number = -1; 16671 #endif 16672 } 16673 16674 static void 16675 f_remote_read(typval_T *argvars UNUSED, typval_T *rettv) 16676 { 16677 char_u *r = NULL; 16678 16679 #ifdef FEAT_CLIENTSERVER 16680 char_u *serverid = get_tv_string_chk(&argvars[0]); 16681 16682 if (serverid != NULL && !check_restricted() && !check_secure()) 16683 { 16684 # ifdef WIN32 16685 /* The server's HWND is encoded in the 'id' parameter */ 16686 long_u n = 0; 16687 16688 sscanf((char *)serverid, SCANF_HEX_LONG_U, &n); 16689 if (n != 0) 16690 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 16691 if (r == NULL) 16692 # else 16693 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 16694 serverStrToWin(serverid), &r, FALSE) < 0) 16695 # endif 16696 EMSG(_("E277: Unable to read a server reply")); 16697 } 16698 #endif 16699 rettv->v_type = VAR_STRING; 16700 rettv->vval.v_string = r; 16701 } 16702 16703 /* 16704 * "remote_send()" function 16705 */ 16706 static void 16707 f_remote_send(typval_T *argvars UNUSED, typval_T *rettv) 16708 { 16709 rettv->v_type = VAR_STRING; 16710 rettv->vval.v_string = NULL; 16711 #ifdef FEAT_CLIENTSERVER 16712 remote_common(argvars, rettv, FALSE); 16713 #endif 16714 } 16715 16716 /* 16717 * "remove()" function 16718 */ 16719 static void 16720 f_remove(typval_T *argvars, typval_T *rettv) 16721 { 16722 list_T *l; 16723 listitem_T *item, *item2; 16724 listitem_T *li; 16725 long idx; 16726 long end; 16727 char_u *key; 16728 dict_T *d; 16729 dictitem_T *di; 16730 char_u *arg_errmsg = (char_u *)N_("remove() argument"); 16731 16732 if (argvars[0].v_type == VAR_DICT) 16733 { 16734 if (argvars[2].v_type != VAR_UNKNOWN) 16735 EMSG2(_(e_toomanyarg), "remove()"); 16736 else if ((d = argvars[0].vval.v_dict) != NULL 16737 && !tv_check_lock(d->dv_lock, arg_errmsg, TRUE)) 16738 { 16739 key = get_tv_string_chk(&argvars[1]); 16740 if (key != NULL) 16741 { 16742 di = dict_find(d, key, -1); 16743 if (di == NULL) 16744 EMSG2(_(e_dictkey), key); 16745 else if (!var_check_fixed(di->di_flags, arg_errmsg, TRUE) 16746 && !var_check_ro(di->di_flags, arg_errmsg, TRUE)) 16747 { 16748 *rettv = di->di_tv; 16749 init_tv(&di->di_tv); 16750 dictitem_remove(d, di); 16751 } 16752 } 16753 } 16754 } 16755 else if (argvars[0].v_type != VAR_LIST) 16756 EMSG2(_(e_listdictarg), "remove()"); 16757 else if ((l = argvars[0].vval.v_list) != NULL 16758 && !tv_check_lock(l->lv_lock, arg_errmsg, TRUE)) 16759 { 16760 int error = FALSE; 16761 16762 idx = get_tv_number_chk(&argvars[1], &error); 16763 if (error) 16764 ; /* type error: do nothing, errmsg already given */ 16765 else if ((item = list_find(l, idx)) == NULL) 16766 EMSGN(_(e_listidx), idx); 16767 else 16768 { 16769 if (argvars[2].v_type == VAR_UNKNOWN) 16770 { 16771 /* Remove one item, return its value. */ 16772 vimlist_remove(l, item, item); 16773 *rettv = item->li_tv; 16774 vim_free(item); 16775 } 16776 else 16777 { 16778 /* Remove range of items, return list with values. */ 16779 end = get_tv_number_chk(&argvars[2], &error); 16780 if (error) 16781 ; /* type error: do nothing */ 16782 else if ((item2 = list_find(l, end)) == NULL) 16783 EMSGN(_(e_listidx), end); 16784 else 16785 { 16786 int cnt = 0; 16787 16788 for (li = item; li != NULL; li = li->li_next) 16789 { 16790 ++cnt; 16791 if (li == item2) 16792 break; 16793 } 16794 if (li == NULL) /* didn't find "item2" after "item" */ 16795 EMSG(_(e_invrange)); 16796 else 16797 { 16798 vimlist_remove(l, item, item2); 16799 if (rettv_list_alloc(rettv) == OK) 16800 { 16801 l = rettv->vval.v_list; 16802 l->lv_first = item; 16803 l->lv_last = item2; 16804 item->li_prev = NULL; 16805 item2->li_next = NULL; 16806 l->lv_len = cnt; 16807 } 16808 } 16809 } 16810 } 16811 } 16812 } 16813 } 16814 16815 /* 16816 * "rename({from}, {to})" function 16817 */ 16818 static void 16819 f_rename(typval_T *argvars, typval_T *rettv) 16820 { 16821 char_u buf[NUMBUFLEN]; 16822 16823 if (check_restricted() || check_secure()) 16824 rettv->vval.v_number = -1; 16825 else 16826 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 16827 get_tv_string_buf(&argvars[1], buf)); 16828 } 16829 16830 /* 16831 * "repeat()" function 16832 */ 16833 static void 16834 f_repeat(typval_T *argvars, typval_T *rettv) 16835 { 16836 char_u *p; 16837 int n; 16838 int slen; 16839 int len; 16840 char_u *r; 16841 int i; 16842 16843 n = get_tv_number(&argvars[1]); 16844 if (argvars[0].v_type == VAR_LIST) 16845 { 16846 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 16847 while (n-- > 0) 16848 if (list_extend(rettv->vval.v_list, 16849 argvars[0].vval.v_list, NULL) == FAIL) 16850 break; 16851 } 16852 else 16853 { 16854 p = get_tv_string(&argvars[0]); 16855 rettv->v_type = VAR_STRING; 16856 rettv->vval.v_string = NULL; 16857 16858 slen = (int)STRLEN(p); 16859 len = slen * n; 16860 if (len <= 0) 16861 return; 16862 16863 r = alloc(len + 1); 16864 if (r != NULL) 16865 { 16866 for (i = 0; i < n; i++) 16867 mch_memmove(r + i * slen, p, (size_t)slen); 16868 r[len] = NUL; 16869 } 16870 16871 rettv->vval.v_string = r; 16872 } 16873 } 16874 16875 /* 16876 * "resolve()" function 16877 */ 16878 static void 16879 f_resolve(typval_T *argvars, typval_T *rettv) 16880 { 16881 char_u *p; 16882 #ifdef HAVE_READLINK 16883 char_u *buf = NULL; 16884 #endif 16885 16886 p = get_tv_string(&argvars[0]); 16887 #ifdef FEAT_SHORTCUT 16888 { 16889 char_u *v = NULL; 16890 16891 v = mch_resolve_shortcut(p); 16892 if (v != NULL) 16893 rettv->vval.v_string = v; 16894 else 16895 rettv->vval.v_string = vim_strsave(p); 16896 } 16897 #else 16898 # ifdef HAVE_READLINK 16899 { 16900 char_u *cpy; 16901 int len; 16902 char_u *remain = NULL; 16903 char_u *q; 16904 int is_relative_to_current = FALSE; 16905 int has_trailing_pathsep = FALSE; 16906 int limit = 100; 16907 16908 p = vim_strsave(p); 16909 16910 if (p[0] == '.' && (vim_ispathsep(p[1]) 16911 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 16912 is_relative_to_current = TRUE; 16913 16914 len = STRLEN(p); 16915 if (len > 0 && after_pathsep(p, p + len)) 16916 { 16917 has_trailing_pathsep = TRUE; 16918 p[len - 1] = NUL; /* the trailing slash breaks readlink() */ 16919 } 16920 16921 q = getnextcomp(p); 16922 if (*q != NUL) 16923 { 16924 /* Separate the first path component in "p", and keep the 16925 * remainder (beginning with the path separator). */ 16926 remain = vim_strsave(q - 1); 16927 q[-1] = NUL; 16928 } 16929 16930 buf = alloc(MAXPATHL + 1); 16931 if (buf == NULL) 16932 goto fail; 16933 16934 for (;;) 16935 { 16936 for (;;) 16937 { 16938 len = readlink((char *)p, (char *)buf, MAXPATHL); 16939 if (len <= 0) 16940 break; 16941 buf[len] = NUL; 16942 16943 if (limit-- == 0) 16944 { 16945 vim_free(p); 16946 vim_free(remain); 16947 EMSG(_("E655: Too many symbolic links (cycle?)")); 16948 rettv->vval.v_string = NULL; 16949 goto fail; 16950 } 16951 16952 /* Ensure that the result will have a trailing path separator 16953 * if the argument has one. */ 16954 if (remain == NULL && has_trailing_pathsep) 16955 add_pathsep(buf); 16956 16957 /* Separate the first path component in the link value and 16958 * concatenate the remainders. */ 16959 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 16960 if (*q != NUL) 16961 { 16962 if (remain == NULL) 16963 remain = vim_strsave(q - 1); 16964 else 16965 { 16966 cpy = concat_str(q - 1, remain); 16967 if (cpy != NULL) 16968 { 16969 vim_free(remain); 16970 remain = cpy; 16971 } 16972 } 16973 q[-1] = NUL; 16974 } 16975 16976 q = gettail(p); 16977 if (q > p && *q == NUL) 16978 { 16979 /* Ignore trailing path separator. */ 16980 q[-1] = NUL; 16981 q = gettail(p); 16982 } 16983 if (q > p && !mch_isFullName(buf)) 16984 { 16985 /* symlink is relative to directory of argument */ 16986 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 16987 if (cpy != NULL) 16988 { 16989 STRCPY(cpy, p); 16990 STRCPY(gettail(cpy), buf); 16991 vim_free(p); 16992 p = cpy; 16993 } 16994 } 16995 else 16996 { 16997 vim_free(p); 16998 p = vim_strsave(buf); 16999 } 17000 } 17001 17002 if (remain == NULL) 17003 break; 17004 17005 /* Append the first path component of "remain" to "p". */ 17006 q = getnextcomp(remain + 1); 17007 len = q - remain - (*q != NUL); 17008 cpy = vim_strnsave(p, STRLEN(p) + len); 17009 if (cpy != NULL) 17010 { 17011 STRNCAT(cpy, remain, len); 17012 vim_free(p); 17013 p = cpy; 17014 } 17015 /* Shorten "remain". */ 17016 if (*q != NUL) 17017 STRMOVE(remain, q - 1); 17018 else 17019 { 17020 vim_free(remain); 17021 remain = NULL; 17022 } 17023 } 17024 17025 /* If the result is a relative path name, make it explicitly relative to 17026 * the current directory if and only if the argument had this form. */ 17027 if (!vim_ispathsep(*p)) 17028 { 17029 if (is_relative_to_current 17030 && *p != NUL 17031 && !(p[0] == '.' 17032 && (p[1] == NUL 17033 || vim_ispathsep(p[1]) 17034 || (p[1] == '.' 17035 && (p[2] == NUL 17036 || vim_ispathsep(p[2])))))) 17037 { 17038 /* Prepend "./". */ 17039 cpy = concat_str((char_u *)"./", p); 17040 if (cpy != NULL) 17041 { 17042 vim_free(p); 17043 p = cpy; 17044 } 17045 } 17046 else if (!is_relative_to_current) 17047 { 17048 /* Strip leading "./". */ 17049 q = p; 17050 while (q[0] == '.' && vim_ispathsep(q[1])) 17051 q += 2; 17052 if (q > p) 17053 STRMOVE(p, p + 2); 17054 } 17055 } 17056 17057 /* Ensure that the result will have no trailing path separator 17058 * if the argument had none. But keep "/" or "//". */ 17059 if (!has_trailing_pathsep) 17060 { 17061 q = p + STRLEN(p); 17062 if (after_pathsep(p, q)) 17063 *gettail_sep(p) = NUL; 17064 } 17065 17066 rettv->vval.v_string = p; 17067 } 17068 # else 17069 rettv->vval.v_string = vim_strsave(p); 17070 # endif 17071 #endif 17072 17073 simplify_filename(rettv->vval.v_string); 17074 17075 #ifdef HAVE_READLINK 17076 fail: 17077 vim_free(buf); 17078 #endif 17079 rettv->v_type = VAR_STRING; 17080 } 17081 17082 /* 17083 * "reverse({list})" function 17084 */ 17085 static void 17086 f_reverse(typval_T *argvars, typval_T *rettv) 17087 { 17088 list_T *l; 17089 listitem_T *li, *ni; 17090 17091 if (argvars[0].v_type != VAR_LIST) 17092 EMSG2(_(e_listarg), "reverse()"); 17093 else if ((l = argvars[0].vval.v_list) != NULL 17094 && !tv_check_lock(l->lv_lock, 17095 (char_u *)N_("reverse() argument"), TRUE)) 17096 { 17097 li = l->lv_last; 17098 l->lv_first = l->lv_last = NULL; 17099 l->lv_len = 0; 17100 while (li != NULL) 17101 { 17102 ni = li->li_prev; 17103 list_append(l, li); 17104 li = ni; 17105 } 17106 rettv->vval.v_list = l; 17107 rettv->v_type = VAR_LIST; 17108 ++l->lv_refcount; 17109 l->lv_idx = l->lv_len - l->lv_idx - 1; 17110 } 17111 } 17112 17113 #define SP_NOMOVE 0x01 /* don't move cursor */ 17114 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 17115 #define SP_RETCOUNT 0x04 /* return matchcount */ 17116 #define SP_SETPCMARK 0x08 /* set previous context mark */ 17117 #define SP_START 0x10 /* accept match at start position */ 17118 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 17119 #define SP_END 0x40 /* leave cursor at end of match */ 17120 #define SP_COLUMN 0x80 /* start at cursor column */ 17121 17122 static int get_search_arg(typval_T *varp, int *flagsp); 17123 17124 /* 17125 * Get flags for a search function. 17126 * Possibly sets "p_ws". 17127 * Returns BACKWARD, FORWARD or zero (for an error). 17128 */ 17129 static int 17130 get_search_arg(typval_T *varp, int *flagsp) 17131 { 17132 int dir = FORWARD; 17133 char_u *flags; 17134 char_u nbuf[NUMBUFLEN]; 17135 int mask; 17136 17137 if (varp->v_type != VAR_UNKNOWN) 17138 { 17139 flags = get_tv_string_buf_chk(varp, nbuf); 17140 if (flags == NULL) 17141 return 0; /* type error; errmsg already given */ 17142 while (*flags != NUL) 17143 { 17144 switch (*flags) 17145 { 17146 case 'b': dir = BACKWARD; break; 17147 case 'w': p_ws = TRUE; break; 17148 case 'W': p_ws = FALSE; break; 17149 default: mask = 0; 17150 if (flagsp != NULL) 17151 switch (*flags) 17152 { 17153 case 'c': mask = SP_START; break; 17154 case 'e': mask = SP_END; break; 17155 case 'm': mask = SP_RETCOUNT; break; 17156 case 'n': mask = SP_NOMOVE; break; 17157 case 'p': mask = SP_SUBPAT; break; 17158 case 'r': mask = SP_REPEAT; break; 17159 case 's': mask = SP_SETPCMARK; break; 17160 case 'z': mask = SP_COLUMN; break; 17161 } 17162 if (mask == 0) 17163 { 17164 EMSG2(_(e_invarg2), flags); 17165 dir = 0; 17166 } 17167 else 17168 *flagsp |= mask; 17169 } 17170 if (dir == 0) 17171 break; 17172 ++flags; 17173 } 17174 } 17175 return dir; 17176 } 17177 17178 /* 17179 * Shared by search() and searchpos() functions. 17180 */ 17181 static int 17182 search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) 17183 { 17184 int flags; 17185 char_u *pat; 17186 pos_T pos; 17187 pos_T save_cursor; 17188 int save_p_ws = p_ws; 17189 int dir; 17190 int retval = 0; /* default: FAIL */ 17191 long lnum_stop = 0; 17192 proftime_T tm; 17193 #ifdef FEAT_RELTIME 17194 long time_limit = 0; 17195 #endif 17196 int options = SEARCH_KEEP; 17197 int subpatnum; 17198 17199 pat = get_tv_string(&argvars[0]); 17200 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 17201 if (dir == 0) 17202 goto theend; 17203 flags = *flagsp; 17204 if (flags & SP_START) 17205 options |= SEARCH_START; 17206 if (flags & SP_END) 17207 options |= SEARCH_END; 17208 if (flags & SP_COLUMN) 17209 options |= SEARCH_COL; 17210 17211 /* Optional arguments: line number to stop searching and timeout. */ 17212 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 17213 { 17214 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 17215 if (lnum_stop < 0) 17216 goto theend; 17217 #ifdef FEAT_RELTIME 17218 if (argvars[3].v_type != VAR_UNKNOWN) 17219 { 17220 time_limit = get_tv_number_chk(&argvars[3], NULL); 17221 if (time_limit < 0) 17222 goto theend; 17223 } 17224 #endif 17225 } 17226 17227 #ifdef FEAT_RELTIME 17228 /* Set the time limit, if there is one. */ 17229 profile_setlimit(time_limit, &tm); 17230 #endif 17231 17232 /* 17233 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 17234 * Check to make sure only those flags are set. 17235 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 17236 * flags cannot be set. Check for that condition also. 17237 */ 17238 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 17239 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 17240 { 17241 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 17242 goto theend; 17243 } 17244 17245 pos = save_cursor = curwin->w_cursor; 17246 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 17247 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 17248 if (subpatnum != FAIL) 17249 { 17250 if (flags & SP_SUBPAT) 17251 retval = subpatnum; 17252 else 17253 retval = pos.lnum; 17254 if (flags & SP_SETPCMARK) 17255 setpcmark(); 17256 curwin->w_cursor = pos; 17257 if (match_pos != NULL) 17258 { 17259 /* Store the match cursor position */ 17260 match_pos->lnum = pos.lnum; 17261 match_pos->col = pos.col + 1; 17262 } 17263 /* "/$" will put the cursor after the end of the line, may need to 17264 * correct that here */ 17265 check_cursor(); 17266 } 17267 17268 /* If 'n' flag is used: restore cursor position. */ 17269 if (flags & SP_NOMOVE) 17270 curwin->w_cursor = save_cursor; 17271 else 17272 curwin->w_set_curswant = TRUE; 17273 theend: 17274 p_ws = save_p_ws; 17275 17276 return retval; 17277 } 17278 17279 #ifdef FEAT_FLOAT 17280 17281 /* 17282 * round() is not in C90, use ceil() or floor() instead. 17283 */ 17284 float_T 17285 vim_round(float_T f) 17286 { 17287 return f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 17288 } 17289 17290 /* 17291 * "round({float})" function 17292 */ 17293 static void 17294 f_round(typval_T *argvars, typval_T *rettv) 17295 { 17296 float_T f = 0.0; 17297 17298 rettv->v_type = VAR_FLOAT; 17299 if (get_float_arg(argvars, &f) == OK) 17300 rettv->vval.v_float = vim_round(f); 17301 else 17302 rettv->vval.v_float = 0.0; 17303 } 17304 #endif 17305 17306 /* 17307 * "screenattr()" function 17308 */ 17309 static void 17310 f_screenattr(typval_T *argvars, typval_T *rettv) 17311 { 17312 int row; 17313 int col; 17314 int c; 17315 17316 row = get_tv_number_chk(&argvars[0], NULL) - 1; 17317 col = get_tv_number_chk(&argvars[1], NULL) - 1; 17318 if (row < 0 || row >= screen_Rows 17319 || col < 0 || col >= screen_Columns) 17320 c = -1; 17321 else 17322 c = ScreenAttrs[LineOffset[row] + col]; 17323 rettv->vval.v_number = c; 17324 } 17325 17326 /* 17327 * "screenchar()" function 17328 */ 17329 static void 17330 f_screenchar(typval_T *argvars, typval_T *rettv) 17331 { 17332 int row; 17333 int col; 17334 int off; 17335 int c; 17336 17337 row = get_tv_number_chk(&argvars[0], NULL) - 1; 17338 col = get_tv_number_chk(&argvars[1], NULL) - 1; 17339 if (row < 0 || row >= screen_Rows 17340 || col < 0 || col >= screen_Columns) 17341 c = -1; 17342 else 17343 { 17344 off = LineOffset[row] + col; 17345 #ifdef FEAT_MBYTE 17346 if (enc_utf8 && ScreenLinesUC[off] != 0) 17347 c = ScreenLinesUC[off]; 17348 else 17349 #endif 17350 c = ScreenLines[off]; 17351 } 17352 rettv->vval.v_number = c; 17353 } 17354 17355 /* 17356 * "screencol()" function 17357 * 17358 * First column is 1 to be consistent with virtcol(). 17359 */ 17360 static void 17361 f_screencol(typval_T *argvars UNUSED, typval_T *rettv) 17362 { 17363 rettv->vval.v_number = screen_screencol() + 1; 17364 } 17365 17366 /* 17367 * "screenrow()" function 17368 */ 17369 static void 17370 f_screenrow(typval_T *argvars UNUSED, typval_T *rettv) 17371 { 17372 rettv->vval.v_number = screen_screenrow() + 1; 17373 } 17374 17375 /* 17376 * "search()" function 17377 */ 17378 static void 17379 f_search(typval_T *argvars, typval_T *rettv) 17380 { 17381 int flags = 0; 17382 17383 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 17384 } 17385 17386 /* 17387 * "searchdecl()" function 17388 */ 17389 static void 17390 f_searchdecl(typval_T *argvars, typval_T *rettv) 17391 { 17392 int locally = 1; 17393 int thisblock = 0; 17394 int error = FALSE; 17395 char_u *name; 17396 17397 rettv->vval.v_number = 1; /* default: FAIL */ 17398 17399 name = get_tv_string_chk(&argvars[0]); 17400 if (argvars[1].v_type != VAR_UNKNOWN) 17401 { 17402 locally = get_tv_number_chk(&argvars[1], &error) == 0; 17403 if (!error && argvars[2].v_type != VAR_UNKNOWN) 17404 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 17405 } 17406 if (!error && name != NULL) 17407 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 17408 locally, thisblock, SEARCH_KEEP) == FAIL; 17409 } 17410 17411 /* 17412 * Used by searchpair() and searchpairpos() 17413 */ 17414 static int 17415 searchpair_cmn(typval_T *argvars, pos_T *match_pos) 17416 { 17417 char_u *spat, *mpat, *epat; 17418 char_u *skip; 17419 int save_p_ws = p_ws; 17420 int dir; 17421 int flags = 0; 17422 char_u nbuf1[NUMBUFLEN]; 17423 char_u nbuf2[NUMBUFLEN]; 17424 char_u nbuf3[NUMBUFLEN]; 17425 int retval = 0; /* default: FAIL */ 17426 long lnum_stop = 0; 17427 long time_limit = 0; 17428 17429 /* Get the three pattern arguments: start, middle, end. */ 17430 spat = get_tv_string_chk(&argvars[0]); 17431 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 17432 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 17433 if (spat == NULL || mpat == NULL || epat == NULL) 17434 goto theend; /* type error */ 17435 17436 /* Handle the optional fourth argument: flags */ 17437 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 17438 if (dir == 0) 17439 goto theend; 17440 17441 /* Don't accept SP_END or SP_SUBPAT. 17442 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 17443 */ 17444 if ((flags & (SP_END | SP_SUBPAT)) != 0 17445 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 17446 { 17447 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 17448 goto theend; 17449 } 17450 17451 /* Using 'r' implies 'W', otherwise it doesn't work. */ 17452 if (flags & SP_REPEAT) 17453 p_ws = FALSE; 17454 17455 /* Optional fifth argument: skip expression */ 17456 if (argvars[3].v_type == VAR_UNKNOWN 17457 || argvars[4].v_type == VAR_UNKNOWN) 17458 skip = (char_u *)""; 17459 else 17460 { 17461 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 17462 if (argvars[5].v_type != VAR_UNKNOWN) 17463 { 17464 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 17465 if (lnum_stop < 0) 17466 goto theend; 17467 #ifdef FEAT_RELTIME 17468 if (argvars[6].v_type != VAR_UNKNOWN) 17469 { 17470 time_limit = get_tv_number_chk(&argvars[6], NULL); 17471 if (time_limit < 0) 17472 goto theend; 17473 } 17474 #endif 17475 } 17476 } 17477 if (skip == NULL) 17478 goto theend; /* type error */ 17479 17480 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 17481 match_pos, lnum_stop, time_limit); 17482 17483 theend: 17484 p_ws = save_p_ws; 17485 17486 return retval; 17487 } 17488 17489 /* 17490 * "searchpair()" function 17491 */ 17492 static void 17493 f_searchpair(typval_T *argvars, typval_T *rettv) 17494 { 17495 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 17496 } 17497 17498 /* 17499 * "searchpairpos()" function 17500 */ 17501 static void 17502 f_searchpairpos(typval_T *argvars, typval_T *rettv) 17503 { 17504 pos_T match_pos; 17505 int lnum = 0; 17506 int col = 0; 17507 17508 if (rettv_list_alloc(rettv) == FAIL) 17509 return; 17510 17511 if (searchpair_cmn(argvars, &match_pos) > 0) 17512 { 17513 lnum = match_pos.lnum; 17514 col = match_pos.col; 17515 } 17516 17517 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 17518 list_append_number(rettv->vval.v_list, (varnumber_T)col); 17519 } 17520 17521 /* 17522 * Search for a start/middle/end thing. 17523 * Used by searchpair(), see its documentation for the details. 17524 * Returns 0 or -1 for no match, 17525 */ 17526 long 17527 do_searchpair( 17528 char_u *spat, /* start pattern */ 17529 char_u *mpat, /* middle pattern */ 17530 char_u *epat, /* end pattern */ 17531 int dir, /* BACKWARD or FORWARD */ 17532 char_u *skip, /* skip expression */ 17533 int flags, /* SP_SETPCMARK and other SP_ values */ 17534 pos_T *match_pos, 17535 linenr_T lnum_stop, /* stop at this line if not zero */ 17536 long time_limit UNUSED) /* stop after this many msec */ 17537 { 17538 char_u *save_cpo; 17539 char_u *pat, *pat2 = NULL, *pat3 = NULL; 17540 long retval = 0; 17541 pos_T pos; 17542 pos_T firstpos; 17543 pos_T foundpos; 17544 pos_T save_cursor; 17545 pos_T save_pos; 17546 int n; 17547 int r; 17548 int nest = 1; 17549 int err; 17550 int options = SEARCH_KEEP; 17551 proftime_T tm; 17552 17553 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 17554 save_cpo = p_cpo; 17555 p_cpo = empty_option; 17556 17557 #ifdef FEAT_RELTIME 17558 /* Set the time limit, if there is one. */ 17559 profile_setlimit(time_limit, &tm); 17560 #endif 17561 17562 /* Make two search patterns: start/end (pat2, for in nested pairs) and 17563 * start/middle/end (pat3, for the top pair). */ 17564 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 17565 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 17566 if (pat2 == NULL || pat3 == NULL) 17567 goto theend; 17568 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 17569 if (*mpat == NUL) 17570 STRCPY(pat3, pat2); 17571 else 17572 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 17573 spat, epat, mpat); 17574 if (flags & SP_START) 17575 options |= SEARCH_START; 17576 17577 save_cursor = curwin->w_cursor; 17578 pos = curwin->w_cursor; 17579 clearpos(&firstpos); 17580 clearpos(&foundpos); 17581 pat = pat3; 17582 for (;;) 17583 { 17584 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 17585 options, RE_SEARCH, lnum_stop, &tm); 17586 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 17587 /* didn't find it or found the first match again: FAIL */ 17588 break; 17589 17590 if (firstpos.lnum == 0) 17591 firstpos = pos; 17592 if (equalpos(pos, foundpos)) 17593 { 17594 /* Found the same position again. Can happen with a pattern that 17595 * has "\zs" at the end and searching backwards. Advance one 17596 * character and try again. */ 17597 if (dir == BACKWARD) 17598 decl(&pos); 17599 else 17600 incl(&pos); 17601 } 17602 foundpos = pos; 17603 17604 /* clear the start flag to avoid getting stuck here */ 17605 options &= ~SEARCH_START; 17606 17607 /* If the skip pattern matches, ignore this match. */ 17608 if (*skip != NUL) 17609 { 17610 save_pos = curwin->w_cursor; 17611 curwin->w_cursor = pos; 17612 r = eval_to_bool(skip, &err, NULL, FALSE); 17613 curwin->w_cursor = save_pos; 17614 if (err) 17615 { 17616 /* Evaluating {skip} caused an error, break here. */ 17617 curwin->w_cursor = save_cursor; 17618 retval = -1; 17619 break; 17620 } 17621 if (r) 17622 continue; 17623 } 17624 17625 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 17626 { 17627 /* Found end when searching backwards or start when searching 17628 * forward: nested pair. */ 17629 ++nest; 17630 pat = pat2; /* nested, don't search for middle */ 17631 } 17632 else 17633 { 17634 /* Found end when searching forward or start when searching 17635 * backward: end of (nested) pair; or found middle in outer pair. */ 17636 if (--nest == 1) 17637 pat = pat3; /* outer level, search for middle */ 17638 } 17639 17640 if (nest == 0) 17641 { 17642 /* Found the match: return matchcount or line number. */ 17643 if (flags & SP_RETCOUNT) 17644 ++retval; 17645 else 17646 retval = pos.lnum; 17647 if (flags & SP_SETPCMARK) 17648 setpcmark(); 17649 curwin->w_cursor = pos; 17650 if (!(flags & SP_REPEAT)) 17651 break; 17652 nest = 1; /* search for next unmatched */ 17653 } 17654 } 17655 17656 if (match_pos != NULL) 17657 { 17658 /* Store the match cursor position */ 17659 match_pos->lnum = curwin->w_cursor.lnum; 17660 match_pos->col = curwin->w_cursor.col + 1; 17661 } 17662 17663 /* If 'n' flag is used or search failed: restore cursor position. */ 17664 if ((flags & SP_NOMOVE) || retval == 0) 17665 curwin->w_cursor = save_cursor; 17666 17667 theend: 17668 vim_free(pat2); 17669 vim_free(pat3); 17670 if (p_cpo == empty_option) 17671 p_cpo = save_cpo; 17672 else 17673 /* Darn, evaluating the {skip} expression changed the value. */ 17674 free_string_option(save_cpo); 17675 17676 return retval; 17677 } 17678 17679 /* 17680 * "searchpos()" function 17681 */ 17682 static void 17683 f_searchpos(typval_T *argvars, typval_T *rettv) 17684 { 17685 pos_T match_pos; 17686 int lnum = 0; 17687 int col = 0; 17688 int n; 17689 int flags = 0; 17690 17691 if (rettv_list_alloc(rettv) == FAIL) 17692 return; 17693 17694 n = search_cmn(argvars, &match_pos, &flags); 17695 if (n > 0) 17696 { 17697 lnum = match_pos.lnum; 17698 col = match_pos.col; 17699 } 17700 17701 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 17702 list_append_number(rettv->vval.v_list, (varnumber_T)col); 17703 if (flags & SP_SUBPAT) 17704 list_append_number(rettv->vval.v_list, (varnumber_T)n); 17705 } 17706 17707 static void 17708 f_server2client(typval_T *argvars UNUSED, typval_T *rettv) 17709 { 17710 #ifdef FEAT_CLIENTSERVER 17711 char_u buf[NUMBUFLEN]; 17712 char_u *server = get_tv_string_chk(&argvars[0]); 17713 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 17714 17715 rettv->vval.v_number = -1; 17716 if (server == NULL || reply == NULL) 17717 return; 17718 if (check_restricted() || check_secure()) 17719 return; 17720 # ifdef FEAT_X11 17721 if (check_connection() == FAIL) 17722 return; 17723 # endif 17724 17725 if (serverSendReply(server, reply) < 0) 17726 { 17727 EMSG(_("E258: Unable to send to client")); 17728 return; 17729 } 17730 rettv->vval.v_number = 0; 17731 #else 17732 rettv->vval.v_number = -1; 17733 #endif 17734 } 17735 17736 static void 17737 f_serverlist(typval_T *argvars UNUSED, typval_T *rettv) 17738 { 17739 char_u *r = NULL; 17740 17741 #ifdef FEAT_CLIENTSERVER 17742 # ifdef WIN32 17743 r = serverGetVimNames(); 17744 # else 17745 make_connection(); 17746 if (X_DISPLAY != NULL) 17747 r = serverGetVimNames(X_DISPLAY); 17748 # endif 17749 #endif 17750 rettv->v_type = VAR_STRING; 17751 rettv->vval.v_string = r; 17752 } 17753 17754 /* 17755 * "setbufvar()" function 17756 */ 17757 static void 17758 f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) 17759 { 17760 buf_T *buf; 17761 aco_save_T aco; 17762 char_u *varname, *bufvarname; 17763 typval_T *varp; 17764 char_u nbuf[NUMBUFLEN]; 17765 17766 if (check_restricted() || check_secure()) 17767 return; 17768 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 17769 varname = get_tv_string_chk(&argvars[1]); 17770 buf = get_buf_tv(&argvars[0], FALSE); 17771 varp = &argvars[2]; 17772 17773 if (buf != NULL && varname != NULL && varp != NULL) 17774 { 17775 /* set curbuf to be our buf, temporarily */ 17776 aucmd_prepbuf(&aco, buf); 17777 17778 if (*varname == '&') 17779 { 17780 long numval; 17781 char_u *strval; 17782 int error = FALSE; 17783 17784 ++varname; 17785 numval = get_tv_number_chk(varp, &error); 17786 strval = get_tv_string_buf_chk(varp, nbuf); 17787 if (!error && strval != NULL) 17788 set_option_value(varname, numval, strval, OPT_LOCAL); 17789 } 17790 else 17791 { 17792 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 17793 if (bufvarname != NULL) 17794 { 17795 STRCPY(bufvarname, "b:"); 17796 STRCPY(bufvarname + 2, varname); 17797 set_var(bufvarname, varp, TRUE); 17798 vim_free(bufvarname); 17799 } 17800 } 17801 17802 /* reset notion of buffer */ 17803 aucmd_restbuf(&aco); 17804 } 17805 } 17806 17807 static void 17808 f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) 17809 { 17810 dict_T *d; 17811 dictitem_T *di; 17812 char_u *csearch; 17813 17814 if (argvars[0].v_type != VAR_DICT) 17815 { 17816 EMSG(_(e_dictreq)); 17817 return; 17818 } 17819 17820 if ((d = argvars[0].vval.v_dict) != NULL) 17821 { 17822 csearch = get_dict_string(d, (char_u *)"char", FALSE); 17823 if (csearch != NULL) 17824 { 17825 #ifdef FEAT_MBYTE 17826 if (enc_utf8) 17827 { 17828 int pcc[MAX_MCO]; 17829 int c = utfc_ptr2char(csearch, pcc); 17830 17831 set_last_csearch(c, csearch, utfc_ptr2len(csearch)); 17832 } 17833 else 17834 #endif 17835 set_last_csearch(PTR2CHAR(csearch), 17836 csearch, MB_PTR2LEN(csearch)); 17837 } 17838 17839 di = dict_find(d, (char_u *)"forward", -1); 17840 if (di != NULL) 17841 set_csearch_direction(get_tv_number(&di->di_tv) 17842 ? FORWARD : BACKWARD); 17843 17844 di = dict_find(d, (char_u *)"until", -1); 17845 if (di != NULL) 17846 set_csearch_until(!!get_tv_number(&di->di_tv)); 17847 } 17848 } 17849 17850 /* 17851 * "setcmdpos()" function 17852 */ 17853 static void 17854 f_setcmdpos(typval_T *argvars, typval_T *rettv) 17855 { 17856 int pos = (int)get_tv_number(&argvars[0]) - 1; 17857 17858 if (pos >= 0) 17859 rettv->vval.v_number = set_cmdline_pos(pos); 17860 } 17861 17862 /* 17863 * "setfperm({fname}, {mode})" function 17864 */ 17865 static void 17866 f_setfperm(typval_T *argvars, typval_T *rettv) 17867 { 17868 char_u *fname; 17869 char_u modebuf[NUMBUFLEN]; 17870 char_u *mode_str; 17871 int i; 17872 int mask; 17873 int mode = 0; 17874 17875 rettv->vval.v_number = 0; 17876 fname = get_tv_string_chk(&argvars[0]); 17877 if (fname == NULL) 17878 return; 17879 mode_str = get_tv_string_buf_chk(&argvars[1], modebuf); 17880 if (mode_str == NULL) 17881 return; 17882 if (STRLEN(mode_str) != 9) 17883 { 17884 EMSG2(_(e_invarg2), mode_str); 17885 return; 17886 } 17887 17888 mask = 1; 17889 for (i = 8; i >= 0; --i) 17890 { 17891 if (mode_str[i] != '-') 17892 mode |= mask; 17893 mask = mask << 1; 17894 } 17895 rettv->vval.v_number = mch_setperm(fname, mode) == OK; 17896 } 17897 17898 /* 17899 * "setline()" function 17900 */ 17901 static void 17902 f_setline(typval_T *argvars, typval_T *rettv) 17903 { 17904 linenr_T lnum; 17905 char_u *line = NULL; 17906 list_T *l = NULL; 17907 listitem_T *li = NULL; 17908 long added = 0; 17909 linenr_T lcount = curbuf->b_ml.ml_line_count; 17910 17911 lnum = get_tv_lnum(&argvars[0]); 17912 if (argvars[1].v_type == VAR_LIST) 17913 { 17914 l = argvars[1].vval.v_list; 17915 li = l->lv_first; 17916 } 17917 else 17918 line = get_tv_string_chk(&argvars[1]); 17919 17920 /* default result is zero == OK */ 17921 for (;;) 17922 { 17923 if (l != NULL) 17924 { 17925 /* list argument, get next string */ 17926 if (li == NULL) 17927 break; 17928 line = get_tv_string_chk(&li->li_tv); 17929 li = li->li_next; 17930 } 17931 17932 rettv->vval.v_number = 1; /* FAIL */ 17933 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 17934 break; 17935 17936 /* When coming here from Insert mode, sync undo, so that this can be 17937 * undone separately from what was previously inserted. */ 17938 if (u_sync_once == 2) 17939 { 17940 u_sync_once = 1; /* notify that u_sync() was called */ 17941 u_sync(TRUE); 17942 } 17943 17944 if (lnum <= curbuf->b_ml.ml_line_count) 17945 { 17946 /* existing line, replace it */ 17947 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 17948 { 17949 changed_bytes(lnum, 0); 17950 if (lnum == curwin->w_cursor.lnum) 17951 check_cursor_col(); 17952 rettv->vval.v_number = 0; /* OK */ 17953 } 17954 } 17955 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 17956 { 17957 /* lnum is one past the last line, append the line */ 17958 ++added; 17959 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 17960 rettv->vval.v_number = 0; /* OK */ 17961 } 17962 17963 if (l == NULL) /* only one string argument */ 17964 break; 17965 ++lnum; 17966 } 17967 17968 if (added > 0) 17969 appended_lines_mark(lcount, added); 17970 } 17971 17972 static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv); 17973 17974 /* 17975 * Used by "setqflist()" and "setloclist()" functions 17976 */ 17977 static void 17978 set_qf_ll_list( 17979 win_T *wp UNUSED, 17980 typval_T *list_arg UNUSED, 17981 typval_T *action_arg UNUSED, 17982 typval_T *rettv) 17983 { 17984 #ifdef FEAT_QUICKFIX 17985 char_u *act; 17986 int action = ' '; 17987 #endif 17988 17989 rettv->vval.v_number = -1; 17990 17991 #ifdef FEAT_QUICKFIX 17992 if (list_arg->v_type != VAR_LIST) 17993 EMSG(_(e_listreq)); 17994 else 17995 { 17996 list_T *l = list_arg->vval.v_list; 17997 17998 if (action_arg->v_type == VAR_STRING) 17999 { 18000 act = get_tv_string_chk(action_arg); 18001 if (act == NULL) 18002 return; /* type error; errmsg already given */ 18003 if (*act == 'a' || *act == 'r') 18004 action = *act; 18005 } 18006 18007 if (l != NULL && set_errorlist(wp, l, action, 18008 (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK) 18009 rettv->vval.v_number = 0; 18010 } 18011 #endif 18012 } 18013 18014 /* 18015 * "setloclist()" function 18016 */ 18017 static void 18018 f_setloclist(typval_T *argvars, typval_T *rettv) 18019 { 18020 win_T *win; 18021 18022 rettv->vval.v_number = -1; 18023 18024 win = find_win_by_nr(&argvars[0], NULL); 18025 if (win != NULL) 18026 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 18027 } 18028 18029 /* 18030 * "setmatches()" function 18031 */ 18032 static void 18033 f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 18034 { 18035 #ifdef FEAT_SEARCH_EXTRA 18036 list_T *l; 18037 listitem_T *li; 18038 dict_T *d; 18039 list_T *s = NULL; 18040 18041 rettv->vval.v_number = -1; 18042 if (argvars[0].v_type != VAR_LIST) 18043 { 18044 EMSG(_(e_listreq)); 18045 return; 18046 } 18047 if ((l = argvars[0].vval.v_list) != NULL) 18048 { 18049 18050 /* To some extent make sure that we are dealing with a list from 18051 * "getmatches()". */ 18052 li = l->lv_first; 18053 while (li != NULL) 18054 { 18055 if (li->li_tv.v_type != VAR_DICT 18056 || (d = li->li_tv.vval.v_dict) == NULL) 18057 { 18058 EMSG(_(e_invarg)); 18059 return; 18060 } 18061 if (!(dict_find(d, (char_u *)"group", -1) != NULL 18062 && (dict_find(d, (char_u *)"pattern", -1) != NULL 18063 || dict_find(d, (char_u *)"pos1", -1) != NULL) 18064 && dict_find(d, (char_u *)"priority", -1) != NULL 18065 && dict_find(d, (char_u *)"id", -1) != NULL)) 18066 { 18067 EMSG(_(e_invarg)); 18068 return; 18069 } 18070 li = li->li_next; 18071 } 18072 18073 clear_matches(curwin); 18074 li = l->lv_first; 18075 while (li != NULL) 18076 { 18077 int i = 0; 18078 char_u buf[5]; 18079 dictitem_T *di; 18080 char_u *group; 18081 int priority; 18082 int id; 18083 char_u *conceal; 18084 18085 d = li->li_tv.vval.v_dict; 18086 if (dict_find(d, (char_u *)"pattern", -1) == NULL) 18087 { 18088 if (s == NULL) 18089 { 18090 s = list_alloc(); 18091 if (s == NULL) 18092 return; 18093 } 18094 18095 /* match from matchaddpos() */ 18096 for (i = 1; i < 9; i++) 18097 { 18098 sprintf((char *)buf, (char *)"pos%d", i); 18099 if ((di = dict_find(d, (char_u *)buf, -1)) != NULL) 18100 { 18101 if (di->di_tv.v_type != VAR_LIST) 18102 return; 18103 18104 list_append_tv(s, &di->di_tv); 18105 s->lv_refcount++; 18106 } 18107 else 18108 break; 18109 } 18110 } 18111 18112 group = get_dict_string(d, (char_u *)"group", FALSE); 18113 priority = (int)get_dict_number(d, (char_u *)"priority"); 18114 id = (int)get_dict_number(d, (char_u *)"id"); 18115 conceal = dict_find(d, (char_u *)"conceal", -1) != NULL 18116 ? get_dict_string(d, (char_u *)"conceal", FALSE) 18117 : NULL; 18118 if (i == 0) 18119 { 18120 match_add(curwin, group, 18121 get_dict_string(d, (char_u *)"pattern", FALSE), 18122 priority, id, NULL, conceal); 18123 } 18124 else 18125 { 18126 match_add(curwin, group, NULL, priority, id, s, conceal); 18127 list_unref(s); 18128 s = NULL; 18129 } 18130 18131 li = li->li_next; 18132 } 18133 rettv->vval.v_number = 0; 18134 } 18135 #endif 18136 } 18137 18138 /* 18139 * "setpos()" function 18140 */ 18141 static void 18142 f_setpos(typval_T *argvars, typval_T *rettv) 18143 { 18144 pos_T pos; 18145 int fnum; 18146 char_u *name; 18147 colnr_T curswant = -1; 18148 18149 rettv->vval.v_number = -1; 18150 name = get_tv_string_chk(argvars); 18151 if (name != NULL) 18152 { 18153 if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) 18154 { 18155 if (--pos.col < 0) 18156 pos.col = 0; 18157 if (name[0] == '.' && name[1] == NUL) 18158 { 18159 /* set cursor */ 18160 if (fnum == curbuf->b_fnum) 18161 { 18162 curwin->w_cursor = pos; 18163 if (curswant >= 0) 18164 { 18165 curwin->w_curswant = curswant - 1; 18166 curwin->w_set_curswant = FALSE; 18167 } 18168 check_cursor(); 18169 rettv->vval.v_number = 0; 18170 } 18171 else 18172 EMSG(_(e_invarg)); 18173 } 18174 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 18175 { 18176 /* set mark */ 18177 if (setmark_pos(name[1], &pos, fnum) == OK) 18178 rettv->vval.v_number = 0; 18179 } 18180 else 18181 EMSG(_(e_invarg)); 18182 } 18183 } 18184 } 18185 18186 /* 18187 * "setqflist()" function 18188 */ 18189 static void 18190 f_setqflist(typval_T *argvars, typval_T *rettv) 18191 { 18192 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 18193 } 18194 18195 /* 18196 * "setreg()" function 18197 */ 18198 static void 18199 f_setreg(typval_T *argvars, typval_T *rettv) 18200 { 18201 int regname; 18202 char_u *strregname; 18203 char_u *stropt; 18204 char_u *strval; 18205 int append; 18206 char_u yank_type; 18207 long block_len; 18208 18209 block_len = -1; 18210 yank_type = MAUTO; 18211 append = FALSE; 18212 18213 strregname = get_tv_string_chk(argvars); 18214 rettv->vval.v_number = 1; /* FAIL is default */ 18215 18216 if (strregname == NULL) 18217 return; /* type error; errmsg already given */ 18218 regname = *strregname; 18219 if (regname == 0 || regname == '@') 18220 regname = '"'; 18221 18222 if (argvars[2].v_type != VAR_UNKNOWN) 18223 { 18224 stropt = get_tv_string_chk(&argvars[2]); 18225 if (stropt == NULL) 18226 return; /* type error */ 18227 for (; *stropt != NUL; ++stropt) 18228 switch (*stropt) 18229 { 18230 case 'a': case 'A': /* append */ 18231 append = TRUE; 18232 break; 18233 case 'v': case 'c': /* character-wise selection */ 18234 yank_type = MCHAR; 18235 break; 18236 case 'V': case 'l': /* line-wise selection */ 18237 yank_type = MLINE; 18238 break; 18239 case 'b': case Ctrl_V: /* block-wise selection */ 18240 yank_type = MBLOCK; 18241 if (VIM_ISDIGIT(stropt[1])) 18242 { 18243 ++stropt; 18244 block_len = getdigits(&stropt) - 1; 18245 --stropt; 18246 } 18247 break; 18248 } 18249 } 18250 18251 if (argvars[1].v_type == VAR_LIST) 18252 { 18253 char_u **lstval; 18254 char_u **allocval; 18255 char_u buf[NUMBUFLEN]; 18256 char_u **curval; 18257 char_u **curallocval; 18258 int len = argvars[1].vval.v_list->lv_len; 18259 listitem_T *li; 18260 18261 /* First half: use for pointers to result lines; second half: use for 18262 * pointers to allocated copies. */ 18263 lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2)); 18264 if (lstval == NULL) 18265 return; 18266 curval = lstval; 18267 allocval = lstval + len + 2; 18268 curallocval = allocval; 18269 18270 for (li = argvars[1].vval.v_list->lv_first; li != NULL; 18271 li = li->li_next) 18272 { 18273 strval = get_tv_string_buf_chk(&li->li_tv, buf); 18274 if (strval == NULL) 18275 goto free_lstval; 18276 if (strval == buf) 18277 { 18278 /* Need to make a copy, next get_tv_string_buf_chk() will 18279 * overwrite the string. */ 18280 strval = vim_strsave(buf); 18281 if (strval == NULL) 18282 goto free_lstval; 18283 *curallocval++ = strval; 18284 } 18285 *curval++ = strval; 18286 } 18287 *curval++ = NULL; 18288 18289 write_reg_contents_lst(regname, lstval, -1, 18290 append, yank_type, block_len); 18291 free_lstval: 18292 while (curallocval > allocval) 18293 vim_free(*--curallocval); 18294 vim_free(lstval); 18295 } 18296 else 18297 { 18298 strval = get_tv_string_chk(&argvars[1]); 18299 if (strval == NULL) 18300 return; 18301 write_reg_contents_ex(regname, strval, -1, 18302 append, yank_type, block_len); 18303 } 18304 rettv->vval.v_number = 0; 18305 } 18306 18307 /* 18308 * "settabvar()" function 18309 */ 18310 static void 18311 f_settabvar(typval_T *argvars, typval_T *rettv) 18312 { 18313 #ifdef FEAT_WINDOWS 18314 tabpage_T *save_curtab; 18315 tabpage_T *tp; 18316 #endif 18317 char_u *varname, *tabvarname; 18318 typval_T *varp; 18319 18320 rettv->vval.v_number = 0; 18321 18322 if (check_restricted() || check_secure()) 18323 return; 18324 18325 #ifdef FEAT_WINDOWS 18326 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 18327 #endif 18328 varname = get_tv_string_chk(&argvars[1]); 18329 varp = &argvars[2]; 18330 18331 if (varname != NULL && varp != NULL 18332 #ifdef FEAT_WINDOWS 18333 && tp != NULL 18334 #endif 18335 ) 18336 { 18337 #ifdef FEAT_WINDOWS 18338 save_curtab = curtab; 18339 goto_tabpage_tp(tp, FALSE, FALSE); 18340 #endif 18341 18342 tabvarname = alloc((unsigned)STRLEN(varname) + 3); 18343 if (tabvarname != NULL) 18344 { 18345 STRCPY(tabvarname, "t:"); 18346 STRCPY(tabvarname + 2, varname); 18347 set_var(tabvarname, varp, TRUE); 18348 vim_free(tabvarname); 18349 } 18350 18351 #ifdef FEAT_WINDOWS 18352 /* Restore current tabpage */ 18353 if (valid_tabpage(save_curtab)) 18354 goto_tabpage_tp(save_curtab, FALSE, FALSE); 18355 #endif 18356 } 18357 } 18358 18359 /* 18360 * "settabwinvar()" function 18361 */ 18362 static void 18363 f_settabwinvar(typval_T *argvars, typval_T *rettv) 18364 { 18365 setwinvar(argvars, rettv, 1); 18366 } 18367 18368 /* 18369 * "setwinvar()" function 18370 */ 18371 static void 18372 f_setwinvar(typval_T *argvars, typval_T *rettv) 18373 { 18374 setwinvar(argvars, rettv, 0); 18375 } 18376 18377 /* 18378 * "setwinvar()" and "settabwinvar()" functions 18379 */ 18380 18381 static void 18382 setwinvar(typval_T *argvars, typval_T *rettv UNUSED, int off) 18383 { 18384 win_T *win; 18385 #ifdef FEAT_WINDOWS 18386 win_T *save_curwin; 18387 tabpage_T *save_curtab; 18388 int need_switch_win; 18389 #endif 18390 char_u *varname, *winvarname; 18391 typval_T *varp; 18392 char_u nbuf[NUMBUFLEN]; 18393 tabpage_T *tp = NULL; 18394 18395 if (check_restricted() || check_secure()) 18396 return; 18397 18398 #ifdef FEAT_WINDOWS 18399 if (off == 1) 18400 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 18401 else 18402 tp = curtab; 18403 #endif 18404 win = find_win_by_nr(&argvars[off], tp); 18405 varname = get_tv_string_chk(&argvars[off + 1]); 18406 varp = &argvars[off + 2]; 18407 18408 if (win != NULL && varname != NULL && varp != NULL) 18409 { 18410 #ifdef FEAT_WINDOWS 18411 need_switch_win = !(tp == curtab && win == curwin); 18412 if (!need_switch_win 18413 || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) 18414 #endif 18415 { 18416 if (*varname == '&') 18417 { 18418 long numval; 18419 char_u *strval; 18420 int error = FALSE; 18421 18422 ++varname; 18423 numval = get_tv_number_chk(varp, &error); 18424 strval = get_tv_string_buf_chk(varp, nbuf); 18425 if (!error && strval != NULL) 18426 set_option_value(varname, numval, strval, OPT_LOCAL); 18427 } 18428 else 18429 { 18430 winvarname = alloc((unsigned)STRLEN(varname) + 3); 18431 if (winvarname != NULL) 18432 { 18433 STRCPY(winvarname, "w:"); 18434 STRCPY(winvarname + 2, varname); 18435 set_var(winvarname, varp, TRUE); 18436 vim_free(winvarname); 18437 } 18438 } 18439 } 18440 #ifdef FEAT_WINDOWS 18441 if (need_switch_win) 18442 restore_win(save_curwin, save_curtab, TRUE); 18443 #endif 18444 } 18445 } 18446 18447 #ifdef FEAT_CRYPT 18448 /* 18449 * "sha256({string})" function 18450 */ 18451 static void 18452 f_sha256(typval_T *argvars, typval_T *rettv) 18453 { 18454 char_u *p; 18455 18456 p = get_tv_string(&argvars[0]); 18457 rettv->vval.v_string = vim_strsave( 18458 sha256_bytes(p, (int)STRLEN(p), NULL, 0)); 18459 rettv->v_type = VAR_STRING; 18460 } 18461 #endif /* FEAT_CRYPT */ 18462 18463 /* 18464 * "shellescape({string})" function 18465 */ 18466 static void 18467 f_shellescape(typval_T *argvars, typval_T *rettv) 18468 { 18469 rettv->vval.v_string = vim_strsave_shellescape( 18470 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), TRUE); 18471 rettv->v_type = VAR_STRING; 18472 } 18473 18474 /* 18475 * shiftwidth() function 18476 */ 18477 static void 18478 f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv) 18479 { 18480 rettv->vval.v_number = get_sw_value(curbuf); 18481 } 18482 18483 /* 18484 * "simplify()" function 18485 */ 18486 static void 18487 f_simplify(typval_T *argvars, typval_T *rettv) 18488 { 18489 char_u *p; 18490 18491 p = get_tv_string(&argvars[0]); 18492 rettv->vval.v_string = vim_strsave(p); 18493 simplify_filename(rettv->vval.v_string); /* simplify in place */ 18494 rettv->v_type = VAR_STRING; 18495 } 18496 18497 #ifdef FEAT_FLOAT 18498 /* 18499 * "sin()" function 18500 */ 18501 static void 18502 f_sin(typval_T *argvars, typval_T *rettv) 18503 { 18504 float_T f = 0.0; 18505 18506 rettv->v_type = VAR_FLOAT; 18507 if (get_float_arg(argvars, &f) == OK) 18508 rettv->vval.v_float = sin(f); 18509 else 18510 rettv->vval.v_float = 0.0; 18511 } 18512 18513 /* 18514 * "sinh()" function 18515 */ 18516 static void 18517 f_sinh(typval_T *argvars, typval_T *rettv) 18518 { 18519 float_T f = 0.0; 18520 18521 rettv->v_type = VAR_FLOAT; 18522 if (get_float_arg(argvars, &f) == OK) 18523 rettv->vval.v_float = sinh(f); 18524 else 18525 rettv->vval.v_float = 0.0; 18526 } 18527 #endif 18528 18529 static int 18530 #ifdef __BORLANDC__ 18531 _RTLENTRYF 18532 #endif 18533 item_compare(const void *s1, const void *s2); 18534 static int 18535 #ifdef __BORLANDC__ 18536 _RTLENTRYF 18537 #endif 18538 item_compare2(const void *s1, const void *s2); 18539 18540 /* struct used in the array that's given to qsort() */ 18541 typedef struct 18542 { 18543 listitem_T *item; 18544 int idx; 18545 } sortItem_T; 18546 18547 /* struct storing information about current sort */ 18548 typedef struct 18549 { 18550 int item_compare_ic; 18551 int item_compare_numeric; 18552 int item_compare_numbers; 18553 #ifdef FEAT_FLOAT 18554 int item_compare_float; 18555 #endif 18556 char_u *item_compare_func; 18557 partial_T *item_compare_partial; 18558 dict_T *item_compare_selfdict; 18559 int item_compare_func_err; 18560 int item_compare_keep_zero; 18561 } sortinfo_T; 18562 static sortinfo_T *sortinfo = NULL; 18563 static void do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort); 18564 #define ITEM_COMPARE_FAIL 999 18565 18566 /* 18567 * Compare functions for f_sort() and f_uniq() below. 18568 */ 18569 static int 18570 #ifdef __BORLANDC__ 18571 _RTLENTRYF 18572 #endif 18573 item_compare(const void *s1, const void *s2) 18574 { 18575 sortItem_T *si1, *si2; 18576 typval_T *tv1, *tv2; 18577 char_u *p1, *p2; 18578 char_u *tofree1 = NULL, *tofree2 = NULL; 18579 int res; 18580 char_u numbuf1[NUMBUFLEN]; 18581 char_u numbuf2[NUMBUFLEN]; 18582 18583 si1 = (sortItem_T *)s1; 18584 si2 = (sortItem_T *)s2; 18585 tv1 = &si1->item->li_tv; 18586 tv2 = &si2->item->li_tv; 18587 18588 if (sortinfo->item_compare_numbers) 18589 { 18590 long v1 = get_tv_number(tv1); 18591 long v2 = get_tv_number(tv2); 18592 18593 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 18594 } 18595 18596 #ifdef FEAT_FLOAT 18597 if (sortinfo->item_compare_float) 18598 { 18599 float_T v1 = get_tv_float(tv1); 18600 float_T v2 = get_tv_float(tv2); 18601 18602 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 18603 } 18604 #endif 18605 18606 /* tv2string() puts quotes around a string and allocates memory. Don't do 18607 * that for string variables. Use a single quote when comparing with a 18608 * non-string to do what the docs promise. */ 18609 if (tv1->v_type == VAR_STRING) 18610 { 18611 if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) 18612 p1 = (char_u *)"'"; 18613 else 18614 p1 = tv1->vval.v_string; 18615 } 18616 else 18617 p1 = tv2string(tv1, &tofree1, numbuf1, 0); 18618 if (tv2->v_type == VAR_STRING) 18619 { 18620 if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) 18621 p2 = (char_u *)"'"; 18622 else 18623 p2 = tv2->vval.v_string; 18624 } 18625 else 18626 p2 = tv2string(tv2, &tofree2, numbuf2, 0); 18627 if (p1 == NULL) 18628 p1 = (char_u *)""; 18629 if (p2 == NULL) 18630 p2 = (char_u *)""; 18631 if (!sortinfo->item_compare_numeric) 18632 { 18633 if (sortinfo->item_compare_ic) 18634 res = STRICMP(p1, p2); 18635 else 18636 res = STRCMP(p1, p2); 18637 } 18638 else 18639 { 18640 double n1, n2; 18641 n1 = strtod((char *)p1, (char **)&p1); 18642 n2 = strtod((char *)p2, (char **)&p2); 18643 res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1; 18644 } 18645 18646 /* When the result would be zero, compare the item indexes. Makes the 18647 * sort stable. */ 18648 if (res == 0 && !sortinfo->item_compare_keep_zero) 18649 res = si1->idx > si2->idx ? 1 : -1; 18650 18651 vim_free(tofree1); 18652 vim_free(tofree2); 18653 return res; 18654 } 18655 18656 static int 18657 #ifdef __BORLANDC__ 18658 _RTLENTRYF 18659 #endif 18660 item_compare2(const void *s1, const void *s2) 18661 { 18662 sortItem_T *si1, *si2; 18663 int res; 18664 typval_T rettv; 18665 typval_T argv[3]; 18666 int dummy; 18667 char_u *func_name; 18668 partial_T *partial = sortinfo->item_compare_partial; 18669 18670 /* shortcut after failure in previous call; compare all items equal */ 18671 if (sortinfo->item_compare_func_err) 18672 return 0; 18673 18674 si1 = (sortItem_T *)s1; 18675 si2 = (sortItem_T *)s2; 18676 18677 if (partial == NULL) 18678 func_name = sortinfo->item_compare_func; 18679 else 18680 func_name = partial->pt_name; 18681 18682 /* Copy the values. This is needed to be able to set v_lock to VAR_FIXED 18683 * in the copy without changing the original list items. */ 18684 copy_tv(&si1->item->li_tv, &argv[0]); 18685 copy_tv(&si2->item->li_tv, &argv[1]); 18686 18687 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 18688 res = call_func(func_name, (int)STRLEN(func_name), 18689 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, 18690 partial, sortinfo->item_compare_selfdict); 18691 clear_tv(&argv[0]); 18692 clear_tv(&argv[1]); 18693 18694 if (res == FAIL) 18695 res = ITEM_COMPARE_FAIL; 18696 else 18697 res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err); 18698 if (sortinfo->item_compare_func_err) 18699 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 18700 clear_tv(&rettv); 18701 18702 /* When the result would be zero, compare the pointers themselves. Makes 18703 * the sort stable. */ 18704 if (res == 0 && !sortinfo->item_compare_keep_zero) 18705 res = si1->idx > si2->idx ? 1 : -1; 18706 18707 return res; 18708 } 18709 18710 /* 18711 * "sort({list})" function 18712 */ 18713 static void 18714 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort) 18715 { 18716 list_T *l; 18717 listitem_T *li; 18718 sortItem_T *ptrs; 18719 sortinfo_T *old_sortinfo; 18720 sortinfo_T info; 18721 long len; 18722 long i; 18723 18724 /* Pointer to current info struct used in compare function. Save and 18725 * restore the current one for nested calls. */ 18726 old_sortinfo = sortinfo; 18727 sortinfo = &info; 18728 18729 if (argvars[0].v_type != VAR_LIST) 18730 EMSG2(_(e_listarg), sort ? "sort()" : "uniq()"); 18731 else 18732 { 18733 l = argvars[0].vval.v_list; 18734 if (l == NULL || tv_check_lock(l->lv_lock, 18735 (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")), 18736 TRUE)) 18737 goto theend; 18738 rettv->vval.v_list = l; 18739 rettv->v_type = VAR_LIST; 18740 ++l->lv_refcount; 18741 18742 len = list_len(l); 18743 if (len <= 1) 18744 goto theend; /* short list sorts pretty quickly */ 18745 18746 info.item_compare_ic = FALSE; 18747 info.item_compare_numeric = FALSE; 18748 info.item_compare_numbers = FALSE; 18749 #ifdef FEAT_FLOAT 18750 info.item_compare_float = FALSE; 18751 #endif 18752 info.item_compare_func = NULL; 18753 info.item_compare_partial = NULL; 18754 info.item_compare_selfdict = NULL; 18755 if (argvars[1].v_type != VAR_UNKNOWN) 18756 { 18757 /* optional second argument: {func} */ 18758 if (argvars[1].v_type == VAR_FUNC) 18759 info.item_compare_func = argvars[1].vval.v_string; 18760 else if (argvars[1].v_type == VAR_PARTIAL) 18761 info.item_compare_partial = argvars[1].vval.v_partial; 18762 else 18763 { 18764 int error = FALSE; 18765 18766 i = get_tv_number_chk(&argvars[1], &error); 18767 if (error) 18768 goto theend; /* type error; errmsg already given */ 18769 if (i == 1) 18770 info.item_compare_ic = TRUE; 18771 else if (argvars[1].v_type != VAR_NUMBER) 18772 info.item_compare_func = get_tv_string(&argvars[1]); 18773 else if (i != 0) 18774 { 18775 EMSG(_(e_invarg)); 18776 goto theend; 18777 } 18778 if (info.item_compare_func != NULL) 18779 { 18780 if (*info.item_compare_func == NUL) 18781 { 18782 /* empty string means default sort */ 18783 info.item_compare_func = NULL; 18784 } 18785 else if (STRCMP(info.item_compare_func, "n") == 0) 18786 { 18787 info.item_compare_func = NULL; 18788 info.item_compare_numeric = TRUE; 18789 } 18790 else if (STRCMP(info.item_compare_func, "N") == 0) 18791 { 18792 info.item_compare_func = NULL; 18793 info.item_compare_numbers = TRUE; 18794 } 18795 #ifdef FEAT_FLOAT 18796 else if (STRCMP(info.item_compare_func, "f") == 0) 18797 { 18798 info.item_compare_func = NULL; 18799 info.item_compare_float = TRUE; 18800 } 18801 #endif 18802 else if (STRCMP(info.item_compare_func, "i") == 0) 18803 { 18804 info.item_compare_func = NULL; 18805 info.item_compare_ic = TRUE; 18806 } 18807 } 18808 } 18809 18810 if (argvars[2].v_type != VAR_UNKNOWN) 18811 { 18812 /* optional third argument: {dict} */ 18813 if (argvars[2].v_type != VAR_DICT) 18814 { 18815 EMSG(_(e_dictreq)); 18816 goto theend; 18817 } 18818 info.item_compare_selfdict = argvars[2].vval.v_dict; 18819 } 18820 } 18821 18822 /* Make an array with each entry pointing to an item in the List. */ 18823 ptrs = (sortItem_T *)alloc((int)(len * sizeof(sortItem_T))); 18824 if (ptrs == NULL) 18825 goto theend; 18826 18827 i = 0; 18828 if (sort) 18829 { 18830 /* sort(): ptrs will be the list to sort */ 18831 for (li = l->lv_first; li != NULL; li = li->li_next) 18832 { 18833 ptrs[i].item = li; 18834 ptrs[i].idx = i; 18835 ++i; 18836 } 18837 18838 info.item_compare_func_err = FALSE; 18839 info.item_compare_keep_zero = FALSE; 18840 /* test the compare function */ 18841 if ((info.item_compare_func != NULL 18842 || info.item_compare_partial != NULL) 18843 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 18844 == ITEM_COMPARE_FAIL) 18845 EMSG(_("E702: Sort compare function failed")); 18846 else 18847 { 18848 /* Sort the array with item pointers. */ 18849 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T), 18850 info.item_compare_func == NULL 18851 && info.item_compare_partial == NULL 18852 ? item_compare : item_compare2); 18853 18854 if (!info.item_compare_func_err) 18855 { 18856 /* Clear the List and append the items in sorted order. */ 18857 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 18858 l->lv_len = 0; 18859 for (i = 0; i < len; ++i) 18860 list_append(l, ptrs[i].item); 18861 } 18862 } 18863 } 18864 else 18865 { 18866 int (*item_compare_func_ptr)(const void *, const void *); 18867 18868 /* f_uniq(): ptrs will be a stack of items to remove */ 18869 info.item_compare_func_err = FALSE; 18870 info.item_compare_keep_zero = TRUE; 18871 item_compare_func_ptr = info.item_compare_func != NULL 18872 || info.item_compare_partial != NULL 18873 ? item_compare2 : item_compare; 18874 18875 for (li = l->lv_first; li != NULL && li->li_next != NULL; 18876 li = li->li_next) 18877 { 18878 if (item_compare_func_ptr((void *)&li, (void *)&li->li_next) 18879 == 0) 18880 ptrs[i++].item = li; 18881 if (info.item_compare_func_err) 18882 { 18883 EMSG(_("E882: Uniq compare function failed")); 18884 break; 18885 } 18886 } 18887 18888 if (!info.item_compare_func_err) 18889 { 18890 while (--i >= 0) 18891 { 18892 li = ptrs[i].item->li_next; 18893 ptrs[i].item->li_next = li->li_next; 18894 if (li->li_next != NULL) 18895 li->li_next->li_prev = ptrs[i].item; 18896 else 18897 l->lv_last = ptrs[i].item; 18898 list_fix_watch(l, li); 18899 listitem_free(li); 18900 l->lv_len--; 18901 } 18902 } 18903 } 18904 18905 vim_free(ptrs); 18906 } 18907 theend: 18908 sortinfo = old_sortinfo; 18909 } 18910 18911 /* 18912 * "sort({list})" function 18913 */ 18914 static void 18915 f_sort(typval_T *argvars, typval_T *rettv) 18916 { 18917 do_sort_uniq(argvars, rettv, TRUE); 18918 } 18919 18920 /* 18921 * "uniq({list})" function 18922 */ 18923 static void 18924 f_uniq(typval_T *argvars, typval_T *rettv) 18925 { 18926 do_sort_uniq(argvars, rettv, FALSE); 18927 } 18928 18929 /* 18930 * "soundfold({word})" function 18931 */ 18932 static void 18933 f_soundfold(typval_T *argvars, typval_T *rettv) 18934 { 18935 char_u *s; 18936 18937 rettv->v_type = VAR_STRING; 18938 s = get_tv_string(&argvars[0]); 18939 #ifdef FEAT_SPELL 18940 rettv->vval.v_string = eval_soundfold(s); 18941 #else 18942 rettv->vval.v_string = vim_strsave(s); 18943 #endif 18944 } 18945 18946 /* 18947 * "spellbadword()" function 18948 */ 18949 static void 18950 f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv) 18951 { 18952 char_u *word = (char_u *)""; 18953 hlf_T attr = HLF_COUNT; 18954 int len = 0; 18955 18956 if (rettv_list_alloc(rettv) == FAIL) 18957 return; 18958 18959 #ifdef FEAT_SPELL 18960 if (argvars[0].v_type == VAR_UNKNOWN) 18961 { 18962 /* Find the start and length of the badly spelled word. */ 18963 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 18964 if (len != 0) 18965 word = ml_get_cursor(); 18966 } 18967 else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) 18968 { 18969 char_u *str = get_tv_string_chk(&argvars[0]); 18970 int capcol = -1; 18971 18972 if (str != NULL) 18973 { 18974 /* Check the argument for spelling. */ 18975 while (*str != NUL) 18976 { 18977 len = spell_check(curwin, str, &attr, &capcol, FALSE); 18978 if (attr != HLF_COUNT) 18979 { 18980 word = str; 18981 break; 18982 } 18983 str += len; 18984 } 18985 } 18986 } 18987 #endif 18988 18989 list_append_string(rettv->vval.v_list, word, len); 18990 list_append_string(rettv->vval.v_list, (char_u *)( 18991 attr == HLF_SPB ? "bad" : 18992 attr == HLF_SPR ? "rare" : 18993 attr == HLF_SPL ? "local" : 18994 attr == HLF_SPC ? "caps" : 18995 ""), -1); 18996 } 18997 18998 /* 18999 * "spellsuggest()" function 19000 */ 19001 static void 19002 f_spellsuggest(typval_T *argvars UNUSED, typval_T *rettv) 19003 { 19004 #ifdef FEAT_SPELL 19005 char_u *str; 19006 int typeerr = FALSE; 19007 int maxcount; 19008 garray_T ga; 19009 int i; 19010 listitem_T *li; 19011 int need_capital = FALSE; 19012 #endif 19013 19014 if (rettv_list_alloc(rettv) == FAIL) 19015 return; 19016 19017 #ifdef FEAT_SPELL 19018 if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) 19019 { 19020 str = get_tv_string(&argvars[0]); 19021 if (argvars[1].v_type != VAR_UNKNOWN) 19022 { 19023 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 19024 if (maxcount <= 0) 19025 return; 19026 if (argvars[2].v_type != VAR_UNKNOWN) 19027 { 19028 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 19029 if (typeerr) 19030 return; 19031 } 19032 } 19033 else 19034 maxcount = 25; 19035 19036 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 19037 19038 for (i = 0; i < ga.ga_len; ++i) 19039 { 19040 str = ((char_u **)ga.ga_data)[i]; 19041 19042 li = listitem_alloc(); 19043 if (li == NULL) 19044 vim_free(str); 19045 else 19046 { 19047 li->li_tv.v_type = VAR_STRING; 19048 li->li_tv.v_lock = 0; 19049 li->li_tv.vval.v_string = str; 19050 list_append(rettv->vval.v_list, li); 19051 } 19052 } 19053 ga_clear(&ga); 19054 } 19055 #endif 19056 } 19057 19058 static void 19059 f_split(typval_T *argvars, typval_T *rettv) 19060 { 19061 char_u *str; 19062 char_u *end; 19063 char_u *pat = NULL; 19064 regmatch_T regmatch; 19065 char_u patbuf[NUMBUFLEN]; 19066 char_u *save_cpo; 19067 int match; 19068 colnr_T col = 0; 19069 int keepempty = FALSE; 19070 int typeerr = FALSE; 19071 19072 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 19073 save_cpo = p_cpo; 19074 p_cpo = (char_u *)""; 19075 19076 str = get_tv_string(&argvars[0]); 19077 if (argvars[1].v_type != VAR_UNKNOWN) 19078 { 19079 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 19080 if (pat == NULL) 19081 typeerr = TRUE; 19082 if (argvars[2].v_type != VAR_UNKNOWN) 19083 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 19084 } 19085 if (pat == NULL || *pat == NUL) 19086 pat = (char_u *)"[\\x01- ]\\+"; 19087 19088 if (rettv_list_alloc(rettv) == FAIL) 19089 return; 19090 if (typeerr) 19091 return; 19092 19093 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19094 if (regmatch.regprog != NULL) 19095 { 19096 regmatch.rm_ic = FALSE; 19097 while (*str != NUL || keepempty) 19098 { 19099 if (*str == NUL) 19100 match = FALSE; /* empty item at the end */ 19101 else 19102 match = vim_regexec_nl(®match, str, col); 19103 if (match) 19104 end = regmatch.startp[0]; 19105 else 19106 end = str + STRLEN(str); 19107 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 19108 && *str != NUL && match && end < regmatch.endp[0])) 19109 { 19110 if (list_append_string(rettv->vval.v_list, str, 19111 (int)(end - str)) == FAIL) 19112 break; 19113 } 19114 if (!match) 19115 break; 19116 /* Advance to just after the match. */ 19117 if (regmatch.endp[0] > str) 19118 col = 0; 19119 else 19120 { 19121 /* Don't get stuck at the same match. */ 19122 #ifdef FEAT_MBYTE 19123 col = (*mb_ptr2len)(regmatch.endp[0]); 19124 #else 19125 col = 1; 19126 #endif 19127 } 19128 str = regmatch.endp[0]; 19129 } 19130 19131 vim_regfree(regmatch.regprog); 19132 } 19133 19134 p_cpo = save_cpo; 19135 } 19136 19137 #ifdef FEAT_FLOAT 19138 /* 19139 * "sqrt()" function 19140 */ 19141 static void 19142 f_sqrt(typval_T *argvars, typval_T *rettv) 19143 { 19144 float_T f = 0.0; 19145 19146 rettv->v_type = VAR_FLOAT; 19147 if (get_float_arg(argvars, &f) == OK) 19148 rettv->vval.v_float = sqrt(f); 19149 else 19150 rettv->vval.v_float = 0.0; 19151 } 19152 19153 /* 19154 * "str2float()" function 19155 */ 19156 static void 19157 f_str2float(typval_T *argvars, typval_T *rettv) 19158 { 19159 char_u *p = skipwhite(get_tv_string(&argvars[0])); 19160 19161 if (*p == '+') 19162 p = skipwhite(p + 1); 19163 (void)string2float(p, &rettv->vval.v_float); 19164 rettv->v_type = VAR_FLOAT; 19165 } 19166 #endif 19167 19168 /* 19169 * "str2nr()" function 19170 */ 19171 static void 19172 f_str2nr(typval_T *argvars, typval_T *rettv) 19173 { 19174 int base = 10; 19175 char_u *p; 19176 long n; 19177 int what; 19178 19179 if (argvars[1].v_type != VAR_UNKNOWN) 19180 { 19181 base = get_tv_number(&argvars[1]); 19182 if (base != 2 && base != 8 && base != 10 && base != 16) 19183 { 19184 EMSG(_(e_invarg)); 19185 return; 19186 } 19187 } 19188 19189 p = skipwhite(get_tv_string(&argvars[0])); 19190 if (*p == '+') 19191 p = skipwhite(p + 1); 19192 switch (base) 19193 { 19194 case 2: what = STR2NR_BIN + STR2NR_FORCE; break; 19195 case 8: what = STR2NR_OCT + STR2NR_FORCE; break; 19196 case 16: what = STR2NR_HEX + STR2NR_FORCE; break; 19197 default: what = 0; 19198 } 19199 vim_str2nr(p, NULL, NULL, what, &n, NULL, 0); 19200 rettv->vval.v_number = n; 19201 } 19202 19203 #ifdef HAVE_STRFTIME 19204 /* 19205 * "strftime({format}[, {time}])" function 19206 */ 19207 static void 19208 f_strftime(typval_T *argvars, typval_T *rettv) 19209 { 19210 char_u result_buf[256]; 19211 struct tm *curtime; 19212 time_t seconds; 19213 char_u *p; 19214 19215 rettv->v_type = VAR_STRING; 19216 19217 p = get_tv_string(&argvars[0]); 19218 if (argvars[1].v_type == VAR_UNKNOWN) 19219 seconds = time(NULL); 19220 else 19221 seconds = (time_t)get_tv_number(&argvars[1]); 19222 curtime = localtime(&seconds); 19223 /* MSVC returns NULL for an invalid value of seconds. */ 19224 if (curtime == NULL) 19225 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 19226 else 19227 { 19228 # ifdef FEAT_MBYTE 19229 vimconv_T conv; 19230 char_u *enc; 19231 19232 conv.vc_type = CONV_NONE; 19233 enc = enc_locale(); 19234 convert_setup(&conv, p_enc, enc); 19235 if (conv.vc_type != CONV_NONE) 19236 p = string_convert(&conv, p, NULL); 19237 # endif 19238 if (p != NULL) 19239 (void)strftime((char *)result_buf, sizeof(result_buf), 19240 (char *)p, curtime); 19241 else 19242 result_buf[0] = NUL; 19243 19244 # ifdef FEAT_MBYTE 19245 if (conv.vc_type != CONV_NONE) 19246 vim_free(p); 19247 convert_setup(&conv, enc, p_enc); 19248 if (conv.vc_type != CONV_NONE) 19249 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 19250 else 19251 # endif 19252 rettv->vval.v_string = vim_strsave(result_buf); 19253 19254 # ifdef FEAT_MBYTE 19255 /* Release conversion descriptors */ 19256 convert_setup(&conv, NULL, NULL); 19257 vim_free(enc); 19258 # endif 19259 } 19260 } 19261 #endif 19262 19263 /* 19264 * "stridx()" function 19265 */ 19266 static void 19267 f_stridx(typval_T *argvars, typval_T *rettv) 19268 { 19269 char_u buf[NUMBUFLEN]; 19270 char_u *needle; 19271 char_u *haystack; 19272 char_u *save_haystack; 19273 char_u *pos; 19274 int start_idx; 19275 19276 needle = get_tv_string_chk(&argvars[1]); 19277 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 19278 rettv->vval.v_number = -1; 19279 if (needle == NULL || haystack == NULL) 19280 return; /* type error; errmsg already given */ 19281 19282 if (argvars[2].v_type != VAR_UNKNOWN) 19283 { 19284 int error = FALSE; 19285 19286 start_idx = get_tv_number_chk(&argvars[2], &error); 19287 if (error || start_idx >= (int)STRLEN(haystack)) 19288 return; 19289 if (start_idx >= 0) 19290 haystack += start_idx; 19291 } 19292 19293 pos = (char_u *)strstr((char *)haystack, (char *)needle); 19294 if (pos != NULL) 19295 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 19296 } 19297 19298 /* 19299 * "string()" function 19300 */ 19301 static void 19302 f_string(typval_T *argvars, typval_T *rettv) 19303 { 19304 char_u *tofree; 19305 char_u numbuf[NUMBUFLEN]; 19306 19307 rettv->v_type = VAR_STRING; 19308 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 19309 get_copyID()); 19310 /* Make a copy if we have a value but it's not in allocated memory. */ 19311 if (rettv->vval.v_string != NULL && tofree == NULL) 19312 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 19313 } 19314 19315 /* 19316 * "strlen()" function 19317 */ 19318 static void 19319 f_strlen(typval_T *argvars, typval_T *rettv) 19320 { 19321 rettv->vval.v_number = (varnumber_T)(STRLEN( 19322 get_tv_string(&argvars[0]))); 19323 } 19324 19325 /* 19326 * "strchars()" function 19327 */ 19328 static void 19329 f_strchars(typval_T *argvars, typval_T *rettv) 19330 { 19331 char_u *s = get_tv_string(&argvars[0]); 19332 int skipcc = 0; 19333 #ifdef FEAT_MBYTE 19334 varnumber_T len = 0; 19335 int (*func_mb_ptr2char_adv)(char_u **pp); 19336 #endif 19337 19338 if (argvars[1].v_type != VAR_UNKNOWN) 19339 skipcc = get_tv_number_chk(&argvars[1], NULL); 19340 if (skipcc < 0 || skipcc > 1) 19341 EMSG(_(e_invarg)); 19342 else 19343 { 19344 #ifdef FEAT_MBYTE 19345 func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv; 19346 while (*s != NUL) 19347 { 19348 func_mb_ptr2char_adv(&s); 19349 ++len; 19350 } 19351 rettv->vval.v_number = len; 19352 #else 19353 rettv->vval.v_number = (varnumber_T)(STRLEN(s)); 19354 #endif 19355 } 19356 } 19357 19358 /* 19359 * "strdisplaywidth()" function 19360 */ 19361 static void 19362 f_strdisplaywidth(typval_T *argvars, typval_T *rettv) 19363 { 19364 char_u *s = get_tv_string(&argvars[0]); 19365 int col = 0; 19366 19367 if (argvars[1].v_type != VAR_UNKNOWN) 19368 col = get_tv_number(&argvars[1]); 19369 19370 rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col); 19371 } 19372 19373 /* 19374 * "strwidth()" function 19375 */ 19376 static void 19377 f_strwidth(typval_T *argvars, typval_T *rettv) 19378 { 19379 char_u *s = get_tv_string(&argvars[0]); 19380 19381 rettv->vval.v_number = (varnumber_T)( 19382 #ifdef FEAT_MBYTE 19383 mb_string2cells(s, -1) 19384 #else 19385 STRLEN(s) 19386 #endif 19387 ); 19388 } 19389 19390 /* 19391 * "strpart()" function 19392 */ 19393 static void 19394 f_strpart(typval_T *argvars, typval_T *rettv) 19395 { 19396 char_u *p; 19397 int n; 19398 int len; 19399 int slen; 19400 int error = FALSE; 19401 19402 p = get_tv_string(&argvars[0]); 19403 slen = (int)STRLEN(p); 19404 19405 n = get_tv_number_chk(&argvars[1], &error); 19406 if (error) 19407 len = 0; 19408 else if (argvars[2].v_type != VAR_UNKNOWN) 19409 len = get_tv_number(&argvars[2]); 19410 else 19411 len = slen - n; /* default len: all bytes that are available. */ 19412 19413 /* 19414 * Only return the overlap between the specified part and the actual 19415 * string. 19416 */ 19417 if (n < 0) 19418 { 19419 len += n; 19420 n = 0; 19421 } 19422 else if (n > slen) 19423 n = slen; 19424 if (len < 0) 19425 len = 0; 19426 else if (n + len > slen) 19427 len = slen - n; 19428 19429 rettv->v_type = VAR_STRING; 19430 rettv->vval.v_string = vim_strnsave(p + n, len); 19431 } 19432 19433 /* 19434 * "strridx()" function 19435 */ 19436 static void 19437 f_strridx(typval_T *argvars, typval_T *rettv) 19438 { 19439 char_u buf[NUMBUFLEN]; 19440 char_u *needle; 19441 char_u *haystack; 19442 char_u *rest; 19443 char_u *lastmatch = NULL; 19444 int haystack_len, end_idx; 19445 19446 needle = get_tv_string_chk(&argvars[1]); 19447 haystack = get_tv_string_buf_chk(&argvars[0], buf); 19448 19449 rettv->vval.v_number = -1; 19450 if (needle == NULL || haystack == NULL) 19451 return; /* type error; errmsg already given */ 19452 19453 haystack_len = (int)STRLEN(haystack); 19454 if (argvars[2].v_type != VAR_UNKNOWN) 19455 { 19456 /* Third argument: upper limit for index */ 19457 end_idx = get_tv_number_chk(&argvars[2], NULL); 19458 if (end_idx < 0) 19459 return; /* can never find a match */ 19460 } 19461 else 19462 end_idx = haystack_len; 19463 19464 if (*needle == NUL) 19465 { 19466 /* Empty string matches past the end. */ 19467 lastmatch = haystack + end_idx; 19468 } 19469 else 19470 { 19471 for (rest = haystack; *rest != '\0'; ++rest) 19472 { 19473 rest = (char_u *)strstr((char *)rest, (char *)needle); 19474 if (rest == NULL || rest > haystack + end_idx) 19475 break; 19476 lastmatch = rest; 19477 } 19478 } 19479 19480 if (lastmatch == NULL) 19481 rettv->vval.v_number = -1; 19482 else 19483 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 19484 } 19485 19486 /* 19487 * "strtrans()" function 19488 */ 19489 static void 19490 f_strtrans(typval_T *argvars, typval_T *rettv) 19491 { 19492 rettv->v_type = VAR_STRING; 19493 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 19494 } 19495 19496 /* 19497 * "submatch()" function 19498 */ 19499 static void 19500 f_submatch(typval_T *argvars, typval_T *rettv) 19501 { 19502 int error = FALSE; 19503 int no; 19504 int retList = 0; 19505 19506 no = (int)get_tv_number_chk(&argvars[0], &error); 19507 if (error) 19508 return; 19509 error = FALSE; 19510 if (argvars[1].v_type != VAR_UNKNOWN) 19511 retList = get_tv_number_chk(&argvars[1], &error); 19512 if (error) 19513 return; 19514 19515 if (retList == 0) 19516 { 19517 rettv->v_type = VAR_STRING; 19518 rettv->vval.v_string = reg_submatch(no); 19519 } 19520 else 19521 { 19522 rettv->v_type = VAR_LIST; 19523 rettv->vval.v_list = reg_submatch_list(no); 19524 } 19525 } 19526 19527 /* 19528 * "substitute()" function 19529 */ 19530 static void 19531 f_substitute(typval_T *argvars, typval_T *rettv) 19532 { 19533 char_u patbuf[NUMBUFLEN]; 19534 char_u subbuf[NUMBUFLEN]; 19535 char_u flagsbuf[NUMBUFLEN]; 19536 19537 char_u *str = get_tv_string_chk(&argvars[0]); 19538 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 19539 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 19540 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 19541 19542 rettv->v_type = VAR_STRING; 19543 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 19544 rettv->vval.v_string = NULL; 19545 else 19546 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 19547 } 19548 19549 /* 19550 * "synID(lnum, col, trans)" function 19551 */ 19552 static void 19553 f_synID(typval_T *argvars UNUSED, typval_T *rettv) 19554 { 19555 int id = 0; 19556 #ifdef FEAT_SYN_HL 19557 long lnum; 19558 long col; 19559 int trans; 19560 int transerr = FALSE; 19561 19562 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19563 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19564 trans = get_tv_number_chk(&argvars[2], &transerr); 19565 19566 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19567 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 19568 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 19569 #endif 19570 19571 rettv->vval.v_number = id; 19572 } 19573 19574 /* 19575 * "synIDattr(id, what [, mode])" function 19576 */ 19577 static void 19578 f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv) 19579 { 19580 char_u *p = NULL; 19581 #ifdef FEAT_SYN_HL 19582 int id; 19583 char_u *what; 19584 char_u *mode; 19585 char_u modebuf[NUMBUFLEN]; 19586 int modec; 19587 19588 id = get_tv_number(&argvars[0]); 19589 what = get_tv_string(&argvars[1]); 19590 if (argvars[2].v_type != VAR_UNKNOWN) 19591 { 19592 mode = get_tv_string_buf(&argvars[2], modebuf); 19593 modec = TOLOWER_ASC(mode[0]); 19594 if (modec != 't' && modec != 'c' && modec != 'g') 19595 modec = 0; /* replace invalid with current */ 19596 } 19597 else 19598 { 19599 #ifdef FEAT_GUI 19600 if (gui.in_use) 19601 modec = 'g'; 19602 else 19603 #endif 19604 if (t_colors > 1) 19605 modec = 'c'; 19606 else 19607 modec = 't'; 19608 } 19609 19610 19611 switch (TOLOWER_ASC(what[0])) 19612 { 19613 case 'b': 19614 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 19615 p = highlight_color(id, what, modec); 19616 else /* bold */ 19617 p = highlight_has_attr(id, HL_BOLD, modec); 19618 break; 19619 19620 case 'f': /* fg[#] or font */ 19621 p = highlight_color(id, what, modec); 19622 break; 19623 19624 case 'i': 19625 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 19626 p = highlight_has_attr(id, HL_INVERSE, modec); 19627 else /* italic */ 19628 p = highlight_has_attr(id, HL_ITALIC, modec); 19629 break; 19630 19631 case 'n': /* name */ 19632 p = get_highlight_name(NULL, id - 1); 19633 break; 19634 19635 case 'r': /* reverse */ 19636 p = highlight_has_attr(id, HL_INVERSE, modec); 19637 break; 19638 19639 case 's': 19640 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 19641 p = highlight_color(id, what, modec); 19642 else /* standout */ 19643 p = highlight_has_attr(id, HL_STANDOUT, modec); 19644 break; 19645 19646 case 'u': 19647 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 19648 /* underline */ 19649 p = highlight_has_attr(id, HL_UNDERLINE, modec); 19650 else 19651 /* undercurl */ 19652 p = highlight_has_attr(id, HL_UNDERCURL, modec); 19653 break; 19654 } 19655 19656 if (p != NULL) 19657 p = vim_strsave(p); 19658 #endif 19659 rettv->v_type = VAR_STRING; 19660 rettv->vval.v_string = p; 19661 } 19662 19663 /* 19664 * "synIDtrans(id)" function 19665 */ 19666 static void 19667 f_synIDtrans(typval_T *argvars UNUSED, typval_T *rettv) 19668 { 19669 int id; 19670 19671 #ifdef FEAT_SYN_HL 19672 id = get_tv_number(&argvars[0]); 19673 19674 if (id > 0) 19675 id = syn_get_final_id(id); 19676 else 19677 #endif 19678 id = 0; 19679 19680 rettv->vval.v_number = id; 19681 } 19682 19683 /* 19684 * "synconcealed(lnum, col)" function 19685 */ 19686 static void 19687 f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv) 19688 { 19689 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 19690 long lnum; 19691 long col; 19692 int syntax_flags = 0; 19693 int cchar; 19694 int matchid = 0; 19695 char_u str[NUMBUFLEN]; 19696 #endif 19697 19698 rettv->v_type = VAR_LIST; 19699 rettv->vval.v_list = NULL; 19700 19701 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 19702 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19703 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19704 19705 vim_memset(str, NUL, sizeof(str)); 19706 19707 if (rettv_list_alloc(rettv) != FAIL) 19708 { 19709 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19710 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 19711 && curwin->w_p_cole > 0) 19712 { 19713 (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE); 19714 syntax_flags = get_syntax_info(&matchid); 19715 19716 /* get the conceal character */ 19717 if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) 19718 { 19719 cchar = syn_get_sub_char(); 19720 if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL) 19721 cchar = lcs_conceal; 19722 if (cchar != NUL) 19723 { 19724 # ifdef FEAT_MBYTE 19725 if (has_mbyte) 19726 (*mb_char2bytes)(cchar, str); 19727 else 19728 # endif 19729 str[0] = cchar; 19730 } 19731 } 19732 } 19733 19734 list_append_number(rettv->vval.v_list, 19735 (syntax_flags & HL_CONCEAL) != 0); 19736 /* -1 to auto-determine strlen */ 19737 list_append_string(rettv->vval.v_list, str, -1); 19738 list_append_number(rettv->vval.v_list, matchid); 19739 } 19740 #endif 19741 } 19742 19743 /* 19744 * "synstack(lnum, col)" function 19745 */ 19746 static void 19747 f_synstack(typval_T *argvars UNUSED, typval_T *rettv) 19748 { 19749 #ifdef FEAT_SYN_HL 19750 long lnum; 19751 long col; 19752 int i; 19753 int id; 19754 #endif 19755 19756 rettv->v_type = VAR_LIST; 19757 rettv->vval.v_list = NULL; 19758 19759 #ifdef FEAT_SYN_HL 19760 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19761 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19762 19763 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19764 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 19765 && rettv_list_alloc(rettv) != FAIL) 19766 { 19767 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 19768 for (i = 0; ; ++i) 19769 { 19770 id = syn_get_stack_item(i); 19771 if (id < 0) 19772 break; 19773 if (list_append_number(rettv->vval.v_list, id) == FAIL) 19774 break; 19775 } 19776 } 19777 #endif 19778 } 19779 19780 static void 19781 get_cmd_output_as_rettv( 19782 typval_T *argvars, 19783 typval_T *rettv, 19784 int retlist) 19785 { 19786 char_u *res = NULL; 19787 char_u *p; 19788 char_u *infile = NULL; 19789 char_u buf[NUMBUFLEN]; 19790 int err = FALSE; 19791 FILE *fd; 19792 list_T *list = NULL; 19793 int flags = SHELL_SILENT; 19794 19795 rettv->v_type = VAR_STRING; 19796 rettv->vval.v_string = NULL; 19797 if (check_restricted() || check_secure()) 19798 goto errret; 19799 19800 if (argvars[1].v_type != VAR_UNKNOWN) 19801 { 19802 /* 19803 * Write the string to a temp file, to be used for input of the shell 19804 * command. 19805 */ 19806 if ((infile = vim_tempname('i', TRUE)) == NULL) 19807 { 19808 EMSG(_(e_notmp)); 19809 goto errret; 19810 } 19811 19812 fd = mch_fopen((char *)infile, WRITEBIN); 19813 if (fd == NULL) 19814 { 19815 EMSG2(_(e_notopen), infile); 19816 goto errret; 19817 } 19818 if (argvars[1].v_type == VAR_LIST) 19819 { 19820 if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL) 19821 err = TRUE; 19822 } 19823 else 19824 { 19825 size_t len; 19826 19827 p = get_tv_string_buf_chk(&argvars[1], buf); 19828 if (p == NULL) 19829 { 19830 fclose(fd); 19831 goto errret; /* type error; errmsg already given */ 19832 } 19833 len = STRLEN(p); 19834 if (len > 0 && fwrite(p, len, 1, fd) != 1) 19835 err = TRUE; 19836 } 19837 if (fclose(fd) != 0) 19838 err = TRUE; 19839 if (err) 19840 { 19841 EMSG(_("E677: Error writing temp file")); 19842 goto errret; 19843 } 19844 } 19845 19846 /* Omit SHELL_COOKED when invoked with ":silent". Avoids that the shell 19847 * echoes typeahead, that messes up the display. */ 19848 if (!msg_silent) 19849 flags += SHELL_COOKED; 19850 19851 if (retlist) 19852 { 19853 int len; 19854 listitem_T *li; 19855 char_u *s = NULL; 19856 char_u *start; 19857 char_u *end; 19858 int i; 19859 19860 res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, &len); 19861 if (res == NULL) 19862 goto errret; 19863 19864 list = list_alloc(); 19865 if (list == NULL) 19866 goto errret; 19867 19868 for (i = 0; i < len; ++i) 19869 { 19870 start = res + i; 19871 while (i < len && res[i] != NL) 19872 ++i; 19873 end = res + i; 19874 19875 s = alloc((unsigned)(end - start + 1)); 19876 if (s == NULL) 19877 goto errret; 19878 19879 for (p = s; start < end; ++p, ++start) 19880 *p = *start == NUL ? NL : *start; 19881 *p = NUL; 19882 19883 li = listitem_alloc(); 19884 if (li == NULL) 19885 { 19886 vim_free(s); 19887 goto errret; 19888 } 19889 li->li_tv.v_type = VAR_STRING; 19890 li->li_tv.v_lock = 0; 19891 li->li_tv.vval.v_string = s; 19892 list_append(list, li); 19893 } 19894 19895 ++list->lv_refcount; 19896 rettv->v_type = VAR_LIST; 19897 rettv->vval.v_list = list; 19898 list = NULL; 19899 } 19900 else 19901 { 19902 res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, NULL); 19903 #ifdef USE_CR 19904 /* translate <CR> into <NL> */ 19905 if (res != NULL) 19906 { 19907 char_u *s; 19908 19909 for (s = res; *s; ++s) 19910 { 19911 if (*s == CAR) 19912 *s = NL; 19913 } 19914 } 19915 #else 19916 # ifdef USE_CRNL 19917 /* translate <CR><NL> into <NL> */ 19918 if (res != NULL) 19919 { 19920 char_u *s, *d; 19921 19922 d = res; 19923 for (s = res; *s; ++s) 19924 { 19925 if (s[0] == CAR && s[1] == NL) 19926 ++s; 19927 *d++ = *s; 19928 } 19929 *d = NUL; 19930 } 19931 # endif 19932 #endif 19933 rettv->vval.v_string = res; 19934 res = NULL; 19935 } 19936 19937 errret: 19938 if (infile != NULL) 19939 { 19940 mch_remove(infile); 19941 vim_free(infile); 19942 } 19943 if (res != NULL) 19944 vim_free(res); 19945 if (list != NULL) 19946 list_free(list, TRUE); 19947 } 19948 19949 /* 19950 * "system()" function 19951 */ 19952 static void 19953 f_system(typval_T *argvars, typval_T *rettv) 19954 { 19955 get_cmd_output_as_rettv(argvars, rettv, FALSE); 19956 } 19957 19958 /* 19959 * "systemlist()" function 19960 */ 19961 static void 19962 f_systemlist(typval_T *argvars, typval_T *rettv) 19963 { 19964 get_cmd_output_as_rettv(argvars, rettv, TRUE); 19965 } 19966 19967 /* 19968 * "tabpagebuflist()" function 19969 */ 19970 static void 19971 f_tabpagebuflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 19972 { 19973 #ifdef FEAT_WINDOWS 19974 tabpage_T *tp; 19975 win_T *wp = NULL; 19976 19977 if (argvars[0].v_type == VAR_UNKNOWN) 19978 wp = firstwin; 19979 else 19980 { 19981 tp = find_tabpage((int)get_tv_number(&argvars[0])); 19982 if (tp != NULL) 19983 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 19984 } 19985 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 19986 { 19987 for (; wp != NULL; wp = wp->w_next) 19988 if (list_append_number(rettv->vval.v_list, 19989 wp->w_buffer->b_fnum) == FAIL) 19990 break; 19991 } 19992 #endif 19993 } 19994 19995 19996 /* 19997 * "tabpagenr()" function 19998 */ 19999 static void 20000 f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv) 20001 { 20002 int nr = 1; 20003 #ifdef FEAT_WINDOWS 20004 char_u *arg; 20005 20006 if (argvars[0].v_type != VAR_UNKNOWN) 20007 { 20008 arg = get_tv_string_chk(&argvars[0]); 20009 nr = 0; 20010 if (arg != NULL) 20011 { 20012 if (STRCMP(arg, "$") == 0) 20013 nr = tabpage_index(NULL) - 1; 20014 else 20015 EMSG2(_(e_invexpr2), arg); 20016 } 20017 } 20018 else 20019 nr = tabpage_index(curtab); 20020 #endif 20021 rettv->vval.v_number = nr; 20022 } 20023 20024 20025 #ifdef FEAT_WINDOWS 20026 static int get_winnr(tabpage_T *tp, typval_T *argvar); 20027 20028 /* 20029 * Common code for tabpagewinnr() and winnr(). 20030 */ 20031 static int 20032 get_winnr(tabpage_T *tp, typval_T *argvar) 20033 { 20034 win_T *twin; 20035 int nr = 1; 20036 win_T *wp; 20037 char_u *arg; 20038 20039 twin = (tp == curtab) ? curwin : tp->tp_curwin; 20040 if (argvar->v_type != VAR_UNKNOWN) 20041 { 20042 arg = get_tv_string_chk(argvar); 20043 if (arg == NULL) 20044 nr = 0; /* type error; errmsg already given */ 20045 else if (STRCMP(arg, "$") == 0) 20046 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 20047 else if (STRCMP(arg, "#") == 0) 20048 { 20049 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 20050 if (twin == NULL) 20051 nr = 0; 20052 } 20053 else 20054 { 20055 EMSG2(_(e_invexpr2), arg); 20056 nr = 0; 20057 } 20058 } 20059 20060 if (nr > 0) 20061 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 20062 wp != twin; wp = wp->w_next) 20063 { 20064 if (wp == NULL) 20065 { 20066 /* didn't find it in this tabpage */ 20067 nr = 0; 20068 break; 20069 } 20070 ++nr; 20071 } 20072 return nr; 20073 } 20074 #endif 20075 20076 /* 20077 * "tabpagewinnr()" function 20078 */ 20079 static void 20080 f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv) 20081 { 20082 int nr = 1; 20083 #ifdef FEAT_WINDOWS 20084 tabpage_T *tp; 20085 20086 tp = find_tabpage((int)get_tv_number(&argvars[0])); 20087 if (tp == NULL) 20088 nr = 0; 20089 else 20090 nr = get_winnr(tp, &argvars[1]); 20091 #endif 20092 rettv->vval.v_number = nr; 20093 } 20094 20095 20096 /* 20097 * "tagfiles()" function 20098 */ 20099 static void 20100 f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv) 20101 { 20102 char_u *fname; 20103 tagname_T tn; 20104 int first; 20105 20106 if (rettv_list_alloc(rettv) == FAIL) 20107 return; 20108 fname = alloc(MAXPATHL); 20109 if (fname == NULL) 20110 return; 20111 20112 for (first = TRUE; ; first = FALSE) 20113 if (get_tagfname(&tn, first, fname) == FAIL 20114 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 20115 break; 20116 tagname_free(&tn); 20117 vim_free(fname); 20118 } 20119 20120 /* 20121 * "taglist()" function 20122 */ 20123 static void 20124 f_taglist(typval_T *argvars, typval_T *rettv) 20125 { 20126 char_u *tag_pattern; 20127 20128 tag_pattern = get_tv_string(&argvars[0]); 20129 20130 rettv->vval.v_number = FALSE; 20131 if (*tag_pattern == NUL) 20132 return; 20133 20134 if (rettv_list_alloc(rettv) == OK) 20135 (void)get_tags(rettv->vval.v_list, tag_pattern); 20136 } 20137 20138 /* 20139 * "tempname()" function 20140 */ 20141 static void 20142 f_tempname(typval_T *argvars UNUSED, typval_T *rettv) 20143 { 20144 static int x = 'A'; 20145 20146 rettv->v_type = VAR_STRING; 20147 rettv->vval.v_string = vim_tempname(x, FALSE); 20148 20149 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 20150 * names. Skip 'I' and 'O', they are used for shell redirection. */ 20151 do 20152 { 20153 if (x == 'Z') 20154 x = '0'; 20155 else if (x == '9') 20156 x = 'A'; 20157 else 20158 { 20159 #ifdef EBCDIC 20160 if (x == 'I') 20161 x = 'J'; 20162 else if (x == 'R') 20163 x = 'S'; 20164 else 20165 #endif 20166 ++x; 20167 } 20168 } while (x == 'I' || x == 'O'); 20169 } 20170 20171 /* 20172 * "test(list)" function: Just checking the walls... 20173 */ 20174 static void 20175 f_test(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 20176 { 20177 /* Used for unit testing. Change the code below to your liking. */ 20178 #if 0 20179 listitem_T *li; 20180 list_T *l; 20181 char_u *bad, *good; 20182 20183 if (argvars[0].v_type != VAR_LIST) 20184 return; 20185 l = argvars[0].vval.v_list; 20186 if (l == NULL) 20187 return; 20188 li = l->lv_first; 20189 if (li == NULL) 20190 return; 20191 bad = get_tv_string(&li->li_tv); 20192 li = li->li_next; 20193 if (li == NULL) 20194 return; 20195 good = get_tv_string(&li->li_tv); 20196 rettv->vval.v_number = test_edit_score(bad, good); 20197 #endif 20198 } 20199 20200 #ifdef FEAT_FLOAT 20201 /* 20202 * "tan()" function 20203 */ 20204 static void 20205 f_tan(typval_T *argvars, typval_T *rettv) 20206 { 20207 float_T f = 0.0; 20208 20209 rettv->v_type = VAR_FLOAT; 20210 if (get_float_arg(argvars, &f) == OK) 20211 rettv->vval.v_float = tan(f); 20212 else 20213 rettv->vval.v_float = 0.0; 20214 } 20215 20216 /* 20217 * "tanh()" function 20218 */ 20219 static void 20220 f_tanh(typval_T *argvars, typval_T *rettv) 20221 { 20222 float_T f = 0.0; 20223 20224 rettv->v_type = VAR_FLOAT; 20225 if (get_float_arg(argvars, &f) == OK) 20226 rettv->vval.v_float = tanh(f); 20227 else 20228 rettv->vval.v_float = 0.0; 20229 } 20230 #endif 20231 20232 #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO) 20233 /* 20234 * Get a callback from "arg". It can be a Funcref or a function name. 20235 * When "arg" is zero return an empty string. 20236 * Return NULL for an invalid argument. 20237 */ 20238 char_u * 20239 get_callback(typval_T *arg, partial_T **pp) 20240 { 20241 if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) 20242 { 20243 *pp = arg->vval.v_partial; 20244 ++(*pp)->pt_refcount; 20245 return (*pp)->pt_name; 20246 } 20247 *pp = NULL; 20248 if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) 20249 return arg->vval.v_string; 20250 if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) 20251 return (char_u *)""; 20252 EMSG(_("E921: Invalid callback argument")); 20253 return NULL; 20254 } 20255 #endif 20256 20257 #ifdef FEAT_TIMERS 20258 /* 20259 * "timer_start(time, callback [, options])" function 20260 */ 20261 static void 20262 f_timer_start(typval_T *argvars, typval_T *rettv) 20263 { 20264 long msec = get_tv_number(&argvars[0]); 20265 timer_T *timer; 20266 int repeat = 0; 20267 char_u *callback; 20268 dict_T *dict; 20269 20270 if (argvars[2].v_type != VAR_UNKNOWN) 20271 { 20272 if (argvars[2].v_type != VAR_DICT 20273 || (dict = argvars[2].vval.v_dict) == NULL) 20274 { 20275 EMSG2(_(e_invarg2), get_tv_string(&argvars[2])); 20276 return; 20277 } 20278 if (dict_find(dict, (char_u *)"repeat", -1) != NULL) 20279 repeat = get_dict_number(dict, (char_u *)"repeat"); 20280 } 20281 20282 timer = create_timer(msec, repeat); 20283 callback = get_callback(&argvars[1], &timer->tr_partial); 20284 if (callback == NULL) 20285 { 20286 stop_timer(timer); 20287 rettv->vval.v_number = -1; 20288 } 20289 else 20290 { 20291 timer->tr_callback = vim_strsave(callback); 20292 rettv->vval.v_number = timer->tr_id; 20293 } 20294 } 20295 20296 /* 20297 * "timer_stop(timer)" function 20298 */ 20299 static void 20300 f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED) 20301 { 20302 timer_T *timer = find_timer(get_tv_number(&argvars[0])); 20303 20304 if (timer != NULL) 20305 stop_timer(timer); 20306 } 20307 #endif 20308 20309 /* 20310 * "tolower(string)" function 20311 */ 20312 static void 20313 f_tolower(typval_T *argvars, typval_T *rettv) 20314 { 20315 char_u *p; 20316 20317 p = vim_strsave(get_tv_string(&argvars[0])); 20318 rettv->v_type = VAR_STRING; 20319 rettv->vval.v_string = p; 20320 20321 if (p != NULL) 20322 while (*p != NUL) 20323 { 20324 #ifdef FEAT_MBYTE 20325 int l; 20326 20327 if (enc_utf8) 20328 { 20329 int c, lc; 20330 20331 c = utf_ptr2char(p); 20332 lc = utf_tolower(c); 20333 l = utf_ptr2len(p); 20334 /* TODO: reallocate string when byte count changes. */ 20335 if (utf_char2len(lc) == l) 20336 utf_char2bytes(lc, p); 20337 p += l; 20338 } 20339 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 20340 p += l; /* skip multi-byte character */ 20341 else 20342 #endif 20343 { 20344 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 20345 ++p; 20346 } 20347 } 20348 } 20349 20350 /* 20351 * "toupper(string)" function 20352 */ 20353 static void 20354 f_toupper(typval_T *argvars, typval_T *rettv) 20355 { 20356 rettv->v_type = VAR_STRING; 20357 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 20358 } 20359 20360 /* 20361 * "tr(string, fromstr, tostr)" function 20362 */ 20363 static void 20364 f_tr(typval_T *argvars, typval_T *rettv) 20365 { 20366 char_u *in_str; 20367 char_u *fromstr; 20368 char_u *tostr; 20369 char_u *p; 20370 #ifdef FEAT_MBYTE 20371 int inlen; 20372 int fromlen; 20373 int tolen; 20374 int idx; 20375 char_u *cpstr; 20376 int cplen; 20377 int first = TRUE; 20378 #endif 20379 char_u buf[NUMBUFLEN]; 20380 char_u buf2[NUMBUFLEN]; 20381 garray_T ga; 20382 20383 in_str = get_tv_string(&argvars[0]); 20384 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 20385 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 20386 20387 /* Default return value: empty string. */ 20388 rettv->v_type = VAR_STRING; 20389 rettv->vval.v_string = NULL; 20390 if (fromstr == NULL || tostr == NULL) 20391 return; /* type error; errmsg already given */ 20392 ga_init2(&ga, (int)sizeof(char), 80); 20393 20394 #ifdef FEAT_MBYTE 20395 if (!has_mbyte) 20396 #endif 20397 /* not multi-byte: fromstr and tostr must be the same length */ 20398 if (STRLEN(fromstr) != STRLEN(tostr)) 20399 { 20400 #ifdef FEAT_MBYTE 20401 error: 20402 #endif 20403 EMSG2(_(e_invarg2), fromstr); 20404 ga_clear(&ga); 20405 return; 20406 } 20407 20408 /* fromstr and tostr have to contain the same number of chars */ 20409 while (*in_str != NUL) 20410 { 20411 #ifdef FEAT_MBYTE 20412 if (has_mbyte) 20413 { 20414 inlen = (*mb_ptr2len)(in_str); 20415 cpstr = in_str; 20416 cplen = inlen; 20417 idx = 0; 20418 for (p = fromstr; *p != NUL; p += fromlen) 20419 { 20420 fromlen = (*mb_ptr2len)(p); 20421 if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) 20422 { 20423 for (p = tostr; *p != NUL; p += tolen) 20424 { 20425 tolen = (*mb_ptr2len)(p); 20426 if (idx-- == 0) 20427 { 20428 cplen = tolen; 20429 cpstr = p; 20430 break; 20431 } 20432 } 20433 if (*p == NUL) /* tostr is shorter than fromstr */ 20434 goto error; 20435 break; 20436 } 20437 ++idx; 20438 } 20439 20440 if (first && cpstr == in_str) 20441 { 20442 /* Check that fromstr and tostr have the same number of 20443 * (multi-byte) characters. Done only once when a character 20444 * of in_str doesn't appear in fromstr. */ 20445 first = FALSE; 20446 for (p = tostr; *p != NUL; p += tolen) 20447 { 20448 tolen = (*mb_ptr2len)(p); 20449 --idx; 20450 } 20451 if (idx != 0) 20452 goto error; 20453 } 20454 20455 (void)ga_grow(&ga, cplen); 20456 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 20457 ga.ga_len += cplen; 20458 20459 in_str += inlen; 20460 } 20461 else 20462 #endif 20463 { 20464 /* When not using multi-byte chars we can do it faster. */ 20465 p = vim_strchr(fromstr, *in_str); 20466 if (p != NULL) 20467 ga_append(&ga, tostr[p - fromstr]); 20468 else 20469 ga_append(&ga, *in_str); 20470 ++in_str; 20471 } 20472 } 20473 20474 /* add a terminating NUL */ 20475 (void)ga_grow(&ga, 1); 20476 ga_append(&ga, NUL); 20477 20478 rettv->vval.v_string = ga.ga_data; 20479 } 20480 20481 #ifdef FEAT_FLOAT 20482 /* 20483 * "trunc({float})" function 20484 */ 20485 static void 20486 f_trunc(typval_T *argvars, typval_T *rettv) 20487 { 20488 float_T f = 0.0; 20489 20490 rettv->v_type = VAR_FLOAT; 20491 if (get_float_arg(argvars, &f) == OK) 20492 /* trunc() is not in C90, use floor() or ceil() instead. */ 20493 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 20494 else 20495 rettv->vval.v_float = 0.0; 20496 } 20497 #endif 20498 20499 /* 20500 * "type(expr)" function 20501 */ 20502 static void 20503 f_type(typval_T *argvars, typval_T *rettv) 20504 { 20505 int n = -1; 20506 20507 switch (argvars[0].v_type) 20508 { 20509 case VAR_NUMBER: n = 0; break; 20510 case VAR_STRING: n = 1; break; 20511 case VAR_PARTIAL: 20512 case VAR_FUNC: n = 2; break; 20513 case VAR_LIST: n = 3; break; 20514 case VAR_DICT: n = 4; break; 20515 case VAR_FLOAT: n = 5; break; 20516 case VAR_SPECIAL: 20517 if (argvars[0].vval.v_number == VVAL_FALSE 20518 || argvars[0].vval.v_number == VVAL_TRUE) 20519 n = 6; 20520 else 20521 n = 7; 20522 break; 20523 case VAR_JOB: n = 8; break; 20524 case VAR_CHANNEL: n = 9; break; 20525 case VAR_UNKNOWN: 20526 EMSG2(_(e_intern2), "f_type(UNKNOWN)"); 20527 n = -1; 20528 break; 20529 } 20530 rettv->vval.v_number = n; 20531 } 20532 20533 /* 20534 * "undofile(name)" function 20535 */ 20536 static void 20537 f_undofile(typval_T *argvars UNUSED, typval_T *rettv) 20538 { 20539 rettv->v_type = VAR_STRING; 20540 #ifdef FEAT_PERSISTENT_UNDO 20541 { 20542 char_u *fname = get_tv_string(&argvars[0]); 20543 20544 if (*fname == NUL) 20545 { 20546 /* If there is no file name there will be no undo file. */ 20547 rettv->vval.v_string = NULL; 20548 } 20549 else 20550 { 20551 char_u *ffname = FullName_save(fname, FALSE); 20552 20553 if (ffname != NULL) 20554 rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); 20555 vim_free(ffname); 20556 } 20557 } 20558 #else 20559 rettv->vval.v_string = NULL; 20560 #endif 20561 } 20562 20563 /* 20564 * "undotree()" function 20565 */ 20566 static void 20567 f_undotree(typval_T *argvars UNUSED, typval_T *rettv) 20568 { 20569 if (rettv_dict_alloc(rettv) == OK) 20570 { 20571 dict_T *dict = rettv->vval.v_dict; 20572 list_T *list; 20573 20574 dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL); 20575 dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL); 20576 dict_add_nr_str(dict, "save_last", 20577 (long)curbuf->b_u_save_nr_last, NULL); 20578 dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL); 20579 dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL); 20580 dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL); 20581 20582 list = list_alloc(); 20583 if (list != NULL) 20584 { 20585 u_eval_tree(curbuf->b_u_oldhead, list); 20586 dict_add_list(dict, "entries", list); 20587 } 20588 } 20589 } 20590 20591 /* 20592 * "values(dict)" function 20593 */ 20594 static void 20595 f_values(typval_T *argvars, typval_T *rettv) 20596 { 20597 dict_list(argvars, rettv, 1); 20598 } 20599 20600 /* 20601 * "virtcol(string)" function 20602 */ 20603 static void 20604 f_virtcol(typval_T *argvars, typval_T *rettv) 20605 { 20606 colnr_T vcol = 0; 20607 pos_T *fp; 20608 int fnum = curbuf->b_fnum; 20609 20610 fp = var2fpos(&argvars[0], FALSE, &fnum); 20611 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 20612 && fnum == curbuf->b_fnum) 20613 { 20614 getvvcol(curwin, fp, NULL, NULL, &vcol); 20615 ++vcol; 20616 } 20617 20618 rettv->vval.v_number = vcol; 20619 } 20620 20621 /* 20622 * "visualmode()" function 20623 */ 20624 static void 20625 f_visualmode(typval_T *argvars, typval_T *rettv) 20626 { 20627 char_u str[2]; 20628 20629 rettv->v_type = VAR_STRING; 20630 str[0] = curbuf->b_visual_mode_eval; 20631 str[1] = NUL; 20632 rettv->vval.v_string = vim_strsave(str); 20633 20634 /* A non-zero number or non-empty string argument: reset mode. */ 20635 if (non_zero_arg(&argvars[0])) 20636 curbuf->b_visual_mode_eval = NUL; 20637 } 20638 20639 /* 20640 * "wildmenumode()" function 20641 */ 20642 static void 20643 f_wildmenumode(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 20644 { 20645 #ifdef FEAT_WILDMENU 20646 if (wild_menu_showing) 20647 rettv->vval.v_number = 1; 20648 #endif 20649 } 20650 20651 /* 20652 * "winbufnr(nr)" function 20653 */ 20654 static void 20655 f_winbufnr(typval_T *argvars, typval_T *rettv) 20656 { 20657 win_T *wp; 20658 20659 wp = find_win_by_nr(&argvars[0], NULL); 20660 if (wp == NULL) 20661 rettv->vval.v_number = -1; 20662 else 20663 rettv->vval.v_number = wp->w_buffer->b_fnum; 20664 } 20665 20666 /* 20667 * "wincol()" function 20668 */ 20669 static void 20670 f_wincol(typval_T *argvars UNUSED, typval_T *rettv) 20671 { 20672 validate_cursor(); 20673 rettv->vval.v_number = curwin->w_wcol + 1; 20674 } 20675 20676 /* 20677 * "winheight(nr)" function 20678 */ 20679 static void 20680 f_winheight(typval_T *argvars, typval_T *rettv) 20681 { 20682 win_T *wp; 20683 20684 wp = find_win_by_nr(&argvars[0], NULL); 20685 if (wp == NULL) 20686 rettv->vval.v_number = -1; 20687 else 20688 rettv->vval.v_number = wp->w_height; 20689 } 20690 20691 /* 20692 * "winline()" function 20693 */ 20694 static void 20695 f_winline(typval_T *argvars UNUSED, typval_T *rettv) 20696 { 20697 validate_cursor(); 20698 rettv->vval.v_number = curwin->w_wrow + 1; 20699 } 20700 20701 /* 20702 * "winnr()" function 20703 */ 20704 static void 20705 f_winnr(typval_T *argvars UNUSED, typval_T *rettv) 20706 { 20707 int nr = 1; 20708 20709 #ifdef FEAT_WINDOWS 20710 nr = get_winnr(curtab, &argvars[0]); 20711 #endif 20712 rettv->vval.v_number = nr; 20713 } 20714 20715 /* 20716 * "winrestcmd()" function 20717 */ 20718 static void 20719 f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv) 20720 { 20721 #ifdef FEAT_WINDOWS 20722 win_T *wp; 20723 int winnr = 1; 20724 garray_T ga; 20725 char_u buf[50]; 20726 20727 ga_init2(&ga, (int)sizeof(char), 70); 20728 for (wp = firstwin; wp != NULL; wp = wp->w_next) 20729 { 20730 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 20731 ga_concat(&ga, buf); 20732 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 20733 ga_concat(&ga, buf); 20734 ++winnr; 20735 } 20736 ga_append(&ga, NUL); 20737 20738 rettv->vval.v_string = ga.ga_data; 20739 #else 20740 rettv->vval.v_string = NULL; 20741 #endif 20742 rettv->v_type = VAR_STRING; 20743 } 20744 20745 /* 20746 * "winrestview()" function 20747 */ 20748 static void 20749 f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) 20750 { 20751 dict_T *dict; 20752 20753 if (argvars[0].v_type != VAR_DICT 20754 || (dict = argvars[0].vval.v_dict) == NULL) 20755 EMSG(_(e_invarg)); 20756 else 20757 { 20758 if (dict_find(dict, (char_u *)"lnum", -1) != NULL) 20759 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 20760 if (dict_find(dict, (char_u *)"col", -1) != NULL) 20761 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 20762 #ifdef FEAT_VIRTUALEDIT 20763 if (dict_find(dict, (char_u *)"coladd", -1) != NULL) 20764 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 20765 #endif 20766 if (dict_find(dict, (char_u *)"curswant", -1) != NULL) 20767 { 20768 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 20769 curwin->w_set_curswant = FALSE; 20770 } 20771 20772 if (dict_find(dict, (char_u *)"topline", -1) != NULL) 20773 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 20774 #ifdef FEAT_DIFF 20775 if (dict_find(dict, (char_u *)"topfill", -1) != NULL) 20776 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 20777 #endif 20778 if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) 20779 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 20780 if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) 20781 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 20782 20783 check_cursor(); 20784 win_new_height(curwin, curwin->w_height); 20785 # ifdef FEAT_WINDOWS 20786 win_new_width(curwin, W_WIDTH(curwin)); 20787 # endif 20788 changed_window_setting(); 20789 20790 if (curwin->w_topline <= 0) 20791 curwin->w_topline = 1; 20792 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 20793 curwin->w_topline = curbuf->b_ml.ml_line_count; 20794 #ifdef FEAT_DIFF 20795 check_topfill(curwin, TRUE); 20796 #endif 20797 } 20798 } 20799 20800 /* 20801 * "winsaveview()" function 20802 */ 20803 static void 20804 f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv) 20805 { 20806 dict_T *dict; 20807 20808 if (rettv_dict_alloc(rettv) == FAIL) 20809 return; 20810 dict = rettv->vval.v_dict; 20811 20812 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 20813 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 20814 #ifdef FEAT_VIRTUALEDIT 20815 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 20816 #endif 20817 update_curswant(); 20818 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 20819 20820 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 20821 #ifdef FEAT_DIFF 20822 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 20823 #endif 20824 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 20825 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 20826 } 20827 20828 /* 20829 * "winwidth(nr)" function 20830 */ 20831 static void 20832 f_winwidth(typval_T *argvars, typval_T *rettv) 20833 { 20834 win_T *wp; 20835 20836 wp = find_win_by_nr(&argvars[0], NULL); 20837 if (wp == NULL) 20838 rettv->vval.v_number = -1; 20839 else 20840 #ifdef FEAT_WINDOWS 20841 rettv->vval.v_number = wp->w_width; 20842 #else 20843 rettv->vval.v_number = Columns; 20844 #endif 20845 } 20846 20847 /* 20848 * "wordcount()" function 20849 */ 20850 static void 20851 f_wordcount(typval_T *argvars UNUSED, typval_T *rettv) 20852 { 20853 if (rettv_dict_alloc(rettv) == FAIL) 20854 return; 20855 cursor_pos_info(rettv->vval.v_dict); 20856 } 20857 20858 /* 20859 * Write list of strings to file 20860 */ 20861 static int 20862 write_list(FILE *fd, list_T *list, int binary) 20863 { 20864 listitem_T *li; 20865 int c; 20866 int ret = OK; 20867 char_u *s; 20868 20869 for (li = list->lv_first; li != NULL; li = li->li_next) 20870 { 20871 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 20872 { 20873 if (*s == '\n') 20874 c = putc(NUL, fd); 20875 else 20876 c = putc(*s, fd); 20877 if (c == EOF) 20878 { 20879 ret = FAIL; 20880 break; 20881 } 20882 } 20883 if (!binary || li->li_next != NULL) 20884 if (putc('\n', fd) == EOF) 20885 { 20886 ret = FAIL; 20887 break; 20888 } 20889 if (ret == FAIL) 20890 { 20891 EMSG(_(e_write)); 20892 break; 20893 } 20894 } 20895 return ret; 20896 } 20897 20898 /* 20899 * "writefile()" function 20900 */ 20901 static void 20902 f_writefile(typval_T *argvars, typval_T *rettv) 20903 { 20904 int binary = FALSE; 20905 int append = FALSE; 20906 char_u *fname; 20907 FILE *fd; 20908 int ret = 0; 20909 20910 if (check_restricted() || check_secure()) 20911 return; 20912 20913 if (argvars[0].v_type != VAR_LIST) 20914 { 20915 EMSG2(_(e_listarg), "writefile()"); 20916 return; 20917 } 20918 if (argvars[0].vval.v_list == NULL) 20919 return; 20920 20921 if (argvars[2].v_type != VAR_UNKNOWN) 20922 { 20923 if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL) 20924 binary = TRUE; 20925 if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL) 20926 append = TRUE; 20927 } 20928 20929 /* Always open the file in binary mode, library functions have a mind of 20930 * their own about CR-LF conversion. */ 20931 fname = get_tv_string(&argvars[1]); 20932 if (*fname == NUL || (fd = mch_fopen((char *)fname, 20933 append ? APPENDBIN : WRITEBIN)) == NULL) 20934 { 20935 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 20936 ret = -1; 20937 } 20938 else 20939 { 20940 if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL) 20941 ret = -1; 20942 fclose(fd); 20943 } 20944 20945 rettv->vval.v_number = ret; 20946 } 20947 20948 /* 20949 * "xor(expr, expr)" function 20950 */ 20951 static void 20952 f_xor(typval_T *argvars, typval_T *rettv) 20953 { 20954 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 20955 ^ get_tv_number_chk(&argvars[1], NULL); 20956 } 20957 20958 20959 /* 20960 * Translate a String variable into a position. 20961 * Returns NULL when there is an error. 20962 */ 20963 static pos_T * 20964 var2fpos( 20965 typval_T *varp, 20966 int dollar_lnum, /* TRUE when $ is last line */ 20967 int *fnum) /* set to fnum for '0, 'A, etc. */ 20968 { 20969 char_u *name; 20970 static pos_T pos; 20971 pos_T *pp; 20972 20973 /* Argument can be [lnum, col, coladd]. */ 20974 if (varp->v_type == VAR_LIST) 20975 { 20976 list_T *l; 20977 int len; 20978 int error = FALSE; 20979 listitem_T *li; 20980 20981 l = varp->vval.v_list; 20982 if (l == NULL) 20983 return NULL; 20984 20985 /* Get the line number */ 20986 pos.lnum = list_find_nr(l, 0L, &error); 20987 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 20988 return NULL; /* invalid line number */ 20989 20990 /* Get the column number */ 20991 pos.col = list_find_nr(l, 1L, &error); 20992 if (error) 20993 return NULL; 20994 len = (long)STRLEN(ml_get(pos.lnum)); 20995 20996 /* We accept "$" for the column number: last column. */ 20997 li = list_find(l, 1L); 20998 if (li != NULL && li->li_tv.v_type == VAR_STRING 20999 && li->li_tv.vval.v_string != NULL 21000 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 21001 pos.col = len + 1; 21002 21003 /* Accept a position up to the NUL after the line. */ 21004 if (pos.col == 0 || (int)pos.col > len + 1) 21005 return NULL; /* invalid column number */ 21006 --pos.col; 21007 21008 #ifdef FEAT_VIRTUALEDIT 21009 /* Get the virtual offset. Defaults to zero. */ 21010 pos.coladd = list_find_nr(l, 2L, &error); 21011 if (error) 21012 pos.coladd = 0; 21013 #endif 21014 21015 return &pos; 21016 } 21017 21018 name = get_tv_string_chk(varp); 21019 if (name == NULL) 21020 return NULL; 21021 if (name[0] == '.') /* cursor */ 21022 return &curwin->w_cursor; 21023 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 21024 { 21025 if (VIsual_active) 21026 return &VIsual; 21027 return &curwin->w_cursor; 21028 } 21029 if (name[0] == '\'') /* mark */ 21030 { 21031 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); 21032 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 21033 return NULL; 21034 return pp; 21035 } 21036 21037 #ifdef FEAT_VIRTUALEDIT 21038 pos.coladd = 0; 21039 #endif 21040 21041 if (name[0] == 'w' && dollar_lnum) 21042 { 21043 pos.col = 0; 21044 if (name[1] == '0') /* "w0": first visible line */ 21045 { 21046 update_topline(); 21047 pos.lnum = curwin->w_topline; 21048 return &pos; 21049 } 21050 else if (name[1] == '$') /* "w$": last visible line */ 21051 { 21052 validate_botline(); 21053 pos.lnum = curwin->w_botline - 1; 21054 return &pos; 21055 } 21056 } 21057 else if (name[0] == '$') /* last column or line */ 21058 { 21059 if (dollar_lnum) 21060 { 21061 pos.lnum = curbuf->b_ml.ml_line_count; 21062 pos.col = 0; 21063 } 21064 else 21065 { 21066 pos.lnum = curwin->w_cursor.lnum; 21067 pos.col = (colnr_T)STRLEN(ml_get_curline()); 21068 } 21069 return &pos; 21070 } 21071 return NULL; 21072 } 21073 21074 /* 21075 * Convert list in "arg" into a position and optional file number. 21076 * When "fnump" is NULL there is no file number, only 3 items. 21077 * Note that the column is passed on as-is, the caller may want to decrement 21078 * it to use 1 for the first column. 21079 * Return FAIL when conversion is not possible, doesn't check the position for 21080 * validity. 21081 */ 21082 static int 21083 list2fpos( 21084 typval_T *arg, 21085 pos_T *posp, 21086 int *fnump, 21087 colnr_T *curswantp) 21088 { 21089 list_T *l = arg->vval.v_list; 21090 long i = 0; 21091 long n; 21092 21093 /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only 21094 * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */ 21095 if (arg->v_type != VAR_LIST 21096 || l == NULL 21097 || l->lv_len < (fnump == NULL ? 2 : 3) 21098 || l->lv_len > (fnump == NULL ? 4 : 5)) 21099 return FAIL; 21100 21101 if (fnump != NULL) 21102 { 21103 n = list_find_nr(l, i++, NULL); /* fnum */ 21104 if (n < 0) 21105 return FAIL; 21106 if (n == 0) 21107 n = curbuf->b_fnum; /* current buffer */ 21108 *fnump = n; 21109 } 21110 21111 n = list_find_nr(l, i++, NULL); /* lnum */ 21112 if (n < 0) 21113 return FAIL; 21114 posp->lnum = n; 21115 21116 n = list_find_nr(l, i++, NULL); /* col */ 21117 if (n < 0) 21118 return FAIL; 21119 posp->col = n; 21120 21121 #ifdef FEAT_VIRTUALEDIT 21122 n = list_find_nr(l, i, NULL); /* off */ 21123 if (n < 0) 21124 posp->coladd = 0; 21125 else 21126 posp->coladd = n; 21127 #endif 21128 21129 if (curswantp != NULL) 21130 *curswantp = list_find_nr(l, i + 1, NULL); /* curswant */ 21131 21132 return OK; 21133 } 21134 21135 /* 21136 * Get the length of an environment variable name. 21137 * Advance "arg" to the first character after the name. 21138 * Return 0 for error. 21139 */ 21140 static int 21141 get_env_len(char_u **arg) 21142 { 21143 char_u *p; 21144 int len; 21145 21146 for (p = *arg; vim_isIDc(*p); ++p) 21147 ; 21148 if (p == *arg) /* no name found */ 21149 return 0; 21150 21151 len = (int)(p - *arg); 21152 *arg = p; 21153 return len; 21154 } 21155 21156 /* 21157 * Get the length of the name of a function or internal variable. 21158 * "arg" is advanced to the first non-white character after the name. 21159 * Return 0 if something is wrong. 21160 */ 21161 static int 21162 get_id_len(char_u **arg) 21163 { 21164 char_u *p; 21165 int len; 21166 21167 /* Find the end of the name. */ 21168 for (p = *arg; eval_isnamec(*p); ++p) 21169 { 21170 if (*p == ':') 21171 { 21172 /* "s:" is start of "s:var", but "n:" is not and can be used in 21173 * slice "[n:]". Also "xx:" is not a namespace. */ 21174 len = (int)(p - *arg); 21175 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL) 21176 || len > 1) 21177 break; 21178 } 21179 } 21180 if (p == *arg) /* no name found */ 21181 return 0; 21182 21183 len = (int)(p - *arg); 21184 *arg = skipwhite(p); 21185 21186 return len; 21187 } 21188 21189 /* 21190 * Get the length of the name of a variable or function. 21191 * Only the name is recognized, does not handle ".key" or "[idx]". 21192 * "arg" is advanced to the first non-white character after the name. 21193 * Return -1 if curly braces expansion failed. 21194 * Return 0 if something else is wrong. 21195 * If the name contains 'magic' {}'s, expand them and return the 21196 * expanded name in an allocated string via 'alias' - caller must free. 21197 */ 21198 static int 21199 get_name_len( 21200 char_u **arg, 21201 char_u **alias, 21202 int evaluate, 21203 int verbose) 21204 { 21205 int len; 21206 char_u *p; 21207 char_u *expr_start; 21208 char_u *expr_end; 21209 21210 *alias = NULL; /* default to no alias */ 21211 21212 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 21213 && (*arg)[2] == (int)KE_SNR) 21214 { 21215 /* hard coded <SNR>, already translated */ 21216 *arg += 3; 21217 return get_id_len(arg) + 3; 21218 } 21219 len = eval_fname_script(*arg); 21220 if (len > 0) 21221 { 21222 /* literal "<SID>", "s:" or "<SNR>" */ 21223 *arg += len; 21224 } 21225 21226 /* 21227 * Find the end of the name; check for {} construction. 21228 */ 21229 p = find_name_end(*arg, &expr_start, &expr_end, 21230 len > 0 ? 0 : FNE_CHECK_START); 21231 if (expr_start != NULL) 21232 { 21233 char_u *temp_string; 21234 21235 if (!evaluate) 21236 { 21237 len += (int)(p - *arg); 21238 *arg = skipwhite(p); 21239 return len; 21240 } 21241 21242 /* 21243 * Include any <SID> etc in the expanded string: 21244 * Thus the -len here. 21245 */ 21246 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 21247 if (temp_string == NULL) 21248 return -1; 21249 *alias = temp_string; 21250 *arg = skipwhite(p); 21251 return (int)STRLEN(temp_string); 21252 } 21253 21254 len += get_id_len(arg); 21255 if (len == 0 && verbose) 21256 EMSG2(_(e_invexpr2), *arg); 21257 21258 return len; 21259 } 21260 21261 /* 21262 * Find the end of a variable or function name, taking care of magic braces. 21263 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 21264 * start and end of the first magic braces item. 21265 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 21266 * Return a pointer to just after the name. Equal to "arg" if there is no 21267 * valid name. 21268 */ 21269 static char_u * 21270 find_name_end( 21271 char_u *arg, 21272 char_u **expr_start, 21273 char_u **expr_end, 21274 int flags) 21275 { 21276 int mb_nest = 0; 21277 int br_nest = 0; 21278 char_u *p; 21279 int len; 21280 21281 if (expr_start != NULL) 21282 { 21283 *expr_start = NULL; 21284 *expr_end = NULL; 21285 } 21286 21287 /* Quick check for valid starting character. */ 21288 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 21289 return arg; 21290 21291 for (p = arg; *p != NUL 21292 && (eval_isnamec(*p) 21293 || *p == '{' 21294 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 21295 || mb_nest != 0 21296 || br_nest != 0); mb_ptr_adv(p)) 21297 { 21298 if (*p == '\'') 21299 { 21300 /* skip over 'string' to avoid counting [ and ] inside it. */ 21301 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 21302 ; 21303 if (*p == NUL) 21304 break; 21305 } 21306 else if (*p == '"') 21307 { 21308 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 21309 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 21310 if (*p == '\\' && p[1] != NUL) 21311 ++p; 21312 if (*p == NUL) 21313 break; 21314 } 21315 else if (br_nest == 0 && mb_nest == 0 && *p == ':') 21316 { 21317 /* "s:" is start of "s:var", but "n:" is not and can be used in 21318 * slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. */ 21319 len = (int)(p - arg); 21320 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL) 21321 || (len > 1 && p[-1] != '}')) 21322 break; 21323 } 21324 21325 if (mb_nest == 0) 21326 { 21327 if (*p == '[') 21328 ++br_nest; 21329 else if (*p == ']') 21330 --br_nest; 21331 } 21332 21333 if (br_nest == 0) 21334 { 21335 if (*p == '{') 21336 { 21337 mb_nest++; 21338 if (expr_start != NULL && *expr_start == NULL) 21339 *expr_start = p; 21340 } 21341 else if (*p == '}') 21342 { 21343 mb_nest--; 21344 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 21345 *expr_end = p; 21346 } 21347 } 21348 } 21349 21350 return p; 21351 } 21352 21353 /* 21354 * Expands out the 'magic' {}'s in a variable/function name. 21355 * Note that this can call itself recursively, to deal with 21356 * constructs like foo{bar}{baz}{bam} 21357 * The four pointer arguments point to "foo{expre}ss{ion}bar" 21358 * "in_start" ^ 21359 * "expr_start" ^ 21360 * "expr_end" ^ 21361 * "in_end" ^ 21362 * 21363 * Returns a new allocated string, which the caller must free. 21364 * Returns NULL for failure. 21365 */ 21366 static char_u * 21367 make_expanded_name( 21368 char_u *in_start, 21369 char_u *expr_start, 21370 char_u *expr_end, 21371 char_u *in_end) 21372 { 21373 char_u c1; 21374 char_u *retval = NULL; 21375 char_u *temp_result; 21376 char_u *nextcmd = NULL; 21377 21378 if (expr_end == NULL || in_end == NULL) 21379 return NULL; 21380 *expr_start = NUL; 21381 *expr_end = NUL; 21382 c1 = *in_end; 21383 *in_end = NUL; 21384 21385 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 21386 if (temp_result != NULL && nextcmd == NULL) 21387 { 21388 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 21389 + (in_end - expr_end) + 1)); 21390 if (retval != NULL) 21391 { 21392 STRCPY(retval, in_start); 21393 STRCAT(retval, temp_result); 21394 STRCAT(retval, expr_end + 1); 21395 } 21396 } 21397 vim_free(temp_result); 21398 21399 *in_end = c1; /* put char back for error messages */ 21400 *expr_start = '{'; 21401 *expr_end = '}'; 21402 21403 if (retval != NULL) 21404 { 21405 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 21406 if (expr_start != NULL) 21407 { 21408 /* Further expansion! */ 21409 temp_result = make_expanded_name(retval, expr_start, 21410 expr_end, temp_result); 21411 vim_free(retval); 21412 retval = temp_result; 21413 } 21414 } 21415 21416 return retval; 21417 } 21418 21419 /* 21420 * Return TRUE if character "c" can be used in a variable or function name. 21421 * Does not include '{' or '}' for magic braces. 21422 */ 21423 static int 21424 eval_isnamec(int c) 21425 { 21426 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 21427 } 21428 21429 /* 21430 * Return TRUE if character "c" can be used as the first character in a 21431 * variable or function name (excluding '{' and '}'). 21432 */ 21433 static int 21434 eval_isnamec1(int c) 21435 { 21436 return (ASCII_ISALPHA(c) || c == '_'); 21437 } 21438 21439 /* 21440 * Set number v: variable to "val". 21441 */ 21442 void 21443 set_vim_var_nr(int idx, long val) 21444 { 21445 vimvars[idx].vv_nr = val; 21446 } 21447 21448 /* 21449 * Get number v: variable value. 21450 */ 21451 long 21452 get_vim_var_nr(int idx) 21453 { 21454 return vimvars[idx].vv_nr; 21455 } 21456 21457 /* 21458 * Get string v: variable value. Uses a static buffer, can only be used once. 21459 */ 21460 char_u * 21461 get_vim_var_str(int idx) 21462 { 21463 return get_tv_string(&vimvars[idx].vv_tv); 21464 } 21465 21466 /* 21467 * Get List v: variable value. Caller must take care of reference count when 21468 * needed. 21469 */ 21470 list_T * 21471 get_vim_var_list(int idx) 21472 { 21473 return vimvars[idx].vv_list; 21474 } 21475 21476 /* 21477 * Set v:char to character "c". 21478 */ 21479 void 21480 set_vim_var_char(int c) 21481 { 21482 char_u buf[MB_MAXBYTES + 1]; 21483 21484 #ifdef FEAT_MBYTE 21485 if (has_mbyte) 21486 buf[(*mb_char2bytes)(c, buf)] = NUL; 21487 else 21488 #endif 21489 { 21490 buf[0] = c; 21491 buf[1] = NUL; 21492 } 21493 set_vim_var_string(VV_CHAR, buf, -1); 21494 } 21495 21496 /* 21497 * Set v:count to "count" and v:count1 to "count1". 21498 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 21499 */ 21500 void 21501 set_vcount( 21502 long count, 21503 long count1, 21504 int set_prevcount) 21505 { 21506 if (set_prevcount) 21507 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 21508 vimvars[VV_COUNT].vv_nr = count; 21509 vimvars[VV_COUNT1].vv_nr = count1; 21510 } 21511 21512 /* 21513 * Set string v: variable to a copy of "val". 21514 */ 21515 void 21516 set_vim_var_string( 21517 int idx, 21518 char_u *val, 21519 int len) /* length of "val" to use or -1 (whole string) */ 21520 { 21521 clear_tv(&vimvars[idx].vv_di.di_tv); 21522 vimvars[idx].vv_type = VAR_STRING; 21523 if (val == NULL) 21524 vimvars[idx].vv_str = NULL; 21525 else if (len == -1) 21526 vimvars[idx].vv_str = vim_strsave(val); 21527 else 21528 vimvars[idx].vv_str = vim_strnsave(val, len); 21529 } 21530 21531 /* 21532 * Set List v: variable to "val". 21533 */ 21534 void 21535 set_vim_var_list(int idx, list_T *val) 21536 { 21537 clear_tv(&vimvars[idx].vv_di.di_tv); 21538 vimvars[idx].vv_type = VAR_LIST; 21539 vimvars[idx].vv_list = val; 21540 if (val != NULL) 21541 ++val->lv_refcount; 21542 } 21543 21544 /* 21545 * Set Dictionary v: variable to "val". 21546 */ 21547 void 21548 set_vim_var_dict(int idx, dict_T *val) 21549 { 21550 int todo; 21551 hashitem_T *hi; 21552 21553 clear_tv(&vimvars[idx].vv_di.di_tv); 21554 vimvars[idx].vv_type = VAR_DICT; 21555 vimvars[idx].vv_dict = val; 21556 if (val != NULL) 21557 { 21558 ++val->dv_refcount; 21559 21560 /* Set readonly */ 21561 todo = (int)val->dv_hashtab.ht_used; 21562 for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) 21563 { 21564 if (HASHITEM_EMPTY(hi)) 21565 continue; 21566 --todo; 21567 HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21568 } 21569 } 21570 } 21571 21572 /* 21573 * Set v:register if needed. 21574 */ 21575 void 21576 set_reg_var(int c) 21577 { 21578 char_u regname; 21579 21580 if (c == 0 || c == ' ') 21581 regname = '"'; 21582 else 21583 regname = c; 21584 /* Avoid free/alloc when the value is already right. */ 21585 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 21586 set_vim_var_string(VV_REG, ®name, 1); 21587 } 21588 21589 /* 21590 * Get or set v:exception. If "oldval" == NULL, return the current value. 21591 * Otherwise, restore the value to "oldval" and return NULL. 21592 * Must always be called in pairs to save and restore v:exception! Does not 21593 * take care of memory allocations. 21594 */ 21595 char_u * 21596 v_exception(char_u *oldval) 21597 { 21598 if (oldval == NULL) 21599 return vimvars[VV_EXCEPTION].vv_str; 21600 21601 vimvars[VV_EXCEPTION].vv_str = oldval; 21602 return NULL; 21603 } 21604 21605 /* 21606 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 21607 * Otherwise, restore the value to "oldval" and return NULL. 21608 * Must always be called in pairs to save and restore v:throwpoint! Does not 21609 * take care of memory allocations. 21610 */ 21611 char_u * 21612 v_throwpoint(char_u *oldval) 21613 { 21614 if (oldval == NULL) 21615 return vimvars[VV_THROWPOINT].vv_str; 21616 21617 vimvars[VV_THROWPOINT].vv_str = oldval; 21618 return NULL; 21619 } 21620 21621 #if defined(FEAT_AUTOCMD) || defined(PROTO) 21622 /* 21623 * Set v:cmdarg. 21624 * If "eap" != NULL, use "eap" to generate the value and return the old value. 21625 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 21626 * Must always be called in pairs! 21627 */ 21628 char_u * 21629 set_cmdarg(exarg_T *eap, char_u *oldarg) 21630 { 21631 char_u *oldval; 21632 char_u *newval; 21633 unsigned len; 21634 21635 oldval = vimvars[VV_CMDARG].vv_str; 21636 if (eap == NULL) 21637 { 21638 vim_free(oldval); 21639 vimvars[VV_CMDARG].vv_str = oldarg; 21640 return NULL; 21641 } 21642 21643 if (eap->force_bin == FORCE_BIN) 21644 len = 6; 21645 else if (eap->force_bin == FORCE_NOBIN) 21646 len = 8; 21647 else 21648 len = 0; 21649 21650 if (eap->read_edit) 21651 len += 7; 21652 21653 if (eap->force_ff != 0) 21654 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 21655 # ifdef FEAT_MBYTE 21656 if (eap->force_enc != 0) 21657 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 21658 if (eap->bad_char != 0) 21659 len += 7 + 4; /* " ++bad=" + "keep" or "drop" */ 21660 # endif 21661 21662 newval = alloc(len + 1); 21663 if (newval == NULL) 21664 return NULL; 21665 21666 if (eap->force_bin == FORCE_BIN) 21667 sprintf((char *)newval, " ++bin"); 21668 else if (eap->force_bin == FORCE_NOBIN) 21669 sprintf((char *)newval, " ++nobin"); 21670 else 21671 *newval = NUL; 21672 21673 if (eap->read_edit) 21674 STRCAT(newval, " ++edit"); 21675 21676 if (eap->force_ff != 0) 21677 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 21678 eap->cmd + eap->force_ff); 21679 # ifdef FEAT_MBYTE 21680 if (eap->force_enc != 0) 21681 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 21682 eap->cmd + eap->force_enc); 21683 if (eap->bad_char == BAD_KEEP) 21684 STRCPY(newval + STRLEN(newval), " ++bad=keep"); 21685 else if (eap->bad_char == BAD_DROP) 21686 STRCPY(newval + STRLEN(newval), " ++bad=drop"); 21687 else if (eap->bad_char != 0) 21688 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); 21689 # endif 21690 vimvars[VV_CMDARG].vv_str = newval; 21691 return oldval; 21692 } 21693 #endif 21694 21695 /* 21696 * Get the value of internal variable "name". 21697 * Return OK or FAIL. 21698 */ 21699 static int 21700 get_var_tv( 21701 char_u *name, 21702 int len, /* length of "name" */ 21703 typval_T *rettv, /* NULL when only checking existence */ 21704 dictitem_T **dip, /* non-NULL when typval's dict item is needed */ 21705 int verbose, /* may give error message */ 21706 int no_autoload) /* do not use script autoloading */ 21707 { 21708 int ret = OK; 21709 typval_T *tv = NULL; 21710 typval_T atv; 21711 dictitem_T *v; 21712 int cc; 21713 21714 /* truncate the name, so that we can use strcmp() */ 21715 cc = name[len]; 21716 name[len] = NUL; 21717 21718 /* 21719 * Check for "b:changedtick". 21720 */ 21721 if (STRCMP(name, "b:changedtick") == 0) 21722 { 21723 atv.v_type = VAR_NUMBER; 21724 atv.vval.v_number = curbuf->b_changedtick; 21725 tv = &atv; 21726 } 21727 21728 /* 21729 * Check for user-defined variables. 21730 */ 21731 else 21732 { 21733 v = find_var(name, NULL, no_autoload); 21734 if (v != NULL) 21735 { 21736 tv = &v->di_tv; 21737 if (dip != NULL) 21738 *dip = v; 21739 } 21740 } 21741 21742 if (tv == NULL) 21743 { 21744 if (rettv != NULL && verbose) 21745 EMSG2(_(e_undefvar), name); 21746 ret = FAIL; 21747 } 21748 else if (rettv != NULL) 21749 copy_tv(tv, rettv); 21750 21751 name[len] = cc; 21752 21753 return ret; 21754 } 21755 21756 /* 21757 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 21758 * Also handle function call with Funcref variable: func(expr) 21759 * Can all be combined: dict.func(expr)[idx]['func'](expr) 21760 */ 21761 static int 21762 handle_subscript( 21763 char_u **arg, 21764 typval_T *rettv, 21765 int evaluate, /* do more than finding the end */ 21766 int verbose) /* give error messages */ 21767 { 21768 int ret = OK; 21769 dict_T *selfdict = NULL; 21770 char_u *s; 21771 int len; 21772 typval_T functv; 21773 21774 while (ret == OK 21775 && (**arg == '[' 21776 || (**arg == '.' && rettv->v_type == VAR_DICT) 21777 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC 21778 || rettv->v_type == VAR_PARTIAL))) 21779 && !vim_iswhite(*(*arg - 1))) 21780 { 21781 if (**arg == '(') 21782 { 21783 partial_T *pt = NULL; 21784 21785 /* need to copy the funcref so that we can clear rettv */ 21786 if (evaluate) 21787 { 21788 functv = *rettv; 21789 rettv->v_type = VAR_UNKNOWN; 21790 21791 /* Invoke the function. Recursive! */ 21792 if (functv.v_type == VAR_PARTIAL) 21793 { 21794 pt = functv.vval.v_partial; 21795 s = pt->pt_name; 21796 } 21797 else 21798 s = functv.vval.v_string; 21799 } 21800 else 21801 s = (char_u *)""; 21802 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 21803 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 21804 &len, evaluate, pt, selfdict); 21805 21806 /* Clear the funcref afterwards, so that deleting it while 21807 * evaluating the arguments is possible (see test55). */ 21808 if (evaluate) 21809 clear_tv(&functv); 21810 21811 /* Stop the expression evaluation when immediately aborting on 21812 * error, or when an interrupt occurred or an exception was thrown 21813 * but not caught. */ 21814 if (aborting()) 21815 { 21816 if (ret == OK) 21817 clear_tv(rettv); 21818 ret = FAIL; 21819 } 21820 dict_unref(selfdict); 21821 selfdict = NULL; 21822 } 21823 else /* **arg == '[' || **arg == '.' */ 21824 { 21825 dict_unref(selfdict); 21826 if (rettv->v_type == VAR_DICT) 21827 { 21828 selfdict = rettv->vval.v_dict; 21829 if (selfdict != NULL) 21830 ++selfdict->dv_refcount; 21831 } 21832 else 21833 selfdict = NULL; 21834 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 21835 { 21836 clear_tv(rettv); 21837 ret = FAIL; 21838 } 21839 } 21840 } 21841 21842 if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL) 21843 && selfdict != NULL) 21844 { 21845 char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string 21846 : rettv->vval.v_partial->pt_name; 21847 char_u *tofree = NULL; 21848 ufunc_T *fp; 21849 char_u fname_buf[FLEN_FIXED + 1]; 21850 int error; 21851 21852 /* Translate "s:func" to the stored function name. */ 21853 fname = fname_trans_sid(fname, fname_buf, &tofree, &error); 21854 fp = find_func(fname); 21855 vim_free(tofree); 21856 21857 /* Turn "dict.Func" into a partial for "Func" with "dict". */ 21858 if (fp != NULL && (fp->uf_flags & FC_DICT)) 21859 { 21860 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); 21861 21862 if (pt != NULL) 21863 { 21864 pt->pt_refcount = 1; 21865 pt->pt_dict = selfdict; 21866 selfdict = NULL; 21867 if (rettv->v_type == VAR_FUNC) 21868 { 21869 /* Just a function: Take over the function name and use 21870 * selfdict. */ 21871 pt->pt_name = rettv->vval.v_string; 21872 } 21873 else 21874 { 21875 partial_T *ret_pt = rettv->vval.v_partial; 21876 int i; 21877 21878 /* Partial: copy the function name, use selfdict and copy 21879 * args. Can't take over name or args, the partial might 21880 * be referenced elsewhere. */ 21881 pt->pt_name = vim_strsave(ret_pt->pt_name); 21882 func_ref(pt->pt_name); 21883 if (ret_pt->pt_argc > 0) 21884 { 21885 pt->pt_argv = (typval_T *)alloc( 21886 sizeof(typval_T) * ret_pt->pt_argc); 21887 if (pt->pt_argv == NULL) 21888 /* out of memory: drop the arguments */ 21889 pt->pt_argc = 0; 21890 else 21891 { 21892 pt->pt_argc = ret_pt->pt_argc; 21893 for (i = 0; i < pt->pt_argc; i++) 21894 copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]); 21895 } 21896 } 21897 partial_unref(ret_pt); 21898 } 21899 rettv->v_type = VAR_PARTIAL; 21900 rettv->vval.v_partial = pt; 21901 } 21902 } 21903 } 21904 21905 dict_unref(selfdict); 21906 return ret; 21907 } 21908 21909 /* 21910 * Allocate memory for a variable type-value, and make it empty (0 or NULL 21911 * value). 21912 */ 21913 typval_T * 21914 alloc_tv(void) 21915 { 21916 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 21917 } 21918 21919 /* 21920 * Allocate memory for a variable type-value, and assign a string to it. 21921 * The string "s" must have been allocated, it is consumed. 21922 * Return NULL for out of memory, the variable otherwise. 21923 */ 21924 static typval_T * 21925 alloc_string_tv(char_u *s) 21926 { 21927 typval_T *rettv; 21928 21929 rettv = alloc_tv(); 21930 if (rettv != NULL) 21931 { 21932 rettv->v_type = VAR_STRING; 21933 rettv->vval.v_string = s; 21934 } 21935 else 21936 vim_free(s); 21937 return rettv; 21938 } 21939 21940 /* 21941 * Free the memory for a variable type-value. 21942 */ 21943 void 21944 free_tv(typval_T *varp) 21945 { 21946 if (varp != NULL) 21947 { 21948 switch (varp->v_type) 21949 { 21950 case VAR_FUNC: 21951 func_unref(varp->vval.v_string); 21952 /*FALLTHROUGH*/ 21953 case VAR_STRING: 21954 vim_free(varp->vval.v_string); 21955 break; 21956 case VAR_PARTIAL: 21957 partial_unref(varp->vval.v_partial); 21958 break; 21959 case VAR_LIST: 21960 list_unref(varp->vval.v_list); 21961 break; 21962 case VAR_DICT: 21963 dict_unref(varp->vval.v_dict); 21964 break; 21965 case VAR_JOB: 21966 #ifdef FEAT_JOB_CHANNEL 21967 job_unref(varp->vval.v_job); 21968 break; 21969 #endif 21970 case VAR_CHANNEL: 21971 #ifdef FEAT_JOB_CHANNEL 21972 channel_unref(varp->vval.v_channel); 21973 break; 21974 #endif 21975 case VAR_NUMBER: 21976 case VAR_FLOAT: 21977 case VAR_UNKNOWN: 21978 case VAR_SPECIAL: 21979 break; 21980 } 21981 vim_free(varp); 21982 } 21983 } 21984 21985 /* 21986 * Free the memory for a variable value and set the value to NULL or 0. 21987 */ 21988 void 21989 clear_tv(typval_T *varp) 21990 { 21991 if (varp != NULL) 21992 { 21993 switch (varp->v_type) 21994 { 21995 case VAR_FUNC: 21996 func_unref(varp->vval.v_string); 21997 /*FALLTHROUGH*/ 21998 case VAR_STRING: 21999 vim_free(varp->vval.v_string); 22000 varp->vval.v_string = NULL; 22001 break; 22002 case VAR_PARTIAL: 22003 partial_unref(varp->vval.v_partial); 22004 varp->vval.v_partial = NULL; 22005 break; 22006 case VAR_LIST: 22007 list_unref(varp->vval.v_list); 22008 varp->vval.v_list = NULL; 22009 break; 22010 case VAR_DICT: 22011 dict_unref(varp->vval.v_dict); 22012 varp->vval.v_dict = NULL; 22013 break; 22014 case VAR_NUMBER: 22015 case VAR_SPECIAL: 22016 varp->vval.v_number = 0; 22017 break; 22018 case VAR_FLOAT: 22019 #ifdef FEAT_FLOAT 22020 varp->vval.v_float = 0.0; 22021 break; 22022 #endif 22023 case VAR_JOB: 22024 #ifdef FEAT_JOB_CHANNEL 22025 job_unref(varp->vval.v_job); 22026 varp->vval.v_job = NULL; 22027 #endif 22028 break; 22029 case VAR_CHANNEL: 22030 #ifdef FEAT_JOB_CHANNEL 22031 channel_unref(varp->vval.v_channel); 22032 varp->vval.v_channel = NULL; 22033 #endif 22034 case VAR_UNKNOWN: 22035 break; 22036 } 22037 varp->v_lock = 0; 22038 } 22039 } 22040 22041 /* 22042 * Set the value of a variable to NULL without freeing items. 22043 */ 22044 static void 22045 init_tv(typval_T *varp) 22046 { 22047 if (varp != NULL) 22048 vim_memset(varp, 0, sizeof(typval_T)); 22049 } 22050 22051 /* 22052 * Get the number value of a variable. 22053 * If it is a String variable, uses vim_str2nr(). 22054 * For incompatible types, return 0. 22055 * get_tv_number_chk() is similar to get_tv_number(), but informs the 22056 * caller of incompatible types: it sets *denote to TRUE if "denote" 22057 * is not NULL or returns -1 otherwise. 22058 */ 22059 long 22060 get_tv_number(typval_T *varp) 22061 { 22062 int error = FALSE; 22063 22064 return get_tv_number_chk(varp, &error); /* return 0L on error */ 22065 } 22066 22067 long 22068 get_tv_number_chk(typval_T *varp, int *denote) 22069 { 22070 long n = 0L; 22071 22072 switch (varp->v_type) 22073 { 22074 case VAR_NUMBER: 22075 return (long)(varp->vval.v_number); 22076 case VAR_FLOAT: 22077 #ifdef FEAT_FLOAT 22078 EMSG(_("E805: Using a Float as a Number")); 22079 break; 22080 #endif 22081 case VAR_FUNC: 22082 case VAR_PARTIAL: 22083 EMSG(_("E703: Using a Funcref as a Number")); 22084 break; 22085 case VAR_STRING: 22086 if (varp->vval.v_string != NULL) 22087 vim_str2nr(varp->vval.v_string, NULL, NULL, 22088 STR2NR_ALL, &n, NULL, 0); 22089 return n; 22090 case VAR_LIST: 22091 EMSG(_("E745: Using a List as a Number")); 22092 break; 22093 case VAR_DICT: 22094 EMSG(_("E728: Using a Dictionary as a Number")); 22095 break; 22096 case VAR_SPECIAL: 22097 return varp->vval.v_number == VVAL_TRUE ? 1 : 0; 22098 break; 22099 case VAR_JOB: 22100 #ifdef FEAT_JOB_CHANNEL 22101 EMSG(_("E910: Using a Job as a Number")); 22102 break; 22103 #endif 22104 case VAR_CHANNEL: 22105 #ifdef FEAT_JOB_CHANNEL 22106 EMSG(_("E913: Using a Channel as a Number")); 22107 break; 22108 #endif 22109 case VAR_UNKNOWN: 22110 EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)"); 22111 break; 22112 } 22113 if (denote == NULL) /* useful for values that must be unsigned */ 22114 n = -1; 22115 else 22116 *denote = TRUE; 22117 return n; 22118 } 22119 22120 #ifdef FEAT_FLOAT 22121 static float_T 22122 get_tv_float(typval_T *varp) 22123 { 22124 switch (varp->v_type) 22125 { 22126 case VAR_NUMBER: 22127 return (float_T)(varp->vval.v_number); 22128 case VAR_FLOAT: 22129 return varp->vval.v_float; 22130 case VAR_FUNC: 22131 case VAR_PARTIAL: 22132 EMSG(_("E891: Using a Funcref as a Float")); 22133 break; 22134 case VAR_STRING: 22135 EMSG(_("E892: Using a String as a Float")); 22136 break; 22137 case VAR_LIST: 22138 EMSG(_("E893: Using a List as a Float")); 22139 break; 22140 case VAR_DICT: 22141 EMSG(_("E894: Using a Dictionary as a Float")); 22142 break; 22143 case VAR_SPECIAL: 22144 EMSG(_("E907: Using a special value as a Float")); 22145 break; 22146 case VAR_JOB: 22147 # ifdef FEAT_JOB_CHANNEL 22148 EMSG(_("E911: Using a Job as a Float")); 22149 break; 22150 # endif 22151 case VAR_CHANNEL: 22152 # ifdef FEAT_JOB_CHANNEL 22153 EMSG(_("E914: Using a Channel as a Float")); 22154 break; 22155 # endif 22156 case VAR_UNKNOWN: 22157 EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)"); 22158 break; 22159 } 22160 return 0; 22161 } 22162 #endif 22163 22164 /* 22165 * Get the lnum from the first argument. 22166 * Also accepts ".", "$", etc., but that only works for the current buffer. 22167 * Returns -1 on error. 22168 */ 22169 static linenr_T 22170 get_tv_lnum(typval_T *argvars) 22171 { 22172 typval_T rettv; 22173 linenr_T lnum; 22174 22175 lnum = get_tv_number_chk(&argvars[0], NULL); 22176 if (lnum == 0) /* no valid number, try using line() */ 22177 { 22178 rettv.v_type = VAR_NUMBER; 22179 f_line(argvars, &rettv); 22180 lnum = rettv.vval.v_number; 22181 clear_tv(&rettv); 22182 } 22183 return lnum; 22184 } 22185 22186 /* 22187 * Get the lnum from the first argument. 22188 * Also accepts "$", then "buf" is used. 22189 * Returns 0 on error. 22190 */ 22191 static linenr_T 22192 get_tv_lnum_buf(typval_T *argvars, buf_T *buf) 22193 { 22194 if (argvars[0].v_type == VAR_STRING 22195 && argvars[0].vval.v_string != NULL 22196 && argvars[0].vval.v_string[0] == '$' 22197 && buf != NULL) 22198 return buf->b_ml.ml_line_count; 22199 return get_tv_number_chk(&argvars[0], NULL); 22200 } 22201 22202 /* 22203 * Get the string value of a variable. 22204 * If it is a Number variable, the number is converted into a string. 22205 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 22206 * get_tv_string_buf() uses a given buffer. 22207 * If the String variable has never been set, return an empty string. 22208 * Never returns NULL; 22209 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 22210 * NULL on error. 22211 */ 22212 char_u * 22213 get_tv_string(typval_T *varp) 22214 { 22215 static char_u mybuf[NUMBUFLEN]; 22216 22217 return get_tv_string_buf(varp, mybuf); 22218 } 22219 22220 char_u * 22221 get_tv_string_buf(typval_T *varp, char_u *buf) 22222 { 22223 char_u *res = get_tv_string_buf_chk(varp, buf); 22224 22225 return res != NULL ? res : (char_u *)""; 22226 } 22227 22228 /* 22229 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 22230 */ 22231 char_u * 22232 get_tv_string_chk(typval_T *varp) 22233 { 22234 static char_u mybuf[NUMBUFLEN]; 22235 22236 return get_tv_string_buf_chk(varp, mybuf); 22237 } 22238 22239 char_u * 22240 get_tv_string_buf_chk(typval_T *varp, char_u *buf) 22241 { 22242 switch (varp->v_type) 22243 { 22244 case VAR_NUMBER: 22245 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 22246 return buf; 22247 case VAR_FUNC: 22248 case VAR_PARTIAL: 22249 EMSG(_("E729: using Funcref as a String")); 22250 break; 22251 case VAR_LIST: 22252 EMSG(_("E730: using List as a String")); 22253 break; 22254 case VAR_DICT: 22255 EMSG(_("E731: using Dictionary as a String")); 22256 break; 22257 case VAR_FLOAT: 22258 #ifdef FEAT_FLOAT 22259 EMSG(_(e_float_as_string)); 22260 break; 22261 #endif 22262 case VAR_STRING: 22263 if (varp->vval.v_string != NULL) 22264 return varp->vval.v_string; 22265 return (char_u *)""; 22266 case VAR_SPECIAL: 22267 STRCPY(buf, get_var_special_name(varp->vval.v_number)); 22268 return buf; 22269 case VAR_JOB: 22270 #ifdef FEAT_JOB_CHANNEL 22271 { 22272 job_T *job = varp->vval.v_job; 22273 char *status; 22274 22275 if (job == NULL) 22276 return (char_u *)"no process"; 22277 status = job->jv_status == JOB_FAILED ? "fail" 22278 : job->jv_status == JOB_ENDED ? "dead" 22279 : "run"; 22280 # ifdef UNIX 22281 vim_snprintf((char *)buf, NUMBUFLEN, 22282 "process %ld %s", (long)job->jv_pid, status); 22283 # elif defined(WIN32) 22284 vim_snprintf((char *)buf, NUMBUFLEN, 22285 "process %ld %s", 22286 (long)job->jv_proc_info.dwProcessId, 22287 status); 22288 # else 22289 /* fall-back */ 22290 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status); 22291 # endif 22292 return buf; 22293 } 22294 #endif 22295 break; 22296 case VAR_CHANNEL: 22297 #ifdef FEAT_JOB_CHANNEL 22298 { 22299 channel_T *channel = varp->vval.v_channel; 22300 char *status = channel_status(channel); 22301 22302 if (channel == NULL) 22303 vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status); 22304 else 22305 vim_snprintf((char *)buf, NUMBUFLEN, 22306 "channel %d %s", channel->ch_id, status); 22307 return buf; 22308 } 22309 #endif 22310 break; 22311 case VAR_UNKNOWN: 22312 EMSG(_("E908: using an invalid value as a String")); 22313 break; 22314 } 22315 return NULL; 22316 } 22317 22318 /* 22319 * Find variable "name" in the list of variables. 22320 * Return a pointer to it if found, NULL if not found. 22321 * Careful: "a:0" variables don't have a name. 22322 * When "htp" is not NULL we are writing to the variable, set "htp" to the 22323 * hashtab_T used. 22324 */ 22325 static dictitem_T * 22326 find_var(char_u *name, hashtab_T **htp, int no_autoload) 22327 { 22328 char_u *varname; 22329 hashtab_T *ht; 22330 22331 ht = find_var_ht(name, &varname); 22332 if (htp != NULL) 22333 *htp = ht; 22334 if (ht == NULL) 22335 return NULL; 22336 return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); 22337 } 22338 22339 /* 22340 * Find variable "varname" in hashtab "ht" with name "htname". 22341 * Returns NULL if not found. 22342 */ 22343 static dictitem_T * 22344 find_var_in_ht( 22345 hashtab_T *ht, 22346 int htname, 22347 char_u *varname, 22348 int no_autoload) 22349 { 22350 hashitem_T *hi; 22351 22352 if (*varname == NUL) 22353 { 22354 /* Must be something like "s:", otherwise "ht" would be NULL. */ 22355 switch (htname) 22356 { 22357 case 's': return &SCRIPT_SV(current_SID)->sv_var; 22358 case 'g': return &globvars_var; 22359 case 'v': return &vimvars_var; 22360 case 'b': return &curbuf->b_bufvar; 22361 case 'w': return &curwin->w_winvar; 22362 #ifdef FEAT_WINDOWS 22363 case 't': return &curtab->tp_winvar; 22364 #endif 22365 case 'l': return current_funccal == NULL 22366 ? NULL : ¤t_funccal->l_vars_var; 22367 case 'a': return current_funccal == NULL 22368 ? NULL : ¤t_funccal->l_avars_var; 22369 } 22370 return NULL; 22371 } 22372 22373 hi = hash_find(ht, varname); 22374 if (HASHITEM_EMPTY(hi)) 22375 { 22376 /* For global variables we may try auto-loading the script. If it 22377 * worked find the variable again. Don't auto-load a script if it was 22378 * loaded already, otherwise it would be loaded every time when 22379 * checking if a function name is a Funcref variable. */ 22380 if (ht == &globvarht && !no_autoload) 22381 { 22382 /* Note: script_autoload() may make "hi" invalid. It must either 22383 * be obtained again or not used. */ 22384 if (!script_autoload(varname, FALSE) || aborting()) 22385 return NULL; 22386 hi = hash_find(ht, varname); 22387 } 22388 if (HASHITEM_EMPTY(hi)) 22389 return NULL; 22390 } 22391 return HI2DI(hi); 22392 } 22393 22394 /* 22395 * Find the hashtab used for a variable name. 22396 * Return NULL if the name is not valid. 22397 * Set "varname" to the start of name without ':'. 22398 */ 22399 static hashtab_T * 22400 find_var_ht(char_u *name, char_u **varname) 22401 { 22402 hashitem_T *hi; 22403 22404 if (name[0] == NUL) 22405 return NULL; 22406 if (name[1] != ':') 22407 { 22408 /* The name must not start with a colon or #. */ 22409 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 22410 return NULL; 22411 *varname = name; 22412 22413 /* "version" is "v:version" in all scopes */ 22414 hi = hash_find(&compat_hashtab, name); 22415 if (!HASHITEM_EMPTY(hi)) 22416 return &compat_hashtab; 22417 22418 if (current_funccal == NULL) 22419 return &globvarht; /* global variable */ 22420 return &get_funccal()->l_vars.dv_hashtab; /* l: variable */ 22421 } 22422 *varname = name + 2; 22423 if (*name == 'g') /* global variable */ 22424 return &globvarht; 22425 /* There must be no ':' or '#' in the rest of the name, unless g: is used 22426 */ 22427 if (vim_strchr(name + 2, ':') != NULL 22428 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 22429 return NULL; 22430 if (*name == 'b') /* buffer variable */ 22431 return &curbuf->b_vars->dv_hashtab; 22432 if (*name == 'w') /* window variable */ 22433 return &curwin->w_vars->dv_hashtab; 22434 #ifdef FEAT_WINDOWS 22435 if (*name == 't') /* tab page variable */ 22436 return &curtab->tp_vars->dv_hashtab; 22437 #endif 22438 if (*name == 'v') /* v: variable */ 22439 return &vimvarht; 22440 if (*name == 'a' && current_funccal != NULL) /* function argument */ 22441 return &get_funccal()->l_avars.dv_hashtab; 22442 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 22443 return &get_funccal()->l_vars.dv_hashtab; 22444 if (*name == 's' /* script variable */ 22445 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 22446 return &SCRIPT_VARS(current_SID); 22447 return NULL; 22448 } 22449 22450 /* 22451 * Get function call environment based on bactrace debug level 22452 */ 22453 static funccall_T * 22454 get_funccal(void) 22455 { 22456 int i; 22457 funccall_T *funccal; 22458 funccall_T *temp_funccal; 22459 22460 funccal = current_funccal; 22461 if (debug_backtrace_level > 0) 22462 { 22463 for (i = 0; i < debug_backtrace_level; i++) 22464 { 22465 temp_funccal = funccal->caller; 22466 if (temp_funccal) 22467 funccal = temp_funccal; 22468 else 22469 /* backtrace level overflow. reset to max */ 22470 debug_backtrace_level = i; 22471 } 22472 } 22473 return funccal; 22474 } 22475 22476 /* 22477 * Get the string value of a (global/local) variable. 22478 * Note: see get_tv_string() for how long the pointer remains valid. 22479 * Returns NULL when it doesn't exist. 22480 */ 22481 char_u * 22482 get_var_value(char_u *name) 22483 { 22484 dictitem_T *v; 22485 22486 v = find_var(name, NULL, FALSE); 22487 if (v == NULL) 22488 return NULL; 22489 return get_tv_string(&v->di_tv); 22490 } 22491 22492 /* 22493 * Allocate a new hashtab for a sourced script. It will be used while 22494 * sourcing this script and when executing functions defined in the script. 22495 */ 22496 void 22497 new_script_vars(scid_T id) 22498 { 22499 int i; 22500 hashtab_T *ht; 22501 scriptvar_T *sv; 22502 22503 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 22504 { 22505 /* Re-allocating ga_data means that an ht_array pointing to 22506 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 22507 * at its init value. Also reset "v_dict", it's always the same. */ 22508 for (i = 1; i <= ga_scripts.ga_len; ++i) 22509 { 22510 ht = &SCRIPT_VARS(i); 22511 if (ht->ht_mask == HT_INIT_SIZE - 1) 22512 ht->ht_array = ht->ht_smallarray; 22513 sv = SCRIPT_SV(i); 22514 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 22515 } 22516 22517 while (ga_scripts.ga_len < id) 22518 { 22519 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = 22520 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); 22521 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); 22522 ++ga_scripts.ga_len; 22523 } 22524 } 22525 } 22526 22527 /* 22528 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 22529 * point to it. 22530 */ 22531 void 22532 init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope) 22533 { 22534 hash_init(&dict->dv_hashtab); 22535 dict->dv_lock = 0; 22536 dict->dv_scope = scope; 22537 dict->dv_refcount = DO_NOT_FREE_CNT; 22538 dict->dv_copyID = 0; 22539 dict_var->di_tv.vval.v_dict = dict; 22540 dict_var->di_tv.v_type = VAR_DICT; 22541 dict_var->di_tv.v_lock = VAR_FIXED; 22542 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 22543 dict_var->di_key[0] = NUL; 22544 } 22545 22546 /* 22547 * Unreference a dictionary initialized by init_var_dict(). 22548 */ 22549 void 22550 unref_var_dict(dict_T *dict) 22551 { 22552 /* Now the dict needs to be freed if no one else is using it, go back to 22553 * normal reference counting. */ 22554 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; 22555 dict_unref(dict); 22556 } 22557 22558 /* 22559 * Clean up a list of internal variables. 22560 * Frees all allocated variables and the value they contain. 22561 * Clears hashtab "ht", does not free it. 22562 */ 22563 void 22564 vars_clear(hashtab_T *ht) 22565 { 22566 vars_clear_ext(ht, TRUE); 22567 } 22568 22569 /* 22570 * Like vars_clear(), but only free the value if "free_val" is TRUE. 22571 */ 22572 static void 22573 vars_clear_ext(hashtab_T *ht, int free_val) 22574 { 22575 int todo; 22576 hashitem_T *hi; 22577 dictitem_T *v; 22578 22579 hash_lock(ht); 22580 todo = (int)ht->ht_used; 22581 for (hi = ht->ht_array; todo > 0; ++hi) 22582 { 22583 if (!HASHITEM_EMPTY(hi)) 22584 { 22585 --todo; 22586 22587 /* Free the variable. Don't remove it from the hashtab, 22588 * ht_array might change then. hash_clear() takes care of it 22589 * later. */ 22590 v = HI2DI(hi); 22591 if (free_val) 22592 clear_tv(&v->di_tv); 22593 if (v->di_flags & DI_FLAGS_ALLOC) 22594 vim_free(v); 22595 } 22596 } 22597 hash_clear(ht); 22598 ht->ht_used = 0; 22599 } 22600 22601 /* 22602 * Delete a variable from hashtab "ht" at item "hi". 22603 * Clear the variable value and free the dictitem. 22604 */ 22605 static void 22606 delete_var(hashtab_T *ht, hashitem_T *hi) 22607 { 22608 dictitem_T *di = HI2DI(hi); 22609 22610 hash_remove(ht, hi); 22611 clear_tv(&di->di_tv); 22612 vim_free(di); 22613 } 22614 22615 /* 22616 * List the value of one internal variable. 22617 */ 22618 static void 22619 list_one_var(dictitem_T *v, char_u *prefix, int *first) 22620 { 22621 char_u *tofree; 22622 char_u *s; 22623 char_u numbuf[NUMBUFLEN]; 22624 22625 s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID()); 22626 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 22627 s == NULL ? (char_u *)"" : s, first); 22628 vim_free(tofree); 22629 } 22630 22631 static void 22632 list_one_var_a( 22633 char_u *prefix, 22634 char_u *name, 22635 int type, 22636 char_u *string, 22637 int *first) /* when TRUE clear rest of screen and set to FALSE */ 22638 { 22639 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 22640 msg_start(); 22641 msg_puts(prefix); 22642 if (name != NULL) /* "a:" vars don't have a name stored */ 22643 msg_puts(name); 22644 msg_putchar(' '); 22645 msg_advance(22); 22646 if (type == VAR_NUMBER) 22647 msg_putchar('#'); 22648 else if (type == VAR_FUNC || type == VAR_PARTIAL) 22649 msg_putchar('*'); 22650 else if (type == VAR_LIST) 22651 { 22652 msg_putchar('['); 22653 if (*string == '[') 22654 ++string; 22655 } 22656 else if (type == VAR_DICT) 22657 { 22658 msg_putchar('{'); 22659 if (*string == '{') 22660 ++string; 22661 } 22662 else 22663 msg_putchar(' '); 22664 22665 msg_outtrans(string); 22666 22667 if (type == VAR_FUNC || type == VAR_PARTIAL) 22668 msg_puts((char_u *)"()"); 22669 if (*first) 22670 { 22671 msg_clr_eos(); 22672 *first = FALSE; 22673 } 22674 } 22675 22676 /* 22677 * Set variable "name" to value in "tv". 22678 * If the variable already exists, the value is updated. 22679 * Otherwise the variable is created. 22680 */ 22681 static void 22682 set_var( 22683 char_u *name, 22684 typval_T *tv, 22685 int copy) /* make copy of value in "tv" */ 22686 { 22687 dictitem_T *v; 22688 char_u *varname; 22689 hashtab_T *ht; 22690 22691 ht = find_var_ht(name, &varname); 22692 if (ht == NULL || *varname == NUL) 22693 { 22694 EMSG2(_(e_illvar), name); 22695 return; 22696 } 22697 v = find_var_in_ht(ht, 0, varname, TRUE); 22698 22699 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) 22700 && var_check_func_name(name, v == NULL)) 22701 return; 22702 22703 if (v != NULL) 22704 { 22705 /* existing variable, need to clear the value */ 22706 if (var_check_ro(v->di_flags, name, FALSE) 22707 || tv_check_lock(v->di_tv.v_lock, name, FALSE)) 22708 return; 22709 22710 /* 22711 * Handle setting internal v: variables separately where needed to 22712 * prevent changing the type. 22713 */ 22714 if (ht == &vimvarht) 22715 { 22716 if (v->di_tv.v_type == VAR_STRING) 22717 { 22718 vim_free(v->di_tv.vval.v_string); 22719 if (copy || tv->v_type != VAR_STRING) 22720 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 22721 else 22722 { 22723 /* Take over the string to avoid an extra alloc/free. */ 22724 v->di_tv.vval.v_string = tv->vval.v_string; 22725 tv->vval.v_string = NULL; 22726 } 22727 return; 22728 } 22729 else if (v->di_tv.v_type == VAR_NUMBER) 22730 { 22731 v->di_tv.vval.v_number = get_tv_number(tv); 22732 if (STRCMP(varname, "searchforward") == 0) 22733 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 22734 #ifdef FEAT_SEARCH_EXTRA 22735 else if (STRCMP(varname, "hlsearch") == 0) 22736 { 22737 no_hlsearch = !v->di_tv.vval.v_number; 22738 redraw_all_later(SOME_VALID); 22739 } 22740 #endif 22741 return; 22742 } 22743 else if (v->di_tv.v_type != tv->v_type) 22744 EMSG2(_(e_intern2), "set_var()"); 22745 } 22746 22747 clear_tv(&v->di_tv); 22748 } 22749 else /* add a new variable */ 22750 { 22751 /* Can't add "v:" variable. */ 22752 if (ht == &vimvarht) 22753 { 22754 EMSG2(_(e_illvar), name); 22755 return; 22756 } 22757 22758 /* Make sure the variable name is valid. */ 22759 if (!valid_varname(varname)) 22760 return; 22761 22762 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 22763 + STRLEN(varname))); 22764 if (v == NULL) 22765 return; 22766 STRCPY(v->di_key, varname); 22767 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 22768 { 22769 vim_free(v); 22770 return; 22771 } 22772 v->di_flags = DI_FLAGS_ALLOC; 22773 } 22774 22775 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 22776 copy_tv(tv, &v->di_tv); 22777 else 22778 { 22779 v->di_tv = *tv; 22780 v->di_tv.v_lock = 0; 22781 init_tv(tv); 22782 } 22783 } 22784 22785 /* 22786 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 22787 * Also give an error message. 22788 */ 22789 static int 22790 var_check_ro(int flags, char_u *name, int use_gettext) 22791 { 22792 if (flags & DI_FLAGS_RO) 22793 { 22794 EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); 22795 return TRUE; 22796 } 22797 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 22798 { 22799 EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name); 22800 return TRUE; 22801 } 22802 return FALSE; 22803 } 22804 22805 /* 22806 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 22807 * Also give an error message. 22808 */ 22809 static int 22810 var_check_fixed(int flags, char_u *name, int use_gettext) 22811 { 22812 if (flags & DI_FLAGS_FIX) 22813 { 22814 EMSG2(_("E795: Cannot delete variable %s"), 22815 use_gettext ? (char_u *)_(name) : name); 22816 return TRUE; 22817 } 22818 return FALSE; 22819 } 22820 22821 /* 22822 * Check if a funcref is assigned to a valid variable name. 22823 * Return TRUE and give an error if not. 22824 */ 22825 static int 22826 var_check_func_name( 22827 char_u *name, /* points to start of variable name */ 22828 int new_var) /* TRUE when creating the variable */ 22829 { 22830 /* Allow for w: b: s: and t:. */ 22831 if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':') 22832 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 22833 ? name[2] : name[0])) 22834 { 22835 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), 22836 name); 22837 return TRUE; 22838 } 22839 /* Don't allow hiding a function. When "v" is not NULL we might be 22840 * assigning another function to the same var, the type is checked 22841 * below. */ 22842 if (new_var && function_exists(name)) 22843 { 22844 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 22845 name); 22846 return TRUE; 22847 } 22848 return FALSE; 22849 } 22850 22851 /* 22852 * Check if a variable name is valid. 22853 * Return FALSE and give an error if not. 22854 */ 22855 static int 22856 valid_varname(char_u *varname) 22857 { 22858 char_u *p; 22859 22860 for (p = varname; *p != NUL; ++p) 22861 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 22862 && *p != AUTOLOAD_CHAR) 22863 { 22864 EMSG2(_(e_illvar), varname); 22865 return FALSE; 22866 } 22867 return TRUE; 22868 } 22869 22870 /* 22871 * Return TRUE if typeval "tv" is set to be locked (immutable). 22872 * Also give an error message, using "name" or _("name") when use_gettext is 22873 * TRUE. 22874 */ 22875 static int 22876 tv_check_lock(int lock, char_u *name, int use_gettext) 22877 { 22878 if (lock & VAR_LOCKED) 22879 { 22880 EMSG2(_("E741: Value is locked: %s"), 22881 name == NULL ? (char_u *)_("Unknown") 22882 : use_gettext ? (char_u *)_(name) 22883 : name); 22884 return TRUE; 22885 } 22886 if (lock & VAR_FIXED) 22887 { 22888 EMSG2(_("E742: Cannot change value of %s"), 22889 name == NULL ? (char_u *)_("Unknown") 22890 : use_gettext ? (char_u *)_(name) 22891 : name); 22892 return TRUE; 22893 } 22894 return FALSE; 22895 } 22896 22897 /* 22898 * Copy the values from typval_T "from" to typval_T "to". 22899 * When needed allocates string or increases reference count. 22900 * Does not make a copy of a list or dict but copies the reference! 22901 * It is OK for "from" and "to" to point to the same item. This is used to 22902 * make a copy later. 22903 */ 22904 void 22905 copy_tv(typval_T *from, typval_T *to) 22906 { 22907 to->v_type = from->v_type; 22908 to->v_lock = 0; 22909 switch (from->v_type) 22910 { 22911 case VAR_NUMBER: 22912 case VAR_SPECIAL: 22913 to->vval.v_number = from->vval.v_number; 22914 break; 22915 case VAR_FLOAT: 22916 #ifdef FEAT_FLOAT 22917 to->vval.v_float = from->vval.v_float; 22918 break; 22919 #endif 22920 case VAR_JOB: 22921 #ifdef FEAT_JOB_CHANNEL 22922 to->vval.v_job = from->vval.v_job; 22923 if (to->vval.v_job != NULL) 22924 ++to->vval.v_job->jv_refcount; 22925 break; 22926 #endif 22927 case VAR_CHANNEL: 22928 #ifdef FEAT_JOB_CHANNEL 22929 to->vval.v_channel = from->vval.v_channel; 22930 if (to->vval.v_channel != NULL) 22931 ++to->vval.v_channel->ch_refcount; 22932 break; 22933 #endif 22934 case VAR_STRING: 22935 case VAR_FUNC: 22936 if (from->vval.v_string == NULL) 22937 to->vval.v_string = NULL; 22938 else 22939 { 22940 to->vval.v_string = vim_strsave(from->vval.v_string); 22941 if (from->v_type == VAR_FUNC) 22942 func_ref(to->vval.v_string); 22943 } 22944 break; 22945 case VAR_PARTIAL: 22946 if (from->vval.v_partial == NULL) 22947 to->vval.v_partial = NULL; 22948 else 22949 { 22950 to->vval.v_partial = from->vval.v_partial; 22951 ++to->vval.v_partial->pt_refcount; 22952 } 22953 break; 22954 case VAR_LIST: 22955 if (from->vval.v_list == NULL) 22956 to->vval.v_list = NULL; 22957 else 22958 { 22959 to->vval.v_list = from->vval.v_list; 22960 ++to->vval.v_list->lv_refcount; 22961 } 22962 break; 22963 case VAR_DICT: 22964 if (from->vval.v_dict == NULL) 22965 to->vval.v_dict = NULL; 22966 else 22967 { 22968 to->vval.v_dict = from->vval.v_dict; 22969 ++to->vval.v_dict->dv_refcount; 22970 } 22971 break; 22972 case VAR_UNKNOWN: 22973 EMSG2(_(e_intern2), "copy_tv(UNKNOWN)"); 22974 break; 22975 } 22976 } 22977 22978 /* 22979 * Make a copy of an item. 22980 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 22981 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 22982 * reference to an already copied list/dict can be used. 22983 * Returns FAIL or OK. 22984 */ 22985 static int 22986 item_copy( 22987 typval_T *from, 22988 typval_T *to, 22989 int deep, 22990 int copyID) 22991 { 22992 static int recurse = 0; 22993 int ret = OK; 22994 22995 if (recurse >= DICT_MAXNEST) 22996 { 22997 EMSG(_("E698: variable nested too deep for making a copy")); 22998 return FAIL; 22999 } 23000 ++recurse; 23001 23002 switch (from->v_type) 23003 { 23004 case VAR_NUMBER: 23005 case VAR_FLOAT: 23006 case VAR_STRING: 23007 case VAR_FUNC: 23008 case VAR_PARTIAL: 23009 case VAR_SPECIAL: 23010 case VAR_JOB: 23011 case VAR_CHANNEL: 23012 copy_tv(from, to); 23013 break; 23014 case VAR_LIST: 23015 to->v_type = VAR_LIST; 23016 to->v_lock = 0; 23017 if (from->vval.v_list == NULL) 23018 to->vval.v_list = NULL; 23019 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 23020 { 23021 /* use the copy made earlier */ 23022 to->vval.v_list = from->vval.v_list->lv_copylist; 23023 ++to->vval.v_list->lv_refcount; 23024 } 23025 else 23026 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 23027 if (to->vval.v_list == NULL) 23028 ret = FAIL; 23029 break; 23030 case VAR_DICT: 23031 to->v_type = VAR_DICT; 23032 to->v_lock = 0; 23033 if (from->vval.v_dict == NULL) 23034 to->vval.v_dict = NULL; 23035 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 23036 { 23037 /* use the copy made earlier */ 23038 to->vval.v_dict = from->vval.v_dict->dv_copydict; 23039 ++to->vval.v_dict->dv_refcount; 23040 } 23041 else 23042 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 23043 if (to->vval.v_dict == NULL) 23044 ret = FAIL; 23045 break; 23046 case VAR_UNKNOWN: 23047 EMSG2(_(e_intern2), "item_copy(UNKNOWN)"); 23048 ret = FAIL; 23049 } 23050 --recurse; 23051 return ret; 23052 } 23053 23054 /* 23055 * ":echo expr1 ..." print each argument separated with a space, add a 23056 * newline at the end. 23057 * ":echon expr1 ..." print each argument plain. 23058 */ 23059 void 23060 ex_echo(exarg_T *eap) 23061 { 23062 char_u *arg = eap->arg; 23063 typval_T rettv; 23064 char_u *tofree; 23065 char_u *p; 23066 int needclr = TRUE; 23067 int atstart = TRUE; 23068 char_u numbuf[NUMBUFLEN]; 23069 23070 if (eap->skip) 23071 ++emsg_skip; 23072 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 23073 { 23074 /* If eval1() causes an error message the text from the command may 23075 * still need to be cleared. E.g., "echo 22,44". */ 23076 need_clr_eos = needclr; 23077 23078 p = arg; 23079 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 23080 { 23081 /* 23082 * Report the invalid expression unless the expression evaluation 23083 * has been cancelled due to an aborting error, an interrupt, or an 23084 * exception. 23085 */ 23086 if (!aborting()) 23087 EMSG2(_(e_invexpr2), p); 23088 need_clr_eos = FALSE; 23089 break; 23090 } 23091 need_clr_eos = FALSE; 23092 23093 if (!eap->skip) 23094 { 23095 if (atstart) 23096 { 23097 atstart = FALSE; 23098 /* Call msg_start() after eval1(), evaluating the expression 23099 * may cause a message to appear. */ 23100 if (eap->cmdidx == CMD_echo) 23101 { 23102 /* Mark the saved text as finishing the line, so that what 23103 * follows is displayed on a new line when scrolling back 23104 * at the more prompt. */ 23105 msg_sb_eol(); 23106 msg_start(); 23107 } 23108 } 23109 else if (eap->cmdidx == CMD_echo) 23110 msg_puts_attr((char_u *)" ", echo_attr); 23111 p = echo_string(&rettv, &tofree, numbuf, get_copyID()); 23112 if (p != NULL) 23113 for ( ; *p != NUL && !got_int; ++p) 23114 { 23115 if (*p == '\n' || *p == '\r' || *p == TAB) 23116 { 23117 if (*p != TAB && needclr) 23118 { 23119 /* remove any text still there from the command */ 23120 msg_clr_eos(); 23121 needclr = FALSE; 23122 } 23123 msg_putchar_attr(*p, echo_attr); 23124 } 23125 else 23126 { 23127 #ifdef FEAT_MBYTE 23128 if (has_mbyte) 23129 { 23130 int i = (*mb_ptr2len)(p); 23131 23132 (void)msg_outtrans_len_attr(p, i, echo_attr); 23133 p += i - 1; 23134 } 23135 else 23136 #endif 23137 (void)msg_outtrans_len_attr(p, 1, echo_attr); 23138 } 23139 } 23140 vim_free(tofree); 23141 } 23142 clear_tv(&rettv); 23143 arg = skipwhite(arg); 23144 } 23145 eap->nextcmd = check_nextcmd(arg); 23146 23147 if (eap->skip) 23148 --emsg_skip; 23149 else 23150 { 23151 /* remove text that may still be there from the command */ 23152 if (needclr) 23153 msg_clr_eos(); 23154 if (eap->cmdidx == CMD_echo) 23155 msg_end(); 23156 } 23157 } 23158 23159 /* 23160 * ":echohl {name}". 23161 */ 23162 void 23163 ex_echohl(exarg_T *eap) 23164 { 23165 int id; 23166 23167 id = syn_name2id(eap->arg); 23168 if (id == 0) 23169 echo_attr = 0; 23170 else 23171 echo_attr = syn_id2attr(id); 23172 } 23173 23174 /* 23175 * ":execute expr1 ..." execute the result of an expression. 23176 * ":echomsg expr1 ..." Print a message 23177 * ":echoerr expr1 ..." Print an error 23178 * Each gets spaces around each argument and a newline at the end for 23179 * echo commands 23180 */ 23181 void 23182 ex_execute(exarg_T *eap) 23183 { 23184 char_u *arg = eap->arg; 23185 typval_T rettv; 23186 int ret = OK; 23187 char_u *p; 23188 garray_T ga; 23189 int len; 23190 int save_did_emsg; 23191 23192 ga_init2(&ga, 1, 80); 23193 23194 if (eap->skip) 23195 ++emsg_skip; 23196 while (*arg != NUL && *arg != '|' && *arg != '\n') 23197 { 23198 p = arg; 23199 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 23200 { 23201 /* 23202 * Report the invalid expression unless the expression evaluation 23203 * has been cancelled due to an aborting error, an interrupt, or an 23204 * exception. 23205 */ 23206 if (!aborting()) 23207 EMSG2(_(e_invexpr2), p); 23208 ret = FAIL; 23209 break; 23210 } 23211 23212 if (!eap->skip) 23213 { 23214 p = get_tv_string(&rettv); 23215 len = (int)STRLEN(p); 23216 if (ga_grow(&ga, len + 2) == FAIL) 23217 { 23218 clear_tv(&rettv); 23219 ret = FAIL; 23220 break; 23221 } 23222 if (ga.ga_len) 23223 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 23224 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 23225 ga.ga_len += len; 23226 } 23227 23228 clear_tv(&rettv); 23229 arg = skipwhite(arg); 23230 } 23231 23232 if (ret != FAIL && ga.ga_data != NULL) 23233 { 23234 if (eap->cmdidx == CMD_echomsg) 23235 { 23236 MSG_ATTR(ga.ga_data, echo_attr); 23237 out_flush(); 23238 } 23239 else if (eap->cmdidx == CMD_echoerr) 23240 { 23241 /* We don't want to abort following commands, restore did_emsg. */ 23242 save_did_emsg = did_emsg; 23243 EMSG((char_u *)ga.ga_data); 23244 if (!force_abort) 23245 did_emsg = save_did_emsg; 23246 } 23247 else if (eap->cmdidx == CMD_execute) 23248 do_cmdline((char_u *)ga.ga_data, 23249 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 23250 } 23251 23252 ga_clear(&ga); 23253 23254 if (eap->skip) 23255 --emsg_skip; 23256 23257 eap->nextcmd = check_nextcmd(arg); 23258 } 23259 23260 /* 23261 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 23262 * "arg" points to the "&" or '+' when called, to "option" when returning. 23263 * Returns NULL when no option name found. Otherwise pointer to the char 23264 * after the option name. 23265 */ 23266 static char_u * 23267 find_option_end(char_u **arg, int *opt_flags) 23268 { 23269 char_u *p = *arg; 23270 23271 ++p; 23272 if (*p == 'g' && p[1] == ':') 23273 { 23274 *opt_flags = OPT_GLOBAL; 23275 p += 2; 23276 } 23277 else if (*p == 'l' && p[1] == ':') 23278 { 23279 *opt_flags = OPT_LOCAL; 23280 p += 2; 23281 } 23282 else 23283 *opt_flags = 0; 23284 23285 if (!ASCII_ISALPHA(*p)) 23286 return NULL; 23287 *arg = p; 23288 23289 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 23290 p += 4; /* termcap option */ 23291 else 23292 while (ASCII_ISALPHA(*p)) 23293 ++p; 23294 return p; 23295 } 23296 23297 /* 23298 * ":function" 23299 */ 23300 void 23301 ex_function(exarg_T *eap) 23302 { 23303 char_u *theline; 23304 int i; 23305 int j; 23306 int c; 23307 int saved_did_emsg; 23308 int saved_wait_return = need_wait_return; 23309 char_u *name = NULL; 23310 char_u *p; 23311 char_u *arg; 23312 char_u *line_arg = NULL; 23313 garray_T newargs; 23314 garray_T newlines; 23315 int varargs = FALSE; 23316 int mustend = FALSE; 23317 int flags = 0; 23318 ufunc_T *fp; 23319 int indent; 23320 int nesting; 23321 char_u *skip_until = NULL; 23322 dictitem_T *v; 23323 funcdict_T fudi; 23324 static int func_nr = 0; /* number for nameless function */ 23325 int paren; 23326 hashtab_T *ht; 23327 int todo; 23328 hashitem_T *hi; 23329 int sourcing_lnum_off; 23330 23331 /* 23332 * ":function" without argument: list functions. 23333 */ 23334 if (ends_excmd(*eap->arg)) 23335 { 23336 if (!eap->skip) 23337 { 23338 todo = (int)func_hashtab.ht_used; 23339 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 23340 { 23341 if (!HASHITEM_EMPTY(hi)) 23342 { 23343 --todo; 23344 fp = HI2UF(hi); 23345 if (!isdigit(*fp->uf_name)) 23346 list_func_head(fp, FALSE); 23347 } 23348 } 23349 } 23350 eap->nextcmd = check_nextcmd(eap->arg); 23351 return; 23352 } 23353 23354 /* 23355 * ":function /pat": list functions matching pattern. 23356 */ 23357 if (*eap->arg == '/') 23358 { 23359 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 23360 if (!eap->skip) 23361 { 23362 regmatch_T regmatch; 23363 23364 c = *p; 23365 *p = NUL; 23366 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 23367 *p = c; 23368 if (regmatch.regprog != NULL) 23369 { 23370 regmatch.rm_ic = p_ic; 23371 23372 todo = (int)func_hashtab.ht_used; 23373 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 23374 { 23375 if (!HASHITEM_EMPTY(hi)) 23376 { 23377 --todo; 23378 fp = HI2UF(hi); 23379 if (!isdigit(*fp->uf_name) 23380 && vim_regexec(®match, fp->uf_name, 0)) 23381 list_func_head(fp, FALSE); 23382 } 23383 } 23384 vim_regfree(regmatch.regprog); 23385 } 23386 } 23387 if (*p == '/') 23388 ++p; 23389 eap->nextcmd = check_nextcmd(p); 23390 return; 23391 } 23392 23393 /* 23394 * Get the function name. There are these situations: 23395 * func normal function name 23396 * "name" == func, "fudi.fd_dict" == NULL 23397 * dict.func new dictionary entry 23398 * "name" == NULL, "fudi.fd_dict" set, 23399 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 23400 * dict.func existing dict entry with a Funcref 23401 * "name" == func, "fudi.fd_dict" set, 23402 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 23403 * dict.func existing dict entry that's not a Funcref 23404 * "name" == NULL, "fudi.fd_dict" set, 23405 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 23406 * s:func script-local function name 23407 * g:func global function name, same as "func" 23408 */ 23409 p = eap->arg; 23410 name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); 23411 paren = (vim_strchr(p, '(') != NULL); 23412 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 23413 { 23414 /* 23415 * Return on an invalid expression in braces, unless the expression 23416 * evaluation has been cancelled due to an aborting error, an 23417 * interrupt, or an exception. 23418 */ 23419 if (!aborting()) 23420 { 23421 if (!eap->skip && fudi.fd_newkey != NULL) 23422 EMSG2(_(e_dictkey), fudi.fd_newkey); 23423 vim_free(fudi.fd_newkey); 23424 return; 23425 } 23426 else 23427 eap->skip = TRUE; 23428 } 23429 23430 /* An error in a function call during evaluation of an expression in magic 23431 * braces should not cause the function not to be defined. */ 23432 saved_did_emsg = did_emsg; 23433 did_emsg = FALSE; 23434 23435 /* 23436 * ":function func" with only function name: list function. 23437 */ 23438 if (!paren) 23439 { 23440 if (!ends_excmd(*skipwhite(p))) 23441 { 23442 EMSG(_(e_trailing)); 23443 goto ret_free; 23444 } 23445 eap->nextcmd = check_nextcmd(p); 23446 if (eap->nextcmd != NULL) 23447 *p = NUL; 23448 if (!eap->skip && !got_int) 23449 { 23450 fp = find_func(name); 23451 if (fp != NULL) 23452 { 23453 list_func_head(fp, TRUE); 23454 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 23455 { 23456 if (FUNCLINE(fp, j) == NULL) 23457 continue; 23458 msg_putchar('\n'); 23459 msg_outnum((long)(j + 1)); 23460 if (j < 9) 23461 msg_putchar(' '); 23462 if (j < 99) 23463 msg_putchar(' '); 23464 msg_prt_line(FUNCLINE(fp, j), FALSE); 23465 out_flush(); /* show a line at a time */ 23466 ui_breakcheck(); 23467 } 23468 if (!got_int) 23469 { 23470 msg_putchar('\n'); 23471 msg_puts((char_u *)" endfunction"); 23472 } 23473 } 23474 else 23475 emsg_funcname(N_("E123: Undefined function: %s"), name); 23476 } 23477 goto ret_free; 23478 } 23479 23480 /* 23481 * ":function name(arg1, arg2)" Define function. 23482 */ 23483 p = skipwhite(p); 23484 if (*p != '(') 23485 { 23486 if (!eap->skip) 23487 { 23488 EMSG2(_("E124: Missing '(': %s"), eap->arg); 23489 goto ret_free; 23490 } 23491 /* attempt to continue by skipping some text */ 23492 if (vim_strchr(p, '(') != NULL) 23493 p = vim_strchr(p, '('); 23494 } 23495 p = skipwhite(p + 1); 23496 23497 ga_init2(&newargs, (int)sizeof(char_u *), 3); 23498 ga_init2(&newlines, (int)sizeof(char_u *), 3); 23499 23500 if (!eap->skip) 23501 { 23502 /* Check the name of the function. Unless it's a dictionary function 23503 * (that we are overwriting). */ 23504 if (name != NULL) 23505 arg = name; 23506 else 23507 arg = fudi.fd_newkey; 23508 if (arg != NULL && (fudi.fd_di == NULL 23509 || (fudi.fd_di->di_tv.v_type != VAR_FUNC 23510 && fudi.fd_di->di_tv.v_type != VAR_PARTIAL))) 23511 { 23512 if (*arg == K_SPECIAL) 23513 j = 3; 23514 else 23515 j = 0; 23516 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 23517 : eval_isnamec(arg[j]))) 23518 ++j; 23519 if (arg[j] != NUL) 23520 emsg_funcname((char *)e_invarg2, arg); 23521 } 23522 /* Disallow using the g: dict. */ 23523 if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) 23524 EMSG(_("E862: Cannot use g: here")); 23525 } 23526 23527 /* 23528 * Isolate the arguments: "arg1, arg2, ...)" 23529 */ 23530 while (*p != ')') 23531 { 23532 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 23533 { 23534 varargs = TRUE; 23535 p += 3; 23536 mustend = TRUE; 23537 } 23538 else 23539 { 23540 arg = p; 23541 while (ASCII_ISALNUM(*p) || *p == '_') 23542 ++p; 23543 if (arg == p || isdigit(*arg) 23544 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 23545 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 23546 { 23547 if (!eap->skip) 23548 EMSG2(_("E125: Illegal argument: %s"), arg); 23549 break; 23550 } 23551 if (ga_grow(&newargs, 1) == FAIL) 23552 goto erret; 23553 c = *p; 23554 *p = NUL; 23555 arg = vim_strsave(arg); 23556 if (arg == NULL) 23557 goto erret; 23558 23559 /* Check for duplicate argument name. */ 23560 for (i = 0; i < newargs.ga_len; ++i) 23561 if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0) 23562 { 23563 EMSG2(_("E853: Duplicate argument name: %s"), arg); 23564 vim_free(arg); 23565 goto erret; 23566 } 23567 23568 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 23569 *p = c; 23570 newargs.ga_len++; 23571 if (*p == ',') 23572 ++p; 23573 else 23574 mustend = TRUE; 23575 } 23576 p = skipwhite(p); 23577 if (mustend && *p != ')') 23578 { 23579 if (!eap->skip) 23580 EMSG2(_(e_invarg2), eap->arg); 23581 break; 23582 } 23583 } 23584 if (*p != ')') 23585 goto erret; 23586 ++p; /* skip the ')' */ 23587 23588 /* find extra arguments "range", "dict" and "abort" */ 23589 for (;;) 23590 { 23591 p = skipwhite(p); 23592 if (STRNCMP(p, "range", 5) == 0) 23593 { 23594 flags |= FC_RANGE; 23595 p += 5; 23596 } 23597 else if (STRNCMP(p, "dict", 4) == 0) 23598 { 23599 flags |= FC_DICT; 23600 p += 4; 23601 } 23602 else if (STRNCMP(p, "abort", 5) == 0) 23603 { 23604 flags |= FC_ABORT; 23605 p += 5; 23606 } 23607 else 23608 break; 23609 } 23610 23611 /* When there is a line break use what follows for the function body. 23612 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 23613 if (*p == '\n') 23614 line_arg = p + 1; 23615 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 23616 EMSG(_(e_trailing)); 23617 23618 /* 23619 * Read the body of the function, until ":endfunction" is found. 23620 */ 23621 if (KeyTyped) 23622 { 23623 /* Check if the function already exists, don't let the user type the 23624 * whole function before telling him it doesn't work! For a script we 23625 * need to skip the body to be able to find what follows. */ 23626 if (!eap->skip && !eap->forceit) 23627 { 23628 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 23629 EMSG(_(e_funcdict)); 23630 else if (name != NULL && find_func(name) != NULL) 23631 emsg_funcname(e_funcexts, name); 23632 } 23633 23634 if (!eap->skip && did_emsg) 23635 goto erret; 23636 23637 msg_putchar('\n'); /* don't overwrite the function name */ 23638 cmdline_row = msg_row; 23639 } 23640 23641 indent = 2; 23642 nesting = 0; 23643 for (;;) 23644 { 23645 if (KeyTyped) 23646 { 23647 msg_scroll = TRUE; 23648 saved_wait_return = FALSE; 23649 } 23650 need_wait_return = FALSE; 23651 sourcing_lnum_off = sourcing_lnum; 23652 23653 if (line_arg != NULL) 23654 { 23655 /* Use eap->arg, split up in parts by line breaks. */ 23656 theline = line_arg; 23657 p = vim_strchr(theline, '\n'); 23658 if (p == NULL) 23659 line_arg += STRLEN(line_arg); 23660 else 23661 { 23662 *p = NUL; 23663 line_arg = p + 1; 23664 } 23665 } 23666 else if (eap->getline == NULL) 23667 theline = getcmdline(':', 0L, indent); 23668 else 23669 theline = eap->getline(':', eap->cookie, indent); 23670 if (KeyTyped) 23671 lines_left = Rows - 1; 23672 if (theline == NULL) 23673 { 23674 EMSG(_("E126: Missing :endfunction")); 23675 goto erret; 23676 } 23677 23678 /* Detect line continuation: sourcing_lnum increased more than one. */ 23679 if (sourcing_lnum > sourcing_lnum_off + 1) 23680 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 23681 else 23682 sourcing_lnum_off = 0; 23683 23684 if (skip_until != NULL) 23685 { 23686 /* between ":append" and "." and between ":python <<EOF" and "EOF" 23687 * don't check for ":endfunc". */ 23688 if (STRCMP(theline, skip_until) == 0) 23689 { 23690 vim_free(skip_until); 23691 skip_until = NULL; 23692 } 23693 } 23694 else 23695 { 23696 /* skip ':' and blanks*/ 23697 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 23698 ; 23699 23700 /* Check for "endfunction". */ 23701 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 23702 { 23703 if (line_arg == NULL) 23704 vim_free(theline); 23705 break; 23706 } 23707 23708 /* Increase indent inside "if", "while", "for" and "try", decrease 23709 * at "end". */ 23710 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 23711 indent -= 2; 23712 else if (STRNCMP(p, "if", 2) == 0 23713 || STRNCMP(p, "wh", 2) == 0 23714 || STRNCMP(p, "for", 3) == 0 23715 || STRNCMP(p, "try", 3) == 0) 23716 indent += 2; 23717 23718 /* Check for defining a function inside this function. */ 23719 if (checkforcmd(&p, "function", 2)) 23720 { 23721 if (*p == '!') 23722 p = skipwhite(p + 1); 23723 p += eval_fname_script(p); 23724 vim_free(trans_function_name(&p, TRUE, 0, NULL, NULL)); 23725 if (*skipwhite(p) == '(') 23726 { 23727 ++nesting; 23728 indent += 2; 23729 } 23730 } 23731 23732 /* Check for ":append" or ":insert". */ 23733 p = skip_range(p, NULL); 23734 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 23735 || (p[0] == 'i' 23736 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 23737 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 23738 skip_until = vim_strsave((char_u *)"."); 23739 23740 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 23741 arg = skipwhite(skiptowhite(p)); 23742 if (arg[0] == '<' && arg[1] =='<' 23743 && ((p[0] == 'p' && p[1] == 'y' 23744 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 23745 || (p[0] == 'p' && p[1] == 'e' 23746 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 23747 || (p[0] == 't' && p[1] == 'c' 23748 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 23749 || (p[0] == 'l' && p[1] == 'u' && p[2] == 'a' 23750 && !ASCII_ISALPHA(p[3])) 23751 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 23752 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 23753 || (p[0] == 'm' && p[1] == 'z' 23754 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 23755 )) 23756 { 23757 /* ":python <<" continues until a dot, like ":append" */ 23758 p = skipwhite(arg + 2); 23759 if (*p == NUL) 23760 skip_until = vim_strsave((char_u *)"."); 23761 else 23762 skip_until = vim_strsave(p); 23763 } 23764 } 23765 23766 /* Add the line to the function. */ 23767 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 23768 { 23769 if (line_arg == NULL) 23770 vim_free(theline); 23771 goto erret; 23772 } 23773 23774 /* Copy the line to newly allocated memory. get_one_sourceline() 23775 * allocates 250 bytes per line, this saves 80% on average. The cost 23776 * is an extra alloc/free. */ 23777 p = vim_strsave(theline); 23778 if (p != NULL) 23779 { 23780 if (line_arg == NULL) 23781 vim_free(theline); 23782 theline = p; 23783 } 23784 23785 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 23786 23787 /* Add NULL lines for continuation lines, so that the line count is 23788 * equal to the index in the growarray. */ 23789 while (sourcing_lnum_off-- > 0) 23790 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 23791 23792 /* Check for end of eap->arg. */ 23793 if (line_arg != NULL && *line_arg == NUL) 23794 line_arg = NULL; 23795 } 23796 23797 /* Don't define the function when skipping commands or when an error was 23798 * detected. */ 23799 if (eap->skip || did_emsg) 23800 goto erret; 23801 23802 /* 23803 * If there are no errors, add the function 23804 */ 23805 if (fudi.fd_dict == NULL) 23806 { 23807 v = find_var(name, &ht, FALSE); 23808 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 23809 { 23810 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 23811 name); 23812 goto erret; 23813 } 23814 23815 fp = find_func(name); 23816 if (fp != NULL) 23817 { 23818 if (!eap->forceit) 23819 { 23820 emsg_funcname(e_funcexts, name); 23821 goto erret; 23822 } 23823 if (fp->uf_calls > 0) 23824 { 23825 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 23826 name); 23827 goto erret; 23828 } 23829 /* redefine existing function */ 23830 ga_clear_strings(&(fp->uf_args)); 23831 ga_clear_strings(&(fp->uf_lines)); 23832 vim_free(name); 23833 name = NULL; 23834 } 23835 } 23836 else 23837 { 23838 char numbuf[20]; 23839 23840 fp = NULL; 23841 if (fudi.fd_newkey == NULL && !eap->forceit) 23842 { 23843 EMSG(_(e_funcdict)); 23844 goto erret; 23845 } 23846 if (fudi.fd_di == NULL) 23847 { 23848 /* Can't add a function to a locked dictionary */ 23849 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, FALSE)) 23850 goto erret; 23851 } 23852 /* Can't change an existing function if it is locked */ 23853 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, FALSE)) 23854 goto erret; 23855 23856 /* Give the function a sequential number. Can only be used with a 23857 * Funcref! */ 23858 vim_free(name); 23859 sprintf(numbuf, "%d", ++func_nr); 23860 name = vim_strsave((char_u *)numbuf); 23861 if (name == NULL) 23862 goto erret; 23863 } 23864 23865 if (fp == NULL) 23866 { 23867 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 23868 { 23869 int slen, plen; 23870 char_u *scriptname; 23871 23872 /* Check that the autoload name matches the script name. */ 23873 j = FAIL; 23874 if (sourcing_name != NULL) 23875 { 23876 scriptname = autoload_name(name); 23877 if (scriptname != NULL) 23878 { 23879 p = vim_strchr(scriptname, '/'); 23880 plen = (int)STRLEN(p); 23881 slen = (int)STRLEN(sourcing_name); 23882 if (slen > plen && fnamecmp(p, 23883 sourcing_name + slen - plen) == 0) 23884 j = OK; 23885 vim_free(scriptname); 23886 } 23887 } 23888 if (j == FAIL) 23889 { 23890 EMSG2(_("E746: Function name does not match script file name: %s"), name); 23891 goto erret; 23892 } 23893 } 23894 23895 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 23896 if (fp == NULL) 23897 goto erret; 23898 23899 if (fudi.fd_dict != NULL) 23900 { 23901 if (fudi.fd_di == NULL) 23902 { 23903 /* add new dict entry */ 23904 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 23905 if (fudi.fd_di == NULL) 23906 { 23907 vim_free(fp); 23908 goto erret; 23909 } 23910 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 23911 { 23912 vim_free(fudi.fd_di); 23913 vim_free(fp); 23914 goto erret; 23915 } 23916 } 23917 else 23918 /* overwrite existing dict entry */ 23919 clear_tv(&fudi.fd_di->di_tv); 23920 fudi.fd_di->di_tv.v_type = VAR_FUNC; 23921 fudi.fd_di->di_tv.v_lock = 0; 23922 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 23923 fp->uf_refcount = 1; 23924 23925 /* behave like "dict" was used */ 23926 flags |= FC_DICT; 23927 } 23928 23929 /* insert the new function in the function list */ 23930 STRCPY(fp->uf_name, name); 23931 if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) 23932 { 23933 vim_free(fp); 23934 goto erret; 23935 } 23936 } 23937 fp->uf_args = newargs; 23938 fp->uf_lines = newlines; 23939 #ifdef FEAT_PROFILE 23940 fp->uf_tml_count = NULL; 23941 fp->uf_tml_total = NULL; 23942 fp->uf_tml_self = NULL; 23943 fp->uf_profiling = FALSE; 23944 if (prof_def_func()) 23945 func_do_profile(fp); 23946 #endif 23947 fp->uf_varargs = varargs; 23948 fp->uf_flags = flags; 23949 fp->uf_calls = 0; 23950 fp->uf_script_ID = current_SID; 23951 goto ret_free; 23952 23953 erret: 23954 ga_clear_strings(&newargs); 23955 ga_clear_strings(&newlines); 23956 ret_free: 23957 vim_free(skip_until); 23958 vim_free(fudi.fd_newkey); 23959 vim_free(name); 23960 did_emsg |= saved_did_emsg; 23961 need_wait_return |= saved_wait_return; 23962 } 23963 23964 /* 23965 * Get a function name, translating "<SID>" and "<SNR>". 23966 * Also handles a Funcref in a List or Dictionary. 23967 * Returns the function name in allocated memory, or NULL for failure. 23968 * flags: 23969 * TFN_INT: internal function name OK 23970 * TFN_QUIET: be quiet 23971 * TFN_NO_AUTOLOAD: do not use script autoloading 23972 * Advances "pp" to just after the function name (if no error). 23973 */ 23974 static char_u * 23975 trans_function_name( 23976 char_u **pp, 23977 int skip, /* only find the end, don't evaluate */ 23978 int flags, 23979 funcdict_T *fdp, /* return: info about dictionary used */ 23980 partial_T **partial) /* return: partial of a FuncRef */ 23981 { 23982 char_u *name = NULL; 23983 char_u *start; 23984 char_u *end; 23985 int lead; 23986 char_u sid_buf[20]; 23987 int len; 23988 lval_T lv; 23989 23990 if (fdp != NULL) 23991 vim_memset(fdp, 0, sizeof(funcdict_T)); 23992 start = *pp; 23993 23994 /* Check for hard coded <SNR>: already translated function ID (from a user 23995 * command). */ 23996 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 23997 && (*pp)[2] == (int)KE_SNR) 23998 { 23999 *pp += 3; 24000 len = get_id_len(pp) + 3; 24001 return vim_strnsave(start, len); 24002 } 24003 24004 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 24005 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 24006 lead = eval_fname_script(start); 24007 if (lead > 2) 24008 start += lead; 24009 24010 /* Note that TFN_ flags use the same values as GLV_ flags. */ 24011 end = get_lval(start, NULL, &lv, FALSE, skip, flags, 24012 lead > 2 ? 0 : FNE_CHECK_START); 24013 if (end == start) 24014 { 24015 if (!skip) 24016 EMSG(_("E129: Function name required")); 24017 goto theend; 24018 } 24019 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 24020 { 24021 /* 24022 * Report an invalid expression in braces, unless the expression 24023 * evaluation has been cancelled due to an aborting error, an 24024 * interrupt, or an exception. 24025 */ 24026 if (!aborting()) 24027 { 24028 if (end != NULL) 24029 EMSG2(_(e_invarg2), start); 24030 } 24031 else 24032 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 24033 goto theend; 24034 } 24035 24036 if (lv.ll_tv != NULL) 24037 { 24038 if (fdp != NULL) 24039 { 24040 fdp->fd_dict = lv.ll_dict; 24041 fdp->fd_newkey = lv.ll_newkey; 24042 lv.ll_newkey = NULL; 24043 fdp->fd_di = lv.ll_di; 24044 } 24045 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 24046 { 24047 name = vim_strsave(lv.ll_tv->vval.v_string); 24048 *pp = end; 24049 } 24050 else if (lv.ll_tv->v_type == VAR_PARTIAL 24051 && lv.ll_tv->vval.v_partial != NULL) 24052 { 24053 name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name); 24054 *pp = end; 24055 if (partial != NULL) 24056 *partial = lv.ll_tv->vval.v_partial; 24057 } 24058 else 24059 { 24060 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 24061 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 24062 EMSG(_(e_funcref)); 24063 else 24064 *pp = end; 24065 name = NULL; 24066 } 24067 goto theend; 24068 } 24069 24070 if (lv.ll_name == NULL) 24071 { 24072 /* Error found, but continue after the function name. */ 24073 *pp = end; 24074 goto theend; 24075 } 24076 24077 /* Check if the name is a Funcref. If so, use the value. */ 24078 if (lv.ll_exp_name != NULL) 24079 { 24080 len = (int)STRLEN(lv.ll_exp_name); 24081 name = deref_func_name(lv.ll_exp_name, &len, partial, 24082 flags & TFN_NO_AUTOLOAD); 24083 if (name == lv.ll_exp_name) 24084 name = NULL; 24085 } 24086 else 24087 { 24088 len = (int)(end - *pp); 24089 name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD); 24090 if (name == *pp) 24091 name = NULL; 24092 } 24093 if (name != NULL) 24094 { 24095 name = vim_strsave(name); 24096 *pp = end; 24097 if (STRNCMP(name, "<SNR>", 5) == 0) 24098 { 24099 /* Change "<SNR>" to the byte sequence. */ 24100 name[0] = K_SPECIAL; 24101 name[1] = KS_EXTRA; 24102 name[2] = (int)KE_SNR; 24103 mch_memmove(name + 3, name + 5, STRLEN(name + 5) + 1); 24104 } 24105 goto theend; 24106 } 24107 24108 if (lv.ll_exp_name != NULL) 24109 { 24110 len = (int)STRLEN(lv.ll_exp_name); 24111 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 24112 && STRNCMP(lv.ll_name, "s:", 2) == 0) 24113 { 24114 /* When there was "s:" already or the name expanded to get a 24115 * leading "s:" then remove it. */ 24116 lv.ll_name += 2; 24117 len -= 2; 24118 lead = 2; 24119 } 24120 } 24121 else 24122 { 24123 /* skip over "s:" and "g:" */ 24124 if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':')) 24125 lv.ll_name += 2; 24126 len = (int)(end - lv.ll_name); 24127 } 24128 24129 /* 24130 * Copy the function name to allocated memory. 24131 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 24132 * Accept <SNR>123_name() outside a script. 24133 */ 24134 if (skip) 24135 lead = 0; /* do nothing */ 24136 else if (lead > 0) 24137 { 24138 lead = 3; 24139 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 24140 || eval_fname_sid(*pp)) 24141 { 24142 /* It's "s:" or "<SID>" */ 24143 if (current_SID <= 0) 24144 { 24145 EMSG(_(e_usingsid)); 24146 goto theend; 24147 } 24148 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 24149 lead += (int)STRLEN(sid_buf); 24150 } 24151 } 24152 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) 24153 { 24154 EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"), 24155 start); 24156 goto theend; 24157 } 24158 if (!skip && !(flags & TFN_QUIET)) 24159 { 24160 char_u *cp = vim_strchr(lv.ll_name, ':'); 24161 24162 if (cp != NULL && cp < end) 24163 { 24164 EMSG2(_("E884: Function name cannot contain a colon: %s"), start); 24165 goto theend; 24166 } 24167 } 24168 24169 name = alloc((unsigned)(len + lead + 1)); 24170 if (name != NULL) 24171 { 24172 if (lead > 0) 24173 { 24174 name[0] = K_SPECIAL; 24175 name[1] = KS_EXTRA; 24176 name[2] = (int)KE_SNR; 24177 if (lead > 3) /* If it's "<SID>" */ 24178 STRCPY(name + 3, sid_buf); 24179 } 24180 mch_memmove(name + lead, lv.ll_name, (size_t)len); 24181 name[lead + len] = NUL; 24182 } 24183 *pp = end; 24184 24185 theend: 24186 clear_lval(&lv); 24187 return name; 24188 } 24189 24190 /* 24191 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 24192 * Return 2 if "p" starts with "s:". 24193 * Return 0 otherwise. 24194 */ 24195 static int 24196 eval_fname_script(char_u *p) 24197 { 24198 /* Use MB_STRICMP() because in Turkish comparing the "I" may not work with 24199 * the standard library function. */ 24200 if (p[0] == '<' && (MB_STRNICMP(p + 1, "SID>", 4) == 0 24201 || MB_STRNICMP(p + 1, "SNR>", 4) == 0)) 24202 return 5; 24203 if (p[0] == 's' && p[1] == ':') 24204 return 2; 24205 return 0; 24206 } 24207 24208 /* 24209 * Return TRUE if "p" starts with "<SID>" or "s:". 24210 * Only works if eval_fname_script() returned non-zero for "p"! 24211 */ 24212 static int 24213 eval_fname_sid(char_u *p) 24214 { 24215 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 24216 } 24217 24218 /* 24219 * List the head of the function: "name(arg1, arg2)". 24220 */ 24221 static void 24222 list_func_head(ufunc_T *fp, int indent) 24223 { 24224 int j; 24225 24226 msg_start(); 24227 if (indent) 24228 MSG_PUTS(" "); 24229 MSG_PUTS("function "); 24230 if (fp->uf_name[0] == K_SPECIAL) 24231 { 24232 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 24233 msg_puts(fp->uf_name + 3); 24234 } 24235 else 24236 msg_puts(fp->uf_name); 24237 msg_putchar('('); 24238 for (j = 0; j < fp->uf_args.ga_len; ++j) 24239 { 24240 if (j) 24241 MSG_PUTS(", "); 24242 msg_puts(FUNCARG(fp, j)); 24243 } 24244 if (fp->uf_varargs) 24245 { 24246 if (j) 24247 MSG_PUTS(", "); 24248 MSG_PUTS("..."); 24249 } 24250 msg_putchar(')'); 24251 if (fp->uf_flags & FC_ABORT) 24252 MSG_PUTS(" abort"); 24253 if (fp->uf_flags & FC_RANGE) 24254 MSG_PUTS(" range"); 24255 if (fp->uf_flags & FC_DICT) 24256 MSG_PUTS(" dict"); 24257 msg_clr_eos(); 24258 if (p_verbose > 0) 24259 last_set_msg(fp->uf_script_ID); 24260 } 24261 24262 /* 24263 * Find a function by name, return pointer to it in ufuncs. 24264 * Return NULL for unknown function. 24265 */ 24266 static ufunc_T * 24267 find_func(char_u *name) 24268 { 24269 hashitem_T *hi; 24270 24271 hi = hash_find(&func_hashtab, name); 24272 if (!HASHITEM_EMPTY(hi)) 24273 return HI2UF(hi); 24274 return NULL; 24275 } 24276 24277 #if defined(EXITFREE) || defined(PROTO) 24278 void 24279 free_all_functions(void) 24280 { 24281 hashitem_T *hi; 24282 24283 /* Need to start all over every time, because func_free() may change the 24284 * hash table. */ 24285 while (func_hashtab.ht_used > 0) 24286 for (hi = func_hashtab.ht_array; ; ++hi) 24287 if (!HASHITEM_EMPTY(hi)) 24288 { 24289 func_free(HI2UF(hi)); 24290 break; 24291 } 24292 } 24293 #endif 24294 24295 int 24296 translated_function_exists(char_u *name) 24297 { 24298 if (builtin_function(name, -1)) 24299 return find_internal_func(name) >= 0; 24300 return find_func(name) != NULL; 24301 } 24302 24303 /* 24304 * Return TRUE if a function "name" exists. 24305 */ 24306 static int 24307 function_exists(char_u *name) 24308 { 24309 char_u *nm = name; 24310 char_u *p; 24311 int n = FALSE; 24312 24313 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, 24314 NULL, NULL); 24315 nm = skipwhite(nm); 24316 24317 /* Only accept "funcname", "funcname ", "funcname (..." and 24318 * "funcname(...", not "funcname!...". */ 24319 if (p != NULL && (*nm == NUL || *nm == '(')) 24320 n = translated_function_exists(p); 24321 vim_free(p); 24322 return n; 24323 } 24324 24325 char_u * 24326 get_expanded_name(char_u *name, int check) 24327 { 24328 char_u *nm = name; 24329 char_u *p; 24330 24331 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL, NULL); 24332 24333 if (p != NULL && *nm == NUL) 24334 if (!check || translated_function_exists(p)) 24335 return p; 24336 24337 vim_free(p); 24338 return NULL; 24339 } 24340 24341 /* 24342 * Return TRUE if "name" looks like a builtin function name: starts with a 24343 * lower case letter and doesn't contain AUTOLOAD_CHAR. 24344 * "len" is the length of "name", or -1 for NUL terminated. 24345 */ 24346 static int 24347 builtin_function(char_u *name, int len) 24348 { 24349 char_u *p; 24350 24351 if (!ASCII_ISLOWER(name[0])) 24352 return FALSE; 24353 p = vim_strchr(name, AUTOLOAD_CHAR); 24354 return p == NULL || (len > 0 && p > name + len); 24355 } 24356 24357 #if defined(FEAT_PROFILE) || defined(PROTO) 24358 /* 24359 * Start profiling function "fp". 24360 */ 24361 static void 24362 func_do_profile(ufunc_T *fp) 24363 { 24364 int len = fp->uf_lines.ga_len; 24365 24366 if (len == 0) 24367 len = 1; /* avoid getting error for allocating zero bytes */ 24368 fp->uf_tm_count = 0; 24369 profile_zero(&fp->uf_tm_self); 24370 profile_zero(&fp->uf_tm_total); 24371 if (fp->uf_tml_count == NULL) 24372 fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len)); 24373 if (fp->uf_tml_total == NULL) 24374 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 24375 (sizeof(proftime_T) * len)); 24376 if (fp->uf_tml_self == NULL) 24377 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 24378 (sizeof(proftime_T) * len)); 24379 fp->uf_tml_idx = -1; 24380 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 24381 || fp->uf_tml_self == NULL) 24382 return; /* out of memory */ 24383 24384 fp->uf_profiling = TRUE; 24385 } 24386 24387 /* 24388 * Dump the profiling results for all functions in file "fd". 24389 */ 24390 void 24391 func_dump_profile(FILE *fd) 24392 { 24393 hashitem_T *hi; 24394 int todo; 24395 ufunc_T *fp; 24396 int i; 24397 ufunc_T **sorttab; 24398 int st_len = 0; 24399 24400 todo = (int)func_hashtab.ht_used; 24401 if (todo == 0) 24402 return; /* nothing to dump */ 24403 24404 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T *) * todo)); 24405 24406 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 24407 { 24408 if (!HASHITEM_EMPTY(hi)) 24409 { 24410 --todo; 24411 fp = HI2UF(hi); 24412 if (fp->uf_profiling) 24413 { 24414 if (sorttab != NULL) 24415 sorttab[st_len++] = fp; 24416 24417 if (fp->uf_name[0] == K_SPECIAL) 24418 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 24419 else 24420 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 24421 if (fp->uf_tm_count == 1) 24422 fprintf(fd, "Called 1 time\n"); 24423 else 24424 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 24425 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 24426 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 24427 fprintf(fd, "\n"); 24428 fprintf(fd, "count total (s) self (s)\n"); 24429 24430 for (i = 0; i < fp->uf_lines.ga_len; ++i) 24431 { 24432 if (FUNCLINE(fp, i) == NULL) 24433 continue; 24434 prof_func_line(fd, fp->uf_tml_count[i], 24435 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 24436 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 24437 } 24438 fprintf(fd, "\n"); 24439 } 24440 } 24441 } 24442 24443 if (sorttab != NULL && st_len > 0) 24444 { 24445 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 24446 prof_total_cmp); 24447 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 24448 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 24449 prof_self_cmp); 24450 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 24451 } 24452 24453 vim_free(sorttab); 24454 } 24455 24456 static void 24457 prof_sort_list( 24458 FILE *fd, 24459 ufunc_T **sorttab, 24460 int st_len, 24461 char *title, 24462 int prefer_self) /* when equal print only self time */ 24463 { 24464 int i; 24465 ufunc_T *fp; 24466 24467 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 24468 fprintf(fd, "count total (s) self (s) function\n"); 24469 for (i = 0; i < 20 && i < st_len; ++i) 24470 { 24471 fp = sorttab[i]; 24472 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 24473 prefer_self); 24474 if (fp->uf_name[0] == K_SPECIAL) 24475 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 24476 else 24477 fprintf(fd, " %s()\n", fp->uf_name); 24478 } 24479 fprintf(fd, "\n"); 24480 } 24481 24482 /* 24483 * Print the count and times for one function or function line. 24484 */ 24485 static void 24486 prof_func_line( 24487 FILE *fd, 24488 int count, 24489 proftime_T *total, 24490 proftime_T *self, 24491 int prefer_self) /* when equal print only self time */ 24492 { 24493 if (count > 0) 24494 { 24495 fprintf(fd, "%5d ", count); 24496 if (prefer_self && profile_equal(total, self)) 24497 fprintf(fd, " "); 24498 else 24499 fprintf(fd, "%s ", profile_msg(total)); 24500 if (!prefer_self && profile_equal(total, self)) 24501 fprintf(fd, " "); 24502 else 24503 fprintf(fd, "%s ", profile_msg(self)); 24504 } 24505 else 24506 fprintf(fd, " "); 24507 } 24508 24509 /* 24510 * Compare function for total time sorting. 24511 */ 24512 static int 24513 #ifdef __BORLANDC__ 24514 _RTLENTRYF 24515 #endif 24516 prof_total_cmp(const void *s1, const void *s2) 24517 { 24518 ufunc_T *p1, *p2; 24519 24520 p1 = *(ufunc_T **)s1; 24521 p2 = *(ufunc_T **)s2; 24522 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 24523 } 24524 24525 /* 24526 * Compare function for self time sorting. 24527 */ 24528 static int 24529 #ifdef __BORLANDC__ 24530 _RTLENTRYF 24531 #endif 24532 prof_self_cmp(const void *s1, const void *s2) 24533 { 24534 ufunc_T *p1, *p2; 24535 24536 p1 = *(ufunc_T **)s1; 24537 p2 = *(ufunc_T **)s2; 24538 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 24539 } 24540 24541 #endif 24542 24543 /* 24544 * If "name" has a package name try autoloading the script for it. 24545 * Return TRUE if a package was loaded. 24546 */ 24547 static int 24548 script_autoload( 24549 char_u *name, 24550 int reload) /* load script again when already loaded */ 24551 { 24552 char_u *p; 24553 char_u *scriptname, *tofree; 24554 int ret = FALSE; 24555 int i; 24556 24557 /* If there is no '#' after name[0] there is no package name. */ 24558 p = vim_strchr(name, AUTOLOAD_CHAR); 24559 if (p == NULL || p == name) 24560 return FALSE; 24561 24562 tofree = scriptname = autoload_name(name); 24563 24564 /* Find the name in the list of previously loaded package names. Skip 24565 * "autoload/", it's always the same. */ 24566 for (i = 0; i < ga_loaded.ga_len; ++i) 24567 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 24568 break; 24569 if (!reload && i < ga_loaded.ga_len) 24570 ret = FALSE; /* was loaded already */ 24571 else 24572 { 24573 /* Remember the name if it wasn't loaded already. */ 24574 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 24575 { 24576 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 24577 tofree = NULL; 24578 } 24579 24580 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 24581 if (source_runtime(scriptname, 0) == OK) 24582 ret = TRUE; 24583 } 24584 24585 vim_free(tofree); 24586 return ret; 24587 } 24588 24589 /* 24590 * Return the autoload script name for a function or variable name. 24591 * Returns NULL when out of memory. 24592 */ 24593 static char_u * 24594 autoload_name(char_u *name) 24595 { 24596 char_u *p; 24597 char_u *scriptname; 24598 24599 /* Get the script file name: replace '#' with '/', append ".vim". */ 24600 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 24601 if (scriptname == NULL) 24602 return FALSE; 24603 STRCPY(scriptname, "autoload/"); 24604 STRCAT(scriptname, name); 24605 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 24606 STRCAT(scriptname, ".vim"); 24607 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 24608 *p = '/'; 24609 return scriptname; 24610 } 24611 24612 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 24613 24614 /* 24615 * Function given to ExpandGeneric() to obtain the list of user defined 24616 * function names. 24617 */ 24618 char_u * 24619 get_user_func_name(expand_T *xp, int idx) 24620 { 24621 static long_u done; 24622 static hashitem_T *hi; 24623 ufunc_T *fp; 24624 24625 if (idx == 0) 24626 { 24627 done = 0; 24628 hi = func_hashtab.ht_array; 24629 } 24630 if (done < func_hashtab.ht_used) 24631 { 24632 if (done++ > 0) 24633 ++hi; 24634 while (HASHITEM_EMPTY(hi)) 24635 ++hi; 24636 fp = HI2UF(hi); 24637 24638 if (fp->uf_flags & FC_DICT) 24639 return (char_u *)""; /* don't show dict functions */ 24640 24641 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 24642 return fp->uf_name; /* prevents overflow */ 24643 24644 cat_func_name(IObuff, fp); 24645 if (xp->xp_context != EXPAND_USER_FUNC) 24646 { 24647 STRCAT(IObuff, "("); 24648 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 24649 STRCAT(IObuff, ")"); 24650 } 24651 return IObuff; 24652 } 24653 return NULL; 24654 } 24655 24656 #endif /* FEAT_CMDL_COMPL */ 24657 24658 /* 24659 * Copy the function name of "fp" to buffer "buf". 24660 * "buf" must be able to hold the function name plus three bytes. 24661 * Takes care of script-local function names. 24662 */ 24663 static void 24664 cat_func_name(char_u *buf, ufunc_T *fp) 24665 { 24666 if (fp->uf_name[0] == K_SPECIAL) 24667 { 24668 STRCPY(buf, "<SNR>"); 24669 STRCAT(buf, fp->uf_name + 3); 24670 } 24671 else 24672 STRCPY(buf, fp->uf_name); 24673 } 24674 24675 /* 24676 * ":delfunction {name}" 24677 */ 24678 void 24679 ex_delfunction(exarg_T *eap) 24680 { 24681 ufunc_T *fp = NULL; 24682 char_u *p; 24683 char_u *name; 24684 funcdict_T fudi; 24685 24686 p = eap->arg; 24687 name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); 24688 vim_free(fudi.fd_newkey); 24689 if (name == NULL) 24690 { 24691 if (fudi.fd_dict != NULL && !eap->skip) 24692 EMSG(_(e_funcref)); 24693 return; 24694 } 24695 if (!ends_excmd(*skipwhite(p))) 24696 { 24697 vim_free(name); 24698 EMSG(_(e_trailing)); 24699 return; 24700 } 24701 eap->nextcmd = check_nextcmd(p); 24702 if (eap->nextcmd != NULL) 24703 *p = NUL; 24704 24705 if (!eap->skip) 24706 fp = find_func(name); 24707 vim_free(name); 24708 24709 if (!eap->skip) 24710 { 24711 if (fp == NULL) 24712 { 24713 EMSG2(_(e_nofunc), eap->arg); 24714 return; 24715 } 24716 if (fp->uf_calls > 0) 24717 { 24718 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 24719 return; 24720 } 24721 24722 if (fudi.fd_dict != NULL) 24723 { 24724 /* Delete the dict item that refers to the function, it will 24725 * invoke func_unref() and possibly delete the function. */ 24726 dictitem_remove(fudi.fd_dict, fudi.fd_di); 24727 } 24728 else 24729 func_free(fp); 24730 } 24731 } 24732 24733 /* 24734 * Free a function and remove it from the list of functions. 24735 */ 24736 static void 24737 func_free(ufunc_T *fp) 24738 { 24739 hashitem_T *hi; 24740 24741 /* clear this function */ 24742 ga_clear_strings(&(fp->uf_args)); 24743 ga_clear_strings(&(fp->uf_lines)); 24744 #ifdef FEAT_PROFILE 24745 vim_free(fp->uf_tml_count); 24746 vim_free(fp->uf_tml_total); 24747 vim_free(fp->uf_tml_self); 24748 #endif 24749 24750 /* remove the function from the function hashtable */ 24751 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 24752 if (HASHITEM_EMPTY(hi)) 24753 EMSG2(_(e_intern2), "func_free()"); 24754 else 24755 hash_remove(&func_hashtab, hi); 24756 24757 vim_free(fp); 24758 } 24759 24760 /* 24761 * Unreference a Function: decrement the reference count and free it when it 24762 * becomes zero. Only for numbered functions. 24763 */ 24764 void 24765 func_unref(char_u *name) 24766 { 24767 ufunc_T *fp; 24768 24769 if (name != NULL && isdigit(*name)) 24770 { 24771 fp = find_func(name); 24772 if (fp == NULL) 24773 EMSG2(_(e_intern2), "func_unref()"); 24774 else if (--fp->uf_refcount <= 0) 24775 { 24776 /* Only delete it when it's not being used. Otherwise it's done 24777 * when "uf_calls" becomes zero. */ 24778 if (fp->uf_calls == 0) 24779 func_free(fp); 24780 } 24781 } 24782 } 24783 24784 /* 24785 * Count a reference to a Function. 24786 */ 24787 void 24788 func_ref(char_u *name) 24789 { 24790 ufunc_T *fp; 24791 24792 if (name != NULL && isdigit(*name)) 24793 { 24794 fp = find_func(name); 24795 if (fp == NULL) 24796 EMSG2(_(e_intern2), "func_ref()"); 24797 else 24798 ++fp->uf_refcount; 24799 } 24800 } 24801 24802 /* 24803 * Call a user function. 24804 */ 24805 static void 24806 call_user_func( 24807 ufunc_T *fp, /* pointer to function */ 24808 int argcount, /* nr of args */ 24809 typval_T *argvars, /* arguments */ 24810 typval_T *rettv, /* return value */ 24811 linenr_T firstline, /* first line of range */ 24812 linenr_T lastline, /* last line of range */ 24813 dict_T *selfdict) /* Dictionary for "self" */ 24814 { 24815 char_u *save_sourcing_name; 24816 linenr_T save_sourcing_lnum; 24817 scid_T save_current_SID; 24818 funccall_T *fc; 24819 int save_did_emsg; 24820 static int depth = 0; 24821 dictitem_T *v; 24822 int fixvar_idx = 0; /* index in fixvar[] */ 24823 int i; 24824 int ai; 24825 char_u numbuf[NUMBUFLEN]; 24826 char_u *name; 24827 size_t len; 24828 #ifdef FEAT_PROFILE 24829 proftime_T wait_start; 24830 proftime_T call_start; 24831 #endif 24832 24833 /* If depth of calling is getting too high, don't execute the function */ 24834 if (depth >= p_mfd) 24835 { 24836 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 24837 rettv->v_type = VAR_NUMBER; 24838 rettv->vval.v_number = -1; 24839 return; 24840 } 24841 ++depth; 24842 24843 line_breakcheck(); /* check for CTRL-C hit */ 24844 24845 fc = (funccall_T *)alloc(sizeof(funccall_T)); 24846 fc->caller = current_funccal; 24847 current_funccal = fc; 24848 fc->func = fp; 24849 fc->rettv = rettv; 24850 rettv->vval.v_number = 0; 24851 fc->linenr = 0; 24852 fc->returned = FALSE; 24853 fc->level = ex_nesting_level; 24854 /* Check if this function has a breakpoint. */ 24855 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 24856 fc->dbg_tick = debug_tick; 24857 24858 /* 24859 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 24860 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 24861 * each argument variable and saves a lot of time. 24862 */ 24863 /* 24864 * Init l: variables. 24865 */ 24866 init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE); 24867 if (selfdict != NULL) 24868 { 24869 /* Set l:self to "selfdict". Use "name" to avoid a warning from 24870 * some compiler that checks the destination size. */ 24871 v = &fc->fixvar[fixvar_idx++].var; 24872 name = v->di_key; 24873 STRCPY(name, "self"); 24874 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 24875 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 24876 v->di_tv.v_type = VAR_DICT; 24877 v->di_tv.v_lock = 0; 24878 v->di_tv.vval.v_dict = selfdict; 24879 ++selfdict->dv_refcount; 24880 } 24881 24882 /* 24883 * Init a: variables. 24884 * Set a:0 to "argcount". 24885 * Set a:000 to a list with room for the "..." arguments. 24886 */ 24887 init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE); 24888 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 24889 (varnumber_T)(argcount - fp->uf_args.ga_len)); 24890 /* Use "name" to avoid a warning from some compiler that checks the 24891 * destination size. */ 24892 v = &fc->fixvar[fixvar_idx++].var; 24893 name = v->di_key; 24894 STRCPY(name, "000"); 24895 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24896 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 24897 v->di_tv.v_type = VAR_LIST; 24898 v->di_tv.v_lock = VAR_FIXED; 24899 v->di_tv.vval.v_list = &fc->l_varlist; 24900 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 24901 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 24902 fc->l_varlist.lv_lock = VAR_FIXED; 24903 24904 /* 24905 * Set a:firstline to "firstline" and a:lastline to "lastline". 24906 * Set a:name to named arguments. 24907 * Set a:N to the "..." arguments. 24908 */ 24909 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 24910 (varnumber_T)firstline); 24911 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 24912 (varnumber_T)lastline); 24913 for (i = 0; i < argcount; ++i) 24914 { 24915 ai = i - fp->uf_args.ga_len; 24916 if (ai < 0) 24917 /* named argument a:name */ 24918 name = FUNCARG(fp, i); 24919 else 24920 { 24921 /* "..." argument a:1, a:2, etc. */ 24922 sprintf((char *)numbuf, "%d", ai + 1); 24923 name = numbuf; 24924 } 24925 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 24926 { 24927 v = &fc->fixvar[fixvar_idx++].var; 24928 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24929 } 24930 else 24931 { 24932 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 24933 + STRLEN(name))); 24934 if (v == NULL) 24935 break; 24936 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC; 24937 } 24938 STRCPY(v->di_key, name); 24939 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 24940 24941 /* Note: the values are copied directly to avoid alloc/free. 24942 * "argvars" must have VAR_FIXED for v_lock. */ 24943 v->di_tv = argvars[i]; 24944 v->di_tv.v_lock = VAR_FIXED; 24945 24946 if (ai >= 0 && ai < MAX_FUNC_ARGS) 24947 { 24948 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 24949 fc->l_listitems[ai].li_tv = argvars[i]; 24950 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 24951 } 24952 } 24953 24954 /* Don't redraw while executing the function. */ 24955 ++RedrawingDisabled; 24956 save_sourcing_name = sourcing_name; 24957 save_sourcing_lnum = sourcing_lnum; 24958 sourcing_lnum = 1; 24959 /* need space for function name + ("function " + 3) or "[number]" */ 24960 len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name)) 24961 + STRLEN(fp->uf_name) + 20; 24962 sourcing_name = alloc((unsigned)len); 24963 if (sourcing_name != NULL) 24964 { 24965 if (save_sourcing_name != NULL 24966 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 24967 sprintf((char *)sourcing_name, "%s[%d]..", 24968 save_sourcing_name, (int)save_sourcing_lnum); 24969 else 24970 STRCPY(sourcing_name, "function "); 24971 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 24972 24973 if (p_verbose >= 12) 24974 { 24975 ++no_wait_return; 24976 verbose_enter_scroll(); 24977 24978 smsg((char_u *)_("calling %s"), sourcing_name); 24979 if (p_verbose >= 14) 24980 { 24981 char_u buf[MSG_BUF_LEN]; 24982 char_u numbuf2[NUMBUFLEN]; 24983 char_u *tofree; 24984 char_u *s; 24985 24986 msg_puts((char_u *)"("); 24987 for (i = 0; i < argcount; ++i) 24988 { 24989 if (i > 0) 24990 msg_puts((char_u *)", "); 24991 if (argvars[i].v_type == VAR_NUMBER) 24992 msg_outnum((long)argvars[i].vval.v_number); 24993 else 24994 { 24995 /* Do not want errors such as E724 here. */ 24996 ++emsg_off; 24997 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 24998 --emsg_off; 24999 if (s != NULL) 25000 { 25001 if (vim_strsize(s) > MSG_BUF_CLEN) 25002 { 25003 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); 25004 s = buf; 25005 } 25006 msg_puts(s); 25007 vim_free(tofree); 25008 } 25009 } 25010 } 25011 msg_puts((char_u *)")"); 25012 } 25013 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 25014 25015 verbose_leave_scroll(); 25016 --no_wait_return; 25017 } 25018 } 25019 #ifdef FEAT_PROFILE 25020 if (do_profiling == PROF_YES) 25021 { 25022 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 25023 func_do_profile(fp); 25024 if (fp->uf_profiling 25025 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 25026 { 25027 ++fp->uf_tm_count; 25028 profile_start(&call_start); 25029 profile_zero(&fp->uf_tm_children); 25030 } 25031 script_prof_save(&wait_start); 25032 } 25033 #endif 25034 25035 save_current_SID = current_SID; 25036 current_SID = fp->uf_script_ID; 25037 save_did_emsg = did_emsg; 25038 did_emsg = FALSE; 25039 25040 /* call do_cmdline() to execute the lines */ 25041 do_cmdline(NULL, get_func_line, (void *)fc, 25042 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 25043 25044 --RedrawingDisabled; 25045 25046 /* when the function was aborted because of an error, return -1 */ 25047 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 25048 { 25049 clear_tv(rettv); 25050 rettv->v_type = VAR_NUMBER; 25051 rettv->vval.v_number = -1; 25052 } 25053 25054 #ifdef FEAT_PROFILE 25055 if (do_profiling == PROF_YES && (fp->uf_profiling 25056 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 25057 { 25058 profile_end(&call_start); 25059 profile_sub_wait(&wait_start, &call_start); 25060 profile_add(&fp->uf_tm_total, &call_start); 25061 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 25062 if (fc->caller != NULL && fc->caller->func->uf_profiling) 25063 { 25064 profile_add(&fc->caller->func->uf_tm_children, &call_start); 25065 profile_add(&fc->caller->func->uf_tml_children, &call_start); 25066 } 25067 } 25068 #endif 25069 25070 /* when being verbose, mention the return value */ 25071 if (p_verbose >= 12) 25072 { 25073 ++no_wait_return; 25074 verbose_enter_scroll(); 25075 25076 if (aborting()) 25077 smsg((char_u *)_("%s aborted"), sourcing_name); 25078 else if (fc->rettv->v_type == VAR_NUMBER) 25079 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 25080 (long)fc->rettv->vval.v_number); 25081 else 25082 { 25083 char_u buf[MSG_BUF_LEN]; 25084 char_u numbuf2[NUMBUFLEN]; 25085 char_u *tofree; 25086 char_u *s; 25087 25088 /* The value may be very long. Skip the middle part, so that we 25089 * have some idea how it starts and ends. smsg() would always 25090 * truncate it at the end. Don't want errors such as E724 here. */ 25091 ++emsg_off; 25092 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 25093 --emsg_off; 25094 if (s != NULL) 25095 { 25096 if (vim_strsize(s) > MSG_BUF_CLEN) 25097 { 25098 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); 25099 s = buf; 25100 } 25101 smsg((char_u *)_("%s returning %s"), sourcing_name, s); 25102 vim_free(tofree); 25103 } 25104 } 25105 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 25106 25107 verbose_leave_scroll(); 25108 --no_wait_return; 25109 } 25110 25111 vim_free(sourcing_name); 25112 sourcing_name = save_sourcing_name; 25113 sourcing_lnum = save_sourcing_lnum; 25114 current_SID = save_current_SID; 25115 #ifdef FEAT_PROFILE 25116 if (do_profiling == PROF_YES) 25117 script_prof_restore(&wait_start); 25118 #endif 25119 25120 if (p_verbose >= 12 && sourcing_name != NULL) 25121 { 25122 ++no_wait_return; 25123 verbose_enter_scroll(); 25124 25125 smsg((char_u *)_("continuing in %s"), sourcing_name); 25126 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 25127 25128 verbose_leave_scroll(); 25129 --no_wait_return; 25130 } 25131 25132 did_emsg |= save_did_emsg; 25133 current_funccal = fc->caller; 25134 --depth; 25135 25136 /* If the a:000 list and the l: and a: dicts are not referenced we can 25137 * free the funccall_T and what's in it. */ 25138 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 25139 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 25140 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 25141 { 25142 free_funccal(fc, FALSE); 25143 } 25144 else 25145 { 25146 hashitem_T *hi; 25147 listitem_T *li; 25148 int todo; 25149 25150 /* "fc" is still in use. This can happen when returning "a:000" or 25151 * assigning "l:" to a global variable. 25152 * Link "fc" in the list for garbage collection later. */ 25153 fc->caller = previous_funccal; 25154 previous_funccal = fc; 25155 25156 /* Make a copy of the a: variables, since we didn't do that above. */ 25157 todo = (int)fc->l_avars.dv_hashtab.ht_used; 25158 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 25159 { 25160 if (!HASHITEM_EMPTY(hi)) 25161 { 25162 --todo; 25163 v = HI2DI(hi); 25164 copy_tv(&v->di_tv, &v->di_tv); 25165 } 25166 } 25167 25168 /* Make a copy of the a:000 items, since we didn't do that above. */ 25169 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 25170 copy_tv(&li->li_tv, &li->li_tv); 25171 } 25172 } 25173 25174 /* 25175 * Return TRUE if items in "fc" do not have "copyID". That means they are not 25176 * referenced from anywhere that is in use. 25177 */ 25178 static int 25179 can_free_funccal(funccall_T *fc, int copyID) 25180 { 25181 return (fc->l_varlist.lv_copyID != copyID 25182 && fc->l_vars.dv_copyID != copyID 25183 && fc->l_avars.dv_copyID != copyID); 25184 } 25185 25186 /* 25187 * Free "fc" and what it contains. 25188 */ 25189 static void 25190 free_funccal( 25191 funccall_T *fc, 25192 int free_val) /* a: vars were allocated */ 25193 { 25194 listitem_T *li; 25195 25196 /* The a: variables typevals may not have been allocated, only free the 25197 * allocated variables. */ 25198 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 25199 25200 /* free all l: variables */ 25201 vars_clear(&fc->l_vars.dv_hashtab); 25202 25203 /* Free the a:000 variables if they were allocated. */ 25204 if (free_val) 25205 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 25206 clear_tv(&li->li_tv); 25207 25208 vim_free(fc); 25209 } 25210 25211 /* 25212 * Add a number variable "name" to dict "dp" with value "nr". 25213 */ 25214 static void 25215 add_nr_var( 25216 dict_T *dp, 25217 dictitem_T *v, 25218 char *name, 25219 varnumber_T nr) 25220 { 25221 STRCPY(v->di_key, name); 25222 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 25223 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 25224 v->di_tv.v_type = VAR_NUMBER; 25225 v->di_tv.v_lock = VAR_FIXED; 25226 v->di_tv.vval.v_number = nr; 25227 } 25228 25229 /* 25230 * ":return [expr]" 25231 */ 25232 void 25233 ex_return(exarg_T *eap) 25234 { 25235 char_u *arg = eap->arg; 25236 typval_T rettv; 25237 int returning = FALSE; 25238 25239 if (current_funccal == NULL) 25240 { 25241 EMSG(_("E133: :return not inside a function")); 25242 return; 25243 } 25244 25245 if (eap->skip) 25246 ++emsg_skip; 25247 25248 eap->nextcmd = NULL; 25249 if ((*arg != NUL && *arg != '|' && *arg != '\n') 25250 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 25251 { 25252 if (!eap->skip) 25253 returning = do_return(eap, FALSE, TRUE, &rettv); 25254 else 25255 clear_tv(&rettv); 25256 } 25257 /* It's safer to return also on error. */ 25258 else if (!eap->skip) 25259 { 25260 /* 25261 * Return unless the expression evaluation has been cancelled due to an 25262 * aborting error, an interrupt, or an exception. 25263 */ 25264 if (!aborting()) 25265 returning = do_return(eap, FALSE, TRUE, NULL); 25266 } 25267 25268 /* When skipping or the return gets pending, advance to the next command 25269 * in this line (!returning). Otherwise, ignore the rest of the line. 25270 * Following lines will be ignored by get_func_line(). */ 25271 if (returning) 25272 eap->nextcmd = NULL; 25273 else if (eap->nextcmd == NULL) /* no argument */ 25274 eap->nextcmd = check_nextcmd(arg); 25275 25276 if (eap->skip) 25277 --emsg_skip; 25278 } 25279 25280 /* 25281 * Return from a function. Possibly makes the return pending. Also called 25282 * for a pending return at the ":endtry" or after returning from an extra 25283 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 25284 * when called due to a ":return" command. "rettv" may point to a typval_T 25285 * with the return rettv. Returns TRUE when the return can be carried out, 25286 * FALSE when the return gets pending. 25287 */ 25288 int 25289 do_return( 25290 exarg_T *eap, 25291 int reanimate, 25292 int is_cmd, 25293 void *rettv) 25294 { 25295 int idx; 25296 struct condstack *cstack = eap->cstack; 25297 25298 if (reanimate) 25299 /* Undo the return. */ 25300 current_funccal->returned = FALSE; 25301 25302 /* 25303 * Cleanup (and inactivate) conditionals, but stop when a try conditional 25304 * not in its finally clause (which then is to be executed next) is found. 25305 * In this case, make the ":return" pending for execution at the ":endtry". 25306 * Otherwise, return normally. 25307 */ 25308 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 25309 if (idx >= 0) 25310 { 25311 cstack->cs_pending[idx] = CSTP_RETURN; 25312 25313 if (!is_cmd && !reanimate) 25314 /* A pending return again gets pending. "rettv" points to an 25315 * allocated variable with the rettv of the original ":return"'s 25316 * argument if present or is NULL else. */ 25317 cstack->cs_rettv[idx] = rettv; 25318 else 25319 { 25320 /* When undoing a return in order to make it pending, get the stored 25321 * return rettv. */ 25322 if (reanimate) 25323 rettv = current_funccal->rettv; 25324 25325 if (rettv != NULL) 25326 { 25327 /* Store the value of the pending return. */ 25328 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 25329 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 25330 else 25331 EMSG(_(e_outofmem)); 25332 } 25333 else 25334 cstack->cs_rettv[idx] = NULL; 25335 25336 if (reanimate) 25337 { 25338 /* The pending return value could be overwritten by a ":return" 25339 * without argument in a finally clause; reset the default 25340 * return value. */ 25341 current_funccal->rettv->v_type = VAR_NUMBER; 25342 current_funccal->rettv->vval.v_number = 0; 25343 } 25344 } 25345 report_make_pending(CSTP_RETURN, rettv); 25346 } 25347 else 25348 { 25349 current_funccal->returned = TRUE; 25350 25351 /* If the return is carried out now, store the return value. For 25352 * a return immediately after reanimation, the value is already 25353 * there. */ 25354 if (!reanimate && rettv != NULL) 25355 { 25356 clear_tv(current_funccal->rettv); 25357 *current_funccal->rettv = *(typval_T *)rettv; 25358 if (!is_cmd) 25359 vim_free(rettv); 25360 } 25361 } 25362 25363 return idx < 0; 25364 } 25365 25366 /* 25367 * Free the variable with a pending return value. 25368 */ 25369 void 25370 discard_pending_return(void *rettv) 25371 { 25372 free_tv((typval_T *)rettv); 25373 } 25374 25375 /* 25376 * Generate a return command for producing the value of "rettv". The result 25377 * is an allocated string. Used by report_pending() for verbose messages. 25378 */ 25379 char_u * 25380 get_return_cmd(void *rettv) 25381 { 25382 char_u *s = NULL; 25383 char_u *tofree = NULL; 25384 char_u numbuf[NUMBUFLEN]; 25385 25386 if (rettv != NULL) 25387 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 25388 if (s == NULL) 25389 s = (char_u *)""; 25390 25391 STRCPY(IObuff, ":return "); 25392 STRNCPY(IObuff + 8, s, IOSIZE - 8); 25393 if (STRLEN(s) + 8 >= IOSIZE) 25394 STRCPY(IObuff + IOSIZE - 4, "..."); 25395 vim_free(tofree); 25396 return vim_strsave(IObuff); 25397 } 25398 25399 /* 25400 * Get next function line. 25401 * Called by do_cmdline() to get the next line. 25402 * Returns allocated string, or NULL for end of function. 25403 */ 25404 char_u * 25405 get_func_line( 25406 int c UNUSED, 25407 void *cookie, 25408 int indent UNUSED) 25409 { 25410 funccall_T *fcp = (funccall_T *)cookie; 25411 ufunc_T *fp = fcp->func; 25412 char_u *retval; 25413 garray_T *gap; /* growarray with function lines */ 25414 25415 /* If breakpoints have been added/deleted need to check for it. */ 25416 if (fcp->dbg_tick != debug_tick) 25417 { 25418 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 25419 sourcing_lnum); 25420 fcp->dbg_tick = debug_tick; 25421 } 25422 #ifdef FEAT_PROFILE 25423 if (do_profiling == PROF_YES) 25424 func_line_end(cookie); 25425 #endif 25426 25427 gap = &fp->uf_lines; 25428 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 25429 || fcp->returned) 25430 retval = NULL; 25431 else 25432 { 25433 /* Skip NULL lines (continuation lines). */ 25434 while (fcp->linenr < gap->ga_len 25435 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 25436 ++fcp->linenr; 25437 if (fcp->linenr >= gap->ga_len) 25438 retval = NULL; 25439 else 25440 { 25441 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 25442 sourcing_lnum = fcp->linenr; 25443 #ifdef FEAT_PROFILE 25444 if (do_profiling == PROF_YES) 25445 func_line_start(cookie); 25446 #endif 25447 } 25448 } 25449 25450 /* Did we encounter a breakpoint? */ 25451 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 25452 { 25453 dbg_breakpoint(fp->uf_name, sourcing_lnum); 25454 /* Find next breakpoint. */ 25455 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 25456 sourcing_lnum); 25457 fcp->dbg_tick = debug_tick; 25458 } 25459 25460 return retval; 25461 } 25462 25463 #if defined(FEAT_PROFILE) || defined(PROTO) 25464 /* 25465 * Called when starting to read a function line. 25466 * "sourcing_lnum" must be correct! 25467 * When skipping lines it may not actually be executed, but we won't find out 25468 * until later and we need to store the time now. 25469 */ 25470 void 25471 func_line_start(void *cookie) 25472 { 25473 funccall_T *fcp = (funccall_T *)cookie; 25474 ufunc_T *fp = fcp->func; 25475 25476 if (fp->uf_profiling && sourcing_lnum >= 1 25477 && sourcing_lnum <= fp->uf_lines.ga_len) 25478 { 25479 fp->uf_tml_idx = sourcing_lnum - 1; 25480 /* Skip continuation lines. */ 25481 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 25482 --fp->uf_tml_idx; 25483 fp->uf_tml_execed = FALSE; 25484 profile_start(&fp->uf_tml_start); 25485 profile_zero(&fp->uf_tml_children); 25486 profile_get_wait(&fp->uf_tml_wait); 25487 } 25488 } 25489 25490 /* 25491 * Called when actually executing a function line. 25492 */ 25493 void 25494 func_line_exec(void *cookie) 25495 { 25496 funccall_T *fcp = (funccall_T *)cookie; 25497 ufunc_T *fp = fcp->func; 25498 25499 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 25500 fp->uf_tml_execed = TRUE; 25501 } 25502 25503 /* 25504 * Called when done with a function line. 25505 */ 25506 void 25507 func_line_end(void *cookie) 25508 { 25509 funccall_T *fcp = (funccall_T *)cookie; 25510 ufunc_T *fp = fcp->func; 25511 25512 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 25513 { 25514 if (fp->uf_tml_execed) 25515 { 25516 ++fp->uf_tml_count[fp->uf_tml_idx]; 25517 profile_end(&fp->uf_tml_start); 25518 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 25519 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 25520 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 25521 &fp->uf_tml_children); 25522 } 25523 fp->uf_tml_idx = -1; 25524 } 25525 } 25526 #endif 25527 25528 /* 25529 * Return TRUE if the currently active function should be ended, because a 25530 * return was encountered or an error occurred. Used inside a ":while". 25531 */ 25532 int 25533 func_has_ended(void *cookie) 25534 { 25535 funccall_T *fcp = (funccall_T *)cookie; 25536 25537 /* Ignore the "abort" flag if the abortion behavior has been changed due to 25538 * an error inside a try conditional. */ 25539 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 25540 || fcp->returned); 25541 } 25542 25543 /* 25544 * return TRUE if cookie indicates a function which "abort"s on errors. 25545 */ 25546 int 25547 func_has_abort( 25548 void *cookie) 25549 { 25550 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 25551 } 25552 25553 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 25554 typedef enum 25555 { 25556 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 25557 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 25558 VAR_FLAVOUR_VIMINFO /* all uppercase */ 25559 } var_flavour_T; 25560 25561 static var_flavour_T var_flavour(char_u *varname); 25562 25563 static var_flavour_T 25564 var_flavour(char_u *varname) 25565 { 25566 char_u *p = varname; 25567 25568 if (ASCII_ISUPPER(*p)) 25569 { 25570 while (*(++p)) 25571 if (ASCII_ISLOWER(*p)) 25572 return VAR_FLAVOUR_SESSION; 25573 return VAR_FLAVOUR_VIMINFO; 25574 } 25575 else 25576 return VAR_FLAVOUR_DEFAULT; 25577 } 25578 #endif 25579 25580 #if defined(FEAT_VIMINFO) || defined(PROTO) 25581 /* 25582 * Restore global vars that start with a capital from the viminfo file 25583 */ 25584 int 25585 read_viminfo_varlist(vir_T *virp, int writing) 25586 { 25587 char_u *tab; 25588 int type = VAR_NUMBER; 25589 typval_T tv; 25590 funccall_T *save_funccal; 25591 25592 if (!writing && (find_viminfo_parameter('!') != NULL)) 25593 { 25594 tab = vim_strchr(virp->vir_line + 1, '\t'); 25595 if (tab != NULL) 25596 { 25597 *tab++ = '\0'; /* isolate the variable name */ 25598 switch (*tab) 25599 { 25600 case 'S': type = VAR_STRING; break; 25601 #ifdef FEAT_FLOAT 25602 case 'F': type = VAR_FLOAT; break; 25603 #endif 25604 case 'D': type = VAR_DICT; break; 25605 case 'L': type = VAR_LIST; break; 25606 case 'X': type = VAR_SPECIAL; break; 25607 } 25608 25609 tab = vim_strchr(tab, '\t'); 25610 if (tab != NULL) 25611 { 25612 tv.v_type = type; 25613 if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST) 25614 tv.vval.v_string = viminfo_readstring(virp, 25615 (int)(tab - virp->vir_line + 1), TRUE); 25616 #ifdef FEAT_FLOAT 25617 else if (type == VAR_FLOAT) 25618 (void)string2float(tab + 1, &tv.vval.v_float); 25619 #endif 25620 else 25621 tv.vval.v_number = atol((char *)tab + 1); 25622 if (type == VAR_DICT || type == VAR_LIST) 25623 { 25624 typval_T *etv = eval_expr(tv.vval.v_string, NULL); 25625 25626 if (etv == NULL) 25627 /* Failed to parse back the dict or list, use it as a 25628 * string. */ 25629 tv.v_type = VAR_STRING; 25630 else 25631 { 25632 vim_free(tv.vval.v_string); 25633 tv = *etv; 25634 vim_free(etv); 25635 } 25636 } 25637 25638 /* when in a function use global variables */ 25639 save_funccal = current_funccal; 25640 current_funccal = NULL; 25641 set_var(virp->vir_line + 1, &tv, FALSE); 25642 current_funccal = save_funccal; 25643 25644 if (tv.v_type == VAR_STRING) 25645 vim_free(tv.vval.v_string); 25646 else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST) 25647 clear_tv(&tv); 25648 } 25649 } 25650 } 25651 25652 return viminfo_readline(virp); 25653 } 25654 25655 /* 25656 * Write global vars that start with a capital to the viminfo file 25657 */ 25658 void 25659 write_viminfo_varlist(FILE *fp) 25660 { 25661 hashitem_T *hi; 25662 dictitem_T *this_var; 25663 int todo; 25664 char *s = ""; 25665 char_u *p; 25666 char_u *tofree; 25667 char_u numbuf[NUMBUFLEN]; 25668 25669 if (find_viminfo_parameter('!') == NULL) 25670 return; 25671 25672 fputs(_("\n# global variables:\n"), fp); 25673 25674 todo = (int)globvarht.ht_used; 25675 for (hi = globvarht.ht_array; todo > 0; ++hi) 25676 { 25677 if (!HASHITEM_EMPTY(hi)) 25678 { 25679 --todo; 25680 this_var = HI2DI(hi); 25681 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 25682 { 25683 switch (this_var->di_tv.v_type) 25684 { 25685 case VAR_STRING: s = "STR"; break; 25686 case VAR_NUMBER: s = "NUM"; break; 25687 case VAR_FLOAT: s = "FLO"; break; 25688 case VAR_DICT: s = "DIC"; break; 25689 case VAR_LIST: s = "LIS"; break; 25690 case VAR_SPECIAL: s = "XPL"; break; 25691 25692 case VAR_UNKNOWN: 25693 case VAR_FUNC: 25694 case VAR_PARTIAL: 25695 case VAR_JOB: 25696 case VAR_CHANNEL: 25697 continue; 25698 } 25699 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 25700 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 25701 if (p != NULL) 25702 viminfo_writestring(fp, p); 25703 vim_free(tofree); 25704 } 25705 } 25706 } 25707 } 25708 #endif 25709 25710 #if defined(FEAT_SESSION) || defined(PROTO) 25711 int 25712 store_session_globals(FILE *fd) 25713 { 25714 hashitem_T *hi; 25715 dictitem_T *this_var; 25716 int todo; 25717 char_u *p, *t; 25718 25719 todo = (int)globvarht.ht_used; 25720 for (hi = globvarht.ht_array; todo > 0; ++hi) 25721 { 25722 if (!HASHITEM_EMPTY(hi)) 25723 { 25724 --todo; 25725 this_var = HI2DI(hi); 25726 if ((this_var->di_tv.v_type == VAR_NUMBER 25727 || this_var->di_tv.v_type == VAR_STRING) 25728 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 25729 { 25730 /* Escape special characters with a backslash. Turn a LF and 25731 * CR into \n and \r. */ 25732 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 25733 (char_u *)"\\\"\n\r"); 25734 if (p == NULL) /* out of memory */ 25735 break; 25736 for (t = p; *t != NUL; ++t) 25737 if (*t == '\n') 25738 *t = 'n'; 25739 else if (*t == '\r') 25740 *t = 'r'; 25741 if ((fprintf(fd, "let %s = %c%s%c", 25742 this_var->di_key, 25743 (this_var->di_tv.v_type == VAR_STRING) ? '"' 25744 : ' ', 25745 p, 25746 (this_var->di_tv.v_type == VAR_STRING) ? '"' 25747 : ' ') < 0) 25748 || put_eol(fd) == FAIL) 25749 { 25750 vim_free(p); 25751 return FAIL; 25752 } 25753 vim_free(p); 25754 } 25755 #ifdef FEAT_FLOAT 25756 else if (this_var->di_tv.v_type == VAR_FLOAT 25757 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 25758 { 25759 float_T f = this_var->di_tv.vval.v_float; 25760 int sign = ' '; 25761 25762 if (f < 0) 25763 { 25764 f = -f; 25765 sign = '-'; 25766 } 25767 if ((fprintf(fd, "let %s = %c%f", 25768 this_var->di_key, sign, f) < 0) 25769 || put_eol(fd) == FAIL) 25770 return FAIL; 25771 } 25772 #endif 25773 } 25774 } 25775 return OK; 25776 } 25777 #endif 25778 25779 /* 25780 * Display script name where an item was last set. 25781 * Should only be invoked when 'verbose' is non-zero. 25782 */ 25783 void 25784 last_set_msg(scid_T scriptID) 25785 { 25786 char_u *p; 25787 25788 if (scriptID != 0) 25789 { 25790 p = home_replace_save(NULL, get_scriptname(scriptID)); 25791 if (p != NULL) 25792 { 25793 verbose_enter(); 25794 MSG_PUTS(_("\n\tLast set from ")); 25795 MSG_PUTS(p); 25796 vim_free(p); 25797 verbose_leave(); 25798 } 25799 } 25800 } 25801 25802 /* 25803 * List v:oldfiles in a nice way. 25804 */ 25805 void 25806 ex_oldfiles(exarg_T *eap UNUSED) 25807 { 25808 list_T *l = vimvars[VV_OLDFILES].vv_list; 25809 listitem_T *li; 25810 int nr = 0; 25811 25812 if (l == NULL) 25813 msg((char_u *)_("No old files")); 25814 else 25815 { 25816 msg_start(); 25817 msg_scroll = TRUE; 25818 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 25819 { 25820 msg_outnum((long)++nr); 25821 MSG_PUTS(": "); 25822 msg_outtrans(get_tv_string(&li->li_tv)); 25823 msg_putchar('\n'); 25824 out_flush(); /* output one line at a time */ 25825 ui_breakcheck(); 25826 } 25827 /* Assume "got_int" was set to truncate the listing. */ 25828 got_int = FALSE; 25829 25830 #ifdef FEAT_BROWSE_CMD 25831 if (cmdmod.browse) 25832 { 25833 quit_more = FALSE; 25834 nr = prompt_for_number(FALSE); 25835 msg_starthere(); 25836 if (nr > 0) 25837 { 25838 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 25839 (long)nr); 25840 25841 if (p != NULL) 25842 { 25843 p = expand_env_save(p); 25844 eap->arg = p; 25845 eap->cmdidx = CMD_edit; 25846 cmdmod.browse = FALSE; 25847 do_exedit(eap, NULL); 25848 vim_free(p); 25849 } 25850 } 25851 } 25852 #endif 25853 } 25854 } 25855 25856 /* reset v:option_new, v:option_old and v:option_type */ 25857 void 25858 reset_v_option_vars(void) 25859 { 25860 set_vim_var_string(VV_OPTION_NEW, NULL, -1); 25861 set_vim_var_string(VV_OPTION_OLD, NULL, -1); 25862 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); 25863 } 25864 25865 25866 #endif /* FEAT_EVAL */ 25867 25868 25869 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 25870 25871 #ifdef WIN3264 25872 /* 25873 * Functions for ":8" filename modifier: get 8.3 version of a filename. 25874 */ 25875 static int get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen); 25876 static int shortpath_for_invalid_fname(char_u **fname, char_u **bufp, int *fnamelen); 25877 static int shortpath_for_partial(char_u **fnamep, char_u **bufp, int *fnamelen); 25878 25879 /* 25880 * Get the short path (8.3) for the filename in "fnamep". 25881 * Only works for a valid file name. 25882 * When the path gets longer "fnamep" is changed and the allocated buffer 25883 * is put in "bufp". 25884 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 25885 * Returns OK on success, FAIL on failure. 25886 */ 25887 static int 25888 get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen) 25889 { 25890 int l, len; 25891 char_u *newbuf; 25892 25893 len = *fnamelen; 25894 l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len); 25895 if (l > len - 1) 25896 { 25897 /* If that doesn't work (not enough space), then save the string 25898 * and try again with a new buffer big enough. */ 25899 newbuf = vim_strnsave(*fnamep, l); 25900 if (newbuf == NULL) 25901 return FAIL; 25902 25903 vim_free(*bufp); 25904 *fnamep = *bufp = newbuf; 25905 25906 /* Really should always succeed, as the buffer is big enough. */ 25907 l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1); 25908 } 25909 25910 *fnamelen = l; 25911 return OK; 25912 } 25913 25914 /* 25915 * Get the short path (8.3) for the filename in "fname". The converted 25916 * path is returned in "bufp". 25917 * 25918 * Some of the directories specified in "fname" may not exist. This function 25919 * will shorten the existing directories at the beginning of the path and then 25920 * append the remaining non-existing path. 25921 * 25922 * fname - Pointer to the filename to shorten. On return, contains the 25923 * pointer to the shortened pathname 25924 * bufp - Pointer to an allocated buffer for the filename. 25925 * fnamelen - Length of the filename pointed to by fname 25926 * 25927 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 25928 */ 25929 static int 25930 shortpath_for_invalid_fname( 25931 char_u **fname, 25932 char_u **bufp, 25933 int *fnamelen) 25934 { 25935 char_u *short_fname, *save_fname, *pbuf_unused; 25936 char_u *endp, *save_endp; 25937 char_u ch; 25938 int old_len, len; 25939 int new_len, sfx_len; 25940 int retval = OK; 25941 25942 /* Make a copy */ 25943 old_len = *fnamelen; 25944 save_fname = vim_strnsave(*fname, old_len); 25945 pbuf_unused = NULL; 25946 short_fname = NULL; 25947 25948 endp = save_fname + old_len - 1; /* Find the end of the copy */ 25949 save_endp = endp; 25950 25951 /* 25952 * Try shortening the supplied path till it succeeds by removing one 25953 * directory at a time from the tail of the path. 25954 */ 25955 len = 0; 25956 for (;;) 25957 { 25958 /* go back one path-separator */ 25959 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 25960 --endp; 25961 if (endp <= save_fname) 25962 break; /* processed the complete path */ 25963 25964 /* 25965 * Replace the path separator with a NUL and try to shorten the 25966 * resulting path. 25967 */ 25968 ch = *endp; 25969 *endp = 0; 25970 short_fname = save_fname; 25971 len = (int)STRLEN(short_fname) + 1; 25972 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 25973 { 25974 retval = FAIL; 25975 goto theend; 25976 } 25977 *endp = ch; /* preserve the string */ 25978 25979 if (len > 0) 25980 break; /* successfully shortened the path */ 25981 25982 /* failed to shorten the path. Skip the path separator */ 25983 --endp; 25984 } 25985 25986 if (len > 0) 25987 { 25988 /* 25989 * Succeeded in shortening the path. Now concatenate the shortened 25990 * path with the remaining path at the tail. 25991 */ 25992 25993 /* Compute the length of the new path. */ 25994 sfx_len = (int)(save_endp - endp) + 1; 25995 new_len = len + sfx_len; 25996 25997 *fnamelen = new_len; 25998 vim_free(*bufp); 25999 if (new_len > old_len) 26000 { 26001 /* There is not enough space in the currently allocated string, 26002 * copy it to a buffer big enough. */ 26003 *fname = *bufp = vim_strnsave(short_fname, new_len); 26004 if (*fname == NULL) 26005 { 26006 retval = FAIL; 26007 goto theend; 26008 } 26009 } 26010 else 26011 { 26012 /* Transfer short_fname to the main buffer (it's big enough), 26013 * unless get_short_pathname() did its work in-place. */ 26014 *fname = *bufp = save_fname; 26015 if (short_fname != save_fname) 26016 vim_strncpy(save_fname, short_fname, len); 26017 save_fname = NULL; 26018 } 26019 26020 /* concat the not-shortened part of the path */ 26021 vim_strncpy(*fname + len, endp, sfx_len); 26022 (*fname)[new_len] = NUL; 26023 } 26024 26025 theend: 26026 vim_free(pbuf_unused); 26027 vim_free(save_fname); 26028 26029 return retval; 26030 } 26031 26032 /* 26033 * Get a pathname for a partial path. 26034 * Returns OK for success, FAIL for failure. 26035 */ 26036 static int 26037 shortpath_for_partial( 26038 char_u **fnamep, 26039 char_u **bufp, 26040 int *fnamelen) 26041 { 26042 int sepcount, len, tflen; 26043 char_u *p; 26044 char_u *pbuf, *tfname; 26045 int hasTilde; 26046 26047 /* Count up the path separators from the RHS.. so we know which part 26048 * of the path to return. */ 26049 sepcount = 0; 26050 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 26051 if (vim_ispathsep(*p)) 26052 ++sepcount; 26053 26054 /* Need full path first (use expand_env() to remove a "~/") */ 26055 hasTilde = (**fnamep == '~'); 26056 if (hasTilde) 26057 pbuf = tfname = expand_env_save(*fnamep); 26058 else 26059 pbuf = tfname = FullName_save(*fnamep, FALSE); 26060 26061 len = tflen = (int)STRLEN(tfname); 26062 26063 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 26064 return FAIL; 26065 26066 if (len == 0) 26067 { 26068 /* Don't have a valid filename, so shorten the rest of the 26069 * path if we can. This CAN give us invalid 8.3 filenames, but 26070 * there's not a lot of point in guessing what it might be. 26071 */ 26072 len = tflen; 26073 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 26074 return FAIL; 26075 } 26076 26077 /* Count the paths backward to find the beginning of the desired string. */ 26078 for (p = tfname + len - 1; p >= tfname; --p) 26079 { 26080 #ifdef FEAT_MBYTE 26081 if (has_mbyte) 26082 p -= mb_head_off(tfname, p); 26083 #endif 26084 if (vim_ispathsep(*p)) 26085 { 26086 if (sepcount == 0 || (hasTilde && sepcount == 1)) 26087 break; 26088 else 26089 sepcount --; 26090 } 26091 } 26092 if (hasTilde) 26093 { 26094 --p; 26095 if (p >= tfname) 26096 *p = '~'; 26097 else 26098 return FAIL; 26099 } 26100 else 26101 ++p; 26102 26103 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 26104 vim_free(*bufp); 26105 *fnamelen = (int)STRLEN(p); 26106 *bufp = pbuf; 26107 *fnamep = p; 26108 26109 return OK; 26110 } 26111 #endif /* WIN3264 */ 26112 26113 /* 26114 * Adjust a filename, according to a string of modifiers. 26115 * *fnamep must be NUL terminated when called. When returning, the length is 26116 * determined by *fnamelen. 26117 * Returns VALID_ flags or -1 for failure. 26118 * When there is an error, *fnamep is set to NULL. 26119 */ 26120 int 26121 modify_fname( 26122 char_u *src, /* string with modifiers */ 26123 int *usedlen, /* characters after src that are used */ 26124 char_u **fnamep, /* file name so far */ 26125 char_u **bufp, /* buffer for allocated file name or NULL */ 26126 int *fnamelen) /* length of fnamep */ 26127 { 26128 int valid = 0; 26129 char_u *tail; 26130 char_u *s, *p, *pbuf; 26131 char_u dirname[MAXPATHL]; 26132 int c; 26133 int has_fullname = 0; 26134 #ifdef WIN3264 26135 char_u *fname_start = *fnamep; 26136 int has_shortname = 0; 26137 #endif 26138 26139 repeat: 26140 /* ":p" - full path/file_name */ 26141 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 26142 { 26143 has_fullname = 1; 26144 26145 valid |= VALID_PATH; 26146 *usedlen += 2; 26147 26148 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 26149 if ((*fnamep)[0] == '~' 26150 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 26151 && ((*fnamep)[1] == '/' 26152 # ifdef BACKSLASH_IN_FILENAME 26153 || (*fnamep)[1] == '\\' 26154 # endif 26155 || (*fnamep)[1] == NUL) 26156 26157 #endif 26158 ) 26159 { 26160 *fnamep = expand_env_save(*fnamep); 26161 vim_free(*bufp); /* free any allocated file name */ 26162 *bufp = *fnamep; 26163 if (*fnamep == NULL) 26164 return -1; 26165 } 26166 26167 /* When "/." or "/.." is used: force expansion to get rid of it. */ 26168 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 26169 { 26170 if (vim_ispathsep(*p) 26171 && p[1] == '.' 26172 && (p[2] == NUL 26173 || vim_ispathsep(p[2]) 26174 || (p[2] == '.' 26175 && (p[3] == NUL || vim_ispathsep(p[3]))))) 26176 break; 26177 } 26178 26179 /* FullName_save() is slow, don't use it when not needed. */ 26180 if (*p != NUL || !vim_isAbsName(*fnamep)) 26181 { 26182 *fnamep = FullName_save(*fnamep, *p != NUL); 26183 vim_free(*bufp); /* free any allocated file name */ 26184 *bufp = *fnamep; 26185 if (*fnamep == NULL) 26186 return -1; 26187 } 26188 26189 #ifdef WIN3264 26190 # if _WIN32_WINNT >= 0x0500 26191 if (vim_strchr(*fnamep, '~') != NULL) 26192 { 26193 /* Expand 8.3 filename to full path. Needed to make sure the same 26194 * file does not have two different names. 26195 * Note: problem does not occur if _WIN32_WINNT < 0x0500. */ 26196 p = alloc(_MAX_PATH + 1); 26197 if (p != NULL) 26198 { 26199 if (GetLongPathName((LPSTR)*fnamep, (LPSTR)p, _MAX_PATH)) 26200 { 26201 vim_free(*bufp); 26202 *bufp = *fnamep = p; 26203 } 26204 else 26205 vim_free(p); 26206 } 26207 } 26208 # endif 26209 #endif 26210 /* Append a path separator to a directory. */ 26211 if (mch_isdir(*fnamep)) 26212 { 26213 /* Make room for one or two extra characters. */ 26214 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 26215 vim_free(*bufp); /* free any allocated file name */ 26216 *bufp = *fnamep; 26217 if (*fnamep == NULL) 26218 return -1; 26219 add_pathsep(*fnamep); 26220 } 26221 } 26222 26223 /* ":." - path relative to the current directory */ 26224 /* ":~" - path relative to the home directory */ 26225 /* ":8" - shortname path - postponed till after */ 26226 while (src[*usedlen] == ':' 26227 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 26228 { 26229 *usedlen += 2; 26230 if (c == '8') 26231 { 26232 #ifdef WIN3264 26233 has_shortname = 1; /* Postpone this. */ 26234 #endif 26235 continue; 26236 } 26237 pbuf = NULL; 26238 /* Need full path first (use expand_env() to remove a "~/") */ 26239 if (!has_fullname) 26240 { 26241 if (c == '.' && **fnamep == '~') 26242 p = pbuf = expand_env_save(*fnamep); 26243 else 26244 p = pbuf = FullName_save(*fnamep, FALSE); 26245 } 26246 else 26247 p = *fnamep; 26248 26249 has_fullname = 0; 26250 26251 if (p != NULL) 26252 { 26253 if (c == '.') 26254 { 26255 mch_dirname(dirname, MAXPATHL); 26256 s = shorten_fname(p, dirname); 26257 if (s != NULL) 26258 { 26259 *fnamep = s; 26260 if (pbuf != NULL) 26261 { 26262 vim_free(*bufp); /* free any allocated file name */ 26263 *bufp = pbuf; 26264 pbuf = NULL; 26265 } 26266 } 26267 } 26268 else 26269 { 26270 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 26271 /* Only replace it when it starts with '~' */ 26272 if (*dirname == '~') 26273 { 26274 s = vim_strsave(dirname); 26275 if (s != NULL) 26276 { 26277 *fnamep = s; 26278 vim_free(*bufp); 26279 *bufp = s; 26280 } 26281 } 26282 } 26283 vim_free(pbuf); 26284 } 26285 } 26286 26287 tail = gettail(*fnamep); 26288 *fnamelen = (int)STRLEN(*fnamep); 26289 26290 /* ":h" - head, remove "/file_name", can be repeated */ 26291 /* Don't remove the first "/" or "c:\" */ 26292 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 26293 { 26294 valid |= VALID_HEAD; 26295 *usedlen += 2; 26296 s = get_past_head(*fnamep); 26297 while (tail > s && after_pathsep(s, tail)) 26298 mb_ptr_back(*fnamep, tail); 26299 *fnamelen = (int)(tail - *fnamep); 26300 #ifdef VMS 26301 if (*fnamelen > 0) 26302 *fnamelen += 1; /* the path separator is part of the path */ 26303 #endif 26304 if (*fnamelen == 0) 26305 { 26306 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 26307 p = vim_strsave((char_u *)"."); 26308 if (p == NULL) 26309 return -1; 26310 vim_free(*bufp); 26311 *bufp = *fnamep = tail = p; 26312 *fnamelen = 1; 26313 } 26314 else 26315 { 26316 while (tail > s && !after_pathsep(s, tail)) 26317 mb_ptr_back(*fnamep, tail); 26318 } 26319 } 26320 26321 /* ":8" - shortname */ 26322 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 26323 { 26324 *usedlen += 2; 26325 #ifdef WIN3264 26326 has_shortname = 1; 26327 #endif 26328 } 26329 26330 #ifdef WIN3264 26331 /* 26332 * Handle ":8" after we have done 'heads' and before we do 'tails'. 26333 */ 26334 if (has_shortname) 26335 { 26336 /* Copy the string if it is shortened by :h and when it wasn't copied 26337 * yet, because we are going to change it in place. Avoids changing 26338 * the buffer name for "%:8". */ 26339 if (*fnamelen < (int)STRLEN(*fnamep) || *fnamep == fname_start) 26340 { 26341 p = vim_strnsave(*fnamep, *fnamelen); 26342 if (p == NULL) 26343 return -1; 26344 vim_free(*bufp); 26345 *bufp = *fnamep = p; 26346 } 26347 26348 /* Split into two implementations - makes it easier. First is where 26349 * there isn't a full name already, second is where there is. */ 26350 if (!has_fullname && !vim_isAbsName(*fnamep)) 26351 { 26352 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 26353 return -1; 26354 } 26355 else 26356 { 26357 int l = *fnamelen; 26358 26359 /* Simple case, already have the full-name. 26360 * Nearly always shorter, so try first time. */ 26361 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 26362 return -1; 26363 26364 if (l == 0) 26365 { 26366 /* Couldn't find the filename, search the paths. */ 26367 l = *fnamelen; 26368 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 26369 return -1; 26370 } 26371 *fnamelen = l; 26372 } 26373 } 26374 #endif /* WIN3264 */ 26375 26376 /* ":t" - tail, just the basename */ 26377 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 26378 { 26379 *usedlen += 2; 26380 *fnamelen -= (int)(tail - *fnamep); 26381 *fnamep = tail; 26382 } 26383 26384 /* ":e" - extension, can be repeated */ 26385 /* ":r" - root, without extension, can be repeated */ 26386 while (src[*usedlen] == ':' 26387 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 26388 { 26389 /* find a '.' in the tail: 26390 * - for second :e: before the current fname 26391 * - otherwise: The last '.' 26392 */ 26393 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 26394 s = *fnamep - 2; 26395 else 26396 s = *fnamep + *fnamelen - 1; 26397 for ( ; s > tail; --s) 26398 if (s[0] == '.') 26399 break; 26400 if (src[*usedlen + 1] == 'e') /* :e */ 26401 { 26402 if (s > tail) 26403 { 26404 *fnamelen += (int)(*fnamep - (s + 1)); 26405 *fnamep = s + 1; 26406 #ifdef VMS 26407 /* cut version from the extension */ 26408 s = *fnamep + *fnamelen - 1; 26409 for ( ; s > *fnamep; --s) 26410 if (s[0] == ';') 26411 break; 26412 if (s > *fnamep) 26413 *fnamelen = s - *fnamep; 26414 #endif 26415 } 26416 else if (*fnamep <= tail) 26417 *fnamelen = 0; 26418 } 26419 else /* :r */ 26420 { 26421 if (s > tail) /* remove one extension */ 26422 *fnamelen = (int)(s - *fnamep); 26423 } 26424 *usedlen += 2; 26425 } 26426 26427 /* ":s?pat?foo?" - substitute */ 26428 /* ":gs?pat?foo?" - global substitute */ 26429 if (src[*usedlen] == ':' 26430 && (src[*usedlen + 1] == 's' 26431 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 26432 { 26433 char_u *str; 26434 char_u *pat; 26435 char_u *sub; 26436 int sep; 26437 char_u *flags; 26438 int didit = FALSE; 26439 26440 flags = (char_u *)""; 26441 s = src + *usedlen + 2; 26442 if (src[*usedlen + 1] == 'g') 26443 { 26444 flags = (char_u *)"g"; 26445 ++s; 26446 } 26447 26448 sep = *s++; 26449 if (sep) 26450 { 26451 /* find end of pattern */ 26452 p = vim_strchr(s, sep); 26453 if (p != NULL) 26454 { 26455 pat = vim_strnsave(s, (int)(p - s)); 26456 if (pat != NULL) 26457 { 26458 s = p + 1; 26459 /* find end of substitution */ 26460 p = vim_strchr(s, sep); 26461 if (p != NULL) 26462 { 26463 sub = vim_strnsave(s, (int)(p - s)); 26464 str = vim_strnsave(*fnamep, *fnamelen); 26465 if (sub != NULL && str != NULL) 26466 { 26467 *usedlen = (int)(p + 1 - src); 26468 s = do_string_sub(str, pat, sub, flags); 26469 if (s != NULL) 26470 { 26471 *fnamep = s; 26472 *fnamelen = (int)STRLEN(s); 26473 vim_free(*bufp); 26474 *bufp = s; 26475 didit = TRUE; 26476 } 26477 } 26478 vim_free(sub); 26479 vim_free(str); 26480 } 26481 vim_free(pat); 26482 } 26483 } 26484 /* after using ":s", repeat all the modifiers */ 26485 if (didit) 26486 goto repeat; 26487 } 26488 } 26489 26490 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S') 26491 { 26492 /* vim_strsave_shellescape() needs a NUL terminated string. */ 26493 c = (*fnamep)[*fnamelen]; 26494 if (c != NUL) 26495 (*fnamep)[*fnamelen] = NUL; 26496 p = vim_strsave_shellescape(*fnamep, FALSE, FALSE); 26497 if (c != NUL) 26498 (*fnamep)[*fnamelen] = c; 26499 if (p == NULL) 26500 return -1; 26501 vim_free(*bufp); 26502 *bufp = *fnamep = p; 26503 *fnamelen = (int)STRLEN(p); 26504 *usedlen += 2; 26505 } 26506 26507 return valid; 26508 } 26509 26510 /* 26511 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 26512 * "flags" can be "g" to do a global substitute. 26513 * Returns an allocated string, NULL for error. 26514 */ 26515 char_u * 26516 do_string_sub( 26517 char_u *str, 26518 char_u *pat, 26519 char_u *sub, 26520 char_u *flags) 26521 { 26522 int sublen; 26523 regmatch_T regmatch; 26524 int i; 26525 int do_all; 26526 char_u *tail; 26527 char_u *end; 26528 garray_T ga; 26529 char_u *ret; 26530 char_u *save_cpo; 26531 char_u *zero_width = NULL; 26532 26533 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 26534 save_cpo = p_cpo; 26535 p_cpo = empty_option; 26536 26537 ga_init2(&ga, 1, 200); 26538 26539 do_all = (flags[0] == 'g'); 26540 26541 regmatch.rm_ic = p_ic; 26542 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 26543 if (regmatch.regprog != NULL) 26544 { 26545 tail = str; 26546 end = str + STRLEN(str); 26547 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 26548 { 26549 /* Skip empty match except for first match. */ 26550 if (regmatch.startp[0] == regmatch.endp[0]) 26551 { 26552 if (zero_width == regmatch.startp[0]) 26553 { 26554 /* avoid getting stuck on a match with an empty string */ 26555 i = MB_PTR2LEN(tail); 26556 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, 26557 (size_t)i); 26558 ga.ga_len += i; 26559 tail += i; 26560 continue; 26561 } 26562 zero_width = regmatch.startp[0]; 26563 } 26564 26565 /* 26566 * Get some space for a temporary buffer to do the substitution 26567 * into. It will contain: 26568 * - The text up to where the match is. 26569 * - The substituted text. 26570 * - The text after the match. 26571 */ 26572 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 26573 if (ga_grow(&ga, (int)((end - tail) + sublen - 26574 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 26575 { 26576 ga_clear(&ga); 26577 break; 26578 } 26579 26580 /* copy the text up to where the match is */ 26581 i = (int)(regmatch.startp[0] - tail); 26582 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 26583 /* add the substituted text */ 26584 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 26585 + ga.ga_len + i, TRUE, TRUE, FALSE); 26586 ga.ga_len += i + sublen - 1; 26587 tail = regmatch.endp[0]; 26588 if (*tail == NUL) 26589 break; 26590 if (!do_all) 26591 break; 26592 } 26593 26594 if (ga.ga_data != NULL) 26595 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 26596 26597 vim_regfree(regmatch.regprog); 26598 } 26599 26600 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 26601 ga_clear(&ga); 26602 if (p_cpo == empty_option) 26603 p_cpo = save_cpo; 26604 else 26605 /* Darn, evaluating {sub} expression changed the value. */ 26606 free_string_option(save_cpo); 26607 26608 return ret; 26609 } 26610 26611 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 26612