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 */ 213 static dict_T *first_dict = NULL; /* list of all dicts */ 214 static list_T *first_list = NULL; /* list of all lists */ 215 216 /* From user function to hashitem and back. */ 217 static ufunc_T dumuf; 218 #define UF2HIKEY(fp) ((fp)->uf_name) 219 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 220 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 221 222 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 223 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 224 225 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 226 #define VAR_SHORT_LEN 20 /* short variable name length */ 227 #define FIXVAR_CNT 12 /* number of fixed variables */ 228 229 /* structure to hold info for a function that is currently being executed. */ 230 typedef struct funccall_S funccall_T; 231 232 struct funccall_S 233 { 234 ufunc_T *func; /* function being called */ 235 int linenr; /* next line to be executed */ 236 int returned; /* ":return" used */ 237 struct /* fixed variables for arguments */ 238 { 239 dictitem_T var; /* variable (without room for name) */ 240 char_u room[VAR_SHORT_LEN]; /* room for the name */ 241 } fixvar[FIXVAR_CNT]; 242 dict_T l_vars; /* l: local function variables */ 243 dictitem_T l_vars_var; /* variable for l: scope */ 244 dict_T l_avars; /* a: argument variables */ 245 dictitem_T l_avars_var; /* variable for a: scope */ 246 list_T l_varlist; /* list for a:000 */ 247 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 248 typval_T *rettv; /* return value */ 249 linenr_T breakpoint; /* next line with breakpoint or zero */ 250 int dbg_tick; /* debug_tick when breakpoint was set */ 251 int level; /* top nesting level of executed function */ 252 #ifdef FEAT_PROFILE 253 proftime_T prof_child; /* time spent in a child */ 254 #endif 255 funccall_T *caller; /* calling function or NULL */ 256 }; 257 258 /* 259 * Info used by a ":for" loop. 260 */ 261 typedef struct 262 { 263 int fi_semicolon; /* TRUE if ending in '; var]' */ 264 int fi_varcount; /* nr of variables in the list */ 265 listwatch_T fi_lw; /* keep an eye on the item used. */ 266 list_T *fi_list; /* list being used */ 267 } forinfo_T; 268 269 /* 270 * Struct used by trans_function_name() 271 */ 272 typedef struct 273 { 274 dict_T *fd_dict; /* Dictionary used */ 275 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 276 dictitem_T *fd_di; /* Dictionary item used */ 277 } funcdict_T; 278 279 280 /* 281 * Array to hold the value of v: variables. 282 * The value is in a dictitem, so that it can also be used in the v: scope. 283 * The reason to use this table anyway is for very quick access to the 284 * variables with the VV_ defines. 285 */ 286 #include "version.h" 287 288 /* values for vv_flags: */ 289 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 290 #define VV_RO 2 /* read-only */ 291 #define VV_RO_SBX 4 /* read-only in the sandbox */ 292 293 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}, {0} 294 295 static struct vimvar 296 { 297 char *vv_name; /* name of variable, without v: */ 298 dictitem_T vv_di; /* value and name for key */ 299 char vv_filler[16]; /* space for LONGEST name below!!! */ 300 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 301 } vimvars[VV_LEN] = 302 { 303 /* 304 * The order here must match the VV_ defines in vim.h! 305 * Initializing a union does not work, leave tv.vval empty to get zero's. 306 */ 307 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 308 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 309 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 310 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 311 {VV_NAME("warningmsg", VAR_STRING), 0}, 312 {VV_NAME("statusmsg", VAR_STRING), 0}, 313 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 314 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 315 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 316 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 317 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 318 {VV_NAME("fname", VAR_STRING), VV_RO}, 319 {VV_NAME("lang", VAR_STRING), VV_RO}, 320 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 321 {VV_NAME("ctype", VAR_STRING), VV_RO}, 322 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 323 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 324 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 325 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 326 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 327 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 328 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 329 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 330 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 331 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 332 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 333 {VV_NAME("progname", VAR_STRING), VV_RO}, 334 {VV_NAME("servername", VAR_STRING), VV_RO}, 335 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 336 {VV_NAME("exception", VAR_STRING), VV_RO}, 337 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 338 {VV_NAME("register", VAR_STRING), VV_RO}, 339 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 340 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 341 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 342 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 343 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 344 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 345 {VV_NAME("fcs_choice", VAR_STRING), 0}, 346 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 347 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 348 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 349 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 350 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 351 {VV_NAME("scrollstart", VAR_STRING), 0}, 352 {VV_NAME("swapname", VAR_STRING), VV_RO}, 353 {VV_NAME("swapchoice", VAR_STRING), 0}, 354 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 355 {VV_NAME("char", VAR_STRING), 0}, 356 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 357 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 358 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 359 {VV_NAME("operator", VAR_STRING), VV_RO}, 360 {VV_NAME("searchforward", VAR_NUMBER), 0}, 361 {VV_NAME("hlsearch", VAR_NUMBER), 0}, 362 {VV_NAME("oldfiles", VAR_LIST), 0}, 363 {VV_NAME("windowid", VAR_NUMBER), VV_RO}, 364 {VV_NAME("progpath", VAR_STRING), VV_RO}, 365 {VV_NAME("completed_item", VAR_DICT), VV_RO}, 366 {VV_NAME("option_new", VAR_STRING), VV_RO}, 367 {VV_NAME("option_old", VAR_STRING), VV_RO}, 368 {VV_NAME("option_type", VAR_STRING), VV_RO}, 369 {VV_NAME("errors", VAR_LIST), 0}, 370 {VV_NAME("false", VAR_SPECIAL), VV_RO}, 371 {VV_NAME("true", VAR_SPECIAL), VV_RO}, 372 {VV_NAME("null", VAR_SPECIAL), VV_RO}, 373 {VV_NAME("none", VAR_SPECIAL), VV_RO}, 374 }; 375 376 /* shorthand */ 377 #define vv_type vv_di.di_tv.v_type 378 #define vv_nr vv_di.di_tv.vval.v_number 379 #define vv_float vv_di.di_tv.vval.v_float 380 #define vv_str vv_di.di_tv.vval.v_string 381 #define vv_list vv_di.di_tv.vval.v_list 382 #define vv_dict vv_di.di_tv.vval.v_dict 383 #define vv_tv vv_di.di_tv 384 385 static dictitem_T vimvars_var; /* variable used for v: */ 386 #define vimvarht vimvardict.dv_hashtab 387 388 static void prepare_vimvar(int idx, typval_T *save_tv); 389 static void restore_vimvar(int idx, typval_T *save_tv); 390 static int ex_let_vars(char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars); 391 static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon); 392 static char_u *skip_var_one(char_u *arg); 393 static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first); 394 static void list_glob_vars(int *first); 395 static void list_buf_vars(int *first); 396 static void list_win_vars(int *first); 397 #ifdef FEAT_WINDOWS 398 static void list_tab_vars(int *first); 399 #endif 400 static void list_vim_vars(int *first); 401 static void list_script_vars(int *first); 402 static void list_func_vars(int *first); 403 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); 404 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op); 405 static int check_changedtick(char_u *arg); 406 static char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags); 407 static void clear_lval(lval_T *lp); 408 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op); 409 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); 410 static void list_fix_watch(list_T *l, listitem_T *item); 411 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); 412 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); 413 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); 414 static void item_lock(typval_T *tv, int deep, int lock); 415 static int tv_islocked(typval_T *tv); 416 417 static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate); 418 static int eval1(char_u **arg, typval_T *rettv, int evaluate); 419 static int eval2(char_u **arg, typval_T *rettv, int evaluate); 420 static int eval3(char_u **arg, typval_T *rettv, int evaluate); 421 static int eval4(char_u **arg, typval_T *rettv, int evaluate); 422 static int eval5(char_u **arg, typval_T *rettv, int evaluate); 423 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); 424 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string); 425 426 static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose); 427 static int get_option_tv(char_u **arg, typval_T *rettv, int evaluate); 428 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); 429 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); 430 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate); 431 static long list_len(list_T *l); 432 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive); 433 static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); 434 static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive); 435 static long list_find_nr(list_T *l, long idx, int *errorp); 436 static long list_idx_of_item(list_T *l, listitem_T *item); 437 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); 438 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); 439 static list_T *list_copy(list_T *orig, int deep, int copyID); 440 static char_u *list2string(typval_T *tv, int copyID); 441 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap); 442 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID); 443 static int free_unref_items(int copyID); 444 static dictitem_T *dictitem_copy(dictitem_T *org); 445 static void dictitem_remove(dict_T *dict, dictitem_T *item); 446 static dict_T *dict_copy(dict_T *orig, int deep, int copyID); 447 static long dict_len(dict_T *d); 448 static char_u *dict2string(typval_T *tv, int copyID); 449 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); 450 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); 451 static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); 452 static char_u *string_quote(char_u *str, int function); 453 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); 454 static int find_internal_func(char_u *name); 455 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); 456 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); 457 static void emsg_funcname(char *ermsg, char_u *name); 458 static int non_zero_arg(typval_T *argvars); 459 460 #ifdef FEAT_FLOAT 461 static void f_abs(typval_T *argvars, typval_T *rettv); 462 static void f_acos(typval_T *argvars, typval_T *rettv); 463 #endif 464 static void f_add(typval_T *argvars, typval_T *rettv); 465 static void f_alloc_fail(typval_T *argvars, typval_T *rettv); 466 static void f_and(typval_T *argvars, typval_T *rettv); 467 static void f_append(typval_T *argvars, typval_T *rettv); 468 static void f_argc(typval_T *argvars, typval_T *rettv); 469 static void f_argidx(typval_T *argvars, typval_T *rettv); 470 static void f_arglistid(typval_T *argvars, typval_T *rettv); 471 static void f_argv(typval_T *argvars, typval_T *rettv); 472 static void f_assert_equal(typval_T *argvars, typval_T *rettv); 473 static void f_assert_exception(typval_T *argvars, typval_T *rettv); 474 static void f_assert_fails(typval_T *argvars, typval_T *rettv); 475 static void f_assert_false(typval_T *argvars, typval_T *rettv); 476 static void f_assert_true(typval_T *argvars, typval_T *rettv); 477 #ifdef FEAT_FLOAT 478 static void f_asin(typval_T *argvars, typval_T *rettv); 479 static void f_atan(typval_T *argvars, typval_T *rettv); 480 static void f_atan2(typval_T *argvars, typval_T *rettv); 481 #endif 482 static void f_browse(typval_T *argvars, typval_T *rettv); 483 static void f_browsedir(typval_T *argvars, typval_T *rettv); 484 static void f_bufexists(typval_T *argvars, typval_T *rettv); 485 static void f_buflisted(typval_T *argvars, typval_T *rettv); 486 static void f_bufloaded(typval_T *argvars, typval_T *rettv); 487 static void f_bufname(typval_T *argvars, typval_T *rettv); 488 static void f_bufnr(typval_T *argvars, typval_T *rettv); 489 static void f_bufwinnr(typval_T *argvars, typval_T *rettv); 490 static void f_byte2line(typval_T *argvars, typval_T *rettv); 491 static void byteidx(typval_T *argvars, typval_T *rettv, int comp); 492 static void f_byteidx(typval_T *argvars, typval_T *rettv); 493 static void f_byteidxcomp(typval_T *argvars, typval_T *rettv); 494 static void f_call(typval_T *argvars, typval_T *rettv); 495 #ifdef FEAT_FLOAT 496 static void f_ceil(typval_T *argvars, typval_T *rettv); 497 #endif 498 #ifdef FEAT_JOB_CHANNEL 499 static void f_ch_close(typval_T *argvars, typval_T *rettv); 500 static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv); 501 static void f_ch_evalraw(typval_T *argvars, typval_T *rettv); 502 static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv); 503 static void f_ch_getjob(typval_T *argvars, typval_T *rettv); 504 static void f_ch_log(typval_T *argvars, typval_T *rettv); 505 static void f_ch_logfile(typval_T *argvars, typval_T *rettv); 506 static void f_ch_open(typval_T *argvars, typval_T *rettv); 507 static void f_ch_read(typval_T *argvars, typval_T *rettv); 508 static void f_ch_readraw(typval_T *argvars, typval_T *rettv); 509 static void f_ch_sendexpr(typval_T *argvars, typval_T *rettv); 510 static void f_ch_sendraw(typval_T *argvars, typval_T *rettv); 511 static void f_ch_setoptions(typval_T *argvars, typval_T *rettv); 512 static void f_ch_status(typval_T *argvars, typval_T *rettv); 513 #endif 514 static void f_changenr(typval_T *argvars, typval_T *rettv); 515 static void f_char2nr(typval_T *argvars, typval_T *rettv); 516 static void f_cindent(typval_T *argvars, typval_T *rettv); 517 static void f_clearmatches(typval_T *argvars, typval_T *rettv); 518 static void f_col(typval_T *argvars, typval_T *rettv); 519 #if defined(FEAT_INS_EXPAND) 520 static void f_complete(typval_T *argvars, typval_T *rettv); 521 static void f_complete_add(typval_T *argvars, typval_T *rettv); 522 static void f_complete_check(typval_T *argvars, typval_T *rettv); 523 #endif 524 static void f_confirm(typval_T *argvars, typval_T *rettv); 525 static void f_copy(typval_T *argvars, typval_T *rettv); 526 #ifdef FEAT_FLOAT 527 static void f_cos(typval_T *argvars, typval_T *rettv); 528 static void f_cosh(typval_T *argvars, typval_T *rettv); 529 #endif 530 static void f_count(typval_T *argvars, typval_T *rettv); 531 static void f_cscope_connection(typval_T *argvars, typval_T *rettv); 532 static void f_cursor(typval_T *argsvars, typval_T *rettv); 533 static void f_deepcopy(typval_T *argvars, typval_T *rettv); 534 static void f_delete(typval_T *argvars, typval_T *rettv); 535 static void f_did_filetype(typval_T *argvars, typval_T *rettv); 536 static void f_diff_filler(typval_T *argvars, typval_T *rettv); 537 static void f_diff_hlID(typval_T *argvars, typval_T *rettv); 538 static void f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv); 539 static void f_empty(typval_T *argvars, typval_T *rettv); 540 static void f_escape(typval_T *argvars, typval_T *rettv); 541 static void f_eval(typval_T *argvars, typval_T *rettv); 542 static void f_eventhandler(typval_T *argvars, typval_T *rettv); 543 static void f_executable(typval_T *argvars, typval_T *rettv); 544 static void f_exepath(typval_T *argvars, typval_T *rettv); 545 static void f_exists(typval_T *argvars, typval_T *rettv); 546 #ifdef FEAT_FLOAT 547 static void f_exp(typval_T *argvars, typval_T *rettv); 548 #endif 549 static void f_expand(typval_T *argvars, typval_T *rettv); 550 static void f_extend(typval_T *argvars, typval_T *rettv); 551 static void f_feedkeys(typval_T *argvars, typval_T *rettv); 552 static void f_filereadable(typval_T *argvars, typval_T *rettv); 553 static void f_filewritable(typval_T *argvars, typval_T *rettv); 554 static void f_filter(typval_T *argvars, typval_T *rettv); 555 static void f_finddir(typval_T *argvars, typval_T *rettv); 556 static void f_findfile(typval_T *argvars, typval_T *rettv); 557 #ifdef FEAT_FLOAT 558 static void f_float2nr(typval_T *argvars, typval_T *rettv); 559 static void f_floor(typval_T *argvars, typval_T *rettv); 560 static void f_fmod(typval_T *argvars, typval_T *rettv); 561 #endif 562 static void f_fnameescape(typval_T *argvars, typval_T *rettv); 563 static void f_fnamemodify(typval_T *argvars, typval_T *rettv); 564 static void f_foldclosed(typval_T *argvars, typval_T *rettv); 565 static void f_foldclosedend(typval_T *argvars, typval_T *rettv); 566 static void f_foldlevel(typval_T *argvars, typval_T *rettv); 567 static void f_foldtext(typval_T *argvars, typval_T *rettv); 568 static void f_foldtextresult(typval_T *argvars, typval_T *rettv); 569 static void f_foreground(typval_T *argvars, typval_T *rettv); 570 static void f_function(typval_T *argvars, typval_T *rettv); 571 static void f_garbagecollect(typval_T *argvars, typval_T *rettv); 572 static void f_get(typval_T *argvars, typval_T *rettv); 573 static void f_getbufline(typval_T *argvars, typval_T *rettv); 574 static void f_getbufvar(typval_T *argvars, typval_T *rettv); 575 static void f_getchar(typval_T *argvars, typval_T *rettv); 576 static void f_getcharmod(typval_T *argvars, typval_T *rettv); 577 static void f_getcharsearch(typval_T *argvars, typval_T *rettv); 578 static void f_getcmdline(typval_T *argvars, typval_T *rettv); 579 static void f_getcmdpos(typval_T *argvars, typval_T *rettv); 580 static void f_getcmdtype(typval_T *argvars, typval_T *rettv); 581 static void f_getcmdwintype(typval_T *argvars, typval_T *rettv); 582 static void f_getcwd(typval_T *argvars, typval_T *rettv); 583 static void f_getfontname(typval_T *argvars, typval_T *rettv); 584 static void f_getfperm(typval_T *argvars, typval_T *rettv); 585 static void f_getfsize(typval_T *argvars, typval_T *rettv); 586 static void f_getftime(typval_T *argvars, typval_T *rettv); 587 static void f_getftype(typval_T *argvars, typval_T *rettv); 588 static void f_getline(typval_T *argvars, typval_T *rettv); 589 static void f_getmatches(typval_T *argvars, typval_T *rettv); 590 static void f_getpid(typval_T *argvars, typval_T *rettv); 591 static void f_getcurpos(typval_T *argvars, typval_T *rettv); 592 static void f_getpos(typval_T *argvars, typval_T *rettv); 593 static void f_getqflist(typval_T *argvars, typval_T *rettv); 594 static void f_getreg(typval_T *argvars, typval_T *rettv); 595 static void f_getregtype(typval_T *argvars, typval_T *rettv); 596 static void f_gettabvar(typval_T *argvars, typval_T *rettv); 597 static void f_gettabwinvar(typval_T *argvars, typval_T *rettv); 598 static void f_getwinposx(typval_T *argvars, typval_T *rettv); 599 static void f_getwinposy(typval_T *argvars, typval_T *rettv); 600 static void f_getwinvar(typval_T *argvars, typval_T *rettv); 601 static void f_glob(typval_T *argvars, typval_T *rettv); 602 static void f_globpath(typval_T *argvars, typval_T *rettv); 603 static void f_glob2regpat(typval_T *argvars, typval_T *rettv); 604 static void f_has(typval_T *argvars, typval_T *rettv); 605 static void f_has_key(typval_T *argvars, typval_T *rettv); 606 static void f_haslocaldir(typval_T *argvars, typval_T *rettv); 607 static void f_hasmapto(typval_T *argvars, typval_T *rettv); 608 static void f_histadd(typval_T *argvars, typval_T *rettv); 609 static void f_histdel(typval_T *argvars, typval_T *rettv); 610 static void f_histget(typval_T *argvars, typval_T *rettv); 611 static void f_histnr(typval_T *argvars, typval_T *rettv); 612 static void f_hlID(typval_T *argvars, typval_T *rettv); 613 static void f_hlexists(typval_T *argvars, typval_T *rettv); 614 static void f_hostname(typval_T *argvars, typval_T *rettv); 615 static void f_iconv(typval_T *argvars, typval_T *rettv); 616 static void f_indent(typval_T *argvars, typval_T *rettv); 617 static void f_index(typval_T *argvars, typval_T *rettv); 618 static void f_input(typval_T *argvars, typval_T *rettv); 619 static void f_inputdialog(typval_T *argvars, typval_T *rettv); 620 static void f_inputlist(typval_T *argvars, typval_T *rettv); 621 static void f_inputrestore(typval_T *argvars, typval_T *rettv); 622 static void f_inputsave(typval_T *argvars, typval_T *rettv); 623 static void f_inputsecret(typval_T *argvars, typval_T *rettv); 624 static void f_insert(typval_T *argvars, typval_T *rettv); 625 static void f_invert(typval_T *argvars, typval_T *rettv); 626 static void f_isdirectory(typval_T *argvars, typval_T *rettv); 627 static void f_islocked(typval_T *argvars, typval_T *rettv); 628 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 629 static void f_isnan(typval_T *argvars, typval_T *rettv); 630 #endif 631 static void f_items(typval_T *argvars, typval_T *rettv); 632 #ifdef FEAT_JOB_CHANNEL 633 static void f_job_getchannel(typval_T *argvars, typval_T *rettv); 634 static void f_job_info(typval_T *argvars, typval_T *rettv); 635 static void f_job_setoptions(typval_T *argvars, typval_T *rettv); 636 static void f_job_start(typval_T *argvars, typval_T *rettv); 637 static void f_job_stop(typval_T *argvars, typval_T *rettv); 638 static void f_job_status(typval_T *argvars, typval_T *rettv); 639 #endif 640 static void f_join(typval_T *argvars, typval_T *rettv); 641 static void f_js_decode(typval_T *argvars, typval_T *rettv); 642 static void f_js_encode(typval_T *argvars, typval_T *rettv); 643 static void f_json_decode(typval_T *argvars, typval_T *rettv); 644 static void f_json_encode(typval_T *argvars, typval_T *rettv); 645 static void f_keys(typval_T *argvars, typval_T *rettv); 646 static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv); 647 static void f_len(typval_T *argvars, typval_T *rettv); 648 static void f_libcall(typval_T *argvars, typval_T *rettv); 649 static void f_libcallnr(typval_T *argvars, typval_T *rettv); 650 static void f_line(typval_T *argvars, typval_T *rettv); 651 static void f_line2byte(typval_T *argvars, typval_T *rettv); 652 static void f_lispindent(typval_T *argvars, typval_T *rettv); 653 static void f_localtime(typval_T *argvars, typval_T *rettv); 654 #ifdef FEAT_FLOAT 655 static void f_log(typval_T *argvars, typval_T *rettv); 656 static void f_log10(typval_T *argvars, typval_T *rettv); 657 #endif 658 #ifdef FEAT_LUA 659 static void f_luaeval(typval_T *argvars, typval_T *rettv); 660 #endif 661 static void f_map(typval_T *argvars, typval_T *rettv); 662 static void f_maparg(typval_T *argvars, typval_T *rettv); 663 static void f_mapcheck(typval_T *argvars, typval_T *rettv); 664 static void f_match(typval_T *argvars, typval_T *rettv); 665 static void f_matchadd(typval_T *argvars, typval_T *rettv); 666 static void f_matchaddpos(typval_T *argvars, typval_T *rettv); 667 static void f_matcharg(typval_T *argvars, typval_T *rettv); 668 static void f_matchdelete(typval_T *argvars, typval_T *rettv); 669 static void f_matchend(typval_T *argvars, typval_T *rettv); 670 static void f_matchlist(typval_T *argvars, typval_T *rettv); 671 static void f_matchstr(typval_T *argvars, typval_T *rettv); 672 static void f_max(typval_T *argvars, typval_T *rettv); 673 static void f_min(typval_T *argvars, typval_T *rettv); 674 #ifdef vim_mkdir 675 static void f_mkdir(typval_T *argvars, typval_T *rettv); 676 #endif 677 static void f_mode(typval_T *argvars, typval_T *rettv); 678 #ifdef FEAT_MZSCHEME 679 static void f_mzeval(typval_T *argvars, typval_T *rettv); 680 #endif 681 static void f_nextnonblank(typval_T *argvars, typval_T *rettv); 682 static void f_nr2char(typval_T *argvars, typval_T *rettv); 683 static void f_or(typval_T *argvars, typval_T *rettv); 684 static void f_pathshorten(typval_T *argvars, typval_T *rettv); 685 #ifdef FEAT_PERL 686 static void f_perleval(typval_T *argvars, typval_T *rettv); 687 #endif 688 #ifdef FEAT_FLOAT 689 static void f_pow(typval_T *argvars, typval_T *rettv); 690 #endif 691 static void f_prevnonblank(typval_T *argvars, typval_T *rettv); 692 static void f_printf(typval_T *argvars, typval_T *rettv); 693 static void f_pumvisible(typval_T *argvars, typval_T *rettv); 694 #ifdef FEAT_PYTHON3 695 static void f_py3eval(typval_T *argvars, typval_T *rettv); 696 #endif 697 #ifdef FEAT_PYTHON 698 static void f_pyeval(typval_T *argvars, typval_T *rettv); 699 #endif 700 static void f_range(typval_T *argvars, typval_T *rettv); 701 static void f_readfile(typval_T *argvars, typval_T *rettv); 702 static void f_reltime(typval_T *argvars, typval_T *rettv); 703 #ifdef FEAT_FLOAT 704 static void f_reltimefloat(typval_T *argvars, typval_T *rettv); 705 #endif 706 static void f_reltimestr(typval_T *argvars, typval_T *rettv); 707 static void f_remote_expr(typval_T *argvars, typval_T *rettv); 708 static void f_remote_foreground(typval_T *argvars, typval_T *rettv); 709 static void f_remote_peek(typval_T *argvars, typval_T *rettv); 710 static void f_remote_read(typval_T *argvars, typval_T *rettv); 711 static void f_remote_send(typval_T *argvars, typval_T *rettv); 712 static void f_remove(typval_T *argvars, typval_T *rettv); 713 static void f_rename(typval_T *argvars, typval_T *rettv); 714 static void f_repeat(typval_T *argvars, typval_T *rettv); 715 static void f_resolve(typval_T *argvars, typval_T *rettv); 716 static void f_reverse(typval_T *argvars, typval_T *rettv); 717 #ifdef FEAT_FLOAT 718 static void f_round(typval_T *argvars, typval_T *rettv); 719 #endif 720 static void f_screenattr(typval_T *argvars, typval_T *rettv); 721 static void f_screenchar(typval_T *argvars, typval_T *rettv); 722 static void f_screencol(typval_T *argvars, typval_T *rettv); 723 static void f_screenrow(typval_T *argvars, typval_T *rettv); 724 static void f_search(typval_T *argvars, typval_T *rettv); 725 static void f_searchdecl(typval_T *argvars, typval_T *rettv); 726 static void f_searchpair(typval_T *argvars, typval_T *rettv); 727 static void f_searchpairpos(typval_T *argvars, typval_T *rettv); 728 static void f_searchpos(typval_T *argvars, typval_T *rettv); 729 static void f_server2client(typval_T *argvars, typval_T *rettv); 730 static void f_serverlist(typval_T *argvars, typval_T *rettv); 731 static void f_setbufvar(typval_T *argvars, typval_T *rettv); 732 static void f_setcharsearch(typval_T *argvars, typval_T *rettv); 733 static void f_setcmdpos(typval_T *argvars, typval_T *rettv); 734 static void f_setfperm(typval_T *argvars, typval_T *rettv); 735 static void f_setline(typval_T *argvars, typval_T *rettv); 736 static void f_setloclist(typval_T *argvars, typval_T *rettv); 737 static void f_setmatches(typval_T *argvars, typval_T *rettv); 738 static void f_setpos(typval_T *argvars, typval_T *rettv); 739 static void f_setqflist(typval_T *argvars, typval_T *rettv); 740 static void f_setreg(typval_T *argvars, typval_T *rettv); 741 static void f_settabvar(typval_T *argvars, typval_T *rettv); 742 static void f_settabwinvar(typval_T *argvars, typval_T *rettv); 743 static void f_setwinvar(typval_T *argvars, typval_T *rettv); 744 #ifdef FEAT_CRYPT 745 static void f_sha256(typval_T *argvars, typval_T *rettv); 746 #endif /* FEAT_CRYPT */ 747 static void f_shellescape(typval_T *argvars, typval_T *rettv); 748 static void f_shiftwidth(typval_T *argvars, typval_T *rettv); 749 static void f_simplify(typval_T *argvars, typval_T *rettv); 750 #ifdef FEAT_FLOAT 751 static void f_sin(typval_T *argvars, typval_T *rettv); 752 static void f_sinh(typval_T *argvars, typval_T *rettv); 753 #endif 754 static void f_sort(typval_T *argvars, typval_T *rettv); 755 static void f_soundfold(typval_T *argvars, typval_T *rettv); 756 static void f_spellbadword(typval_T *argvars, typval_T *rettv); 757 static void f_spellsuggest(typval_T *argvars, typval_T *rettv); 758 static void f_split(typval_T *argvars, typval_T *rettv); 759 #ifdef FEAT_FLOAT 760 static void f_sqrt(typval_T *argvars, typval_T *rettv); 761 static void f_str2float(typval_T *argvars, typval_T *rettv); 762 #endif 763 static void f_str2nr(typval_T *argvars, typval_T *rettv); 764 static void f_strchars(typval_T *argvars, typval_T *rettv); 765 #ifdef HAVE_STRFTIME 766 static void f_strftime(typval_T *argvars, typval_T *rettv); 767 #endif 768 static void f_stridx(typval_T *argvars, typval_T *rettv); 769 static void f_string(typval_T *argvars, typval_T *rettv); 770 static void f_strlen(typval_T *argvars, typval_T *rettv); 771 static void f_strpart(typval_T *argvars, typval_T *rettv); 772 static void f_strridx(typval_T *argvars, typval_T *rettv); 773 static void f_strtrans(typval_T *argvars, typval_T *rettv); 774 static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv); 775 static void f_strwidth(typval_T *argvars, typval_T *rettv); 776 static void f_submatch(typval_T *argvars, typval_T *rettv); 777 static void f_substitute(typval_T *argvars, typval_T *rettv); 778 static void f_synID(typval_T *argvars, typval_T *rettv); 779 static void f_synIDattr(typval_T *argvars, typval_T *rettv); 780 static void f_synIDtrans(typval_T *argvars, typval_T *rettv); 781 static void f_synstack(typval_T *argvars, typval_T *rettv); 782 static void f_synconcealed(typval_T *argvars, typval_T *rettv); 783 static void f_system(typval_T *argvars, typval_T *rettv); 784 static void f_systemlist(typval_T *argvars, typval_T *rettv); 785 static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv); 786 static void f_tabpagenr(typval_T *argvars, typval_T *rettv); 787 static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv); 788 static void f_taglist(typval_T *argvars, typval_T *rettv); 789 static void f_tagfiles(typval_T *argvars, typval_T *rettv); 790 static void f_tempname(typval_T *argvars, typval_T *rettv); 791 static void f_test(typval_T *argvars, typval_T *rettv); 792 #ifdef FEAT_FLOAT 793 static void f_tan(typval_T *argvars, typval_T *rettv); 794 static void f_tanh(typval_T *argvars, typval_T *rettv); 795 #endif 796 #ifdef FEAT_TIMERS 797 static void f_timer_start(typval_T *argvars, typval_T *rettv); 798 static void f_timer_stop(typval_T *argvars, typval_T *rettv); 799 #endif 800 static void f_tolower(typval_T *argvars, typval_T *rettv); 801 static void f_toupper(typval_T *argvars, typval_T *rettv); 802 static void f_tr(typval_T *argvars, typval_T *rettv); 803 #ifdef FEAT_FLOAT 804 static void f_trunc(typval_T *argvars, typval_T *rettv); 805 #endif 806 static void f_type(typval_T *argvars, typval_T *rettv); 807 static void f_undofile(typval_T *argvars, typval_T *rettv); 808 static void f_undotree(typval_T *argvars, typval_T *rettv); 809 static void f_uniq(typval_T *argvars, typval_T *rettv); 810 static void f_values(typval_T *argvars, typval_T *rettv); 811 static void f_virtcol(typval_T *argvars, typval_T *rettv); 812 static void f_visualmode(typval_T *argvars, typval_T *rettv); 813 static void f_wildmenumode(typval_T *argvars, typval_T *rettv); 814 static void f_win_findbuf(typval_T *argvars, typval_T *rettv); 815 static void f_win_getid(typval_T *argvars, typval_T *rettv); 816 static void f_win_gotoid(typval_T *argvars, typval_T *rettv); 817 static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv); 818 static void f_win_id2win(typval_T *argvars, typval_T *rettv); 819 static void f_winbufnr(typval_T *argvars, typval_T *rettv); 820 static void f_wincol(typval_T *argvars, typval_T *rettv); 821 static void f_winheight(typval_T *argvars, typval_T *rettv); 822 static void f_winline(typval_T *argvars, typval_T *rettv); 823 static void f_winnr(typval_T *argvars, typval_T *rettv); 824 static void f_winrestcmd(typval_T *argvars, typval_T *rettv); 825 static void f_winrestview(typval_T *argvars, typval_T *rettv); 826 static void f_winsaveview(typval_T *argvars, typval_T *rettv); 827 static void f_winwidth(typval_T *argvars, typval_T *rettv); 828 static void f_writefile(typval_T *argvars, typval_T *rettv); 829 static void f_wordcount(typval_T *argvars, typval_T *rettv); 830 static void f_xor(typval_T *argvars, typval_T *rettv); 831 832 static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp); 833 static pos_T *var2fpos(typval_T *varp, int dollar_lnum, int *fnum); 834 static int get_env_len(char_u **arg); 835 static int get_id_len(char_u **arg); 836 static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose); 837 static char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags); 838 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 839 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 840 valid character */ 841 static char_u * make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); 842 static int eval_isnamec(int c); 843 static int eval_isnamec1(int c); 844 static int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload); 845 static int handle_subscript(char_u **arg, typval_T *rettv, int evaluate, int verbose); 846 static typval_T *alloc_string_tv(char_u *string); 847 static void init_tv(typval_T *varp); 848 #ifdef FEAT_FLOAT 849 static float_T get_tv_float(typval_T *varp); 850 #endif 851 static linenr_T get_tv_lnum(typval_T *argvars); 852 static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf); 853 static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload); 854 static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload); 855 static hashtab_T *find_var_ht(char_u *name, char_u **varname); 856 static funccall_T *get_funccal(void); 857 static void vars_clear_ext(hashtab_T *ht, int free_val); 858 static void delete_var(hashtab_T *ht, hashitem_T *hi); 859 static void list_one_var(dictitem_T *v, char_u *prefix, int *first); 860 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first); 861 static void set_var(char_u *name, typval_T *varp, int copy); 862 static int var_check_ro(int flags, char_u *name, int use_gettext); 863 static int var_check_fixed(int flags, char_u *name, int use_gettext); 864 static int var_check_func_name(char_u *name, int new_var); 865 static int valid_varname(char_u *varname); 866 static int tv_check_lock(int lock, char_u *name, int use_gettext); 867 static int item_copy(typval_T *from, typval_T *to, int deep, int copyID); 868 static char_u *find_option_end(char_u **arg, int *opt_flags); 869 static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial); 870 static int eval_fname_script(char_u *p); 871 static int eval_fname_sid(char_u *p); 872 static void list_func_head(ufunc_T *fp, int indent); 873 static ufunc_T *find_func(char_u *name); 874 static int function_exists(char_u *name); 875 static int builtin_function(char_u *name, int len); 876 #ifdef FEAT_PROFILE 877 static void func_do_profile(ufunc_T *fp); 878 static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self); 879 static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self); 880 static int 881 # ifdef __BORLANDC__ 882 _RTLENTRYF 883 # endif 884 prof_total_cmp(const void *s1, const void *s2); 885 static int 886 # ifdef __BORLANDC__ 887 _RTLENTRYF 888 # endif 889 prof_self_cmp(const void *s1, const void *s2); 890 #endif 891 static int script_autoload(char_u *name, int reload); 892 static char_u *autoload_name(char_u *name); 893 static void cat_func_name(char_u *buf, ufunc_T *fp); 894 static void func_free(ufunc_T *fp); 895 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); 896 static int can_free_funccal(funccall_T *fc, int copyID) ; 897 static void free_funccal(funccall_T *fc, int free_val); 898 static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr); 899 static win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); 900 static win_T *find_tabwin(typval_T *wvp, typval_T *tvp); 901 static void getwinvar(typval_T *argvars, typval_T *rettv, int off); 902 static int searchpair_cmn(typval_T *argvars, pos_T *match_pos); 903 static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp); 904 static void setwinvar(typval_T *argvars, typval_T *rettv, int off); 905 static int write_list(FILE *fd, list_T *list, int binary); 906 static void get_cmd_output_as_rettv(typval_T *argvars, typval_T *rettv, int retlist); 907 908 909 #ifdef EBCDIC 910 static int compare_func_name(const void *s1, const void *s2); 911 static void sortFunctions(); 912 #endif 913 914 /* 915 * Initialize the global and v: variables. 916 */ 917 void 918 eval_init(void) 919 { 920 int i; 921 struct vimvar *p; 922 923 init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); 924 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); 925 vimvardict.dv_lock = VAR_FIXED; 926 hash_init(&compat_hashtab); 927 hash_init(&func_hashtab); 928 929 for (i = 0; i < VV_LEN; ++i) 930 { 931 p = &vimvars[i]; 932 STRCPY(p->vv_di.di_key, p->vv_name); 933 if (p->vv_flags & VV_RO) 934 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 935 else if (p->vv_flags & VV_RO_SBX) 936 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 937 else 938 p->vv_di.di_flags = DI_FLAGS_FIX; 939 940 /* add to v: scope dict, unless the value is not always available */ 941 if (p->vv_type != VAR_UNKNOWN) 942 hash_add(&vimvarht, p->vv_di.di_key); 943 if (p->vv_flags & VV_COMPAT) 944 /* add to compat scope dict */ 945 hash_add(&compat_hashtab, p->vv_di.di_key); 946 } 947 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 948 949 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 950 set_vim_var_nr(VV_HLSEARCH, 1L); 951 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); 952 set_vim_var_list(VV_ERRORS, list_alloc()); 953 954 set_vim_var_nr(VV_FALSE, VVAL_FALSE); 955 set_vim_var_nr(VV_TRUE, VVAL_TRUE); 956 set_vim_var_nr(VV_NONE, VVAL_NONE); 957 set_vim_var_nr(VV_NULL, VVAL_NULL); 958 959 set_reg_var(0); /* default for v:register is not 0 but '"' */ 960 961 #ifdef EBCDIC 962 /* 963 * Sort the function table, to enable binary search. 964 */ 965 sortFunctions(); 966 #endif 967 } 968 969 #if defined(EXITFREE) || defined(PROTO) 970 void 971 eval_clear(void) 972 { 973 int i; 974 struct vimvar *p; 975 976 for (i = 0; i < VV_LEN; ++i) 977 { 978 p = &vimvars[i]; 979 if (p->vv_di.di_tv.v_type == VAR_STRING) 980 { 981 vim_free(p->vv_str); 982 p->vv_str = NULL; 983 } 984 else if (p->vv_di.di_tv.v_type == VAR_LIST) 985 { 986 list_unref(p->vv_list); 987 p->vv_list = NULL; 988 } 989 } 990 hash_clear(&vimvarht); 991 hash_init(&vimvarht); /* garbage_collect() will access it */ 992 hash_clear(&compat_hashtab); 993 994 free_scriptnames(); 995 # if defined(FEAT_CMDL_COMPL) 996 free_locales(); 997 # endif 998 999 /* global variables */ 1000 vars_clear(&globvarht); 1001 1002 /* autoloaded script names */ 1003 ga_clear_strings(&ga_loaded); 1004 1005 /* Script-local variables. First clear all the variables and in a second 1006 * loop free the scriptvar_T, because a variable in one script might hold 1007 * a reference to the whole scope of another script. */ 1008 for (i = 1; i <= ga_scripts.ga_len; ++i) 1009 vars_clear(&SCRIPT_VARS(i)); 1010 for (i = 1; i <= ga_scripts.ga_len; ++i) 1011 vim_free(SCRIPT_SV(i)); 1012 ga_clear(&ga_scripts); 1013 1014 /* unreferenced lists and dicts */ 1015 (void)garbage_collect(); 1016 1017 /* functions */ 1018 free_all_functions(); 1019 hash_clear(&func_hashtab); 1020 } 1021 #endif 1022 1023 /* 1024 * Return the name of the executed function. 1025 */ 1026 char_u * 1027 func_name(void *cookie) 1028 { 1029 return ((funccall_T *)cookie)->func->uf_name; 1030 } 1031 1032 /* 1033 * Return the address holding the next breakpoint line for a funccall cookie. 1034 */ 1035 linenr_T * 1036 func_breakpoint(void *cookie) 1037 { 1038 return &((funccall_T *)cookie)->breakpoint; 1039 } 1040 1041 /* 1042 * Return the address holding the debug tick for a funccall cookie. 1043 */ 1044 int * 1045 func_dbg_tick(void *cookie) 1046 { 1047 return &((funccall_T *)cookie)->dbg_tick; 1048 } 1049 1050 /* 1051 * Return the nesting level for a funccall cookie. 1052 */ 1053 int 1054 func_level(void *cookie) 1055 { 1056 return ((funccall_T *)cookie)->level; 1057 } 1058 1059 /* pointer to funccal for currently active function */ 1060 funccall_T *current_funccal = NULL; 1061 1062 /* pointer to list of previously used funccal, still around because some 1063 * item in it is still being used. */ 1064 funccall_T *previous_funccal = NULL; 1065 1066 /* 1067 * Return TRUE when a function was ended by a ":return" command. 1068 */ 1069 int 1070 current_func_returned(void) 1071 { 1072 return current_funccal->returned; 1073 } 1074 1075 1076 /* 1077 * Set an internal variable to a string value. Creates the variable if it does 1078 * not already exist. 1079 */ 1080 void 1081 set_internal_string_var(char_u *name, char_u *value) 1082 { 1083 char_u *val; 1084 typval_T *tvp; 1085 1086 val = vim_strsave(value); 1087 if (val != NULL) 1088 { 1089 tvp = alloc_string_tv(val); 1090 if (tvp != NULL) 1091 { 1092 set_var(name, tvp, FALSE); 1093 free_tv(tvp); 1094 } 1095 } 1096 } 1097 1098 static lval_T *redir_lval = NULL; 1099 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 1100 static char_u *redir_endp = NULL; 1101 static char_u *redir_varname = NULL; 1102 1103 /* 1104 * Start recording command output to a variable 1105 * When "append" is TRUE append to an existing variable. 1106 * Returns OK if successfully completed the setup. FAIL otherwise. 1107 */ 1108 int 1109 var_redir_start(char_u *name, int append) 1110 { 1111 int save_emsg; 1112 int err; 1113 typval_T tv; 1114 1115 /* Catch a bad name early. */ 1116 if (!eval_isnamec1(*name)) 1117 { 1118 EMSG(_(e_invarg)); 1119 return FAIL; 1120 } 1121 1122 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 1123 redir_varname = vim_strsave(name); 1124 if (redir_varname == NULL) 1125 return FAIL; 1126 1127 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1128 if (redir_lval == NULL) 1129 { 1130 var_redir_stop(); 1131 return FAIL; 1132 } 1133 1134 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1135 ga_init2(&redir_ga, (int)sizeof(char), 500); 1136 1137 /* Parse the variable name (can be a dict or list entry). */ 1138 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0, 1139 FNE_CHECK_START); 1140 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1141 { 1142 clear_lval(redir_lval); 1143 if (redir_endp != NULL && *redir_endp != NUL) 1144 /* Trailing characters are present after the variable name */ 1145 EMSG(_(e_trailing)); 1146 else 1147 EMSG(_(e_invarg)); 1148 redir_endp = NULL; /* don't store a value, only cleanup */ 1149 var_redir_stop(); 1150 return FAIL; 1151 } 1152 1153 /* check if we can write to the variable: set it to or append an empty 1154 * string */ 1155 save_emsg = did_emsg; 1156 did_emsg = FALSE; 1157 tv.v_type = VAR_STRING; 1158 tv.vval.v_string = (char_u *)""; 1159 if (append) 1160 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1161 else 1162 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1163 clear_lval(redir_lval); 1164 err = did_emsg; 1165 did_emsg |= save_emsg; 1166 if (err) 1167 { 1168 redir_endp = NULL; /* don't store a value, only cleanup */ 1169 var_redir_stop(); 1170 return FAIL; 1171 } 1172 1173 return OK; 1174 } 1175 1176 /* 1177 * Append "value[value_len]" to the variable set by var_redir_start(). 1178 * The actual appending is postponed until redirection ends, because the value 1179 * appended may in fact be the string we write to, changing it may cause freed 1180 * memory to be used: 1181 * :redir => foo 1182 * :let foo 1183 * :redir END 1184 */ 1185 void 1186 var_redir_str(char_u *value, int value_len) 1187 { 1188 int len; 1189 1190 if (redir_lval == NULL) 1191 return; 1192 1193 if (value_len == -1) 1194 len = (int)STRLEN(value); /* Append the entire string */ 1195 else 1196 len = value_len; /* Append only "value_len" characters */ 1197 1198 if (ga_grow(&redir_ga, len) == OK) 1199 { 1200 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1201 redir_ga.ga_len += len; 1202 } 1203 else 1204 var_redir_stop(); 1205 } 1206 1207 /* 1208 * Stop redirecting command output to a variable. 1209 * Frees the allocated memory. 1210 */ 1211 void 1212 var_redir_stop(void) 1213 { 1214 typval_T tv; 1215 1216 if (redir_lval != NULL) 1217 { 1218 /* If there was no error: assign the text to the variable. */ 1219 if (redir_endp != NULL) 1220 { 1221 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1222 tv.v_type = VAR_STRING; 1223 tv.vval.v_string = redir_ga.ga_data; 1224 /* Call get_lval() again, if it's inside a Dict or List it may 1225 * have changed. */ 1226 redir_endp = get_lval(redir_varname, NULL, redir_lval, 1227 FALSE, FALSE, 0, FNE_CHECK_START); 1228 if (redir_endp != NULL && redir_lval->ll_name != NULL) 1229 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1230 clear_lval(redir_lval); 1231 } 1232 1233 /* free the collected output */ 1234 vim_free(redir_ga.ga_data); 1235 redir_ga.ga_data = NULL; 1236 1237 vim_free(redir_lval); 1238 redir_lval = NULL; 1239 } 1240 vim_free(redir_varname); 1241 redir_varname = NULL; 1242 } 1243 1244 # if defined(FEAT_MBYTE) || defined(PROTO) 1245 int 1246 eval_charconvert( 1247 char_u *enc_from, 1248 char_u *enc_to, 1249 char_u *fname_from, 1250 char_u *fname_to) 1251 { 1252 int err = FALSE; 1253 1254 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1255 set_vim_var_string(VV_CC_TO, enc_to, -1); 1256 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1257 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1258 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1259 err = TRUE; 1260 set_vim_var_string(VV_CC_FROM, NULL, -1); 1261 set_vim_var_string(VV_CC_TO, NULL, -1); 1262 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1263 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1264 1265 if (err) 1266 return FAIL; 1267 return OK; 1268 } 1269 # endif 1270 1271 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1272 int 1273 eval_printexpr(char_u *fname, char_u *args) 1274 { 1275 int err = FALSE; 1276 1277 set_vim_var_string(VV_FNAME_IN, fname, -1); 1278 set_vim_var_string(VV_CMDARG, args, -1); 1279 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1280 err = TRUE; 1281 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1282 set_vim_var_string(VV_CMDARG, NULL, -1); 1283 1284 if (err) 1285 { 1286 mch_remove(fname); 1287 return FAIL; 1288 } 1289 return OK; 1290 } 1291 # endif 1292 1293 # if defined(FEAT_DIFF) || defined(PROTO) 1294 void 1295 eval_diff( 1296 char_u *origfile, 1297 char_u *newfile, 1298 char_u *outfile) 1299 { 1300 int err = FALSE; 1301 1302 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1303 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1304 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1305 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1306 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1307 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1308 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1309 } 1310 1311 void 1312 eval_patch( 1313 char_u *origfile, 1314 char_u *difffile, 1315 char_u *outfile) 1316 { 1317 int err; 1318 1319 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1320 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1321 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1322 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1323 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1324 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1325 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1326 } 1327 # endif 1328 1329 /* 1330 * Top level evaluation function, returning a boolean. 1331 * Sets "error" to TRUE if there was an error. 1332 * Return TRUE or FALSE. 1333 */ 1334 int 1335 eval_to_bool( 1336 char_u *arg, 1337 int *error, 1338 char_u **nextcmd, 1339 int skip) /* only parse, don't execute */ 1340 { 1341 typval_T tv; 1342 int retval = FALSE; 1343 1344 if (skip) 1345 ++emsg_skip; 1346 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1347 *error = TRUE; 1348 else 1349 { 1350 *error = FALSE; 1351 if (!skip) 1352 { 1353 retval = (get_tv_number_chk(&tv, error) != 0); 1354 clear_tv(&tv); 1355 } 1356 } 1357 if (skip) 1358 --emsg_skip; 1359 1360 return retval; 1361 } 1362 1363 /* 1364 * Top level evaluation function, returning a string. If "skip" is TRUE, 1365 * only parsing to "nextcmd" is done, without reporting errors. Return 1366 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1367 */ 1368 char_u * 1369 eval_to_string_skip( 1370 char_u *arg, 1371 char_u **nextcmd, 1372 int skip) /* only parse, don't execute */ 1373 { 1374 typval_T tv; 1375 char_u *retval; 1376 1377 if (skip) 1378 ++emsg_skip; 1379 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1380 retval = NULL; 1381 else 1382 { 1383 retval = vim_strsave(get_tv_string(&tv)); 1384 clear_tv(&tv); 1385 } 1386 if (skip) 1387 --emsg_skip; 1388 1389 return retval; 1390 } 1391 1392 /* 1393 * Skip over an expression at "*pp". 1394 * Return FAIL for an error, OK otherwise. 1395 */ 1396 int 1397 skip_expr(char_u **pp) 1398 { 1399 typval_T rettv; 1400 1401 *pp = skipwhite(*pp); 1402 return eval1(pp, &rettv, FALSE); 1403 } 1404 1405 /* 1406 * Top level evaluation function, returning a string. 1407 * When "convert" is TRUE convert a List into a sequence of lines and convert 1408 * a Float to a String. 1409 * Return pointer to allocated memory, or NULL for failure. 1410 */ 1411 char_u * 1412 eval_to_string( 1413 char_u *arg, 1414 char_u **nextcmd, 1415 int convert) 1416 { 1417 typval_T tv; 1418 char_u *retval; 1419 garray_T ga; 1420 #ifdef FEAT_FLOAT 1421 char_u numbuf[NUMBUFLEN]; 1422 #endif 1423 1424 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1425 retval = NULL; 1426 else 1427 { 1428 if (convert && tv.v_type == VAR_LIST) 1429 { 1430 ga_init2(&ga, (int)sizeof(char), 80); 1431 if (tv.vval.v_list != NULL) 1432 { 1433 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1434 if (tv.vval.v_list->lv_len > 0) 1435 ga_append(&ga, NL); 1436 } 1437 ga_append(&ga, NUL); 1438 retval = (char_u *)ga.ga_data; 1439 } 1440 #ifdef FEAT_FLOAT 1441 else if (convert && tv.v_type == VAR_FLOAT) 1442 { 1443 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1444 retval = vim_strsave(numbuf); 1445 } 1446 #endif 1447 else 1448 retval = vim_strsave(get_tv_string(&tv)); 1449 clear_tv(&tv); 1450 } 1451 1452 return retval; 1453 } 1454 1455 /* 1456 * Call eval_to_string() without using current local variables and using 1457 * textlock. When "use_sandbox" is TRUE use the sandbox. 1458 */ 1459 char_u * 1460 eval_to_string_safe( 1461 char_u *arg, 1462 char_u **nextcmd, 1463 int use_sandbox) 1464 { 1465 char_u *retval; 1466 void *save_funccalp; 1467 1468 save_funccalp = save_funccal(); 1469 if (use_sandbox) 1470 ++sandbox; 1471 ++textlock; 1472 retval = eval_to_string(arg, nextcmd, FALSE); 1473 if (use_sandbox) 1474 --sandbox; 1475 --textlock; 1476 restore_funccal(save_funccalp); 1477 return retval; 1478 } 1479 1480 /* 1481 * Top level evaluation function, returning a number. 1482 * Evaluates "expr" silently. 1483 * Returns -1 for an error. 1484 */ 1485 int 1486 eval_to_number(char_u *expr) 1487 { 1488 typval_T rettv; 1489 int retval; 1490 char_u *p = skipwhite(expr); 1491 1492 ++emsg_off; 1493 1494 if (eval1(&p, &rettv, TRUE) == FAIL) 1495 retval = -1; 1496 else 1497 { 1498 retval = get_tv_number_chk(&rettv, NULL); 1499 clear_tv(&rettv); 1500 } 1501 --emsg_off; 1502 1503 return retval; 1504 } 1505 1506 /* 1507 * Prepare v: variable "idx" to be used. 1508 * Save the current typeval in "save_tv". 1509 * When not used yet add the variable to the v: hashtable. 1510 */ 1511 static void 1512 prepare_vimvar(int idx, typval_T *save_tv) 1513 { 1514 *save_tv = vimvars[idx].vv_tv; 1515 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1516 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1517 } 1518 1519 /* 1520 * Restore v: variable "idx" to typeval "save_tv". 1521 * When no longer defined, remove the variable from the v: hashtable. 1522 */ 1523 static void 1524 restore_vimvar(int idx, typval_T *save_tv) 1525 { 1526 hashitem_T *hi; 1527 1528 vimvars[idx].vv_tv = *save_tv; 1529 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1530 { 1531 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1532 if (HASHITEM_EMPTY(hi)) 1533 EMSG2(_(e_intern2), "restore_vimvar()"); 1534 else 1535 hash_remove(&vimvarht, hi); 1536 } 1537 } 1538 1539 #if defined(FEAT_SPELL) || defined(PROTO) 1540 /* 1541 * Evaluate an expression to a list with suggestions. 1542 * For the "expr:" part of 'spellsuggest'. 1543 * Returns NULL when there is an error. 1544 */ 1545 list_T * 1546 eval_spell_expr(char_u *badword, char_u *expr) 1547 { 1548 typval_T save_val; 1549 typval_T rettv; 1550 list_T *list = NULL; 1551 char_u *p = skipwhite(expr); 1552 1553 /* Set "v:val" to the bad word. */ 1554 prepare_vimvar(VV_VAL, &save_val); 1555 vimvars[VV_VAL].vv_type = VAR_STRING; 1556 vimvars[VV_VAL].vv_str = badword; 1557 if (p_verbose == 0) 1558 ++emsg_off; 1559 1560 if (eval1(&p, &rettv, TRUE) == OK) 1561 { 1562 if (rettv.v_type != VAR_LIST) 1563 clear_tv(&rettv); 1564 else 1565 list = rettv.vval.v_list; 1566 } 1567 1568 if (p_verbose == 0) 1569 --emsg_off; 1570 restore_vimvar(VV_VAL, &save_val); 1571 1572 return list; 1573 } 1574 1575 /* 1576 * "list" is supposed to contain two items: a word and a number. Return the 1577 * word in "pp" and the number as the return value. 1578 * Return -1 if anything isn't right. 1579 * Used to get the good word and score from the eval_spell_expr() result. 1580 */ 1581 int 1582 get_spellword(list_T *list, char_u **pp) 1583 { 1584 listitem_T *li; 1585 1586 li = list->lv_first; 1587 if (li == NULL) 1588 return -1; 1589 *pp = get_tv_string(&li->li_tv); 1590 1591 li = li->li_next; 1592 if (li == NULL) 1593 return -1; 1594 return get_tv_number(&li->li_tv); 1595 } 1596 #endif 1597 1598 /* 1599 * Top level evaluation function. 1600 * Returns an allocated typval_T with the result. 1601 * Returns NULL when there is an error. 1602 */ 1603 typval_T * 1604 eval_expr(char_u *arg, char_u **nextcmd) 1605 { 1606 typval_T *tv; 1607 1608 tv = (typval_T *)alloc(sizeof(typval_T)); 1609 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1610 { 1611 vim_free(tv); 1612 tv = NULL; 1613 } 1614 1615 return tv; 1616 } 1617 1618 1619 /* 1620 * Call some vimL function and return the result in "*rettv". 1621 * Uses argv[argc] for the function arguments. Only Number and String 1622 * arguments are currently supported. 1623 * Returns OK or FAIL. 1624 */ 1625 int 1626 call_vim_function( 1627 char_u *func, 1628 int argc, 1629 char_u **argv, 1630 int safe, /* use the sandbox */ 1631 int str_arg_only, /* all arguments are strings */ 1632 typval_T *rettv) 1633 { 1634 typval_T *argvars; 1635 long n; 1636 int len; 1637 int i; 1638 int doesrange; 1639 void *save_funccalp = NULL; 1640 int ret; 1641 1642 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1643 if (argvars == NULL) 1644 return FAIL; 1645 1646 for (i = 0; i < argc; i++) 1647 { 1648 /* Pass a NULL or empty argument as an empty string */ 1649 if (argv[i] == NULL || *argv[i] == NUL) 1650 { 1651 argvars[i].v_type = VAR_STRING; 1652 argvars[i].vval.v_string = (char_u *)""; 1653 continue; 1654 } 1655 1656 if (str_arg_only) 1657 len = 0; 1658 else 1659 /* Recognize a number argument, the others must be strings. */ 1660 vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0); 1661 if (len != 0 && len == (int)STRLEN(argv[i])) 1662 { 1663 argvars[i].v_type = VAR_NUMBER; 1664 argvars[i].vval.v_number = n; 1665 } 1666 else 1667 { 1668 argvars[i].v_type = VAR_STRING; 1669 argvars[i].vval.v_string = argv[i]; 1670 } 1671 } 1672 1673 if (safe) 1674 { 1675 save_funccalp = save_funccal(); 1676 ++sandbox; 1677 } 1678 1679 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1680 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1681 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1682 &doesrange, TRUE, NULL, NULL); 1683 if (safe) 1684 { 1685 --sandbox; 1686 restore_funccal(save_funccalp); 1687 } 1688 vim_free(argvars); 1689 1690 if (ret == FAIL) 1691 clear_tv(rettv); 1692 1693 return ret; 1694 } 1695 1696 /* 1697 * Call vimL function "func" and return the result as a number. 1698 * Returns -1 when calling the function fails. 1699 * Uses argv[argc] for the function arguments. 1700 */ 1701 long 1702 call_func_retnr( 1703 char_u *func, 1704 int argc, 1705 char_u **argv, 1706 int safe) /* use the sandbox */ 1707 { 1708 typval_T rettv; 1709 long retval; 1710 1711 /* All arguments are passed as strings, no conversion to number. */ 1712 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1713 return -1; 1714 1715 retval = get_tv_number_chk(&rettv, NULL); 1716 clear_tv(&rettv); 1717 return retval; 1718 } 1719 1720 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1721 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1722 1723 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1724 /* 1725 * Call vimL function "func" and return the result as a string. 1726 * Returns NULL when calling the function fails. 1727 * Uses argv[argc] for the function arguments. 1728 */ 1729 void * 1730 call_func_retstr( 1731 char_u *func, 1732 int argc, 1733 char_u **argv, 1734 int safe) /* use the sandbox */ 1735 { 1736 typval_T rettv; 1737 char_u *retval; 1738 1739 /* All arguments are passed as strings, no conversion to number. */ 1740 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1741 return NULL; 1742 1743 retval = vim_strsave(get_tv_string(&rettv)); 1744 clear_tv(&rettv); 1745 return retval; 1746 } 1747 # endif 1748 1749 /* 1750 * Call vimL function "func" and return the result as a List. 1751 * Uses argv[argc] for the function arguments. 1752 * Returns NULL when there is something wrong. 1753 */ 1754 void * 1755 call_func_retlist( 1756 char_u *func, 1757 int argc, 1758 char_u **argv, 1759 int safe) /* use the sandbox */ 1760 { 1761 typval_T rettv; 1762 1763 /* All arguments are passed as strings, no conversion to number. */ 1764 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1765 return NULL; 1766 1767 if (rettv.v_type != VAR_LIST) 1768 { 1769 clear_tv(&rettv); 1770 return NULL; 1771 } 1772 1773 return rettv.vval.v_list; 1774 } 1775 #endif 1776 1777 /* 1778 * Save the current function call pointer, and set it to NULL. 1779 * Used when executing autocommands and for ":source". 1780 */ 1781 void * 1782 save_funccal(void) 1783 { 1784 funccall_T *fc = current_funccal; 1785 1786 current_funccal = NULL; 1787 return (void *)fc; 1788 } 1789 1790 void 1791 restore_funccal(void *vfc) 1792 { 1793 funccall_T *fc = (funccall_T *)vfc; 1794 1795 current_funccal = fc; 1796 } 1797 1798 #if defined(FEAT_PROFILE) || defined(PROTO) 1799 /* 1800 * Prepare profiling for entering a child or something else that is not 1801 * counted for the script/function itself. 1802 * Should always be called in pair with prof_child_exit(). 1803 */ 1804 void 1805 prof_child_enter( 1806 proftime_T *tm) /* place to store waittime */ 1807 { 1808 funccall_T *fc = current_funccal; 1809 1810 if (fc != NULL && fc->func->uf_profiling) 1811 profile_start(&fc->prof_child); 1812 script_prof_save(tm); 1813 } 1814 1815 /* 1816 * Take care of time spent in a child. 1817 * Should always be called after prof_child_enter(). 1818 */ 1819 void 1820 prof_child_exit( 1821 proftime_T *tm) /* where waittime was stored */ 1822 { 1823 funccall_T *fc = current_funccal; 1824 1825 if (fc != NULL && fc->func->uf_profiling) 1826 { 1827 profile_end(&fc->prof_child); 1828 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1829 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1830 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1831 } 1832 script_prof_restore(tm); 1833 } 1834 #endif 1835 1836 1837 #ifdef FEAT_FOLDING 1838 /* 1839 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1840 * it in "*cp". Doesn't give error messages. 1841 */ 1842 int 1843 eval_foldexpr(char_u *arg, int *cp) 1844 { 1845 typval_T tv; 1846 int retval; 1847 char_u *s; 1848 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1849 OPT_LOCAL); 1850 1851 ++emsg_off; 1852 if (use_sandbox) 1853 ++sandbox; 1854 ++textlock; 1855 *cp = NUL; 1856 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1857 retval = 0; 1858 else 1859 { 1860 /* If the result is a number, just return the number. */ 1861 if (tv.v_type == VAR_NUMBER) 1862 retval = tv.vval.v_number; 1863 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1864 retval = 0; 1865 else 1866 { 1867 /* If the result is a string, check if there is a non-digit before 1868 * the number. */ 1869 s = tv.vval.v_string; 1870 if (!VIM_ISDIGIT(*s) && *s != '-') 1871 *cp = *s++; 1872 retval = atol((char *)s); 1873 } 1874 clear_tv(&tv); 1875 } 1876 --emsg_off; 1877 if (use_sandbox) 1878 --sandbox; 1879 --textlock; 1880 1881 return retval; 1882 } 1883 #endif 1884 1885 /* 1886 * ":let" list all variable values 1887 * ":let var1 var2" list variable values 1888 * ":let var = expr" assignment command. 1889 * ":let var += expr" assignment command. 1890 * ":let var -= expr" assignment command. 1891 * ":let var .= expr" assignment command. 1892 * ":let [var1, var2] = expr" unpack list. 1893 */ 1894 void 1895 ex_let(exarg_T *eap) 1896 { 1897 char_u *arg = eap->arg; 1898 char_u *expr = NULL; 1899 typval_T rettv; 1900 int i; 1901 int var_count = 0; 1902 int semicolon = 0; 1903 char_u op[2]; 1904 char_u *argend; 1905 int first = TRUE; 1906 1907 argend = skip_var_list(arg, &var_count, &semicolon); 1908 if (argend == NULL) 1909 return; 1910 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1911 --argend; 1912 expr = skipwhite(argend); 1913 if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL 1914 && expr[1] == '=')) 1915 { 1916 /* 1917 * ":let" without "=": list variables 1918 */ 1919 if (*arg == '[') 1920 EMSG(_(e_invarg)); 1921 else if (!ends_excmd(*arg)) 1922 /* ":let var1 var2" */ 1923 arg = list_arg_vars(eap, arg, &first); 1924 else if (!eap->skip) 1925 { 1926 /* ":let" */ 1927 list_glob_vars(&first); 1928 list_buf_vars(&first); 1929 list_win_vars(&first); 1930 #ifdef FEAT_WINDOWS 1931 list_tab_vars(&first); 1932 #endif 1933 list_script_vars(&first); 1934 list_func_vars(&first); 1935 list_vim_vars(&first); 1936 } 1937 eap->nextcmd = check_nextcmd(arg); 1938 } 1939 else 1940 { 1941 op[0] = '='; 1942 op[1] = NUL; 1943 if (*expr != '=') 1944 { 1945 if (vim_strchr((char_u *)"+-.", *expr) != NULL) 1946 op[0] = *expr; /* +=, -= or .= */ 1947 expr = skipwhite(expr + 2); 1948 } 1949 else 1950 expr = skipwhite(expr + 1); 1951 1952 if (eap->skip) 1953 ++emsg_skip; 1954 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1955 if (eap->skip) 1956 { 1957 if (i != FAIL) 1958 clear_tv(&rettv); 1959 --emsg_skip; 1960 } 1961 else if (i != FAIL) 1962 { 1963 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1964 op); 1965 clear_tv(&rettv); 1966 } 1967 } 1968 } 1969 1970 /* 1971 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1972 * Handles both "var" with any type and "[var, var; var]" with a list type. 1973 * When "nextchars" is not NULL it points to a string with characters that 1974 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1975 * or concatenate. 1976 * Returns OK or FAIL; 1977 */ 1978 static int 1979 ex_let_vars( 1980 char_u *arg_start, 1981 typval_T *tv, 1982 int copy, /* copy values from "tv", don't move */ 1983 int semicolon, /* from skip_var_list() */ 1984 int var_count, /* from skip_var_list() */ 1985 char_u *nextchars) 1986 { 1987 char_u *arg = arg_start; 1988 list_T *l; 1989 int i; 1990 listitem_T *item; 1991 typval_T ltv; 1992 1993 if (*arg != '[') 1994 { 1995 /* 1996 * ":let var = expr" or ":for var in list" 1997 */ 1998 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1999 return FAIL; 2000 return OK; 2001 } 2002 2003 /* 2004 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 2005 */ 2006 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 2007 { 2008 EMSG(_(e_listreq)); 2009 return FAIL; 2010 } 2011 2012 i = list_len(l); 2013 if (semicolon == 0 && var_count < i) 2014 { 2015 EMSG(_("E687: Less targets than List items")); 2016 return FAIL; 2017 } 2018 if (var_count - semicolon > i) 2019 { 2020 EMSG(_("E688: More targets than List items")); 2021 return FAIL; 2022 } 2023 2024 item = l->lv_first; 2025 while (*arg != ']') 2026 { 2027 arg = skipwhite(arg + 1); 2028 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 2029 item = item->li_next; 2030 if (arg == NULL) 2031 return FAIL; 2032 2033 arg = skipwhite(arg); 2034 if (*arg == ';') 2035 { 2036 /* Put the rest of the list (may be empty) in the var after ';'. 2037 * Create a new list for this. */ 2038 l = list_alloc(); 2039 if (l == NULL) 2040 return FAIL; 2041 while (item != NULL) 2042 { 2043 list_append_tv(l, &item->li_tv); 2044 item = item->li_next; 2045 } 2046 2047 ltv.v_type = VAR_LIST; 2048 ltv.v_lock = 0; 2049 ltv.vval.v_list = l; 2050 l->lv_refcount = 1; 2051 2052 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 2053 (char_u *)"]", nextchars); 2054 clear_tv(<v); 2055 if (arg == NULL) 2056 return FAIL; 2057 break; 2058 } 2059 else if (*arg != ',' && *arg != ']') 2060 { 2061 EMSG2(_(e_intern2), "ex_let_vars()"); 2062 return FAIL; 2063 } 2064 } 2065 2066 return OK; 2067 } 2068 2069 /* 2070 * Skip over assignable variable "var" or list of variables "[var, var]". 2071 * Used for ":let varvar = expr" and ":for varvar in expr". 2072 * For "[var, var]" increment "*var_count" for each variable. 2073 * for "[var, var; var]" set "semicolon". 2074 * Return NULL for an error. 2075 */ 2076 static char_u * 2077 skip_var_list( 2078 char_u *arg, 2079 int *var_count, 2080 int *semicolon) 2081 { 2082 char_u *p, *s; 2083 2084 if (*arg == '[') 2085 { 2086 /* "[var, var]": find the matching ']'. */ 2087 p = arg; 2088 for (;;) 2089 { 2090 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 2091 s = skip_var_one(p); 2092 if (s == p) 2093 { 2094 EMSG2(_(e_invarg2), p); 2095 return NULL; 2096 } 2097 ++*var_count; 2098 2099 p = skipwhite(s); 2100 if (*p == ']') 2101 break; 2102 else if (*p == ';') 2103 { 2104 if (*semicolon == 1) 2105 { 2106 EMSG(_("Double ; in list of variables")); 2107 return NULL; 2108 } 2109 *semicolon = 1; 2110 } 2111 else if (*p != ',') 2112 { 2113 EMSG2(_(e_invarg2), p); 2114 return NULL; 2115 } 2116 } 2117 return p + 1; 2118 } 2119 else 2120 return skip_var_one(arg); 2121 } 2122 2123 /* 2124 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2125 * l[idx]. 2126 */ 2127 static char_u * 2128 skip_var_one(char_u *arg) 2129 { 2130 if (*arg == '@' && arg[1] != NUL) 2131 return arg + 2; 2132 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2133 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2134 } 2135 2136 /* 2137 * List variables for hashtab "ht" with prefix "prefix". 2138 * If "empty" is TRUE also list NULL strings as empty strings. 2139 */ 2140 static void 2141 list_hashtable_vars( 2142 hashtab_T *ht, 2143 char_u *prefix, 2144 int empty, 2145 int *first) 2146 { 2147 hashitem_T *hi; 2148 dictitem_T *di; 2149 int todo; 2150 2151 todo = (int)ht->ht_used; 2152 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2153 { 2154 if (!HASHITEM_EMPTY(hi)) 2155 { 2156 --todo; 2157 di = HI2DI(hi); 2158 if (empty || di->di_tv.v_type != VAR_STRING 2159 || di->di_tv.vval.v_string != NULL) 2160 list_one_var(di, prefix, first); 2161 } 2162 } 2163 } 2164 2165 /* 2166 * List global variables. 2167 */ 2168 static void 2169 list_glob_vars(int *first) 2170 { 2171 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2172 } 2173 2174 /* 2175 * List buffer variables. 2176 */ 2177 static void 2178 list_buf_vars(int *first) 2179 { 2180 char_u numbuf[NUMBUFLEN]; 2181 2182 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:", 2183 TRUE, first); 2184 2185 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2186 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2187 numbuf, first); 2188 } 2189 2190 /* 2191 * List window variables. 2192 */ 2193 static void 2194 list_win_vars(int *first) 2195 { 2196 list_hashtable_vars(&curwin->w_vars->dv_hashtab, 2197 (char_u *)"w:", TRUE, first); 2198 } 2199 2200 #ifdef FEAT_WINDOWS 2201 /* 2202 * List tab page variables. 2203 */ 2204 static void 2205 list_tab_vars(int *first) 2206 { 2207 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, 2208 (char_u *)"t:", TRUE, first); 2209 } 2210 #endif 2211 2212 /* 2213 * List Vim variables. 2214 */ 2215 static void 2216 list_vim_vars(int *first) 2217 { 2218 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2219 } 2220 2221 /* 2222 * List script-local variables, if there is a script. 2223 */ 2224 static void 2225 list_script_vars(int *first) 2226 { 2227 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2228 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2229 (char_u *)"s:", FALSE, first); 2230 } 2231 2232 /* 2233 * List function variables, if there is a function. 2234 */ 2235 static void 2236 list_func_vars(int *first) 2237 { 2238 if (current_funccal != NULL) 2239 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2240 (char_u *)"l:", FALSE, first); 2241 } 2242 2243 /* 2244 * List variables in "arg". 2245 */ 2246 static char_u * 2247 list_arg_vars(exarg_T *eap, char_u *arg, int *first) 2248 { 2249 int error = FALSE; 2250 int len; 2251 char_u *name; 2252 char_u *name_start; 2253 char_u *arg_subsc; 2254 char_u *tofree; 2255 typval_T tv; 2256 2257 while (!ends_excmd(*arg) && !got_int) 2258 { 2259 if (error || eap->skip) 2260 { 2261 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2262 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2263 { 2264 emsg_severe = TRUE; 2265 EMSG(_(e_trailing)); 2266 break; 2267 } 2268 } 2269 else 2270 { 2271 /* get_name_len() takes care of expanding curly braces */ 2272 name_start = name = arg; 2273 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2274 if (len <= 0) 2275 { 2276 /* This is mainly to keep test 49 working: when expanding 2277 * curly braces fails overrule the exception error message. */ 2278 if (len < 0 && !aborting()) 2279 { 2280 emsg_severe = TRUE; 2281 EMSG2(_(e_invarg2), arg); 2282 break; 2283 } 2284 error = TRUE; 2285 } 2286 else 2287 { 2288 if (tofree != NULL) 2289 name = tofree; 2290 if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL) 2291 error = TRUE; 2292 else 2293 { 2294 /* handle d.key, l[idx], f(expr) */ 2295 arg_subsc = arg; 2296 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2297 error = TRUE; 2298 else 2299 { 2300 if (arg == arg_subsc && len == 2 && name[1] == ':') 2301 { 2302 switch (*name) 2303 { 2304 case 'g': list_glob_vars(first); break; 2305 case 'b': list_buf_vars(first); break; 2306 case 'w': list_win_vars(first); break; 2307 #ifdef FEAT_WINDOWS 2308 case 't': list_tab_vars(first); break; 2309 #endif 2310 case 'v': list_vim_vars(first); break; 2311 case 's': list_script_vars(first); break; 2312 case 'l': list_func_vars(first); break; 2313 default: 2314 EMSG2(_("E738: Can't list variables for %s"), name); 2315 } 2316 } 2317 else 2318 { 2319 char_u numbuf[NUMBUFLEN]; 2320 char_u *tf; 2321 int c; 2322 char_u *s; 2323 2324 s = echo_string(&tv, &tf, numbuf, 0); 2325 c = *arg; 2326 *arg = NUL; 2327 list_one_var_a((char_u *)"", 2328 arg == arg_subsc ? name : name_start, 2329 tv.v_type, 2330 s == NULL ? (char_u *)"" : s, 2331 first); 2332 *arg = c; 2333 vim_free(tf); 2334 } 2335 clear_tv(&tv); 2336 } 2337 } 2338 } 2339 2340 vim_free(tofree); 2341 } 2342 2343 arg = skipwhite(arg); 2344 } 2345 2346 return arg; 2347 } 2348 2349 /* 2350 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2351 * Returns a pointer to the char just after the var name. 2352 * Returns NULL if there is an error. 2353 */ 2354 static char_u * 2355 ex_let_one( 2356 char_u *arg, /* points to variable name */ 2357 typval_T *tv, /* value to assign to variable */ 2358 int copy, /* copy value from "tv" */ 2359 char_u *endchars, /* valid chars after variable name or NULL */ 2360 char_u *op) /* "+", "-", "." or NULL*/ 2361 { 2362 int c1; 2363 char_u *name; 2364 char_u *p; 2365 char_u *arg_end = NULL; 2366 int len; 2367 int opt_flags; 2368 char_u *tofree = NULL; 2369 2370 /* 2371 * ":let $VAR = expr": Set environment variable. 2372 */ 2373 if (*arg == '$') 2374 { 2375 /* Find the end of the name. */ 2376 ++arg; 2377 name = arg; 2378 len = get_env_len(&arg); 2379 if (len == 0) 2380 EMSG2(_(e_invarg2), name - 1); 2381 else 2382 { 2383 if (op != NULL && (*op == '+' || *op == '-')) 2384 EMSG2(_(e_letwrong), op); 2385 else if (endchars != NULL 2386 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2387 EMSG(_(e_letunexp)); 2388 else if (!check_secure()) 2389 { 2390 c1 = name[len]; 2391 name[len] = NUL; 2392 p = get_tv_string_chk(tv); 2393 if (p != NULL && op != NULL && *op == '.') 2394 { 2395 int mustfree = FALSE; 2396 char_u *s = vim_getenv(name, &mustfree); 2397 2398 if (s != NULL) 2399 { 2400 p = tofree = concat_str(s, p); 2401 if (mustfree) 2402 vim_free(s); 2403 } 2404 } 2405 if (p != NULL) 2406 { 2407 vim_setenv(name, p); 2408 if (STRICMP(name, "HOME") == 0) 2409 init_homedir(); 2410 else if (didset_vim && STRICMP(name, "VIM") == 0) 2411 didset_vim = FALSE; 2412 else if (didset_vimruntime 2413 && STRICMP(name, "VIMRUNTIME") == 0) 2414 didset_vimruntime = FALSE; 2415 arg_end = arg; 2416 } 2417 name[len] = c1; 2418 vim_free(tofree); 2419 } 2420 } 2421 } 2422 2423 /* 2424 * ":let &option = expr": Set option value. 2425 * ":let &l:option = expr": Set local option value. 2426 * ":let &g:option = expr": Set global option value. 2427 */ 2428 else if (*arg == '&') 2429 { 2430 /* Find the end of the name. */ 2431 p = find_option_end(&arg, &opt_flags); 2432 if (p == NULL || (endchars != NULL 2433 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2434 EMSG(_(e_letunexp)); 2435 else 2436 { 2437 long n; 2438 int opt_type; 2439 long numval; 2440 char_u *stringval = NULL; 2441 char_u *s; 2442 2443 c1 = *p; 2444 *p = NUL; 2445 2446 n = get_tv_number(tv); 2447 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2448 if (s != NULL && op != NULL && *op != '=') 2449 { 2450 opt_type = get_option_value(arg, &numval, 2451 &stringval, opt_flags); 2452 if ((opt_type == 1 && *op == '.') 2453 || (opt_type == 0 && *op != '.')) 2454 EMSG2(_(e_letwrong), op); 2455 else 2456 { 2457 if (opt_type == 1) /* number */ 2458 { 2459 if (*op == '+') 2460 n = numval + n; 2461 else 2462 n = numval - n; 2463 } 2464 else if (opt_type == 0 && stringval != NULL) /* string */ 2465 { 2466 s = concat_str(stringval, s); 2467 vim_free(stringval); 2468 stringval = s; 2469 } 2470 } 2471 } 2472 if (s != NULL) 2473 { 2474 set_option_value(arg, n, s, opt_flags); 2475 arg_end = p; 2476 } 2477 *p = c1; 2478 vim_free(stringval); 2479 } 2480 } 2481 2482 /* 2483 * ":let @r = expr": Set register contents. 2484 */ 2485 else if (*arg == '@') 2486 { 2487 ++arg; 2488 if (op != NULL && (*op == '+' || *op == '-')) 2489 EMSG2(_(e_letwrong), op); 2490 else if (endchars != NULL 2491 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2492 EMSG(_(e_letunexp)); 2493 else 2494 { 2495 char_u *ptofree = NULL; 2496 char_u *s; 2497 2498 p = get_tv_string_chk(tv); 2499 if (p != NULL && op != NULL && *op == '.') 2500 { 2501 s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); 2502 if (s != NULL) 2503 { 2504 p = ptofree = concat_str(s, p); 2505 vim_free(s); 2506 } 2507 } 2508 if (p != NULL) 2509 { 2510 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2511 arg_end = arg + 1; 2512 } 2513 vim_free(ptofree); 2514 } 2515 } 2516 2517 /* 2518 * ":let var = expr": Set internal variable. 2519 * ":let {expr} = expr": Idem, name made with curly braces 2520 */ 2521 else if (eval_isnamec1(*arg) || *arg == '{') 2522 { 2523 lval_T lv; 2524 2525 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); 2526 if (p != NULL && lv.ll_name != NULL) 2527 { 2528 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2529 EMSG(_(e_letunexp)); 2530 else 2531 { 2532 set_var_lval(&lv, p, tv, copy, op); 2533 arg_end = p; 2534 } 2535 } 2536 clear_lval(&lv); 2537 } 2538 2539 else 2540 EMSG2(_(e_invarg2), arg); 2541 2542 return arg_end; 2543 } 2544 2545 /* 2546 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2547 */ 2548 static int 2549 check_changedtick(char_u *arg) 2550 { 2551 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2552 { 2553 EMSG2(_(e_readonlyvar), arg); 2554 return TRUE; 2555 } 2556 return FALSE; 2557 } 2558 2559 /* 2560 * Get an lval: variable, Dict item or List item that can be assigned a value 2561 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2562 * "name.key", "name.key[expr]" etc. 2563 * Indexing only works if "name" is an existing List or Dictionary. 2564 * "name" points to the start of the name. 2565 * If "rettv" is not NULL it points to the value to be assigned. 2566 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2567 * wrong; must end in space or cmd separator. 2568 * 2569 * flags: 2570 * GLV_QUIET: do not give error messages 2571 * GLV_NO_AUTOLOAD: do not use script autoloading 2572 * 2573 * Returns a pointer to just after the name, including indexes. 2574 * When an evaluation error occurs "lp->ll_name" is NULL; 2575 * Returns NULL for a parsing error. Still need to free items in "lp"! 2576 */ 2577 static char_u * 2578 get_lval( 2579 char_u *name, 2580 typval_T *rettv, 2581 lval_T *lp, 2582 int unlet, 2583 int skip, 2584 int flags, /* GLV_ values */ 2585 int fne_flags) /* flags for find_name_end() */ 2586 { 2587 char_u *p; 2588 char_u *expr_start, *expr_end; 2589 int cc; 2590 dictitem_T *v; 2591 typval_T var1; 2592 typval_T var2; 2593 int empty1 = FALSE; 2594 listitem_T *ni; 2595 char_u *key = NULL; 2596 int len; 2597 hashtab_T *ht; 2598 int quiet = flags & GLV_QUIET; 2599 2600 /* Clear everything in "lp". */ 2601 vim_memset(lp, 0, sizeof(lval_T)); 2602 2603 if (skip) 2604 { 2605 /* When skipping just find the end of the name. */ 2606 lp->ll_name = name; 2607 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2608 } 2609 2610 /* Find the end of the name. */ 2611 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2612 if (expr_start != NULL) 2613 { 2614 /* Don't expand the name when we already know there is an error. */ 2615 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2616 && *p != '[' && *p != '.') 2617 { 2618 EMSG(_(e_trailing)); 2619 return NULL; 2620 } 2621 2622 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2623 if (lp->ll_exp_name == NULL) 2624 { 2625 /* Report an invalid expression in braces, unless the 2626 * expression evaluation has been cancelled due to an 2627 * aborting error, an interrupt, or an exception. */ 2628 if (!aborting() && !quiet) 2629 { 2630 emsg_severe = TRUE; 2631 EMSG2(_(e_invarg2), name); 2632 return NULL; 2633 } 2634 } 2635 lp->ll_name = lp->ll_exp_name; 2636 } 2637 else 2638 lp->ll_name = name; 2639 2640 /* Without [idx] or .key we are done. */ 2641 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2642 return p; 2643 2644 cc = *p; 2645 *p = NUL; 2646 v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD); 2647 if (v == NULL && !quiet) 2648 EMSG2(_(e_undefvar), lp->ll_name); 2649 *p = cc; 2650 if (v == NULL) 2651 return NULL; 2652 2653 /* 2654 * Loop until no more [idx] or .key is following. 2655 */ 2656 lp->ll_tv = &v->di_tv; 2657 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2658 { 2659 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2660 && !(lp->ll_tv->v_type == VAR_DICT 2661 && lp->ll_tv->vval.v_dict != NULL)) 2662 { 2663 if (!quiet) 2664 EMSG(_("E689: Can only index a List or Dictionary")); 2665 return NULL; 2666 } 2667 if (lp->ll_range) 2668 { 2669 if (!quiet) 2670 EMSG(_("E708: [:] must come last")); 2671 return NULL; 2672 } 2673 2674 len = -1; 2675 if (*p == '.') 2676 { 2677 key = p + 1; 2678 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2679 ; 2680 if (len == 0) 2681 { 2682 if (!quiet) 2683 EMSG(_(e_emptykey)); 2684 return NULL; 2685 } 2686 p = key + len; 2687 } 2688 else 2689 { 2690 /* Get the index [expr] or the first index [expr: ]. */ 2691 p = skipwhite(p + 1); 2692 if (*p == ':') 2693 empty1 = TRUE; 2694 else 2695 { 2696 empty1 = FALSE; 2697 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2698 return NULL; 2699 if (get_tv_string_chk(&var1) == NULL) 2700 { 2701 /* not a number or string */ 2702 clear_tv(&var1); 2703 return NULL; 2704 } 2705 } 2706 2707 /* Optionally get the second index [ :expr]. */ 2708 if (*p == ':') 2709 { 2710 if (lp->ll_tv->v_type == VAR_DICT) 2711 { 2712 if (!quiet) 2713 EMSG(_(e_dictrange)); 2714 if (!empty1) 2715 clear_tv(&var1); 2716 return NULL; 2717 } 2718 if (rettv != NULL && (rettv->v_type != VAR_LIST 2719 || rettv->vval.v_list == NULL)) 2720 { 2721 if (!quiet) 2722 EMSG(_("E709: [:] requires a List value")); 2723 if (!empty1) 2724 clear_tv(&var1); 2725 return NULL; 2726 } 2727 p = skipwhite(p + 1); 2728 if (*p == ']') 2729 lp->ll_empty2 = TRUE; 2730 else 2731 { 2732 lp->ll_empty2 = FALSE; 2733 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2734 { 2735 if (!empty1) 2736 clear_tv(&var1); 2737 return NULL; 2738 } 2739 if (get_tv_string_chk(&var2) == NULL) 2740 { 2741 /* not a number or string */ 2742 if (!empty1) 2743 clear_tv(&var1); 2744 clear_tv(&var2); 2745 return NULL; 2746 } 2747 } 2748 lp->ll_range = TRUE; 2749 } 2750 else 2751 lp->ll_range = FALSE; 2752 2753 if (*p != ']') 2754 { 2755 if (!quiet) 2756 EMSG(_(e_missbrac)); 2757 if (!empty1) 2758 clear_tv(&var1); 2759 if (lp->ll_range && !lp->ll_empty2) 2760 clear_tv(&var2); 2761 return NULL; 2762 } 2763 2764 /* Skip to past ']'. */ 2765 ++p; 2766 } 2767 2768 if (lp->ll_tv->v_type == VAR_DICT) 2769 { 2770 if (len == -1) 2771 { 2772 /* "[key]": get key from "var1" */ 2773 key = get_tv_string(&var1); /* is number or string */ 2774 if (*key == NUL) 2775 { 2776 if (!quiet) 2777 EMSG(_(e_emptykey)); 2778 clear_tv(&var1); 2779 return NULL; 2780 } 2781 } 2782 lp->ll_list = NULL; 2783 lp->ll_dict = lp->ll_tv->vval.v_dict; 2784 lp->ll_di = dict_find(lp->ll_dict, key, len); 2785 2786 /* When assigning to a scope dictionary check that a function and 2787 * variable name is valid (only variable name unless it is l: or 2788 * g: dictionary). Disallow overwriting a builtin function. */ 2789 if (rettv != NULL && lp->ll_dict->dv_scope != 0) 2790 { 2791 int prevval; 2792 int wrong; 2793 2794 if (len != -1) 2795 { 2796 prevval = key[len]; 2797 key[len] = NUL; 2798 } 2799 else 2800 prevval = 0; /* avoid compiler warning */ 2801 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE 2802 && rettv->v_type == VAR_FUNC 2803 && var_check_func_name(key, lp->ll_di == NULL)) 2804 || !valid_varname(key); 2805 if (len != -1) 2806 key[len] = prevval; 2807 if (wrong) 2808 return NULL; 2809 } 2810 2811 if (lp->ll_di == NULL) 2812 { 2813 /* Can't add "v:" variable. */ 2814 if (lp->ll_dict == &vimvardict) 2815 { 2816 EMSG2(_(e_illvar), name); 2817 return NULL; 2818 } 2819 2820 /* Key does not exist in dict: may need to add it. */ 2821 if (*p == '[' || *p == '.' || unlet) 2822 { 2823 if (!quiet) 2824 EMSG2(_(e_dictkey), key); 2825 if (len == -1) 2826 clear_tv(&var1); 2827 return NULL; 2828 } 2829 if (len == -1) 2830 lp->ll_newkey = vim_strsave(key); 2831 else 2832 lp->ll_newkey = vim_strnsave(key, len); 2833 if (len == -1) 2834 clear_tv(&var1); 2835 if (lp->ll_newkey == NULL) 2836 p = NULL; 2837 break; 2838 } 2839 /* existing variable, need to check if it can be changed */ 2840 else if (var_check_ro(lp->ll_di->di_flags, name, FALSE)) 2841 return NULL; 2842 2843 if (len == -1) 2844 clear_tv(&var1); 2845 lp->ll_tv = &lp->ll_di->di_tv; 2846 } 2847 else 2848 { 2849 /* 2850 * Get the number and item for the only or first index of the List. 2851 */ 2852 if (empty1) 2853 lp->ll_n1 = 0; 2854 else 2855 { 2856 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2857 clear_tv(&var1); 2858 } 2859 lp->ll_dict = NULL; 2860 lp->ll_list = lp->ll_tv->vval.v_list; 2861 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2862 if (lp->ll_li == NULL) 2863 { 2864 if (lp->ll_n1 < 0) 2865 { 2866 lp->ll_n1 = 0; 2867 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2868 } 2869 } 2870 if (lp->ll_li == NULL) 2871 { 2872 if (lp->ll_range && !lp->ll_empty2) 2873 clear_tv(&var2); 2874 if (!quiet) 2875 EMSGN(_(e_listidx), lp->ll_n1); 2876 return NULL; 2877 } 2878 2879 /* 2880 * May need to find the item or absolute index for the second 2881 * index of a range. 2882 * When no index given: "lp->ll_empty2" is TRUE. 2883 * Otherwise "lp->ll_n2" is set to the second index. 2884 */ 2885 if (lp->ll_range && !lp->ll_empty2) 2886 { 2887 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2888 clear_tv(&var2); 2889 if (lp->ll_n2 < 0) 2890 { 2891 ni = list_find(lp->ll_list, lp->ll_n2); 2892 if (ni == NULL) 2893 { 2894 if (!quiet) 2895 EMSGN(_(e_listidx), lp->ll_n2); 2896 return NULL; 2897 } 2898 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2899 } 2900 2901 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2902 if (lp->ll_n1 < 0) 2903 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2904 if (lp->ll_n2 < lp->ll_n1) 2905 { 2906 if (!quiet) 2907 EMSGN(_(e_listidx), lp->ll_n2); 2908 return NULL; 2909 } 2910 } 2911 2912 lp->ll_tv = &lp->ll_li->li_tv; 2913 } 2914 } 2915 2916 return p; 2917 } 2918 2919 /* 2920 * Clear lval "lp" that was filled by get_lval(). 2921 */ 2922 static void 2923 clear_lval(lval_T *lp) 2924 { 2925 vim_free(lp->ll_exp_name); 2926 vim_free(lp->ll_newkey); 2927 } 2928 2929 /* 2930 * Set a variable that was parsed by get_lval() to "rettv". 2931 * "endp" points to just after the parsed name. 2932 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2933 */ 2934 static void 2935 set_var_lval( 2936 lval_T *lp, 2937 char_u *endp, 2938 typval_T *rettv, 2939 int copy, 2940 char_u *op) 2941 { 2942 int cc; 2943 listitem_T *ri; 2944 dictitem_T *di; 2945 2946 if (lp->ll_tv == NULL) 2947 { 2948 if (!check_changedtick(lp->ll_name)) 2949 { 2950 cc = *endp; 2951 *endp = NUL; 2952 if (op != NULL && *op != '=') 2953 { 2954 typval_T tv; 2955 2956 /* handle +=, -= and .= */ 2957 di = NULL; 2958 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2959 &tv, &di, TRUE, FALSE) == OK) 2960 { 2961 if ((di == NULL 2962 || (!var_check_ro(di->di_flags, lp->ll_name, FALSE) 2963 && !tv_check_lock(di->di_tv.v_lock, lp->ll_name, 2964 FALSE))) 2965 && tv_op(&tv, rettv, op) == OK) 2966 set_var(lp->ll_name, &tv, FALSE); 2967 clear_tv(&tv); 2968 } 2969 } 2970 else 2971 set_var(lp->ll_name, rettv, copy); 2972 *endp = cc; 2973 } 2974 } 2975 else if (tv_check_lock(lp->ll_newkey == NULL 2976 ? lp->ll_tv->v_lock 2977 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) 2978 ; 2979 else if (lp->ll_range) 2980 { 2981 listitem_T *ll_li = lp->ll_li; 2982 int ll_n1 = lp->ll_n1; 2983 2984 /* 2985 * Check whether any of the list items is locked 2986 */ 2987 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) 2988 { 2989 if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) 2990 return; 2991 ri = ri->li_next; 2992 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1)) 2993 break; 2994 ll_li = ll_li->li_next; 2995 ++ll_n1; 2996 } 2997 2998 /* 2999 * Assign the List values to the list items. 3000 */ 3001 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 3002 { 3003 if (op != NULL && *op != '=') 3004 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 3005 else 3006 { 3007 clear_tv(&lp->ll_li->li_tv); 3008 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 3009 } 3010 ri = ri->li_next; 3011 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 3012 break; 3013 if (lp->ll_li->li_next == NULL) 3014 { 3015 /* Need to add an empty item. */ 3016 if (list_append_number(lp->ll_list, 0) == FAIL) 3017 { 3018 ri = NULL; 3019 break; 3020 } 3021 } 3022 lp->ll_li = lp->ll_li->li_next; 3023 ++lp->ll_n1; 3024 } 3025 if (ri != NULL) 3026 EMSG(_("E710: List value has more items than target")); 3027 else if (lp->ll_empty2 3028 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 3029 : lp->ll_n1 != lp->ll_n2) 3030 EMSG(_("E711: List value has not enough items")); 3031 } 3032 else 3033 { 3034 /* 3035 * Assign to a List or Dictionary item. 3036 */ 3037 if (lp->ll_newkey != NULL) 3038 { 3039 if (op != NULL && *op != '=') 3040 { 3041 EMSG2(_(e_letwrong), op); 3042 return; 3043 } 3044 3045 /* Need to add an item to the Dictionary. */ 3046 di = dictitem_alloc(lp->ll_newkey); 3047 if (di == NULL) 3048 return; 3049 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 3050 { 3051 vim_free(di); 3052 return; 3053 } 3054 lp->ll_tv = &di->di_tv; 3055 } 3056 else if (op != NULL && *op != '=') 3057 { 3058 tv_op(lp->ll_tv, rettv, op); 3059 return; 3060 } 3061 else 3062 clear_tv(lp->ll_tv); 3063 3064 /* 3065 * Assign the value to the variable or list item. 3066 */ 3067 if (copy) 3068 copy_tv(rettv, lp->ll_tv); 3069 else 3070 { 3071 *lp->ll_tv = *rettv; 3072 lp->ll_tv->v_lock = 0; 3073 init_tv(rettv); 3074 } 3075 } 3076 } 3077 3078 /* 3079 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 3080 * Returns OK or FAIL. 3081 */ 3082 static int 3083 tv_op(typval_T *tv1, typval_T *tv2, char_u *op) 3084 { 3085 long n; 3086 char_u numbuf[NUMBUFLEN]; 3087 char_u *s; 3088 3089 /* Can't do anything with a Funcref, Dict, v:true on the right. */ 3090 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT 3091 && tv2->v_type != VAR_SPECIAL) 3092 { 3093 switch (tv1->v_type) 3094 { 3095 case VAR_UNKNOWN: 3096 case VAR_DICT: 3097 case VAR_FUNC: 3098 case VAR_PARTIAL: 3099 case VAR_SPECIAL: 3100 case VAR_JOB: 3101 case VAR_CHANNEL: 3102 break; 3103 3104 case VAR_LIST: 3105 if (*op != '+' || tv2->v_type != VAR_LIST) 3106 break; 3107 /* List += List */ 3108 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 3109 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 3110 return OK; 3111 3112 case VAR_NUMBER: 3113 case VAR_STRING: 3114 if (tv2->v_type == VAR_LIST) 3115 break; 3116 if (*op == '+' || *op == '-') 3117 { 3118 /* nr += nr or nr -= nr*/ 3119 n = get_tv_number(tv1); 3120 #ifdef FEAT_FLOAT 3121 if (tv2->v_type == VAR_FLOAT) 3122 { 3123 float_T f = n; 3124 3125 if (*op == '+') 3126 f += tv2->vval.v_float; 3127 else 3128 f -= tv2->vval.v_float; 3129 clear_tv(tv1); 3130 tv1->v_type = VAR_FLOAT; 3131 tv1->vval.v_float = f; 3132 } 3133 else 3134 #endif 3135 { 3136 if (*op == '+') 3137 n += get_tv_number(tv2); 3138 else 3139 n -= get_tv_number(tv2); 3140 clear_tv(tv1); 3141 tv1->v_type = VAR_NUMBER; 3142 tv1->vval.v_number = n; 3143 } 3144 } 3145 else 3146 { 3147 if (tv2->v_type == VAR_FLOAT) 3148 break; 3149 3150 /* str .= str */ 3151 s = get_tv_string(tv1); 3152 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 3153 clear_tv(tv1); 3154 tv1->v_type = VAR_STRING; 3155 tv1->vval.v_string = s; 3156 } 3157 return OK; 3158 3159 case VAR_FLOAT: 3160 #ifdef FEAT_FLOAT 3161 { 3162 float_T f; 3163 3164 if (*op == '.' || (tv2->v_type != VAR_FLOAT 3165 && tv2->v_type != VAR_NUMBER 3166 && tv2->v_type != VAR_STRING)) 3167 break; 3168 if (tv2->v_type == VAR_FLOAT) 3169 f = tv2->vval.v_float; 3170 else 3171 f = get_tv_number(tv2); 3172 if (*op == '+') 3173 tv1->vval.v_float += f; 3174 else 3175 tv1->vval.v_float -= f; 3176 } 3177 #endif 3178 return OK; 3179 } 3180 } 3181 3182 EMSG2(_(e_letwrong), op); 3183 return FAIL; 3184 } 3185 3186 /* 3187 * Add a watcher to a list. 3188 */ 3189 void 3190 list_add_watch(list_T *l, listwatch_T *lw) 3191 { 3192 lw->lw_next = l->lv_watch; 3193 l->lv_watch = lw; 3194 } 3195 3196 /* 3197 * Remove a watcher from a list. 3198 * No warning when it isn't found... 3199 */ 3200 void 3201 list_rem_watch(list_T *l, listwatch_T *lwrem) 3202 { 3203 listwatch_T *lw, **lwp; 3204 3205 lwp = &l->lv_watch; 3206 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3207 { 3208 if (lw == lwrem) 3209 { 3210 *lwp = lw->lw_next; 3211 break; 3212 } 3213 lwp = &lw->lw_next; 3214 } 3215 } 3216 3217 /* 3218 * Just before removing an item from a list: advance watchers to the next 3219 * item. 3220 */ 3221 static void 3222 list_fix_watch(list_T *l, listitem_T *item) 3223 { 3224 listwatch_T *lw; 3225 3226 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3227 if (lw->lw_item == item) 3228 lw->lw_item = item->li_next; 3229 } 3230 3231 /* 3232 * Evaluate the expression used in a ":for var in expr" command. 3233 * "arg" points to "var". 3234 * Set "*errp" to TRUE for an error, FALSE otherwise; 3235 * Return a pointer that holds the info. Null when there is an error. 3236 */ 3237 void * 3238 eval_for_line( 3239 char_u *arg, 3240 int *errp, 3241 char_u **nextcmdp, 3242 int skip) 3243 { 3244 forinfo_T *fi; 3245 char_u *expr; 3246 typval_T tv; 3247 list_T *l; 3248 3249 *errp = TRUE; /* default: there is an error */ 3250 3251 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3252 if (fi == NULL) 3253 return NULL; 3254 3255 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3256 if (expr == NULL) 3257 return fi; 3258 3259 expr = skipwhite(expr); 3260 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3261 { 3262 EMSG(_("E690: Missing \"in\" after :for")); 3263 return fi; 3264 } 3265 3266 if (skip) 3267 ++emsg_skip; 3268 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3269 { 3270 *errp = FALSE; 3271 if (!skip) 3272 { 3273 l = tv.vval.v_list; 3274 if (tv.v_type != VAR_LIST || l == NULL) 3275 { 3276 EMSG(_(e_listreq)); 3277 clear_tv(&tv); 3278 } 3279 else 3280 { 3281 /* No need to increment the refcount, it's already set for the 3282 * list being used in "tv". */ 3283 fi->fi_list = l; 3284 list_add_watch(l, &fi->fi_lw); 3285 fi->fi_lw.lw_item = l->lv_first; 3286 } 3287 } 3288 } 3289 if (skip) 3290 --emsg_skip; 3291 3292 return fi; 3293 } 3294 3295 /* 3296 * Use the first item in a ":for" list. Advance to the next. 3297 * Assign the values to the variable (list). "arg" points to the first one. 3298 * Return TRUE when a valid item was found, FALSE when at end of list or 3299 * something wrong. 3300 */ 3301 int 3302 next_for_item(void *fi_void, char_u *arg) 3303 { 3304 forinfo_T *fi = (forinfo_T *)fi_void; 3305 int result; 3306 listitem_T *item; 3307 3308 item = fi->fi_lw.lw_item; 3309 if (item == NULL) 3310 result = FALSE; 3311 else 3312 { 3313 fi->fi_lw.lw_item = item->li_next; 3314 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3315 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3316 } 3317 return result; 3318 } 3319 3320 /* 3321 * Free the structure used to store info used by ":for". 3322 */ 3323 void 3324 free_for_info(void *fi_void) 3325 { 3326 forinfo_T *fi = (forinfo_T *)fi_void; 3327 3328 if (fi != NULL && fi->fi_list != NULL) 3329 { 3330 list_rem_watch(fi->fi_list, &fi->fi_lw); 3331 list_unref(fi->fi_list); 3332 } 3333 vim_free(fi); 3334 } 3335 3336 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3337 3338 void 3339 set_context_for_expression( 3340 expand_T *xp, 3341 char_u *arg, 3342 cmdidx_T cmdidx) 3343 { 3344 int got_eq = FALSE; 3345 int c; 3346 char_u *p; 3347 3348 if (cmdidx == CMD_let) 3349 { 3350 xp->xp_context = EXPAND_USER_VARS; 3351 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3352 { 3353 /* ":let var1 var2 ...": find last space. */ 3354 for (p = arg + STRLEN(arg); p >= arg; ) 3355 { 3356 xp->xp_pattern = p; 3357 mb_ptr_back(arg, p); 3358 if (vim_iswhite(*p)) 3359 break; 3360 } 3361 return; 3362 } 3363 } 3364 else 3365 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3366 : EXPAND_EXPRESSION; 3367 while ((xp->xp_pattern = vim_strpbrk(arg, 3368 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3369 { 3370 c = *xp->xp_pattern; 3371 if (c == '&') 3372 { 3373 c = xp->xp_pattern[1]; 3374 if (c == '&') 3375 { 3376 ++xp->xp_pattern; 3377 xp->xp_context = cmdidx != CMD_let || got_eq 3378 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3379 } 3380 else if (c != ' ') 3381 { 3382 xp->xp_context = EXPAND_SETTINGS; 3383 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3384 xp->xp_pattern += 2; 3385 3386 } 3387 } 3388 else if (c == '$') 3389 { 3390 /* environment variable */ 3391 xp->xp_context = EXPAND_ENV_VARS; 3392 } 3393 else if (c == '=') 3394 { 3395 got_eq = TRUE; 3396 xp->xp_context = EXPAND_EXPRESSION; 3397 } 3398 else if ((c == '<' || c == '#') 3399 && xp->xp_context == EXPAND_FUNCTIONS 3400 && vim_strchr(xp->xp_pattern, '(') == NULL) 3401 { 3402 /* Function name can start with "<SNR>" and contain '#'. */ 3403 break; 3404 } 3405 else if (cmdidx != CMD_let || got_eq) 3406 { 3407 if (c == '"') /* string */ 3408 { 3409 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3410 if (c == '\\' && xp->xp_pattern[1] != NUL) 3411 ++xp->xp_pattern; 3412 xp->xp_context = EXPAND_NOTHING; 3413 } 3414 else if (c == '\'') /* literal string */ 3415 { 3416 /* Trick: '' is like stopping and starting a literal string. */ 3417 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3418 /* skip */ ; 3419 xp->xp_context = EXPAND_NOTHING; 3420 } 3421 else if (c == '|') 3422 { 3423 if (xp->xp_pattern[1] == '|') 3424 { 3425 ++xp->xp_pattern; 3426 xp->xp_context = EXPAND_EXPRESSION; 3427 } 3428 else 3429 xp->xp_context = EXPAND_COMMANDS; 3430 } 3431 else 3432 xp->xp_context = EXPAND_EXPRESSION; 3433 } 3434 else 3435 /* Doesn't look like something valid, expand as an expression 3436 * anyway. */ 3437 xp->xp_context = EXPAND_EXPRESSION; 3438 arg = xp->xp_pattern; 3439 if (*arg != NUL) 3440 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3441 /* skip */ ; 3442 } 3443 xp->xp_pattern = arg; 3444 } 3445 3446 #endif /* FEAT_CMDL_COMPL */ 3447 3448 /* 3449 * ":1,25call func(arg1, arg2)" function call. 3450 */ 3451 void 3452 ex_call(exarg_T *eap) 3453 { 3454 char_u *arg = eap->arg; 3455 char_u *startarg; 3456 char_u *name; 3457 char_u *tofree; 3458 int len; 3459 typval_T rettv; 3460 linenr_T lnum; 3461 int doesrange; 3462 int failed = FALSE; 3463 funcdict_T fudi; 3464 partial_T *partial = NULL; 3465 3466 if (eap->skip) 3467 { 3468 /* trans_function_name() doesn't work well when skipping, use eval0() 3469 * instead to skip to any following command, e.g. for: 3470 * :if 0 | call dict.foo().bar() | endif */ 3471 ++emsg_skip; 3472 if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL) 3473 clear_tv(&rettv); 3474 --emsg_skip; 3475 return; 3476 } 3477 3478 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial); 3479 if (fudi.fd_newkey != NULL) 3480 { 3481 /* Still need to give an error message for missing key. */ 3482 EMSG2(_(e_dictkey), fudi.fd_newkey); 3483 vim_free(fudi.fd_newkey); 3484 } 3485 if (tofree == NULL) 3486 return; 3487 3488 /* Increase refcount on dictionary, it could get deleted when evaluating 3489 * the arguments. */ 3490 if (fudi.fd_dict != NULL) 3491 ++fudi.fd_dict->dv_refcount; 3492 3493 /* If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its 3494 * contents. For VAR_PARTIAL get its partial, unless we already have one 3495 * from trans_function_name(). */ 3496 len = (int)STRLEN(tofree); 3497 name = deref_func_name(tofree, &len, 3498 partial != NULL ? NULL : &partial, FALSE); 3499 3500 /* Skip white space to allow ":call func ()". Not good, but required for 3501 * backward compatibility. */ 3502 startarg = skipwhite(arg); 3503 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3504 3505 if (*startarg != '(') 3506 { 3507 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3508 goto end; 3509 } 3510 3511 /* 3512 * When skipping, evaluate the function once, to find the end of the 3513 * arguments. 3514 * When the function takes a range, this is discovered after the first 3515 * call, and the loop is broken. 3516 */ 3517 if (eap->skip) 3518 { 3519 ++emsg_skip; 3520 lnum = eap->line2; /* do it once, also with an invalid range */ 3521 } 3522 else 3523 lnum = eap->line1; 3524 for ( ; lnum <= eap->line2; ++lnum) 3525 { 3526 if (!eap->skip && eap->addr_count > 0) 3527 { 3528 curwin->w_cursor.lnum = lnum; 3529 curwin->w_cursor.col = 0; 3530 #ifdef FEAT_VIRTUALEDIT 3531 curwin->w_cursor.coladd = 0; 3532 #endif 3533 } 3534 arg = startarg; 3535 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3536 eap->line1, eap->line2, &doesrange, 3537 !eap->skip, partial, fudi.fd_dict) == FAIL) 3538 { 3539 failed = TRUE; 3540 break; 3541 } 3542 3543 /* Handle a function returning a Funcref, Dictionary or List. */ 3544 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3545 { 3546 failed = TRUE; 3547 break; 3548 } 3549 3550 clear_tv(&rettv); 3551 if (doesrange || eap->skip) 3552 break; 3553 3554 /* Stop when immediately aborting on error, or when an interrupt 3555 * occurred or an exception was thrown but not caught. 3556 * get_func_tv() returned OK, so that the check for trailing 3557 * characters below is executed. */ 3558 if (aborting()) 3559 break; 3560 } 3561 if (eap->skip) 3562 --emsg_skip; 3563 3564 if (!failed) 3565 { 3566 /* Check for trailing illegal characters and a following command. */ 3567 if (!ends_excmd(*arg)) 3568 { 3569 emsg_severe = TRUE; 3570 EMSG(_(e_trailing)); 3571 } 3572 else 3573 eap->nextcmd = check_nextcmd(arg); 3574 } 3575 3576 end: 3577 dict_unref(fudi.fd_dict); 3578 vim_free(tofree); 3579 } 3580 3581 /* 3582 * ":unlet[!] var1 ... " command. 3583 */ 3584 void 3585 ex_unlet(exarg_T *eap) 3586 { 3587 ex_unletlock(eap, eap->arg, 0); 3588 } 3589 3590 /* 3591 * ":lockvar" and ":unlockvar" commands 3592 */ 3593 void 3594 ex_lockvar(exarg_T *eap) 3595 { 3596 char_u *arg = eap->arg; 3597 int deep = 2; 3598 3599 if (eap->forceit) 3600 deep = -1; 3601 else if (vim_isdigit(*arg)) 3602 { 3603 deep = getdigits(&arg); 3604 arg = skipwhite(arg); 3605 } 3606 3607 ex_unletlock(eap, arg, deep); 3608 } 3609 3610 /* 3611 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3612 */ 3613 static void 3614 ex_unletlock( 3615 exarg_T *eap, 3616 char_u *argstart, 3617 int deep) 3618 { 3619 char_u *arg = argstart; 3620 char_u *name_end; 3621 int error = FALSE; 3622 lval_T lv; 3623 3624 do 3625 { 3626 /* Parse the name and find the end. */ 3627 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, 3628 FNE_CHECK_START); 3629 if (lv.ll_name == NULL) 3630 error = TRUE; /* error but continue parsing */ 3631 if (name_end == NULL || (!vim_iswhite(*name_end) 3632 && !ends_excmd(*name_end))) 3633 { 3634 if (name_end != NULL) 3635 { 3636 emsg_severe = TRUE; 3637 EMSG(_(e_trailing)); 3638 } 3639 if (!(eap->skip || error)) 3640 clear_lval(&lv); 3641 break; 3642 } 3643 3644 if (!error && !eap->skip) 3645 { 3646 if (eap->cmdidx == CMD_unlet) 3647 { 3648 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3649 error = TRUE; 3650 } 3651 else 3652 { 3653 if (do_lock_var(&lv, name_end, deep, 3654 eap->cmdidx == CMD_lockvar) == FAIL) 3655 error = TRUE; 3656 } 3657 } 3658 3659 if (!eap->skip) 3660 clear_lval(&lv); 3661 3662 arg = skipwhite(name_end); 3663 } while (!ends_excmd(*arg)); 3664 3665 eap->nextcmd = check_nextcmd(arg); 3666 } 3667 3668 static int 3669 do_unlet_var( 3670 lval_T *lp, 3671 char_u *name_end, 3672 int forceit) 3673 { 3674 int ret = OK; 3675 int cc; 3676 3677 if (lp->ll_tv == NULL) 3678 { 3679 cc = *name_end; 3680 *name_end = NUL; 3681 3682 /* Normal name or expanded name. */ 3683 if (check_changedtick(lp->ll_name)) 3684 ret = FAIL; 3685 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3686 ret = FAIL; 3687 *name_end = cc; 3688 } 3689 else if ((lp->ll_list != NULL 3690 && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) 3691 || (lp->ll_dict != NULL 3692 && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) 3693 return FAIL; 3694 else if (lp->ll_range) 3695 { 3696 listitem_T *li; 3697 listitem_T *ll_li = lp->ll_li; 3698 int ll_n1 = lp->ll_n1; 3699 3700 while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) 3701 { 3702 li = ll_li->li_next; 3703 if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) 3704 return FAIL; 3705 ll_li = li; 3706 ++ll_n1; 3707 } 3708 3709 /* Delete a range of List items. */ 3710 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3711 { 3712 li = lp->ll_li->li_next; 3713 listitem_remove(lp->ll_list, lp->ll_li); 3714 lp->ll_li = li; 3715 ++lp->ll_n1; 3716 } 3717 } 3718 else 3719 { 3720 if (lp->ll_list != NULL) 3721 /* unlet a List item. */ 3722 listitem_remove(lp->ll_list, lp->ll_li); 3723 else 3724 /* unlet a Dictionary item. */ 3725 dictitem_remove(lp->ll_dict, lp->ll_di); 3726 } 3727 3728 return ret; 3729 } 3730 3731 /* 3732 * "unlet" a variable. Return OK if it existed, FAIL if not. 3733 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3734 */ 3735 int 3736 do_unlet(char_u *name, int forceit) 3737 { 3738 hashtab_T *ht; 3739 hashitem_T *hi; 3740 char_u *varname; 3741 dict_T *d; 3742 dictitem_T *di; 3743 3744 ht = find_var_ht(name, &varname); 3745 if (ht != NULL && *varname != NUL) 3746 { 3747 if (ht == &globvarht) 3748 d = &globvardict; 3749 else if (current_funccal != NULL 3750 && ht == ¤t_funccal->l_vars.dv_hashtab) 3751 d = ¤t_funccal->l_vars; 3752 else if (ht == &compat_hashtab) 3753 d = &vimvardict; 3754 else 3755 { 3756 di = find_var_in_ht(ht, *name, (char_u *)"", FALSE); 3757 d = di == NULL ? NULL : di->di_tv.vval.v_dict; 3758 } 3759 if (d == NULL) 3760 { 3761 EMSG2(_(e_intern2), "do_unlet()"); 3762 return FAIL; 3763 } 3764 hi = hash_find(ht, varname); 3765 if (!HASHITEM_EMPTY(hi)) 3766 { 3767 di = HI2DI(hi); 3768 if (var_check_fixed(di->di_flags, name, FALSE) 3769 || var_check_ro(di->di_flags, name, FALSE) 3770 || tv_check_lock(d->dv_lock, name, FALSE)) 3771 return FAIL; 3772 3773 delete_var(ht, hi); 3774 return OK; 3775 } 3776 } 3777 if (forceit) 3778 return OK; 3779 EMSG2(_("E108: No such variable: \"%s\""), name); 3780 return FAIL; 3781 } 3782 3783 /* 3784 * Lock or unlock variable indicated by "lp". 3785 * "deep" is the levels to go (-1 for unlimited); 3786 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3787 */ 3788 static int 3789 do_lock_var( 3790 lval_T *lp, 3791 char_u *name_end, 3792 int deep, 3793 int lock) 3794 { 3795 int ret = OK; 3796 int cc; 3797 dictitem_T *di; 3798 3799 if (deep == 0) /* nothing to do */ 3800 return OK; 3801 3802 if (lp->ll_tv == NULL) 3803 { 3804 cc = *name_end; 3805 *name_end = NUL; 3806 3807 /* Normal name or expanded name. */ 3808 if (check_changedtick(lp->ll_name)) 3809 ret = FAIL; 3810 else 3811 { 3812 di = find_var(lp->ll_name, NULL, TRUE); 3813 if (di == NULL) 3814 ret = FAIL; 3815 else 3816 { 3817 if (lock) 3818 di->di_flags |= DI_FLAGS_LOCK; 3819 else 3820 di->di_flags &= ~DI_FLAGS_LOCK; 3821 item_lock(&di->di_tv, deep, lock); 3822 } 3823 } 3824 *name_end = cc; 3825 } 3826 else if (lp->ll_range) 3827 { 3828 listitem_T *li = lp->ll_li; 3829 3830 /* (un)lock a range of List items. */ 3831 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3832 { 3833 item_lock(&li->li_tv, deep, lock); 3834 li = li->li_next; 3835 ++lp->ll_n1; 3836 } 3837 } 3838 else if (lp->ll_list != NULL) 3839 /* (un)lock a List item. */ 3840 item_lock(&lp->ll_li->li_tv, deep, lock); 3841 else 3842 /* (un)lock a Dictionary item. */ 3843 item_lock(&lp->ll_di->di_tv, deep, lock); 3844 3845 return ret; 3846 } 3847 3848 /* 3849 * Lock or unlock an item. "deep" is nr of levels to go. 3850 */ 3851 static void 3852 item_lock(typval_T *tv, int deep, int lock) 3853 { 3854 static int recurse = 0; 3855 list_T *l; 3856 listitem_T *li; 3857 dict_T *d; 3858 hashitem_T *hi; 3859 int todo; 3860 3861 if (recurse >= DICT_MAXNEST) 3862 { 3863 EMSG(_("E743: variable nested too deep for (un)lock")); 3864 return; 3865 } 3866 if (deep == 0) 3867 return; 3868 ++recurse; 3869 3870 /* lock/unlock the item itself */ 3871 if (lock) 3872 tv->v_lock |= VAR_LOCKED; 3873 else 3874 tv->v_lock &= ~VAR_LOCKED; 3875 3876 switch (tv->v_type) 3877 { 3878 case VAR_UNKNOWN: 3879 case VAR_NUMBER: 3880 case VAR_STRING: 3881 case VAR_FUNC: 3882 case VAR_PARTIAL: 3883 case VAR_FLOAT: 3884 case VAR_SPECIAL: 3885 case VAR_JOB: 3886 case VAR_CHANNEL: 3887 break; 3888 3889 case VAR_LIST: 3890 if ((l = tv->vval.v_list) != NULL) 3891 { 3892 if (lock) 3893 l->lv_lock |= VAR_LOCKED; 3894 else 3895 l->lv_lock &= ~VAR_LOCKED; 3896 if (deep < 0 || deep > 1) 3897 /* recursive: lock/unlock the items the List contains */ 3898 for (li = l->lv_first; li != NULL; li = li->li_next) 3899 item_lock(&li->li_tv, deep - 1, lock); 3900 } 3901 break; 3902 case VAR_DICT: 3903 if ((d = tv->vval.v_dict) != NULL) 3904 { 3905 if (lock) 3906 d->dv_lock |= VAR_LOCKED; 3907 else 3908 d->dv_lock &= ~VAR_LOCKED; 3909 if (deep < 0 || deep > 1) 3910 { 3911 /* recursive: lock/unlock the items the List contains */ 3912 todo = (int)d->dv_hashtab.ht_used; 3913 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3914 { 3915 if (!HASHITEM_EMPTY(hi)) 3916 { 3917 --todo; 3918 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3919 } 3920 } 3921 } 3922 } 3923 } 3924 --recurse; 3925 } 3926 3927 /* 3928 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3929 * or it refers to a List or Dictionary that is locked. 3930 */ 3931 static int 3932 tv_islocked(typval_T *tv) 3933 { 3934 return (tv->v_lock & VAR_LOCKED) 3935 || (tv->v_type == VAR_LIST 3936 && tv->vval.v_list != NULL 3937 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3938 || (tv->v_type == VAR_DICT 3939 && tv->vval.v_dict != NULL 3940 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3941 } 3942 3943 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3944 /* 3945 * Delete all "menutrans_" variables. 3946 */ 3947 void 3948 del_menutrans_vars(void) 3949 { 3950 hashitem_T *hi; 3951 int todo; 3952 3953 hash_lock(&globvarht); 3954 todo = (int)globvarht.ht_used; 3955 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3956 { 3957 if (!HASHITEM_EMPTY(hi)) 3958 { 3959 --todo; 3960 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3961 delete_var(&globvarht, hi); 3962 } 3963 } 3964 hash_unlock(&globvarht); 3965 } 3966 #endif 3967 3968 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3969 3970 /* 3971 * Local string buffer for the next two functions to store a variable name 3972 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3973 * get_user_var_name(). 3974 */ 3975 3976 static char_u *cat_prefix_varname(int prefix, char_u *name); 3977 3978 static char_u *varnamebuf = NULL; 3979 static int varnamebuflen = 0; 3980 3981 /* 3982 * Function to concatenate a prefix and a variable name. 3983 */ 3984 static char_u * 3985 cat_prefix_varname(int prefix, char_u *name) 3986 { 3987 int len; 3988 3989 len = (int)STRLEN(name) + 3; 3990 if (len > varnamebuflen) 3991 { 3992 vim_free(varnamebuf); 3993 len += 10; /* some additional space */ 3994 varnamebuf = alloc(len); 3995 if (varnamebuf == NULL) 3996 { 3997 varnamebuflen = 0; 3998 return NULL; 3999 } 4000 varnamebuflen = len; 4001 } 4002 *varnamebuf = prefix; 4003 varnamebuf[1] = ':'; 4004 STRCPY(varnamebuf + 2, name); 4005 return varnamebuf; 4006 } 4007 4008 /* 4009 * Function given to ExpandGeneric() to obtain the list of user defined 4010 * (global/buffer/window/built-in) variable names. 4011 */ 4012 char_u * 4013 get_user_var_name(expand_T *xp, int idx) 4014 { 4015 static long_u gdone; 4016 static long_u bdone; 4017 static long_u wdone; 4018 #ifdef FEAT_WINDOWS 4019 static long_u tdone; 4020 #endif 4021 static int vidx; 4022 static hashitem_T *hi; 4023 hashtab_T *ht; 4024 4025 if (idx == 0) 4026 { 4027 gdone = bdone = wdone = vidx = 0; 4028 #ifdef FEAT_WINDOWS 4029 tdone = 0; 4030 #endif 4031 } 4032 4033 /* Global variables */ 4034 if (gdone < globvarht.ht_used) 4035 { 4036 if (gdone++ == 0) 4037 hi = globvarht.ht_array; 4038 else 4039 ++hi; 4040 while (HASHITEM_EMPTY(hi)) 4041 ++hi; 4042 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 4043 return cat_prefix_varname('g', hi->hi_key); 4044 return hi->hi_key; 4045 } 4046 4047 /* b: variables */ 4048 ht = &curbuf->b_vars->dv_hashtab; 4049 if (bdone < ht->ht_used) 4050 { 4051 if (bdone++ == 0) 4052 hi = ht->ht_array; 4053 else 4054 ++hi; 4055 while (HASHITEM_EMPTY(hi)) 4056 ++hi; 4057 return cat_prefix_varname('b', hi->hi_key); 4058 } 4059 if (bdone == ht->ht_used) 4060 { 4061 ++bdone; 4062 return (char_u *)"b:changedtick"; 4063 } 4064 4065 /* w: variables */ 4066 ht = &curwin->w_vars->dv_hashtab; 4067 if (wdone < ht->ht_used) 4068 { 4069 if (wdone++ == 0) 4070 hi = ht->ht_array; 4071 else 4072 ++hi; 4073 while (HASHITEM_EMPTY(hi)) 4074 ++hi; 4075 return cat_prefix_varname('w', hi->hi_key); 4076 } 4077 4078 #ifdef FEAT_WINDOWS 4079 /* t: variables */ 4080 ht = &curtab->tp_vars->dv_hashtab; 4081 if (tdone < ht->ht_used) 4082 { 4083 if (tdone++ == 0) 4084 hi = ht->ht_array; 4085 else 4086 ++hi; 4087 while (HASHITEM_EMPTY(hi)) 4088 ++hi; 4089 return cat_prefix_varname('t', hi->hi_key); 4090 } 4091 #endif 4092 4093 /* v: variables */ 4094 if (vidx < VV_LEN) 4095 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 4096 4097 vim_free(varnamebuf); 4098 varnamebuf = NULL; 4099 varnamebuflen = 0; 4100 return NULL; 4101 } 4102 4103 #endif /* FEAT_CMDL_COMPL */ 4104 4105 /* 4106 * types for expressions. 4107 */ 4108 typedef enum 4109 { 4110 TYPE_UNKNOWN = 0 4111 , TYPE_EQUAL /* == */ 4112 , TYPE_NEQUAL /* != */ 4113 , TYPE_GREATER /* > */ 4114 , TYPE_GEQUAL /* >= */ 4115 , TYPE_SMALLER /* < */ 4116 , TYPE_SEQUAL /* <= */ 4117 , TYPE_MATCH /* =~ */ 4118 , TYPE_NOMATCH /* !~ */ 4119 } exptype_T; 4120 4121 /* 4122 * The "evaluate" argument: When FALSE, the argument is only parsed but not 4123 * executed. The function may return OK, but the rettv will be of type 4124 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 4125 */ 4126 4127 /* 4128 * Handle zero level expression. 4129 * This calls eval1() and handles error message and nextcmd. 4130 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 4131 * Note: "rettv.v_lock" is not set. 4132 * Return OK or FAIL. 4133 */ 4134 static int 4135 eval0( 4136 char_u *arg, 4137 typval_T *rettv, 4138 char_u **nextcmd, 4139 int evaluate) 4140 { 4141 int ret; 4142 char_u *p; 4143 4144 p = skipwhite(arg); 4145 ret = eval1(&p, rettv, evaluate); 4146 if (ret == FAIL || !ends_excmd(*p)) 4147 { 4148 if (ret != FAIL) 4149 clear_tv(rettv); 4150 /* 4151 * Report the invalid expression unless the expression evaluation has 4152 * been cancelled due to an aborting error, an interrupt, or an 4153 * exception. 4154 */ 4155 if (!aborting()) 4156 EMSG2(_(e_invexpr2), arg); 4157 ret = FAIL; 4158 } 4159 if (nextcmd != NULL) 4160 *nextcmd = check_nextcmd(p); 4161 4162 return ret; 4163 } 4164 4165 /* 4166 * Handle top level expression: 4167 * expr2 ? expr1 : expr1 4168 * 4169 * "arg" must point to the first non-white of the expression. 4170 * "arg" is advanced to the next non-white after the recognized expression. 4171 * 4172 * Note: "rettv.v_lock" is not set. 4173 * 4174 * Return OK or FAIL. 4175 */ 4176 static int 4177 eval1(char_u **arg, typval_T *rettv, int evaluate) 4178 { 4179 int result; 4180 typval_T var2; 4181 4182 /* 4183 * Get the first variable. 4184 */ 4185 if (eval2(arg, rettv, evaluate) == FAIL) 4186 return FAIL; 4187 4188 if ((*arg)[0] == '?') 4189 { 4190 result = FALSE; 4191 if (evaluate) 4192 { 4193 int error = FALSE; 4194 4195 if (get_tv_number_chk(rettv, &error) != 0) 4196 result = TRUE; 4197 clear_tv(rettv); 4198 if (error) 4199 return FAIL; 4200 } 4201 4202 /* 4203 * Get the second variable. 4204 */ 4205 *arg = skipwhite(*arg + 1); 4206 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 4207 return FAIL; 4208 4209 /* 4210 * Check for the ":". 4211 */ 4212 if ((*arg)[0] != ':') 4213 { 4214 EMSG(_("E109: Missing ':' after '?'")); 4215 if (evaluate && result) 4216 clear_tv(rettv); 4217 return FAIL; 4218 } 4219 4220 /* 4221 * Get the third variable. 4222 */ 4223 *arg = skipwhite(*arg + 1); 4224 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4225 { 4226 if (evaluate && result) 4227 clear_tv(rettv); 4228 return FAIL; 4229 } 4230 if (evaluate && !result) 4231 *rettv = var2; 4232 } 4233 4234 return OK; 4235 } 4236 4237 /* 4238 * Handle first level expression: 4239 * expr2 || expr2 || expr2 logical OR 4240 * 4241 * "arg" must point to the first non-white of the expression. 4242 * "arg" is advanced to the next non-white after the recognized expression. 4243 * 4244 * Return OK or FAIL. 4245 */ 4246 static int 4247 eval2(char_u **arg, typval_T *rettv, int evaluate) 4248 { 4249 typval_T var2; 4250 long result; 4251 int first; 4252 int error = FALSE; 4253 4254 /* 4255 * Get the first variable. 4256 */ 4257 if (eval3(arg, rettv, evaluate) == FAIL) 4258 return FAIL; 4259 4260 /* 4261 * Repeat until there is no following "||". 4262 */ 4263 first = TRUE; 4264 result = FALSE; 4265 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4266 { 4267 if (evaluate && first) 4268 { 4269 if (get_tv_number_chk(rettv, &error) != 0) 4270 result = TRUE; 4271 clear_tv(rettv); 4272 if (error) 4273 return FAIL; 4274 first = FALSE; 4275 } 4276 4277 /* 4278 * Get the second variable. 4279 */ 4280 *arg = skipwhite(*arg + 2); 4281 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4282 return FAIL; 4283 4284 /* 4285 * Compute the result. 4286 */ 4287 if (evaluate && !result) 4288 { 4289 if (get_tv_number_chk(&var2, &error) != 0) 4290 result = TRUE; 4291 clear_tv(&var2); 4292 if (error) 4293 return FAIL; 4294 } 4295 if (evaluate) 4296 { 4297 rettv->v_type = VAR_NUMBER; 4298 rettv->vval.v_number = result; 4299 } 4300 } 4301 4302 return OK; 4303 } 4304 4305 /* 4306 * Handle second level expression: 4307 * expr3 && expr3 && expr3 logical AND 4308 * 4309 * "arg" must point to the first non-white of the expression. 4310 * "arg" is advanced to the next non-white after the recognized expression. 4311 * 4312 * Return OK or FAIL. 4313 */ 4314 static int 4315 eval3(char_u **arg, typval_T *rettv, int evaluate) 4316 { 4317 typval_T var2; 4318 long result; 4319 int first; 4320 int error = FALSE; 4321 4322 /* 4323 * Get the first variable. 4324 */ 4325 if (eval4(arg, rettv, evaluate) == FAIL) 4326 return FAIL; 4327 4328 /* 4329 * Repeat until there is no following "&&". 4330 */ 4331 first = TRUE; 4332 result = TRUE; 4333 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4334 { 4335 if (evaluate && first) 4336 { 4337 if (get_tv_number_chk(rettv, &error) == 0) 4338 result = FALSE; 4339 clear_tv(rettv); 4340 if (error) 4341 return FAIL; 4342 first = FALSE; 4343 } 4344 4345 /* 4346 * Get the second variable. 4347 */ 4348 *arg = skipwhite(*arg + 2); 4349 if (eval4(arg, &var2, evaluate && result) == FAIL) 4350 return FAIL; 4351 4352 /* 4353 * Compute the result. 4354 */ 4355 if (evaluate && result) 4356 { 4357 if (get_tv_number_chk(&var2, &error) == 0) 4358 result = FALSE; 4359 clear_tv(&var2); 4360 if (error) 4361 return FAIL; 4362 } 4363 if (evaluate) 4364 { 4365 rettv->v_type = VAR_NUMBER; 4366 rettv->vval.v_number = result; 4367 } 4368 } 4369 4370 return OK; 4371 } 4372 4373 /* 4374 * Handle third level expression: 4375 * var1 == var2 4376 * var1 =~ var2 4377 * var1 != var2 4378 * var1 !~ var2 4379 * var1 > var2 4380 * var1 >= var2 4381 * var1 < var2 4382 * var1 <= var2 4383 * var1 is var2 4384 * var1 isnot var2 4385 * 4386 * "arg" must point to the first non-white of the expression. 4387 * "arg" is advanced to the next non-white after the recognized expression. 4388 * 4389 * Return OK or FAIL. 4390 */ 4391 static int 4392 eval4(char_u **arg, typval_T *rettv, int evaluate) 4393 { 4394 typval_T var2; 4395 char_u *p; 4396 int i; 4397 exptype_T type = TYPE_UNKNOWN; 4398 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4399 int len = 2; 4400 long n1, n2; 4401 char_u *s1, *s2; 4402 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4403 regmatch_T regmatch; 4404 int ic; 4405 char_u *save_cpo; 4406 4407 /* 4408 * Get the first variable. 4409 */ 4410 if (eval5(arg, rettv, evaluate) == FAIL) 4411 return FAIL; 4412 4413 p = *arg; 4414 switch (p[0]) 4415 { 4416 case '=': if (p[1] == '=') 4417 type = TYPE_EQUAL; 4418 else if (p[1] == '~') 4419 type = TYPE_MATCH; 4420 break; 4421 case '!': if (p[1] == '=') 4422 type = TYPE_NEQUAL; 4423 else if (p[1] == '~') 4424 type = TYPE_NOMATCH; 4425 break; 4426 case '>': if (p[1] != '=') 4427 { 4428 type = TYPE_GREATER; 4429 len = 1; 4430 } 4431 else 4432 type = TYPE_GEQUAL; 4433 break; 4434 case '<': if (p[1] != '=') 4435 { 4436 type = TYPE_SMALLER; 4437 len = 1; 4438 } 4439 else 4440 type = TYPE_SEQUAL; 4441 break; 4442 case 'i': if (p[1] == 's') 4443 { 4444 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4445 len = 5; 4446 i = p[len]; 4447 if (!isalnum(i) && i != '_') 4448 { 4449 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4450 type_is = TRUE; 4451 } 4452 } 4453 break; 4454 } 4455 4456 /* 4457 * If there is a comparative operator, use it. 4458 */ 4459 if (type != TYPE_UNKNOWN) 4460 { 4461 /* extra question mark appended: ignore case */ 4462 if (p[len] == '?') 4463 { 4464 ic = TRUE; 4465 ++len; 4466 } 4467 /* extra '#' appended: match case */ 4468 else if (p[len] == '#') 4469 { 4470 ic = FALSE; 4471 ++len; 4472 } 4473 /* nothing appended: use 'ignorecase' */ 4474 else 4475 ic = p_ic; 4476 4477 /* 4478 * Get the second variable. 4479 */ 4480 *arg = skipwhite(p + len); 4481 if (eval5(arg, &var2, evaluate) == FAIL) 4482 { 4483 clear_tv(rettv); 4484 return FAIL; 4485 } 4486 4487 if (evaluate) 4488 { 4489 if (type_is && rettv->v_type != var2.v_type) 4490 { 4491 /* For "is" a different type always means FALSE, for "notis" 4492 * it means TRUE. */ 4493 n1 = (type == TYPE_NEQUAL); 4494 } 4495 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4496 { 4497 if (type_is) 4498 { 4499 n1 = (rettv->v_type == var2.v_type 4500 && rettv->vval.v_list == var2.vval.v_list); 4501 if (type == TYPE_NEQUAL) 4502 n1 = !n1; 4503 } 4504 else if (rettv->v_type != var2.v_type 4505 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4506 { 4507 if (rettv->v_type != var2.v_type) 4508 EMSG(_("E691: Can only compare List with List")); 4509 else 4510 EMSG(_("E692: Invalid operation for List")); 4511 clear_tv(rettv); 4512 clear_tv(&var2); 4513 return FAIL; 4514 } 4515 else 4516 { 4517 /* Compare two Lists for being equal or unequal. */ 4518 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, 4519 ic, FALSE); 4520 if (type == TYPE_NEQUAL) 4521 n1 = !n1; 4522 } 4523 } 4524 4525 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4526 { 4527 if (type_is) 4528 { 4529 n1 = (rettv->v_type == var2.v_type 4530 && rettv->vval.v_dict == var2.vval.v_dict); 4531 if (type == TYPE_NEQUAL) 4532 n1 = !n1; 4533 } 4534 else if (rettv->v_type != var2.v_type 4535 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4536 { 4537 if (rettv->v_type != var2.v_type) 4538 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4539 else 4540 EMSG(_("E736: Invalid operation for Dictionary")); 4541 clear_tv(rettv); 4542 clear_tv(&var2); 4543 return FAIL; 4544 } 4545 else 4546 { 4547 /* Compare two Dictionaries for being equal or unequal. */ 4548 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, 4549 ic, FALSE); 4550 if (type == TYPE_NEQUAL) 4551 n1 = !n1; 4552 } 4553 } 4554 4555 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC 4556 || rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL) 4557 { 4558 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) 4559 { 4560 EMSG(_("E694: Invalid operation for Funcrefs")); 4561 clear_tv(rettv); 4562 clear_tv(&var2); 4563 return FAIL; 4564 } 4565 n1 = tv_equal(rettv, &var2, FALSE, FALSE); 4566 if (type == TYPE_NEQUAL) 4567 n1 = !n1; 4568 } 4569 4570 #ifdef FEAT_FLOAT 4571 /* 4572 * If one of the two variables is a float, compare as a float. 4573 * When using "=~" or "!~", always compare as string. 4574 */ 4575 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4576 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4577 { 4578 float_T f1, f2; 4579 4580 if (rettv->v_type == VAR_FLOAT) 4581 f1 = rettv->vval.v_float; 4582 else 4583 f1 = get_tv_number(rettv); 4584 if (var2.v_type == VAR_FLOAT) 4585 f2 = var2.vval.v_float; 4586 else 4587 f2 = get_tv_number(&var2); 4588 n1 = FALSE; 4589 switch (type) 4590 { 4591 case TYPE_EQUAL: n1 = (f1 == f2); break; 4592 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4593 case TYPE_GREATER: n1 = (f1 > f2); break; 4594 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4595 case TYPE_SMALLER: n1 = (f1 < f2); break; 4596 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4597 case TYPE_UNKNOWN: 4598 case TYPE_MATCH: 4599 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4600 } 4601 } 4602 #endif 4603 4604 /* 4605 * If one of the two variables is a number, compare as a number. 4606 * When using "=~" or "!~", always compare as string. 4607 */ 4608 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4609 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4610 { 4611 n1 = get_tv_number(rettv); 4612 n2 = get_tv_number(&var2); 4613 switch (type) 4614 { 4615 case TYPE_EQUAL: n1 = (n1 == n2); break; 4616 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4617 case TYPE_GREATER: n1 = (n1 > n2); break; 4618 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4619 case TYPE_SMALLER: n1 = (n1 < n2); break; 4620 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4621 case TYPE_UNKNOWN: 4622 case TYPE_MATCH: 4623 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4624 } 4625 } 4626 else 4627 { 4628 s1 = get_tv_string_buf(rettv, buf1); 4629 s2 = get_tv_string_buf(&var2, buf2); 4630 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4631 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4632 else 4633 i = 0; 4634 n1 = FALSE; 4635 switch (type) 4636 { 4637 case TYPE_EQUAL: n1 = (i == 0); break; 4638 case TYPE_NEQUAL: n1 = (i != 0); break; 4639 case TYPE_GREATER: n1 = (i > 0); break; 4640 case TYPE_GEQUAL: n1 = (i >= 0); break; 4641 case TYPE_SMALLER: n1 = (i < 0); break; 4642 case TYPE_SEQUAL: n1 = (i <= 0); break; 4643 4644 case TYPE_MATCH: 4645 case TYPE_NOMATCH: 4646 /* avoid 'l' flag in 'cpoptions' */ 4647 save_cpo = p_cpo; 4648 p_cpo = (char_u *)""; 4649 regmatch.regprog = vim_regcomp(s2, 4650 RE_MAGIC + RE_STRING); 4651 regmatch.rm_ic = ic; 4652 if (regmatch.regprog != NULL) 4653 { 4654 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4655 vim_regfree(regmatch.regprog); 4656 if (type == TYPE_NOMATCH) 4657 n1 = !n1; 4658 } 4659 p_cpo = save_cpo; 4660 break; 4661 4662 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4663 } 4664 } 4665 clear_tv(rettv); 4666 clear_tv(&var2); 4667 rettv->v_type = VAR_NUMBER; 4668 rettv->vval.v_number = n1; 4669 } 4670 } 4671 4672 return OK; 4673 } 4674 4675 /* 4676 * Handle fourth level expression: 4677 * + number addition 4678 * - number subtraction 4679 * . string concatenation 4680 * 4681 * "arg" must point to the first non-white of the expression. 4682 * "arg" is advanced to the next non-white after the recognized expression. 4683 * 4684 * Return OK or FAIL. 4685 */ 4686 static int 4687 eval5(char_u **arg, typval_T *rettv, int evaluate) 4688 { 4689 typval_T var2; 4690 typval_T var3; 4691 int op; 4692 long n1, n2; 4693 #ifdef FEAT_FLOAT 4694 float_T f1 = 0, f2 = 0; 4695 #endif 4696 char_u *s1, *s2; 4697 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4698 char_u *p; 4699 4700 /* 4701 * Get the first variable. 4702 */ 4703 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4704 return FAIL; 4705 4706 /* 4707 * Repeat computing, until no '+', '-' or '.' is following. 4708 */ 4709 for (;;) 4710 { 4711 op = **arg; 4712 if (op != '+' && op != '-' && op != '.') 4713 break; 4714 4715 if ((op != '+' || rettv->v_type != VAR_LIST) 4716 #ifdef FEAT_FLOAT 4717 && (op == '.' || rettv->v_type != VAR_FLOAT) 4718 #endif 4719 ) 4720 { 4721 /* For "list + ...", an illegal use of the first operand as 4722 * a number cannot be determined before evaluating the 2nd 4723 * operand: if this is also a list, all is ok. 4724 * For "something . ...", "something - ..." or "non-list + ...", 4725 * we know that the first operand needs to be a string or number 4726 * without evaluating the 2nd operand. So check before to avoid 4727 * side effects after an error. */ 4728 if (evaluate && get_tv_string_chk(rettv) == NULL) 4729 { 4730 clear_tv(rettv); 4731 return FAIL; 4732 } 4733 } 4734 4735 /* 4736 * Get the second variable. 4737 */ 4738 *arg = skipwhite(*arg + 1); 4739 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4740 { 4741 clear_tv(rettv); 4742 return FAIL; 4743 } 4744 4745 if (evaluate) 4746 { 4747 /* 4748 * Compute the result. 4749 */ 4750 if (op == '.') 4751 { 4752 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4753 s2 = get_tv_string_buf_chk(&var2, buf2); 4754 if (s2 == NULL) /* type error ? */ 4755 { 4756 clear_tv(rettv); 4757 clear_tv(&var2); 4758 return FAIL; 4759 } 4760 p = concat_str(s1, s2); 4761 clear_tv(rettv); 4762 rettv->v_type = VAR_STRING; 4763 rettv->vval.v_string = p; 4764 } 4765 else if (op == '+' && rettv->v_type == VAR_LIST 4766 && var2.v_type == VAR_LIST) 4767 { 4768 /* concatenate Lists */ 4769 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4770 &var3) == FAIL) 4771 { 4772 clear_tv(rettv); 4773 clear_tv(&var2); 4774 return FAIL; 4775 } 4776 clear_tv(rettv); 4777 *rettv = var3; 4778 } 4779 else 4780 { 4781 int error = FALSE; 4782 4783 #ifdef FEAT_FLOAT 4784 if (rettv->v_type == VAR_FLOAT) 4785 { 4786 f1 = rettv->vval.v_float; 4787 n1 = 0; 4788 } 4789 else 4790 #endif 4791 { 4792 n1 = get_tv_number_chk(rettv, &error); 4793 if (error) 4794 { 4795 /* This can only happen for "list + non-list". For 4796 * "non-list + ..." or "something - ...", we returned 4797 * before evaluating the 2nd operand. */ 4798 clear_tv(rettv); 4799 return FAIL; 4800 } 4801 #ifdef FEAT_FLOAT 4802 if (var2.v_type == VAR_FLOAT) 4803 f1 = n1; 4804 #endif 4805 } 4806 #ifdef FEAT_FLOAT 4807 if (var2.v_type == VAR_FLOAT) 4808 { 4809 f2 = var2.vval.v_float; 4810 n2 = 0; 4811 } 4812 else 4813 #endif 4814 { 4815 n2 = get_tv_number_chk(&var2, &error); 4816 if (error) 4817 { 4818 clear_tv(rettv); 4819 clear_tv(&var2); 4820 return FAIL; 4821 } 4822 #ifdef FEAT_FLOAT 4823 if (rettv->v_type == VAR_FLOAT) 4824 f2 = n2; 4825 #endif 4826 } 4827 clear_tv(rettv); 4828 4829 #ifdef FEAT_FLOAT 4830 /* If there is a float on either side the result is a float. */ 4831 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4832 { 4833 if (op == '+') 4834 f1 = f1 + f2; 4835 else 4836 f1 = f1 - f2; 4837 rettv->v_type = VAR_FLOAT; 4838 rettv->vval.v_float = f1; 4839 } 4840 else 4841 #endif 4842 { 4843 if (op == '+') 4844 n1 = n1 + n2; 4845 else 4846 n1 = n1 - n2; 4847 rettv->v_type = VAR_NUMBER; 4848 rettv->vval.v_number = n1; 4849 } 4850 } 4851 clear_tv(&var2); 4852 } 4853 } 4854 return OK; 4855 } 4856 4857 /* 4858 * Handle fifth level expression: 4859 * * number multiplication 4860 * / number division 4861 * % number modulo 4862 * 4863 * "arg" must point to the first non-white of the expression. 4864 * "arg" is advanced to the next non-white after the recognized expression. 4865 * 4866 * Return OK or FAIL. 4867 */ 4868 static int 4869 eval6( 4870 char_u **arg, 4871 typval_T *rettv, 4872 int evaluate, 4873 int want_string) /* after "." operator */ 4874 { 4875 typval_T var2; 4876 int op; 4877 long n1, n2; 4878 #ifdef FEAT_FLOAT 4879 int use_float = FALSE; 4880 float_T f1 = 0, f2; 4881 #endif 4882 int error = FALSE; 4883 4884 /* 4885 * Get the first variable. 4886 */ 4887 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4888 return FAIL; 4889 4890 /* 4891 * Repeat computing, until no '*', '/' or '%' is following. 4892 */ 4893 for (;;) 4894 { 4895 op = **arg; 4896 if (op != '*' && op != '/' && op != '%') 4897 break; 4898 4899 if (evaluate) 4900 { 4901 #ifdef FEAT_FLOAT 4902 if (rettv->v_type == VAR_FLOAT) 4903 { 4904 f1 = rettv->vval.v_float; 4905 use_float = TRUE; 4906 n1 = 0; 4907 } 4908 else 4909 #endif 4910 n1 = get_tv_number_chk(rettv, &error); 4911 clear_tv(rettv); 4912 if (error) 4913 return FAIL; 4914 } 4915 else 4916 n1 = 0; 4917 4918 /* 4919 * Get the second variable. 4920 */ 4921 *arg = skipwhite(*arg + 1); 4922 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4923 return FAIL; 4924 4925 if (evaluate) 4926 { 4927 #ifdef FEAT_FLOAT 4928 if (var2.v_type == VAR_FLOAT) 4929 { 4930 if (!use_float) 4931 { 4932 f1 = n1; 4933 use_float = TRUE; 4934 } 4935 f2 = var2.vval.v_float; 4936 n2 = 0; 4937 } 4938 else 4939 #endif 4940 { 4941 n2 = get_tv_number_chk(&var2, &error); 4942 clear_tv(&var2); 4943 if (error) 4944 return FAIL; 4945 #ifdef FEAT_FLOAT 4946 if (use_float) 4947 f2 = n2; 4948 #endif 4949 } 4950 4951 /* 4952 * Compute the result. 4953 * When either side is a float the result is a float. 4954 */ 4955 #ifdef FEAT_FLOAT 4956 if (use_float) 4957 { 4958 if (op == '*') 4959 f1 = f1 * f2; 4960 else if (op == '/') 4961 { 4962 # ifdef VMS 4963 /* VMS crashes on divide by zero, work around it */ 4964 if (f2 == 0.0) 4965 { 4966 if (f1 == 0) 4967 f1 = -1 * __F_FLT_MAX - 1L; /* similar to NaN */ 4968 else if (f1 < 0) 4969 f1 = -1 * __F_FLT_MAX; 4970 else 4971 f1 = __F_FLT_MAX; 4972 } 4973 else 4974 f1 = f1 / f2; 4975 # else 4976 /* We rely on the floating point library to handle divide 4977 * by zero to result in "inf" and not a crash. */ 4978 f1 = f1 / f2; 4979 # endif 4980 } 4981 else 4982 { 4983 EMSG(_("E804: Cannot use '%' with Float")); 4984 return FAIL; 4985 } 4986 rettv->v_type = VAR_FLOAT; 4987 rettv->vval.v_float = f1; 4988 } 4989 else 4990 #endif 4991 { 4992 if (op == '*') 4993 n1 = n1 * n2; 4994 else if (op == '/') 4995 { 4996 if (n2 == 0) /* give an error message? */ 4997 { 4998 if (n1 == 0) 4999 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 5000 else if (n1 < 0) 5001 n1 = -0x7fffffffL; 5002 else 5003 n1 = 0x7fffffffL; 5004 } 5005 else 5006 n1 = n1 / n2; 5007 } 5008 else 5009 { 5010 if (n2 == 0) /* give an error message? */ 5011 n1 = 0; 5012 else 5013 n1 = n1 % n2; 5014 } 5015 rettv->v_type = VAR_NUMBER; 5016 rettv->vval.v_number = n1; 5017 } 5018 } 5019 } 5020 5021 return OK; 5022 } 5023 5024 /* 5025 * Handle sixth level expression: 5026 * number number constant 5027 * "string" string constant 5028 * 'string' literal string constant 5029 * &option-name option value 5030 * @r register contents 5031 * identifier variable value 5032 * function() function call 5033 * $VAR environment variable 5034 * (expression) nested expression 5035 * [expr, expr] List 5036 * {key: val, key: val} Dictionary 5037 * 5038 * Also handle: 5039 * ! in front logical NOT 5040 * - in front unary minus 5041 * + in front unary plus (ignored) 5042 * trailing [] subscript in String or List 5043 * trailing .name entry in Dictionary 5044 * 5045 * "arg" must point to the first non-white of the expression. 5046 * "arg" is advanced to the next non-white after the recognized expression. 5047 * 5048 * Return OK or FAIL. 5049 */ 5050 static int 5051 eval7( 5052 char_u **arg, 5053 typval_T *rettv, 5054 int evaluate, 5055 int want_string UNUSED) /* after "." operator */ 5056 { 5057 long n; 5058 int len; 5059 char_u *s; 5060 char_u *start_leader, *end_leader; 5061 int ret = OK; 5062 char_u *alias; 5063 5064 /* 5065 * Initialise variable so that clear_tv() can't mistake this for a 5066 * string and free a string that isn't there. 5067 */ 5068 rettv->v_type = VAR_UNKNOWN; 5069 5070 /* 5071 * Skip '!' and '-' characters. They are handled later. 5072 */ 5073 start_leader = *arg; 5074 while (**arg == '!' || **arg == '-' || **arg == '+') 5075 *arg = skipwhite(*arg + 1); 5076 end_leader = *arg; 5077 5078 switch (**arg) 5079 { 5080 /* 5081 * Number constant. 5082 */ 5083 case '0': 5084 case '1': 5085 case '2': 5086 case '3': 5087 case '4': 5088 case '5': 5089 case '6': 5090 case '7': 5091 case '8': 5092 case '9': 5093 { 5094 #ifdef FEAT_FLOAT 5095 char_u *p = skipdigits(*arg + 1); 5096 int get_float = FALSE; 5097 5098 /* We accept a float when the format matches 5099 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 5100 * strict to avoid backwards compatibility problems. 5101 * Don't look for a float after the "." operator, so that 5102 * ":let vers = 1.2.3" doesn't fail. */ 5103 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 5104 { 5105 get_float = TRUE; 5106 p = skipdigits(p + 2); 5107 if (*p == 'e' || *p == 'E') 5108 { 5109 ++p; 5110 if (*p == '-' || *p == '+') 5111 ++p; 5112 if (!vim_isdigit(*p)) 5113 get_float = FALSE; 5114 else 5115 p = skipdigits(p + 1); 5116 } 5117 if (ASCII_ISALPHA(*p) || *p == '.') 5118 get_float = FALSE; 5119 } 5120 if (get_float) 5121 { 5122 float_T f; 5123 5124 *arg += string2float(*arg, &f); 5125 if (evaluate) 5126 { 5127 rettv->v_type = VAR_FLOAT; 5128 rettv->vval.v_float = f; 5129 } 5130 } 5131 else 5132 #endif 5133 { 5134 vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0); 5135 *arg += len; 5136 if (evaluate) 5137 { 5138 rettv->v_type = VAR_NUMBER; 5139 rettv->vval.v_number = n; 5140 } 5141 } 5142 break; 5143 } 5144 5145 /* 5146 * String constant: "string". 5147 */ 5148 case '"': ret = get_string_tv(arg, rettv, evaluate); 5149 break; 5150 5151 /* 5152 * Literal string constant: 'str''ing'. 5153 */ 5154 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 5155 break; 5156 5157 /* 5158 * List: [expr, expr] 5159 */ 5160 case '[': ret = get_list_tv(arg, rettv, evaluate); 5161 break; 5162 5163 /* 5164 * Dictionary: {key: val, key: val} 5165 */ 5166 case '{': ret = get_dict_tv(arg, rettv, evaluate); 5167 break; 5168 5169 /* 5170 * Option value: &name 5171 */ 5172 case '&': ret = get_option_tv(arg, rettv, evaluate); 5173 break; 5174 5175 /* 5176 * Environment variable: $VAR. 5177 */ 5178 case '$': ret = get_env_tv(arg, rettv, evaluate); 5179 break; 5180 5181 /* 5182 * Register contents: @r. 5183 */ 5184 case '@': ++*arg; 5185 if (evaluate) 5186 { 5187 rettv->v_type = VAR_STRING; 5188 rettv->vval.v_string = get_reg_contents(**arg, 5189 GREG_EXPR_SRC); 5190 } 5191 if (**arg != NUL) 5192 ++*arg; 5193 break; 5194 5195 /* 5196 * nested expression: (expression). 5197 */ 5198 case '(': *arg = skipwhite(*arg + 1); 5199 ret = eval1(arg, rettv, evaluate); /* recursive! */ 5200 if (**arg == ')') 5201 ++*arg; 5202 else if (ret == OK) 5203 { 5204 EMSG(_("E110: Missing ')'")); 5205 clear_tv(rettv); 5206 ret = FAIL; 5207 } 5208 break; 5209 5210 default: ret = NOTDONE; 5211 break; 5212 } 5213 5214 if (ret == NOTDONE) 5215 { 5216 /* 5217 * Must be a variable or function name. 5218 * Can also be a curly-braces kind of name: {expr}. 5219 */ 5220 s = *arg; 5221 len = get_name_len(arg, &alias, evaluate, TRUE); 5222 if (alias != NULL) 5223 s = alias; 5224 5225 if (len <= 0) 5226 ret = FAIL; 5227 else 5228 { 5229 if (**arg == '(') /* recursive! */ 5230 { 5231 partial_T *partial; 5232 5233 /* If "s" is the name of a variable of type VAR_FUNC 5234 * use its contents. */ 5235 s = deref_func_name(s, &len, &partial, !evaluate); 5236 5237 /* Invoke the function. */ 5238 ret = get_func_tv(s, len, rettv, arg, 5239 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5240 &len, evaluate, partial, NULL); 5241 5242 /* If evaluate is FALSE rettv->v_type was not set in 5243 * get_func_tv, but it's needed in handle_subscript() to parse 5244 * what follows. So set it here. */ 5245 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') 5246 { 5247 rettv->vval.v_string = vim_strsave((char_u *)""); 5248 rettv->v_type = VAR_FUNC; 5249 } 5250 5251 /* Stop the expression evaluation when immediately 5252 * aborting on error, or when an interrupt occurred or 5253 * an exception was thrown but not caught. */ 5254 if (aborting()) 5255 { 5256 if (ret == OK) 5257 clear_tv(rettv); 5258 ret = FAIL; 5259 } 5260 } 5261 else if (evaluate) 5262 ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE); 5263 else 5264 ret = OK; 5265 } 5266 vim_free(alias); 5267 } 5268 5269 *arg = skipwhite(*arg); 5270 5271 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5272 * expr(expr). */ 5273 if (ret == OK) 5274 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5275 5276 /* 5277 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5278 */ 5279 if (ret == OK && evaluate && end_leader > start_leader) 5280 { 5281 int error = FALSE; 5282 int val = 0; 5283 #ifdef FEAT_FLOAT 5284 float_T f = 0.0; 5285 5286 if (rettv->v_type == VAR_FLOAT) 5287 f = rettv->vval.v_float; 5288 else 5289 #endif 5290 val = get_tv_number_chk(rettv, &error); 5291 if (error) 5292 { 5293 clear_tv(rettv); 5294 ret = FAIL; 5295 } 5296 else 5297 { 5298 while (end_leader > start_leader) 5299 { 5300 --end_leader; 5301 if (*end_leader == '!') 5302 { 5303 #ifdef FEAT_FLOAT 5304 if (rettv->v_type == VAR_FLOAT) 5305 f = !f; 5306 else 5307 #endif 5308 val = !val; 5309 } 5310 else if (*end_leader == '-') 5311 { 5312 #ifdef FEAT_FLOAT 5313 if (rettv->v_type == VAR_FLOAT) 5314 f = -f; 5315 else 5316 #endif 5317 val = -val; 5318 } 5319 } 5320 #ifdef FEAT_FLOAT 5321 if (rettv->v_type == VAR_FLOAT) 5322 { 5323 clear_tv(rettv); 5324 rettv->vval.v_float = f; 5325 } 5326 else 5327 #endif 5328 { 5329 clear_tv(rettv); 5330 rettv->v_type = VAR_NUMBER; 5331 rettv->vval.v_number = val; 5332 } 5333 } 5334 } 5335 5336 return ret; 5337 } 5338 5339 /* 5340 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5341 * "*arg" points to the '[' or '.'. 5342 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5343 */ 5344 static int 5345 eval_index( 5346 char_u **arg, 5347 typval_T *rettv, 5348 int evaluate, 5349 int verbose) /* give error messages */ 5350 { 5351 int empty1 = FALSE, empty2 = FALSE; 5352 typval_T var1, var2; 5353 long n1, n2 = 0; 5354 long len = -1; 5355 int range = FALSE; 5356 char_u *s; 5357 char_u *key = NULL; 5358 5359 switch (rettv->v_type) 5360 { 5361 case VAR_FUNC: 5362 case VAR_PARTIAL: 5363 if (verbose) 5364 EMSG(_("E695: Cannot index a Funcref")); 5365 return FAIL; 5366 case VAR_FLOAT: 5367 #ifdef FEAT_FLOAT 5368 if (verbose) 5369 EMSG(_(e_float_as_string)); 5370 return FAIL; 5371 #endif 5372 case VAR_SPECIAL: 5373 case VAR_JOB: 5374 case VAR_CHANNEL: 5375 if (verbose) 5376 EMSG(_("E909: Cannot index a special variable")); 5377 return FAIL; 5378 case VAR_UNKNOWN: 5379 if (evaluate) 5380 return FAIL; 5381 /* FALLTHROUGH */ 5382 5383 case VAR_STRING: 5384 case VAR_NUMBER: 5385 case VAR_LIST: 5386 case VAR_DICT: 5387 break; 5388 } 5389 5390 init_tv(&var1); 5391 init_tv(&var2); 5392 if (**arg == '.') 5393 { 5394 /* 5395 * dict.name 5396 */ 5397 key = *arg + 1; 5398 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5399 ; 5400 if (len == 0) 5401 return FAIL; 5402 *arg = skipwhite(key + len); 5403 } 5404 else 5405 { 5406 /* 5407 * something[idx] 5408 * 5409 * Get the (first) variable from inside the []. 5410 */ 5411 *arg = skipwhite(*arg + 1); 5412 if (**arg == ':') 5413 empty1 = TRUE; 5414 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5415 return FAIL; 5416 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5417 { 5418 /* not a number or string */ 5419 clear_tv(&var1); 5420 return FAIL; 5421 } 5422 5423 /* 5424 * Get the second variable from inside the [:]. 5425 */ 5426 if (**arg == ':') 5427 { 5428 range = TRUE; 5429 *arg = skipwhite(*arg + 1); 5430 if (**arg == ']') 5431 empty2 = TRUE; 5432 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5433 { 5434 if (!empty1) 5435 clear_tv(&var1); 5436 return FAIL; 5437 } 5438 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5439 { 5440 /* not a number or string */ 5441 if (!empty1) 5442 clear_tv(&var1); 5443 clear_tv(&var2); 5444 return FAIL; 5445 } 5446 } 5447 5448 /* Check for the ']'. */ 5449 if (**arg != ']') 5450 { 5451 if (verbose) 5452 EMSG(_(e_missbrac)); 5453 clear_tv(&var1); 5454 if (range) 5455 clear_tv(&var2); 5456 return FAIL; 5457 } 5458 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5459 } 5460 5461 if (evaluate) 5462 { 5463 n1 = 0; 5464 if (!empty1 && rettv->v_type != VAR_DICT) 5465 { 5466 n1 = get_tv_number(&var1); 5467 clear_tv(&var1); 5468 } 5469 if (range) 5470 { 5471 if (empty2) 5472 n2 = -1; 5473 else 5474 { 5475 n2 = get_tv_number(&var2); 5476 clear_tv(&var2); 5477 } 5478 } 5479 5480 switch (rettv->v_type) 5481 { 5482 case VAR_UNKNOWN: 5483 case VAR_FUNC: 5484 case VAR_PARTIAL: 5485 case VAR_FLOAT: 5486 case VAR_SPECIAL: 5487 case VAR_JOB: 5488 case VAR_CHANNEL: 5489 break; /* not evaluating, skipping over subscript */ 5490 5491 case VAR_NUMBER: 5492 case VAR_STRING: 5493 s = get_tv_string(rettv); 5494 len = (long)STRLEN(s); 5495 if (range) 5496 { 5497 /* The resulting variable is a substring. If the indexes 5498 * are out of range the result is empty. */ 5499 if (n1 < 0) 5500 { 5501 n1 = len + n1; 5502 if (n1 < 0) 5503 n1 = 0; 5504 } 5505 if (n2 < 0) 5506 n2 = len + n2; 5507 else if (n2 >= len) 5508 n2 = len; 5509 if (n1 >= len || n2 < 0 || n1 > n2) 5510 s = NULL; 5511 else 5512 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5513 } 5514 else 5515 { 5516 /* The resulting variable is a string of a single 5517 * character. If the index is too big or negative the 5518 * result is empty. */ 5519 if (n1 >= len || n1 < 0) 5520 s = NULL; 5521 else 5522 s = vim_strnsave(s + n1, 1); 5523 } 5524 clear_tv(rettv); 5525 rettv->v_type = VAR_STRING; 5526 rettv->vval.v_string = s; 5527 break; 5528 5529 case VAR_LIST: 5530 len = list_len(rettv->vval.v_list); 5531 if (n1 < 0) 5532 n1 = len + n1; 5533 if (!empty1 && (n1 < 0 || n1 >= len)) 5534 { 5535 /* For a range we allow invalid values and return an empty 5536 * list. A list index out of range is an error. */ 5537 if (!range) 5538 { 5539 if (verbose) 5540 EMSGN(_(e_listidx), n1); 5541 return FAIL; 5542 } 5543 n1 = len; 5544 } 5545 if (range) 5546 { 5547 list_T *l; 5548 listitem_T *item; 5549 5550 if (n2 < 0) 5551 n2 = len + n2; 5552 else if (n2 >= len) 5553 n2 = len - 1; 5554 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5555 n2 = -1; 5556 l = list_alloc(); 5557 if (l == NULL) 5558 return FAIL; 5559 for (item = list_find(rettv->vval.v_list, n1); 5560 n1 <= n2; ++n1) 5561 { 5562 if (list_append_tv(l, &item->li_tv) == FAIL) 5563 { 5564 list_free(l, TRUE); 5565 return FAIL; 5566 } 5567 item = item->li_next; 5568 } 5569 clear_tv(rettv); 5570 rettv->v_type = VAR_LIST; 5571 rettv->vval.v_list = l; 5572 ++l->lv_refcount; 5573 } 5574 else 5575 { 5576 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5577 clear_tv(rettv); 5578 *rettv = var1; 5579 } 5580 break; 5581 5582 case VAR_DICT: 5583 if (range) 5584 { 5585 if (verbose) 5586 EMSG(_(e_dictrange)); 5587 if (len == -1) 5588 clear_tv(&var1); 5589 return FAIL; 5590 } 5591 { 5592 dictitem_T *item; 5593 5594 if (len == -1) 5595 { 5596 key = get_tv_string(&var1); 5597 if (*key == NUL) 5598 { 5599 if (verbose) 5600 EMSG(_(e_emptykey)); 5601 clear_tv(&var1); 5602 return FAIL; 5603 } 5604 } 5605 5606 item = dict_find(rettv->vval.v_dict, key, (int)len); 5607 5608 if (item == NULL && verbose) 5609 EMSG2(_(e_dictkey), key); 5610 if (len == -1) 5611 clear_tv(&var1); 5612 if (item == NULL) 5613 return FAIL; 5614 5615 copy_tv(&item->di_tv, &var1); 5616 clear_tv(rettv); 5617 *rettv = var1; 5618 } 5619 break; 5620 } 5621 } 5622 5623 return OK; 5624 } 5625 5626 /* 5627 * Get an option value. 5628 * "arg" points to the '&' or '+' before the option name. 5629 * "arg" is advanced to character after the option name. 5630 * Return OK or FAIL. 5631 */ 5632 static int 5633 get_option_tv( 5634 char_u **arg, 5635 typval_T *rettv, /* when NULL, only check if option exists */ 5636 int evaluate) 5637 { 5638 char_u *option_end; 5639 long numval; 5640 char_u *stringval; 5641 int opt_type; 5642 int c; 5643 int working = (**arg == '+'); /* has("+option") */ 5644 int ret = OK; 5645 int opt_flags; 5646 5647 /* 5648 * Isolate the option name and find its value. 5649 */ 5650 option_end = find_option_end(arg, &opt_flags); 5651 if (option_end == NULL) 5652 { 5653 if (rettv != NULL) 5654 EMSG2(_("E112: Option name missing: %s"), *arg); 5655 return FAIL; 5656 } 5657 5658 if (!evaluate) 5659 { 5660 *arg = option_end; 5661 return OK; 5662 } 5663 5664 c = *option_end; 5665 *option_end = NUL; 5666 opt_type = get_option_value(*arg, &numval, 5667 rettv == NULL ? NULL : &stringval, opt_flags); 5668 5669 if (opt_type == -3) /* invalid name */ 5670 { 5671 if (rettv != NULL) 5672 EMSG2(_("E113: Unknown option: %s"), *arg); 5673 ret = FAIL; 5674 } 5675 else if (rettv != NULL) 5676 { 5677 if (opt_type == -2) /* hidden string option */ 5678 { 5679 rettv->v_type = VAR_STRING; 5680 rettv->vval.v_string = NULL; 5681 } 5682 else if (opt_type == -1) /* hidden number option */ 5683 { 5684 rettv->v_type = VAR_NUMBER; 5685 rettv->vval.v_number = 0; 5686 } 5687 else if (opt_type == 1) /* number option */ 5688 { 5689 rettv->v_type = VAR_NUMBER; 5690 rettv->vval.v_number = numval; 5691 } 5692 else /* string option */ 5693 { 5694 rettv->v_type = VAR_STRING; 5695 rettv->vval.v_string = stringval; 5696 } 5697 } 5698 else if (working && (opt_type == -2 || opt_type == -1)) 5699 ret = FAIL; 5700 5701 *option_end = c; /* put back for error messages */ 5702 *arg = option_end; 5703 5704 return ret; 5705 } 5706 5707 /* 5708 * Allocate a variable for a string constant. 5709 * Return OK or FAIL. 5710 */ 5711 static int 5712 get_string_tv(char_u **arg, typval_T *rettv, int evaluate) 5713 { 5714 char_u *p; 5715 char_u *name; 5716 int extra = 0; 5717 5718 /* 5719 * Find the end of the string, skipping backslashed characters. 5720 */ 5721 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5722 { 5723 if (*p == '\\' && p[1] != NUL) 5724 { 5725 ++p; 5726 /* A "\<x>" form occupies at least 4 characters, and produces up 5727 * to 6 characters: reserve space for 2 extra */ 5728 if (*p == '<') 5729 extra += 2; 5730 } 5731 } 5732 5733 if (*p != '"') 5734 { 5735 EMSG2(_("E114: Missing quote: %s"), *arg); 5736 return FAIL; 5737 } 5738 5739 /* If only parsing, set *arg and return here */ 5740 if (!evaluate) 5741 { 5742 *arg = p + 1; 5743 return OK; 5744 } 5745 5746 /* 5747 * Copy the string into allocated memory, handling backslashed 5748 * characters. 5749 */ 5750 name = alloc((unsigned)(p - *arg + extra)); 5751 if (name == NULL) 5752 return FAIL; 5753 rettv->v_type = VAR_STRING; 5754 rettv->vval.v_string = name; 5755 5756 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5757 { 5758 if (*p == '\\') 5759 { 5760 switch (*++p) 5761 { 5762 case 'b': *name++ = BS; ++p; break; 5763 case 'e': *name++ = ESC; ++p; break; 5764 case 'f': *name++ = FF; ++p; break; 5765 case 'n': *name++ = NL; ++p; break; 5766 case 'r': *name++ = CAR; ++p; break; 5767 case 't': *name++ = TAB; ++p; break; 5768 5769 case 'X': /* hex: "\x1", "\x12" */ 5770 case 'x': 5771 case 'u': /* Unicode: "\u0023" */ 5772 case 'U': 5773 if (vim_isxdigit(p[1])) 5774 { 5775 int n, nr; 5776 int c = toupper(*p); 5777 5778 if (c == 'X') 5779 n = 2; 5780 else if (*p == 'u') 5781 n = 4; 5782 else 5783 n = 8; 5784 nr = 0; 5785 while (--n >= 0 && vim_isxdigit(p[1])) 5786 { 5787 ++p; 5788 nr = (nr << 4) + hex2nr(*p); 5789 } 5790 ++p; 5791 #ifdef FEAT_MBYTE 5792 /* For "\u" store the number according to 5793 * 'encoding'. */ 5794 if (c != 'X') 5795 name += (*mb_char2bytes)(nr, name); 5796 else 5797 #endif 5798 *name++ = nr; 5799 } 5800 break; 5801 5802 /* octal: "\1", "\12", "\123" */ 5803 case '0': 5804 case '1': 5805 case '2': 5806 case '3': 5807 case '4': 5808 case '5': 5809 case '6': 5810 case '7': *name = *p++ - '0'; 5811 if (*p >= '0' && *p <= '7') 5812 { 5813 *name = (*name << 3) + *p++ - '0'; 5814 if (*p >= '0' && *p <= '7') 5815 *name = (*name << 3) + *p++ - '0'; 5816 } 5817 ++name; 5818 break; 5819 5820 /* Special key, e.g.: "\<C-W>" */ 5821 case '<': extra = trans_special(&p, name, TRUE); 5822 if (extra != 0) 5823 { 5824 name += extra; 5825 break; 5826 } 5827 /* FALLTHROUGH */ 5828 5829 default: MB_COPY_CHAR(p, name); 5830 break; 5831 } 5832 } 5833 else 5834 MB_COPY_CHAR(p, name); 5835 5836 } 5837 *name = NUL; 5838 *arg = p + 1; 5839 5840 return OK; 5841 } 5842 5843 /* 5844 * Allocate a variable for a 'str''ing' constant. 5845 * Return OK or FAIL. 5846 */ 5847 static int 5848 get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) 5849 { 5850 char_u *p; 5851 char_u *str; 5852 int reduce = 0; 5853 5854 /* 5855 * Find the end of the string, skipping ''. 5856 */ 5857 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5858 { 5859 if (*p == '\'') 5860 { 5861 if (p[1] != '\'') 5862 break; 5863 ++reduce; 5864 ++p; 5865 } 5866 } 5867 5868 if (*p != '\'') 5869 { 5870 EMSG2(_("E115: Missing quote: %s"), *arg); 5871 return FAIL; 5872 } 5873 5874 /* If only parsing return after setting "*arg" */ 5875 if (!evaluate) 5876 { 5877 *arg = p + 1; 5878 return OK; 5879 } 5880 5881 /* 5882 * Copy the string into allocated memory, handling '' to ' reduction. 5883 */ 5884 str = alloc((unsigned)((p - *arg) - reduce)); 5885 if (str == NULL) 5886 return FAIL; 5887 rettv->v_type = VAR_STRING; 5888 rettv->vval.v_string = str; 5889 5890 for (p = *arg + 1; *p != NUL; ) 5891 { 5892 if (*p == '\'') 5893 { 5894 if (p[1] != '\'') 5895 break; 5896 ++p; 5897 } 5898 MB_COPY_CHAR(p, str); 5899 } 5900 *str = NUL; 5901 *arg = p + 1; 5902 5903 return OK; 5904 } 5905 5906 /* 5907 * Allocate a variable for a List and fill it from "*arg". 5908 * Return OK or FAIL. 5909 */ 5910 static int 5911 get_list_tv(char_u **arg, typval_T *rettv, int evaluate) 5912 { 5913 list_T *l = NULL; 5914 typval_T tv; 5915 listitem_T *item; 5916 5917 if (evaluate) 5918 { 5919 l = list_alloc(); 5920 if (l == NULL) 5921 return FAIL; 5922 } 5923 5924 *arg = skipwhite(*arg + 1); 5925 while (**arg != ']' && **arg != NUL) 5926 { 5927 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5928 goto failret; 5929 if (evaluate) 5930 { 5931 item = listitem_alloc(); 5932 if (item != NULL) 5933 { 5934 item->li_tv = tv; 5935 item->li_tv.v_lock = 0; 5936 list_append(l, item); 5937 } 5938 else 5939 clear_tv(&tv); 5940 } 5941 5942 if (**arg == ']') 5943 break; 5944 if (**arg != ',') 5945 { 5946 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5947 goto failret; 5948 } 5949 *arg = skipwhite(*arg + 1); 5950 } 5951 5952 if (**arg != ']') 5953 { 5954 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5955 failret: 5956 if (evaluate) 5957 list_free(l, TRUE); 5958 return FAIL; 5959 } 5960 5961 *arg = skipwhite(*arg + 1); 5962 if (evaluate) 5963 { 5964 rettv->v_type = VAR_LIST; 5965 rettv->vval.v_list = l; 5966 ++l->lv_refcount; 5967 } 5968 5969 return OK; 5970 } 5971 5972 /* 5973 * Allocate an empty header for a list. 5974 * Caller should take care of the reference count. 5975 */ 5976 list_T * 5977 list_alloc(void) 5978 { 5979 list_T *l; 5980 5981 l = (list_T *)alloc_clear(sizeof(list_T)); 5982 if (l != NULL) 5983 { 5984 /* Prepend the list to the list of lists for garbage collection. */ 5985 if (first_list != NULL) 5986 first_list->lv_used_prev = l; 5987 l->lv_used_prev = NULL; 5988 l->lv_used_next = first_list; 5989 first_list = l; 5990 } 5991 return l; 5992 } 5993 5994 /* 5995 * Allocate an empty list for a return value. 5996 * Returns OK or FAIL. 5997 */ 5998 int 5999 rettv_list_alloc(typval_T *rettv) 6000 { 6001 list_T *l = list_alloc(); 6002 6003 if (l == NULL) 6004 return FAIL; 6005 6006 rettv->vval.v_list = l; 6007 rettv->v_type = VAR_LIST; 6008 ++l->lv_refcount; 6009 return OK; 6010 } 6011 6012 /* 6013 * Unreference a list: decrement the reference count and free it when it 6014 * becomes zero. 6015 */ 6016 void 6017 list_unref(list_T *l) 6018 { 6019 if (l != NULL && --l->lv_refcount <= 0) 6020 list_free(l, TRUE); 6021 } 6022 6023 /* 6024 * Free a list, including all non-container items it points to. 6025 * Ignores the reference count. 6026 */ 6027 void 6028 list_free( 6029 list_T *l, 6030 int recurse) /* Free Lists and Dictionaries recursively. */ 6031 { 6032 listitem_T *item; 6033 6034 /* Remove the list from the list of lists for garbage collection. */ 6035 if (l->lv_used_prev == NULL) 6036 first_list = l->lv_used_next; 6037 else 6038 l->lv_used_prev->lv_used_next = l->lv_used_next; 6039 if (l->lv_used_next != NULL) 6040 l->lv_used_next->lv_used_prev = l->lv_used_prev; 6041 6042 for (item = l->lv_first; item != NULL; item = l->lv_first) 6043 { 6044 /* Remove the item before deleting it. */ 6045 l->lv_first = item->li_next; 6046 if (recurse || (item->li_tv.v_type != VAR_LIST 6047 && item->li_tv.v_type != VAR_DICT)) 6048 clear_tv(&item->li_tv); 6049 vim_free(item); 6050 } 6051 vim_free(l); 6052 } 6053 6054 /* 6055 * Allocate a list item. 6056 * It is not initialized, don't forget to set v_lock. 6057 */ 6058 listitem_T * 6059 listitem_alloc(void) 6060 { 6061 return (listitem_T *)alloc(sizeof(listitem_T)); 6062 } 6063 6064 /* 6065 * Free a list item. Also clears the value. Does not notify watchers. 6066 */ 6067 void 6068 listitem_free(listitem_T *item) 6069 { 6070 clear_tv(&item->li_tv); 6071 vim_free(item); 6072 } 6073 6074 /* 6075 * Remove a list item from a List and free it. Also clears the value. 6076 */ 6077 void 6078 listitem_remove(list_T *l, listitem_T *item) 6079 { 6080 vimlist_remove(l, item, item); 6081 listitem_free(item); 6082 } 6083 6084 /* 6085 * Get the number of items in a list. 6086 */ 6087 static long 6088 list_len(list_T *l) 6089 { 6090 if (l == NULL) 6091 return 0L; 6092 return l->lv_len; 6093 } 6094 6095 /* 6096 * Return TRUE when two lists have exactly the same values. 6097 */ 6098 static int 6099 list_equal( 6100 list_T *l1, 6101 list_T *l2, 6102 int ic, /* ignore case for strings */ 6103 int recursive) /* TRUE when used recursively */ 6104 { 6105 listitem_T *item1, *item2; 6106 6107 if (l1 == NULL || l2 == NULL) 6108 return FALSE; 6109 if (l1 == l2) 6110 return TRUE; 6111 if (list_len(l1) != list_len(l2)) 6112 return FALSE; 6113 6114 for (item1 = l1->lv_first, item2 = l2->lv_first; 6115 item1 != NULL && item2 != NULL; 6116 item1 = item1->li_next, item2 = item2->li_next) 6117 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) 6118 return FALSE; 6119 return item1 == NULL && item2 == NULL; 6120 } 6121 6122 /* 6123 * Return the dictitem that an entry in a hashtable points to. 6124 */ 6125 dictitem_T * 6126 dict_lookup(hashitem_T *hi) 6127 { 6128 return HI2DI(hi); 6129 } 6130 6131 /* 6132 * Return TRUE when two dictionaries have exactly the same key/values. 6133 */ 6134 static int 6135 dict_equal( 6136 dict_T *d1, 6137 dict_T *d2, 6138 int ic, /* ignore case for strings */ 6139 int recursive) /* TRUE when used recursively */ 6140 { 6141 hashitem_T *hi; 6142 dictitem_T *item2; 6143 int todo; 6144 6145 if (d1 == NULL || d2 == NULL) 6146 return FALSE; 6147 if (d1 == d2) 6148 return TRUE; 6149 if (dict_len(d1) != dict_len(d2)) 6150 return FALSE; 6151 6152 todo = (int)d1->dv_hashtab.ht_used; 6153 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 6154 { 6155 if (!HASHITEM_EMPTY(hi)) 6156 { 6157 item2 = dict_find(d2, hi->hi_key, -1); 6158 if (item2 == NULL) 6159 return FALSE; 6160 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive)) 6161 return FALSE; 6162 --todo; 6163 } 6164 } 6165 return TRUE; 6166 } 6167 6168 static int tv_equal_recurse_limit; 6169 6170 /* 6171 * Return TRUE if "tv1" and "tv2" have the same value. 6172 * Compares the items just like "==" would compare them, but strings and 6173 * numbers are different. Floats and numbers are also different. 6174 */ 6175 static int 6176 tv_equal( 6177 typval_T *tv1, 6178 typval_T *tv2, 6179 int ic, /* ignore case */ 6180 int recursive) /* TRUE when used recursively */ 6181 { 6182 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 6183 char_u *s1, *s2; 6184 static int recursive_cnt = 0; /* catch recursive loops */ 6185 int r; 6186 6187 /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ 6188 if ((tv1->v_type == VAR_FUNC 6189 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) 6190 && (tv2->v_type == VAR_FUNC 6191 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) 6192 { 6193 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string 6194 : tv1->vval.v_partial->pt_name; 6195 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string 6196 : tv2->vval.v_partial->pt_name; 6197 return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0); 6198 } 6199 6200 if (tv1->v_type != tv2->v_type) 6201 return FALSE; 6202 6203 /* Catch lists and dicts that have an endless loop by limiting 6204 * recursiveness to a limit. We guess they are equal then. 6205 * A fixed limit has the problem of still taking an awful long time. 6206 * Reduce the limit every time running into it. That should work fine for 6207 * deeply linked structures that are not recursively linked and catch 6208 * recursiveness quickly. */ 6209 if (!recursive) 6210 tv_equal_recurse_limit = 1000; 6211 if (recursive_cnt >= tv_equal_recurse_limit) 6212 { 6213 --tv_equal_recurse_limit; 6214 return TRUE; 6215 } 6216 6217 switch (tv1->v_type) 6218 { 6219 case VAR_LIST: 6220 ++recursive_cnt; 6221 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); 6222 --recursive_cnt; 6223 return r; 6224 6225 case VAR_DICT: 6226 ++recursive_cnt; 6227 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE); 6228 --recursive_cnt; 6229 return r; 6230 6231 case VAR_NUMBER: 6232 return tv1->vval.v_number == tv2->vval.v_number; 6233 6234 case VAR_STRING: 6235 s1 = get_tv_string_buf(tv1, buf1); 6236 s2 = get_tv_string_buf(tv2, buf2); 6237 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 6238 6239 case VAR_SPECIAL: 6240 return tv1->vval.v_number == tv2->vval.v_number; 6241 6242 case VAR_FLOAT: 6243 #ifdef FEAT_FLOAT 6244 return tv1->vval.v_float == tv2->vval.v_float; 6245 #endif 6246 case VAR_JOB: 6247 #ifdef FEAT_JOB_CHANNEL 6248 return tv1->vval.v_job == tv2->vval.v_job; 6249 #endif 6250 case VAR_CHANNEL: 6251 #ifdef FEAT_JOB_CHANNEL 6252 return tv1->vval.v_channel == tv2->vval.v_channel; 6253 #endif 6254 case VAR_FUNC: 6255 case VAR_PARTIAL: 6256 case VAR_UNKNOWN: 6257 break; 6258 } 6259 6260 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it 6261 * does not equal anything, not even itself. */ 6262 return FALSE; 6263 } 6264 6265 /* 6266 * Locate item with index "n" in list "l" and return it. 6267 * A negative index is counted from the end; -1 is the last item. 6268 * Returns NULL when "n" is out of range. 6269 */ 6270 listitem_T * 6271 list_find(list_T *l, long n) 6272 { 6273 listitem_T *item; 6274 long idx; 6275 6276 if (l == NULL) 6277 return NULL; 6278 6279 /* Negative index is relative to the end. */ 6280 if (n < 0) 6281 n = l->lv_len + n; 6282 6283 /* Check for index out of range. */ 6284 if (n < 0 || n >= l->lv_len) 6285 return NULL; 6286 6287 /* When there is a cached index may start search from there. */ 6288 if (l->lv_idx_item != NULL) 6289 { 6290 if (n < l->lv_idx / 2) 6291 { 6292 /* closest to the start of the list */ 6293 item = l->lv_first; 6294 idx = 0; 6295 } 6296 else if (n > (l->lv_idx + l->lv_len) / 2) 6297 { 6298 /* closest to the end of the list */ 6299 item = l->lv_last; 6300 idx = l->lv_len - 1; 6301 } 6302 else 6303 { 6304 /* closest to the cached index */ 6305 item = l->lv_idx_item; 6306 idx = l->lv_idx; 6307 } 6308 } 6309 else 6310 { 6311 if (n < l->lv_len / 2) 6312 { 6313 /* closest to the start of the list */ 6314 item = l->lv_first; 6315 idx = 0; 6316 } 6317 else 6318 { 6319 /* closest to the end of the list */ 6320 item = l->lv_last; 6321 idx = l->lv_len - 1; 6322 } 6323 } 6324 6325 while (n > idx) 6326 { 6327 /* search forward */ 6328 item = item->li_next; 6329 ++idx; 6330 } 6331 while (n < idx) 6332 { 6333 /* search backward */ 6334 item = item->li_prev; 6335 --idx; 6336 } 6337 6338 /* cache the used index */ 6339 l->lv_idx = idx; 6340 l->lv_idx_item = item; 6341 6342 return item; 6343 } 6344 6345 /* 6346 * Get list item "l[idx]" as a number. 6347 */ 6348 static long 6349 list_find_nr( 6350 list_T *l, 6351 long idx, 6352 int *errorp) /* set to TRUE when something wrong */ 6353 { 6354 listitem_T *li; 6355 6356 li = list_find(l, idx); 6357 if (li == NULL) 6358 { 6359 if (errorp != NULL) 6360 *errorp = TRUE; 6361 return -1L; 6362 } 6363 return get_tv_number_chk(&li->li_tv, errorp); 6364 } 6365 6366 /* 6367 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6368 */ 6369 char_u * 6370 list_find_str(list_T *l, long idx) 6371 { 6372 listitem_T *li; 6373 6374 li = list_find(l, idx - 1); 6375 if (li == NULL) 6376 { 6377 EMSGN(_(e_listidx), idx); 6378 return NULL; 6379 } 6380 return get_tv_string(&li->li_tv); 6381 } 6382 6383 /* 6384 * Locate "item" list "l" and return its index. 6385 * Returns -1 when "item" is not in the list. 6386 */ 6387 static long 6388 list_idx_of_item(list_T *l, listitem_T *item) 6389 { 6390 long idx = 0; 6391 listitem_T *li; 6392 6393 if (l == NULL) 6394 return -1; 6395 idx = 0; 6396 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6397 ++idx; 6398 if (li == NULL) 6399 return -1; 6400 return idx; 6401 } 6402 6403 /* 6404 * Append item "item" to the end of list "l". 6405 */ 6406 void 6407 list_append(list_T *l, listitem_T *item) 6408 { 6409 if (l->lv_last == NULL) 6410 { 6411 /* empty list */ 6412 l->lv_first = item; 6413 l->lv_last = item; 6414 item->li_prev = NULL; 6415 } 6416 else 6417 { 6418 l->lv_last->li_next = item; 6419 item->li_prev = l->lv_last; 6420 l->lv_last = item; 6421 } 6422 ++l->lv_len; 6423 item->li_next = NULL; 6424 } 6425 6426 /* 6427 * Append typval_T "tv" to the end of list "l". 6428 * Return FAIL when out of memory. 6429 */ 6430 int 6431 list_append_tv(list_T *l, typval_T *tv) 6432 { 6433 listitem_T *li = listitem_alloc(); 6434 6435 if (li == NULL) 6436 return FAIL; 6437 copy_tv(tv, &li->li_tv); 6438 list_append(l, li); 6439 return OK; 6440 } 6441 6442 /* 6443 * Add a dictionary to a list. Used by getqflist(). 6444 * Return FAIL when out of memory. 6445 */ 6446 int 6447 list_append_dict(list_T *list, dict_T *dict) 6448 { 6449 listitem_T *li = listitem_alloc(); 6450 6451 if (li == NULL) 6452 return FAIL; 6453 li->li_tv.v_type = VAR_DICT; 6454 li->li_tv.v_lock = 0; 6455 li->li_tv.vval.v_dict = dict; 6456 list_append(list, li); 6457 ++dict->dv_refcount; 6458 return OK; 6459 } 6460 6461 /* 6462 * Make a copy of "str" and append it as an item to list "l". 6463 * When "len" >= 0 use "str[len]". 6464 * Returns FAIL when out of memory. 6465 */ 6466 int 6467 list_append_string(list_T *l, char_u *str, int len) 6468 { 6469 listitem_T *li = listitem_alloc(); 6470 6471 if (li == NULL) 6472 return FAIL; 6473 list_append(l, li); 6474 li->li_tv.v_type = VAR_STRING; 6475 li->li_tv.v_lock = 0; 6476 if (str == NULL) 6477 li->li_tv.vval.v_string = NULL; 6478 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6479 : vim_strsave(str))) == NULL) 6480 return FAIL; 6481 return OK; 6482 } 6483 6484 /* 6485 * Append "n" to list "l". 6486 * Returns FAIL when out of memory. 6487 */ 6488 int 6489 list_append_number(list_T *l, varnumber_T n) 6490 { 6491 listitem_T *li; 6492 6493 li = listitem_alloc(); 6494 if (li == NULL) 6495 return FAIL; 6496 li->li_tv.v_type = VAR_NUMBER; 6497 li->li_tv.v_lock = 0; 6498 li->li_tv.vval.v_number = n; 6499 list_append(l, li); 6500 return OK; 6501 } 6502 6503 /* 6504 * Insert typval_T "tv" in list "l" before "item". 6505 * If "item" is NULL append at the end. 6506 * Return FAIL when out of memory. 6507 */ 6508 int 6509 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item) 6510 { 6511 listitem_T *ni = listitem_alloc(); 6512 6513 if (ni == NULL) 6514 return FAIL; 6515 copy_tv(tv, &ni->li_tv); 6516 list_insert(l, ni, item); 6517 return OK; 6518 } 6519 6520 void 6521 list_insert(list_T *l, listitem_T *ni, listitem_T *item) 6522 { 6523 if (item == NULL) 6524 /* Append new item at end of list. */ 6525 list_append(l, ni); 6526 else 6527 { 6528 /* Insert new item before existing item. */ 6529 ni->li_prev = item->li_prev; 6530 ni->li_next = item; 6531 if (item->li_prev == NULL) 6532 { 6533 l->lv_first = ni; 6534 ++l->lv_idx; 6535 } 6536 else 6537 { 6538 item->li_prev->li_next = ni; 6539 l->lv_idx_item = NULL; 6540 } 6541 item->li_prev = ni; 6542 ++l->lv_len; 6543 } 6544 } 6545 6546 /* 6547 * Extend "l1" with "l2". 6548 * If "bef" is NULL append at the end, otherwise insert before this item. 6549 * Returns FAIL when out of memory. 6550 */ 6551 static int 6552 list_extend(list_T *l1, list_T *l2, listitem_T *bef) 6553 { 6554 listitem_T *item; 6555 int todo = l2->lv_len; 6556 6557 /* We also quit the loop when we have inserted the original item count of 6558 * the list, avoid a hang when we extend a list with itself. */ 6559 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6560 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6561 return FAIL; 6562 return OK; 6563 } 6564 6565 /* 6566 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6567 * Return FAIL when out of memory. 6568 */ 6569 static int 6570 list_concat(list_T *l1, list_T *l2, typval_T *tv) 6571 { 6572 list_T *l; 6573 6574 if (l1 == NULL || l2 == NULL) 6575 return FAIL; 6576 6577 /* make a copy of the first list. */ 6578 l = list_copy(l1, FALSE, 0); 6579 if (l == NULL) 6580 return FAIL; 6581 tv->v_type = VAR_LIST; 6582 tv->vval.v_list = l; 6583 6584 /* append all items from the second list */ 6585 return list_extend(l, l2, NULL); 6586 } 6587 6588 /* 6589 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6590 * The refcount of the new list is set to 1. 6591 * See item_copy() for "copyID". 6592 * Returns NULL when out of memory. 6593 */ 6594 static list_T * 6595 list_copy(list_T *orig, int deep, int copyID) 6596 { 6597 list_T *copy; 6598 listitem_T *item; 6599 listitem_T *ni; 6600 6601 if (orig == NULL) 6602 return NULL; 6603 6604 copy = list_alloc(); 6605 if (copy != NULL) 6606 { 6607 if (copyID != 0) 6608 { 6609 /* Do this before adding the items, because one of the items may 6610 * refer back to this list. */ 6611 orig->lv_copyID = copyID; 6612 orig->lv_copylist = copy; 6613 } 6614 for (item = orig->lv_first; item != NULL && !got_int; 6615 item = item->li_next) 6616 { 6617 ni = listitem_alloc(); 6618 if (ni == NULL) 6619 break; 6620 if (deep) 6621 { 6622 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6623 { 6624 vim_free(ni); 6625 break; 6626 } 6627 } 6628 else 6629 copy_tv(&item->li_tv, &ni->li_tv); 6630 list_append(copy, ni); 6631 } 6632 ++copy->lv_refcount; 6633 if (item != NULL) 6634 { 6635 list_unref(copy); 6636 copy = NULL; 6637 } 6638 } 6639 6640 return copy; 6641 } 6642 6643 /* 6644 * Remove items "item" to "item2" from list "l". 6645 * Does not free the listitem or the value! 6646 * This used to be called list_remove, but that conflicts with a Sun header 6647 * file. 6648 */ 6649 void 6650 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2) 6651 { 6652 listitem_T *ip; 6653 6654 /* notify watchers */ 6655 for (ip = item; ip != NULL; ip = ip->li_next) 6656 { 6657 --l->lv_len; 6658 list_fix_watch(l, ip); 6659 if (ip == item2) 6660 break; 6661 } 6662 6663 if (item2->li_next == NULL) 6664 l->lv_last = item->li_prev; 6665 else 6666 item2->li_next->li_prev = item->li_prev; 6667 if (item->li_prev == NULL) 6668 l->lv_first = item2->li_next; 6669 else 6670 item->li_prev->li_next = item2->li_next; 6671 l->lv_idx_item = NULL; 6672 } 6673 6674 /* 6675 * Return an allocated string with the string representation of a list. 6676 * May return NULL. 6677 */ 6678 static char_u * 6679 list2string(typval_T *tv, int copyID) 6680 { 6681 garray_T ga; 6682 6683 if (tv->vval.v_list == NULL) 6684 return NULL; 6685 ga_init2(&ga, (int)sizeof(char), 80); 6686 ga_append(&ga, '['); 6687 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6688 { 6689 vim_free(ga.ga_data); 6690 return NULL; 6691 } 6692 ga_append(&ga, ']'); 6693 ga_append(&ga, NUL); 6694 return (char_u *)ga.ga_data; 6695 } 6696 6697 typedef struct join_S { 6698 char_u *s; 6699 char_u *tofree; 6700 } join_T; 6701 6702 static int 6703 list_join_inner( 6704 garray_T *gap, /* to store the result in */ 6705 list_T *l, 6706 char_u *sep, 6707 int echo_style, 6708 int copyID, 6709 garray_T *join_gap) /* to keep each list item string */ 6710 { 6711 int i; 6712 join_T *p; 6713 int len; 6714 int sumlen = 0; 6715 int first = TRUE; 6716 char_u *tofree; 6717 char_u numbuf[NUMBUFLEN]; 6718 listitem_T *item; 6719 char_u *s; 6720 6721 /* Stringify each item in the list. */ 6722 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6723 { 6724 if (echo_style) 6725 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6726 else 6727 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6728 if (s == NULL) 6729 return FAIL; 6730 6731 len = (int)STRLEN(s); 6732 sumlen += len; 6733 6734 (void)ga_grow(join_gap, 1); 6735 p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++); 6736 if (tofree != NULL || s != numbuf) 6737 { 6738 p->s = s; 6739 p->tofree = tofree; 6740 } 6741 else 6742 { 6743 p->s = vim_strnsave(s, len); 6744 p->tofree = p->s; 6745 } 6746 6747 line_breakcheck(); 6748 if (did_echo_string_emsg) /* recursion error, bail out */ 6749 break; 6750 } 6751 6752 /* Allocate result buffer with its total size, avoid re-allocation and 6753 * multiple copy operations. Add 2 for a tailing ']' and NUL. */ 6754 if (join_gap->ga_len >= 2) 6755 sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1); 6756 if (ga_grow(gap, sumlen + 2) == FAIL) 6757 return FAIL; 6758 6759 for (i = 0; i < join_gap->ga_len && !got_int; ++i) 6760 { 6761 if (first) 6762 first = FALSE; 6763 else 6764 ga_concat(gap, sep); 6765 p = ((join_T *)join_gap->ga_data) + i; 6766 6767 if (p->s != NULL) 6768 ga_concat(gap, p->s); 6769 line_breakcheck(); 6770 } 6771 6772 return OK; 6773 } 6774 6775 /* 6776 * Join list "l" into a string in "*gap", using separator "sep". 6777 * When "echo_style" is TRUE use String as echoed, otherwise as inside a List. 6778 * Return FAIL or OK. 6779 */ 6780 static int 6781 list_join( 6782 garray_T *gap, 6783 list_T *l, 6784 char_u *sep, 6785 int echo_style, 6786 int copyID) 6787 { 6788 garray_T join_ga; 6789 int retval; 6790 join_T *p; 6791 int i; 6792 6793 if (l->lv_len < 1) 6794 return OK; /* nothing to do */ 6795 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); 6796 retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga); 6797 6798 /* Dispose each item in join_ga. */ 6799 if (join_ga.ga_data != NULL) 6800 { 6801 p = (join_T *)join_ga.ga_data; 6802 for (i = 0; i < join_ga.ga_len; ++i) 6803 { 6804 vim_free(p->tofree); 6805 ++p; 6806 } 6807 ga_clear(&join_ga); 6808 } 6809 6810 return retval; 6811 } 6812 6813 /* 6814 * Return the next (unique) copy ID. 6815 * Used for serializing nested structures. 6816 */ 6817 int 6818 get_copyID(void) 6819 { 6820 current_copyID += COPYID_INC; 6821 return current_copyID; 6822 } 6823 6824 /* 6825 * Garbage collection for lists and dictionaries. 6826 * 6827 * We use reference counts to be able to free most items right away when they 6828 * are no longer used. But for composite items it's possible that it becomes 6829 * unused while the reference count is > 0: When there is a recursive 6830 * reference. Example: 6831 * :let l = [1, 2, 3] 6832 * :let d = {9: l} 6833 * :let l[1] = d 6834 * 6835 * Since this is quite unusual we handle this with garbage collection: every 6836 * once in a while find out which lists and dicts are not referenced from any 6837 * variable. 6838 * 6839 * Here is a good reference text about garbage collection (refers to Python 6840 * but it applies to all reference-counting mechanisms): 6841 * http://python.ca/nas/python/gc/ 6842 */ 6843 6844 /* 6845 * Do garbage collection for lists and dicts. 6846 * Return TRUE if some memory was freed. 6847 */ 6848 int 6849 garbage_collect(void) 6850 { 6851 int copyID; 6852 int abort = FALSE; 6853 buf_T *buf; 6854 win_T *wp; 6855 int i; 6856 funccall_T *fc, **pfc; 6857 int did_free = FALSE; 6858 int did_free_funccal = FALSE; 6859 #ifdef FEAT_WINDOWS 6860 tabpage_T *tp; 6861 #endif 6862 6863 /* Only do this once. */ 6864 want_garbage_collect = FALSE; 6865 may_garbage_collect = FALSE; 6866 garbage_collect_at_exit = FALSE; 6867 6868 /* We advance by two because we add one for items referenced through 6869 * previous_funccal. */ 6870 copyID = get_copyID(); 6871 6872 /* 6873 * 1. Go through all accessible variables and mark all lists and dicts 6874 * with copyID. 6875 */ 6876 6877 /* Don't free variables in the previous_funccal list unless they are only 6878 * referenced through previous_funccal. This must be first, because if 6879 * the item is referenced elsewhere the funccal must not be freed. */ 6880 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6881 { 6882 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, 6883 NULL); 6884 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, 6885 NULL); 6886 } 6887 6888 /* script-local variables */ 6889 for (i = 1; i <= ga_scripts.ga_len; ++i) 6890 abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); 6891 6892 /* buffer-local variables */ 6893 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6894 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID, 6895 NULL, NULL); 6896 6897 /* window-local variables */ 6898 FOR_ALL_TAB_WINDOWS(tp, wp) 6899 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, 6900 NULL, NULL); 6901 #ifdef FEAT_AUTOCMD 6902 if (aucmd_win != NULL) 6903 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID, 6904 NULL, NULL); 6905 #endif 6906 6907 #ifdef FEAT_WINDOWS 6908 /* tabpage-local variables */ 6909 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6910 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID, 6911 NULL, NULL); 6912 #endif 6913 6914 /* global variables */ 6915 abort = abort || set_ref_in_ht(&globvarht, copyID, NULL); 6916 6917 /* function-local variables */ 6918 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6919 { 6920 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL); 6921 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL); 6922 } 6923 6924 /* v: vars */ 6925 abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL); 6926 6927 #ifdef FEAT_LUA 6928 abort = abort || set_ref_in_lua(copyID); 6929 #endif 6930 6931 #ifdef FEAT_PYTHON 6932 abort = abort || set_ref_in_python(copyID); 6933 #endif 6934 6935 #ifdef FEAT_PYTHON3 6936 abort = abort || set_ref_in_python3(copyID); 6937 #endif 6938 6939 #ifdef FEAT_JOB_CHANNEL 6940 abort = abort || set_ref_in_channel(copyID); 6941 #endif 6942 6943 if (!abort) 6944 { 6945 /* 6946 * 2. Free lists and dictionaries that are not referenced. 6947 */ 6948 did_free = free_unref_items(copyID); 6949 6950 /* 6951 * 3. Check if any funccal can be freed now. 6952 */ 6953 for (pfc = &previous_funccal; *pfc != NULL; ) 6954 { 6955 if (can_free_funccal(*pfc, copyID)) 6956 { 6957 fc = *pfc; 6958 *pfc = fc->caller; 6959 free_funccal(fc, TRUE); 6960 did_free = TRUE; 6961 did_free_funccal = TRUE; 6962 } 6963 else 6964 pfc = &(*pfc)->caller; 6965 } 6966 if (did_free_funccal) 6967 /* When a funccal was freed some more items might be garbage 6968 * collected, so run again. */ 6969 (void)garbage_collect(); 6970 } 6971 else if (p_verbose > 0) 6972 { 6973 verb_msg((char_u *)_("Not enough memory to set references, garbage collection aborted!")); 6974 } 6975 6976 return did_free; 6977 } 6978 6979 /* 6980 * Free lists, dictionaries and jobs that are no longer referenced. 6981 */ 6982 static int 6983 free_unref_items(int copyID) 6984 { 6985 dict_T *dd, *dd_next; 6986 list_T *ll, *ll_next; 6987 int did_free = FALSE; 6988 6989 /* 6990 * Go through the list of dicts and free items without the copyID. 6991 */ 6992 for (dd = first_dict; dd != NULL; ) 6993 { 6994 dd_next = dd->dv_used_next; 6995 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 6996 { 6997 /* Free the Dictionary and ordinary items it contains, but don't 6998 * recurse into Lists and Dictionaries, they will be in the list 6999 * of dicts or list of lists. */ 7000 dict_free(dd, FALSE); 7001 did_free = TRUE; 7002 } 7003 dd = dd_next; 7004 } 7005 7006 /* 7007 * Go through the list of lists and free items without the copyID. 7008 * But don't free a list that has a watcher (used in a for loop), these 7009 * are not referenced anywhere. 7010 */ 7011 for (ll = first_list; ll != NULL; ) 7012 { 7013 ll_next = ll->lv_used_next; 7014 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 7015 && ll->lv_watch == NULL) 7016 { 7017 /* Free the List and ordinary items it contains, but don't recurse 7018 * into Lists and Dictionaries, they will be in the list of dicts 7019 * or list of lists. */ 7020 list_free(ll, FALSE); 7021 did_free = TRUE; 7022 } 7023 ll = ll_next; 7024 } 7025 7026 return did_free; 7027 } 7028 7029 /* 7030 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 7031 * "list_stack" is used to add lists to be marked. Can be NULL. 7032 * 7033 * Returns TRUE if setting references failed somehow. 7034 */ 7035 int 7036 set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack) 7037 { 7038 int todo; 7039 int abort = FALSE; 7040 hashitem_T *hi; 7041 hashtab_T *cur_ht; 7042 ht_stack_T *ht_stack = NULL; 7043 ht_stack_T *tempitem; 7044 7045 cur_ht = ht; 7046 for (;;) 7047 { 7048 if (!abort) 7049 { 7050 /* Mark each item in the hashtab. If the item contains a hashtab 7051 * it is added to ht_stack, if it contains a list it is added to 7052 * list_stack. */ 7053 todo = (int)cur_ht->ht_used; 7054 for (hi = cur_ht->ht_array; todo > 0; ++hi) 7055 if (!HASHITEM_EMPTY(hi)) 7056 { 7057 --todo; 7058 abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID, 7059 &ht_stack, list_stack); 7060 } 7061 } 7062 7063 if (ht_stack == NULL) 7064 break; 7065 7066 /* take an item from the stack */ 7067 cur_ht = ht_stack->ht; 7068 tempitem = ht_stack; 7069 ht_stack = ht_stack->prev; 7070 free(tempitem); 7071 } 7072 7073 return abort; 7074 } 7075 7076 /* 7077 * Mark all lists and dicts referenced through list "l" with "copyID". 7078 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 7079 * 7080 * Returns TRUE if setting references failed somehow. 7081 */ 7082 int 7083 set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack) 7084 { 7085 listitem_T *li; 7086 int abort = FALSE; 7087 list_T *cur_l; 7088 list_stack_T *list_stack = NULL; 7089 list_stack_T *tempitem; 7090 7091 cur_l = l; 7092 for (;;) 7093 { 7094 if (!abort) 7095 /* Mark each item in the list. If the item contains a hashtab 7096 * it is added to ht_stack, if it contains a list it is added to 7097 * list_stack. */ 7098 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next) 7099 abort = abort || set_ref_in_item(&li->li_tv, copyID, 7100 ht_stack, &list_stack); 7101 if (list_stack == NULL) 7102 break; 7103 7104 /* take an item from the stack */ 7105 cur_l = list_stack->list; 7106 tempitem = list_stack; 7107 list_stack = list_stack->prev; 7108 free(tempitem); 7109 } 7110 7111 return abort; 7112 } 7113 7114 /* 7115 * Mark all lists and dicts referenced through typval "tv" with "copyID". 7116 * "list_stack" is used to add lists to be marked. Can be NULL. 7117 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 7118 * 7119 * Returns TRUE if setting references failed somehow. 7120 */ 7121 int 7122 set_ref_in_item( 7123 typval_T *tv, 7124 int copyID, 7125 ht_stack_T **ht_stack, 7126 list_stack_T **list_stack) 7127 { 7128 dict_T *dd; 7129 list_T *ll; 7130 int abort = FALSE; 7131 7132 if (tv->v_type == VAR_DICT) 7133 { 7134 dd = tv->vval.v_dict; 7135 if (dd != NULL && dd->dv_copyID != copyID) 7136 { 7137 /* Didn't see this dict yet. */ 7138 dd->dv_copyID = copyID; 7139 if (ht_stack == NULL) 7140 { 7141 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); 7142 } 7143 else 7144 { 7145 ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T)); 7146 if (newitem == NULL) 7147 abort = TRUE; 7148 else 7149 { 7150 newitem->ht = &dd->dv_hashtab; 7151 newitem->prev = *ht_stack; 7152 *ht_stack = newitem; 7153 } 7154 } 7155 } 7156 } 7157 else if (tv->v_type == VAR_LIST) 7158 { 7159 ll = tv->vval.v_list; 7160 if (ll != NULL && ll->lv_copyID != copyID) 7161 { 7162 /* Didn't see this list yet. */ 7163 ll->lv_copyID = copyID; 7164 if (list_stack == NULL) 7165 { 7166 abort = set_ref_in_list(ll, copyID, ht_stack); 7167 } 7168 else 7169 { 7170 list_stack_T *newitem = (list_stack_T*)malloc( 7171 sizeof(list_stack_T)); 7172 if (newitem == NULL) 7173 abort = TRUE; 7174 else 7175 { 7176 newitem->list = ll; 7177 newitem->prev = *list_stack; 7178 *list_stack = newitem; 7179 } 7180 } 7181 } 7182 } 7183 return abort; 7184 } 7185 7186 /* 7187 * Allocate an empty header for a dictionary. 7188 */ 7189 dict_T * 7190 dict_alloc(void) 7191 { 7192 dict_T *d; 7193 7194 d = (dict_T *)alloc(sizeof(dict_T)); 7195 if (d != NULL) 7196 { 7197 /* Add the dict to the list of dicts for garbage collection. */ 7198 if (first_dict != NULL) 7199 first_dict->dv_used_prev = d; 7200 d->dv_used_next = first_dict; 7201 d->dv_used_prev = NULL; 7202 first_dict = d; 7203 7204 hash_init(&d->dv_hashtab); 7205 d->dv_lock = 0; 7206 d->dv_scope = 0; 7207 d->dv_refcount = 0; 7208 d->dv_copyID = 0; 7209 } 7210 return d; 7211 } 7212 7213 /* 7214 * Allocate an empty dict for a return value. 7215 * Returns OK or FAIL. 7216 */ 7217 int 7218 rettv_dict_alloc(typval_T *rettv) 7219 { 7220 dict_T *d = dict_alloc(); 7221 7222 if (d == NULL) 7223 return FAIL; 7224 7225 rettv->vval.v_dict = d; 7226 rettv->v_type = VAR_DICT; 7227 ++d->dv_refcount; 7228 return OK; 7229 } 7230 7231 7232 /* 7233 * Unreference a Dictionary: decrement the reference count and free it when it 7234 * becomes zero. 7235 */ 7236 void 7237 dict_unref(dict_T *d) 7238 { 7239 if (d != NULL && --d->dv_refcount <= 0) 7240 dict_free(d, TRUE); 7241 } 7242 7243 /* 7244 * Free a Dictionary, including all non-container items it contains. 7245 * Ignores the reference count. 7246 */ 7247 void 7248 dict_free( 7249 dict_T *d, 7250 int recurse) /* Free Lists and Dictionaries recursively. */ 7251 { 7252 int todo; 7253 hashitem_T *hi; 7254 dictitem_T *di; 7255 7256 /* Remove the dict from the list of dicts for garbage collection. */ 7257 if (d->dv_used_prev == NULL) 7258 first_dict = d->dv_used_next; 7259 else 7260 d->dv_used_prev->dv_used_next = d->dv_used_next; 7261 if (d->dv_used_next != NULL) 7262 d->dv_used_next->dv_used_prev = d->dv_used_prev; 7263 7264 /* Lock the hashtab, we don't want it to resize while freeing items. */ 7265 hash_lock(&d->dv_hashtab); 7266 todo = (int)d->dv_hashtab.ht_used; 7267 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 7268 { 7269 if (!HASHITEM_EMPTY(hi)) 7270 { 7271 /* Remove the item before deleting it, just in case there is 7272 * something recursive causing trouble. */ 7273 di = HI2DI(hi); 7274 hash_remove(&d->dv_hashtab, hi); 7275 if (recurse || (di->di_tv.v_type != VAR_LIST 7276 && di->di_tv.v_type != VAR_DICT)) 7277 clear_tv(&di->di_tv); 7278 vim_free(di); 7279 --todo; 7280 } 7281 } 7282 hash_clear(&d->dv_hashtab); 7283 vim_free(d); 7284 } 7285 7286 /* 7287 * Allocate a Dictionary item. 7288 * The "key" is copied to the new item. 7289 * Note that the value of the item "di_tv" still needs to be initialized! 7290 * Returns NULL when out of memory. 7291 */ 7292 dictitem_T * 7293 dictitem_alloc(char_u *key) 7294 { 7295 dictitem_T *di; 7296 7297 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 7298 if (di != NULL) 7299 { 7300 STRCPY(di->di_key, key); 7301 di->di_flags = DI_FLAGS_ALLOC; 7302 } 7303 return di; 7304 } 7305 7306 /* 7307 * Make a copy of a Dictionary item. 7308 */ 7309 static dictitem_T * 7310 dictitem_copy(dictitem_T *org) 7311 { 7312 dictitem_T *di; 7313 7314 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 7315 + STRLEN(org->di_key))); 7316 if (di != NULL) 7317 { 7318 STRCPY(di->di_key, org->di_key); 7319 di->di_flags = DI_FLAGS_ALLOC; 7320 copy_tv(&org->di_tv, &di->di_tv); 7321 } 7322 return di; 7323 } 7324 7325 /* 7326 * Remove item "item" from Dictionary "dict" and free it. 7327 */ 7328 static void 7329 dictitem_remove(dict_T *dict, dictitem_T *item) 7330 { 7331 hashitem_T *hi; 7332 7333 hi = hash_find(&dict->dv_hashtab, item->di_key); 7334 if (HASHITEM_EMPTY(hi)) 7335 EMSG2(_(e_intern2), "dictitem_remove()"); 7336 else 7337 hash_remove(&dict->dv_hashtab, hi); 7338 dictitem_free(item); 7339 } 7340 7341 /* 7342 * Free a dict item. Also clears the value. 7343 */ 7344 void 7345 dictitem_free(dictitem_T *item) 7346 { 7347 clear_tv(&item->di_tv); 7348 if (item->di_flags & DI_FLAGS_ALLOC) 7349 vim_free(item); 7350 } 7351 7352 /* 7353 * Make a copy of dict "d". Shallow if "deep" is FALSE. 7354 * The refcount of the new dict is set to 1. 7355 * See item_copy() for "copyID". 7356 * Returns NULL when out of memory. 7357 */ 7358 static dict_T * 7359 dict_copy(dict_T *orig, int deep, int copyID) 7360 { 7361 dict_T *copy; 7362 dictitem_T *di; 7363 int todo; 7364 hashitem_T *hi; 7365 7366 if (orig == NULL) 7367 return NULL; 7368 7369 copy = dict_alloc(); 7370 if (copy != NULL) 7371 { 7372 if (copyID != 0) 7373 { 7374 orig->dv_copyID = copyID; 7375 orig->dv_copydict = copy; 7376 } 7377 todo = (int)orig->dv_hashtab.ht_used; 7378 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7379 { 7380 if (!HASHITEM_EMPTY(hi)) 7381 { 7382 --todo; 7383 7384 di = dictitem_alloc(hi->hi_key); 7385 if (di == NULL) 7386 break; 7387 if (deep) 7388 { 7389 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 7390 copyID) == FAIL) 7391 { 7392 vim_free(di); 7393 break; 7394 } 7395 } 7396 else 7397 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 7398 if (dict_add(copy, di) == FAIL) 7399 { 7400 dictitem_free(di); 7401 break; 7402 } 7403 } 7404 } 7405 7406 ++copy->dv_refcount; 7407 if (todo > 0) 7408 { 7409 dict_unref(copy); 7410 copy = NULL; 7411 } 7412 } 7413 7414 return copy; 7415 } 7416 7417 /* 7418 * Add item "item" to Dictionary "d". 7419 * Returns FAIL when out of memory and when key already exists. 7420 */ 7421 int 7422 dict_add(dict_T *d, dictitem_T *item) 7423 { 7424 return hash_add(&d->dv_hashtab, item->di_key); 7425 } 7426 7427 /* 7428 * Add a number or string entry to dictionary "d". 7429 * When "str" is NULL use number "nr", otherwise use "str". 7430 * Returns FAIL when out of memory and when key already exists. 7431 */ 7432 int 7433 dict_add_nr_str( 7434 dict_T *d, 7435 char *key, 7436 long nr, 7437 char_u *str) 7438 { 7439 dictitem_T *item; 7440 7441 item = dictitem_alloc((char_u *)key); 7442 if (item == NULL) 7443 return FAIL; 7444 item->di_tv.v_lock = 0; 7445 if (str == NULL) 7446 { 7447 item->di_tv.v_type = VAR_NUMBER; 7448 item->di_tv.vval.v_number = nr; 7449 } 7450 else 7451 { 7452 item->di_tv.v_type = VAR_STRING; 7453 item->di_tv.vval.v_string = vim_strsave(str); 7454 } 7455 if (dict_add(d, item) == FAIL) 7456 { 7457 dictitem_free(item); 7458 return FAIL; 7459 } 7460 return OK; 7461 } 7462 7463 /* 7464 * Add a list entry to dictionary "d". 7465 * Returns FAIL when out of memory and when key already exists. 7466 */ 7467 int 7468 dict_add_list(dict_T *d, char *key, list_T *list) 7469 { 7470 dictitem_T *item; 7471 7472 item = dictitem_alloc((char_u *)key); 7473 if (item == NULL) 7474 return FAIL; 7475 item->di_tv.v_lock = 0; 7476 item->di_tv.v_type = VAR_LIST; 7477 item->di_tv.vval.v_list = list; 7478 if (dict_add(d, item) == FAIL) 7479 { 7480 dictitem_free(item); 7481 return FAIL; 7482 } 7483 ++list->lv_refcount; 7484 return OK; 7485 } 7486 7487 /* 7488 * Get the number of items in a Dictionary. 7489 */ 7490 static long 7491 dict_len(dict_T *d) 7492 { 7493 if (d == NULL) 7494 return 0L; 7495 return (long)d->dv_hashtab.ht_used; 7496 } 7497 7498 /* 7499 * Find item "key[len]" in Dictionary "d". 7500 * If "len" is negative use strlen(key). 7501 * Returns NULL when not found. 7502 */ 7503 dictitem_T * 7504 dict_find(dict_T *d, char_u *key, int len) 7505 { 7506 #define AKEYLEN 200 7507 char_u buf[AKEYLEN]; 7508 char_u *akey; 7509 char_u *tofree = NULL; 7510 hashitem_T *hi; 7511 7512 if (len < 0) 7513 akey = key; 7514 else if (len >= AKEYLEN) 7515 { 7516 tofree = akey = vim_strnsave(key, len); 7517 if (akey == NULL) 7518 return NULL; 7519 } 7520 else 7521 { 7522 /* Avoid a malloc/free by using buf[]. */ 7523 vim_strncpy(buf, key, len); 7524 akey = buf; 7525 } 7526 7527 hi = hash_find(&d->dv_hashtab, akey); 7528 vim_free(tofree); 7529 if (HASHITEM_EMPTY(hi)) 7530 return NULL; 7531 return HI2DI(hi); 7532 } 7533 7534 /* 7535 * Get a string item from a dictionary. 7536 * When "save" is TRUE allocate memory for it. 7537 * Returns NULL if the entry doesn't exist or out of memory. 7538 */ 7539 char_u * 7540 get_dict_string(dict_T *d, char_u *key, int save) 7541 { 7542 dictitem_T *di; 7543 char_u *s; 7544 7545 di = dict_find(d, key, -1); 7546 if (di == NULL) 7547 return NULL; 7548 s = get_tv_string(&di->di_tv); 7549 if (save && s != NULL) 7550 s = vim_strsave(s); 7551 return s; 7552 } 7553 7554 /* 7555 * Get a number item from a dictionary. 7556 * Returns 0 if the entry doesn't exist. 7557 */ 7558 long 7559 get_dict_number(dict_T *d, char_u *key) 7560 { 7561 dictitem_T *di; 7562 7563 di = dict_find(d, key, -1); 7564 if (di == NULL) 7565 return 0; 7566 return get_tv_number(&di->di_tv); 7567 } 7568 7569 /* 7570 * Return an allocated string with the string representation of a Dictionary. 7571 * May return NULL. 7572 */ 7573 static char_u * 7574 dict2string(typval_T *tv, int copyID) 7575 { 7576 garray_T ga; 7577 int first = TRUE; 7578 char_u *tofree; 7579 char_u numbuf[NUMBUFLEN]; 7580 hashitem_T *hi; 7581 char_u *s; 7582 dict_T *d; 7583 int todo; 7584 7585 if ((d = tv->vval.v_dict) == NULL) 7586 return NULL; 7587 ga_init2(&ga, (int)sizeof(char), 80); 7588 ga_append(&ga, '{'); 7589 7590 todo = (int)d->dv_hashtab.ht_used; 7591 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7592 { 7593 if (!HASHITEM_EMPTY(hi)) 7594 { 7595 --todo; 7596 7597 if (first) 7598 first = FALSE; 7599 else 7600 ga_concat(&ga, (char_u *)", "); 7601 7602 tofree = string_quote(hi->hi_key, FALSE); 7603 if (tofree != NULL) 7604 { 7605 ga_concat(&ga, tofree); 7606 vim_free(tofree); 7607 } 7608 ga_concat(&ga, (char_u *)": "); 7609 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7610 if (s != NULL) 7611 ga_concat(&ga, s); 7612 vim_free(tofree); 7613 if (s == NULL || did_echo_string_emsg) 7614 break; 7615 line_breakcheck(); 7616 7617 } 7618 } 7619 if (todo > 0) 7620 { 7621 vim_free(ga.ga_data); 7622 return NULL; 7623 } 7624 7625 ga_append(&ga, '}'); 7626 ga_append(&ga, NUL); 7627 return (char_u *)ga.ga_data; 7628 } 7629 7630 /* 7631 * Allocate a variable for a Dictionary and fill it from "*arg". 7632 * Return OK or FAIL. Returns NOTDONE for {expr}. 7633 */ 7634 static int 7635 get_dict_tv(char_u **arg, typval_T *rettv, int evaluate) 7636 { 7637 dict_T *d = NULL; 7638 typval_T tvkey; 7639 typval_T tv; 7640 char_u *key = NULL; 7641 dictitem_T *item; 7642 char_u *start = skipwhite(*arg + 1); 7643 char_u buf[NUMBUFLEN]; 7644 7645 /* 7646 * First check if it's not a curly-braces thing: {expr}. 7647 * Must do this without evaluating, otherwise a function may be called 7648 * twice. Unfortunately this means we need to call eval1() twice for the 7649 * first item. 7650 * But {} is an empty Dictionary. 7651 */ 7652 if (*start != '}') 7653 { 7654 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7655 return FAIL; 7656 if (*start == '}') 7657 return NOTDONE; 7658 } 7659 7660 if (evaluate) 7661 { 7662 d = dict_alloc(); 7663 if (d == NULL) 7664 return FAIL; 7665 } 7666 tvkey.v_type = VAR_UNKNOWN; 7667 tv.v_type = VAR_UNKNOWN; 7668 7669 *arg = skipwhite(*arg + 1); 7670 while (**arg != '}' && **arg != NUL) 7671 { 7672 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7673 goto failret; 7674 if (**arg != ':') 7675 { 7676 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7677 clear_tv(&tvkey); 7678 goto failret; 7679 } 7680 if (evaluate) 7681 { 7682 key = get_tv_string_buf_chk(&tvkey, buf); 7683 if (key == NULL || *key == NUL) 7684 { 7685 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7686 if (key != NULL) 7687 EMSG(_(e_emptykey)); 7688 clear_tv(&tvkey); 7689 goto failret; 7690 } 7691 } 7692 7693 *arg = skipwhite(*arg + 1); 7694 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7695 { 7696 if (evaluate) 7697 clear_tv(&tvkey); 7698 goto failret; 7699 } 7700 if (evaluate) 7701 { 7702 item = dict_find(d, key, -1); 7703 if (item != NULL) 7704 { 7705 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7706 clear_tv(&tvkey); 7707 clear_tv(&tv); 7708 goto failret; 7709 } 7710 item = dictitem_alloc(key); 7711 clear_tv(&tvkey); 7712 if (item != NULL) 7713 { 7714 item->di_tv = tv; 7715 item->di_tv.v_lock = 0; 7716 if (dict_add(d, item) == FAIL) 7717 dictitem_free(item); 7718 } 7719 } 7720 7721 if (**arg == '}') 7722 break; 7723 if (**arg != ',') 7724 { 7725 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7726 goto failret; 7727 } 7728 *arg = skipwhite(*arg + 1); 7729 } 7730 7731 if (**arg != '}') 7732 { 7733 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7734 failret: 7735 if (evaluate) 7736 dict_free(d, TRUE); 7737 return FAIL; 7738 } 7739 7740 *arg = skipwhite(*arg + 1); 7741 if (evaluate) 7742 { 7743 rettv->v_type = VAR_DICT; 7744 rettv->vval.v_dict = d; 7745 ++d->dv_refcount; 7746 } 7747 7748 return OK; 7749 } 7750 7751 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) 7752 #endif 7753 7754 static char * 7755 get_var_special_name(int nr) 7756 { 7757 switch (nr) 7758 { 7759 case VVAL_FALSE: return "v:false"; 7760 case VVAL_TRUE: return "v:true"; 7761 case VVAL_NONE: return "v:none"; 7762 case VVAL_NULL: return "v:null"; 7763 } 7764 EMSG2(_(e_intern2), "get_var_special_name()"); 7765 return "42"; 7766 } 7767 7768 /* 7769 * Return a string with the string representation of a variable. 7770 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7771 * "numbuf" is used for a number. 7772 * Does not put quotes around strings, as ":echo" displays values. 7773 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7774 * May return NULL. 7775 */ 7776 static char_u * 7777 echo_string( 7778 typval_T *tv, 7779 char_u **tofree, 7780 char_u *numbuf, 7781 int copyID) 7782 { 7783 static int recurse = 0; 7784 char_u *r = NULL; 7785 7786 if (recurse >= DICT_MAXNEST) 7787 { 7788 if (!did_echo_string_emsg) 7789 { 7790 /* Only give this message once for a recursive call to avoid 7791 * flooding the user with errors. And stop iterating over lists 7792 * and dicts. */ 7793 did_echo_string_emsg = TRUE; 7794 EMSG(_("E724: variable nested too deep for displaying")); 7795 } 7796 *tofree = NULL; 7797 return (char_u *)"{E724}"; 7798 } 7799 ++recurse; 7800 7801 switch (tv->v_type) 7802 { 7803 case VAR_FUNC: 7804 *tofree = NULL; 7805 r = tv->vval.v_string; 7806 break; 7807 7808 case VAR_PARTIAL: 7809 *tofree = NULL; 7810 /* TODO: arguments */ 7811 r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name; 7812 break; 7813 7814 case VAR_LIST: 7815 if (tv->vval.v_list == NULL) 7816 { 7817 *tofree = NULL; 7818 r = NULL; 7819 } 7820 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7821 { 7822 *tofree = NULL; 7823 r = (char_u *)"[...]"; 7824 } 7825 else 7826 { 7827 tv->vval.v_list->lv_copyID = copyID; 7828 *tofree = list2string(tv, copyID); 7829 r = *tofree; 7830 } 7831 break; 7832 7833 case VAR_DICT: 7834 if (tv->vval.v_dict == NULL) 7835 { 7836 *tofree = NULL; 7837 r = NULL; 7838 } 7839 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7840 { 7841 *tofree = NULL; 7842 r = (char_u *)"{...}"; 7843 } 7844 else 7845 { 7846 tv->vval.v_dict->dv_copyID = copyID; 7847 *tofree = dict2string(tv, copyID); 7848 r = *tofree; 7849 } 7850 break; 7851 7852 case VAR_STRING: 7853 case VAR_NUMBER: 7854 case VAR_UNKNOWN: 7855 case VAR_JOB: 7856 case VAR_CHANNEL: 7857 *tofree = NULL; 7858 r = get_tv_string_buf(tv, numbuf); 7859 break; 7860 7861 case VAR_FLOAT: 7862 #ifdef FEAT_FLOAT 7863 *tofree = NULL; 7864 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7865 r = numbuf; 7866 break; 7867 #endif 7868 7869 case VAR_SPECIAL: 7870 *tofree = NULL; 7871 r = (char_u *)get_var_special_name(tv->vval.v_number); 7872 break; 7873 } 7874 7875 if (--recurse == 0) 7876 did_echo_string_emsg = FALSE; 7877 return r; 7878 } 7879 7880 /* 7881 * Return a string with the string representation of a variable. 7882 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7883 * "numbuf" is used for a number. 7884 * Puts quotes around strings, so that they can be parsed back by eval(). 7885 * May return NULL. 7886 */ 7887 static char_u * 7888 tv2string( 7889 typval_T *tv, 7890 char_u **tofree, 7891 char_u *numbuf, 7892 int copyID) 7893 { 7894 switch (tv->v_type) 7895 { 7896 case VAR_FUNC: 7897 *tofree = string_quote(tv->vval.v_string, TRUE); 7898 return *tofree; 7899 case VAR_PARTIAL: 7900 { 7901 partial_T *pt = tv->vval.v_partial; 7902 char_u *fname = string_quote(pt == NULL ? NULL 7903 : pt->pt_name, FALSE); 7904 garray_T ga; 7905 int i; 7906 char_u *tf; 7907 7908 ga_init2(&ga, 1, 100); 7909 ga_concat(&ga, (char_u *)"function("); 7910 if (fname != NULL) 7911 { 7912 ga_concat(&ga, fname); 7913 vim_free(fname); 7914 } 7915 if (pt != NULL && pt->pt_argc > 0) 7916 { 7917 ga_concat(&ga, (char_u *)", ["); 7918 for (i = 0; i < pt->pt_argc; ++i) 7919 { 7920 if (i > 0) 7921 ga_concat(&ga, (char_u *)", "); 7922 ga_concat(&ga, 7923 tv2string(&pt->pt_argv[i], &tf, numbuf, copyID)); 7924 vim_free(tf); 7925 } 7926 ga_concat(&ga, (char_u *)"]"); 7927 } 7928 if (pt != NULL && pt->pt_dict != NULL) 7929 { 7930 typval_T dtv; 7931 7932 ga_concat(&ga, (char_u *)", "); 7933 dtv.v_type = VAR_DICT; 7934 dtv.vval.v_dict = pt->pt_dict; 7935 ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID)); 7936 vim_free(tf); 7937 } 7938 ga_concat(&ga, (char_u *)")"); 7939 7940 *tofree = ga.ga_data; 7941 return *tofree; 7942 } 7943 case VAR_STRING: 7944 *tofree = string_quote(tv->vval.v_string, FALSE); 7945 return *tofree; 7946 case VAR_FLOAT: 7947 #ifdef FEAT_FLOAT 7948 *tofree = NULL; 7949 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 7950 return numbuf; 7951 #endif 7952 case VAR_NUMBER: 7953 case VAR_LIST: 7954 case VAR_DICT: 7955 case VAR_SPECIAL: 7956 case VAR_JOB: 7957 case VAR_CHANNEL: 7958 case VAR_UNKNOWN: 7959 break; 7960 } 7961 return echo_string(tv, tofree, numbuf, copyID); 7962 } 7963 7964 /* 7965 * Return string "str" in ' quotes, doubling ' characters. 7966 * If "str" is NULL an empty string is assumed. 7967 * If "function" is TRUE make it function('string'). 7968 */ 7969 static char_u * 7970 string_quote(char_u *str, int function) 7971 { 7972 unsigned len; 7973 char_u *p, *r, *s; 7974 7975 len = (function ? 13 : 3); 7976 if (str != NULL) 7977 { 7978 len += (unsigned)STRLEN(str); 7979 for (p = str; *p != NUL; mb_ptr_adv(p)) 7980 if (*p == '\'') 7981 ++len; 7982 } 7983 s = r = alloc(len); 7984 if (r != NULL) 7985 { 7986 if (function) 7987 { 7988 STRCPY(r, "function('"); 7989 r += 10; 7990 } 7991 else 7992 *r++ = '\''; 7993 if (str != NULL) 7994 for (p = str; *p != NUL; ) 7995 { 7996 if (*p == '\'') 7997 *r++ = '\''; 7998 MB_COPY_CHAR(p, r); 7999 } 8000 *r++ = '\''; 8001 if (function) 8002 *r++ = ')'; 8003 *r++ = NUL; 8004 } 8005 return s; 8006 } 8007 8008 #if defined(FEAT_FLOAT) || defined(PROTO) 8009 /* 8010 * Convert the string "text" to a floating point number. 8011 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 8012 * this always uses a decimal point. 8013 * Returns the length of the text that was consumed. 8014 */ 8015 int 8016 string2float( 8017 char_u *text, 8018 float_T *value) /* result stored here */ 8019 { 8020 char *s = (char *)text; 8021 float_T f; 8022 8023 f = strtod(s, &s); 8024 *value = f; 8025 return (int)((char_u *)s - text); 8026 } 8027 #endif 8028 8029 /* 8030 * Get the value of an environment variable. 8031 * "arg" is pointing to the '$'. It is advanced to after the name. 8032 * If the environment variable was not set, silently assume it is empty. 8033 * Return FAIL if the name is invalid. 8034 */ 8035 static int 8036 get_env_tv(char_u **arg, typval_T *rettv, int evaluate) 8037 { 8038 char_u *string = NULL; 8039 int len; 8040 int cc; 8041 char_u *name; 8042 int mustfree = FALSE; 8043 8044 ++*arg; 8045 name = *arg; 8046 len = get_env_len(arg); 8047 if (evaluate) 8048 { 8049 if (len == 0) 8050 return FAIL; /* invalid empty name */ 8051 8052 cc = name[len]; 8053 name[len] = NUL; 8054 /* first try vim_getenv(), fast for normal environment vars */ 8055 string = vim_getenv(name, &mustfree); 8056 if (string != NULL && *string != NUL) 8057 { 8058 if (!mustfree) 8059 string = vim_strsave(string); 8060 } 8061 else 8062 { 8063 if (mustfree) 8064 vim_free(string); 8065 8066 /* next try expanding things like $VIM and ${HOME} */ 8067 string = expand_env_save(name - 1); 8068 if (string != NULL && *string == '$') 8069 { 8070 vim_free(string); 8071 string = NULL; 8072 } 8073 } 8074 name[len] = cc; 8075 8076 rettv->v_type = VAR_STRING; 8077 rettv->vval.v_string = string; 8078 } 8079 8080 return OK; 8081 } 8082 8083 /* 8084 * Array with names and number of arguments of all internal functions 8085 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 8086 */ 8087 static struct fst 8088 { 8089 char *f_name; /* function name */ 8090 char f_min_argc; /* minimal number of arguments */ 8091 char f_max_argc; /* maximal number of arguments */ 8092 void (*f_func)(typval_T *args, typval_T *rvar); 8093 /* implementation of function */ 8094 } functions[] = 8095 { 8096 #ifdef FEAT_FLOAT 8097 {"abs", 1, 1, f_abs}, 8098 {"acos", 1, 1, f_acos}, /* WJMc */ 8099 #endif 8100 {"add", 2, 2, f_add}, 8101 {"alloc_fail", 3, 3, f_alloc_fail}, 8102 {"and", 2, 2, f_and}, 8103 {"append", 2, 2, f_append}, 8104 {"argc", 0, 0, f_argc}, 8105 {"argidx", 0, 0, f_argidx}, 8106 {"arglistid", 0, 2, f_arglistid}, 8107 {"argv", 0, 1, f_argv}, 8108 #ifdef FEAT_FLOAT 8109 {"asin", 1, 1, f_asin}, /* WJMc */ 8110 #endif 8111 {"assert_equal", 2, 3, f_assert_equal}, 8112 {"assert_exception", 1, 2, f_assert_exception}, 8113 {"assert_fails", 1, 2, f_assert_fails}, 8114 {"assert_false", 1, 2, f_assert_false}, 8115 {"assert_true", 1, 2, f_assert_true}, 8116 #ifdef FEAT_FLOAT 8117 {"atan", 1, 1, f_atan}, 8118 {"atan2", 2, 2, f_atan2}, 8119 #endif 8120 {"browse", 4, 4, f_browse}, 8121 {"browsedir", 2, 2, f_browsedir}, 8122 {"bufexists", 1, 1, f_bufexists}, 8123 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 8124 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 8125 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 8126 {"buflisted", 1, 1, f_buflisted}, 8127 {"bufloaded", 1, 1, f_bufloaded}, 8128 {"bufname", 1, 1, f_bufname}, 8129 {"bufnr", 1, 2, f_bufnr}, 8130 {"bufwinnr", 1, 1, f_bufwinnr}, 8131 {"byte2line", 1, 1, f_byte2line}, 8132 {"byteidx", 2, 2, f_byteidx}, 8133 {"byteidxcomp", 2, 2, f_byteidxcomp}, 8134 {"call", 2, 3, f_call}, 8135 #ifdef FEAT_FLOAT 8136 {"ceil", 1, 1, f_ceil}, 8137 #endif 8138 #ifdef FEAT_JOB_CHANNEL 8139 {"ch_close", 1, 1, f_ch_close}, 8140 {"ch_evalexpr", 2, 3, f_ch_evalexpr}, 8141 {"ch_evalraw", 2, 3, f_ch_evalraw}, 8142 {"ch_getbufnr", 2, 2, f_ch_getbufnr}, 8143 {"ch_getjob", 1, 1, f_ch_getjob}, 8144 {"ch_log", 1, 2, f_ch_log}, 8145 {"ch_logfile", 1, 2, f_ch_logfile}, 8146 {"ch_open", 1, 2, f_ch_open}, 8147 {"ch_read", 1, 2, f_ch_read}, 8148 {"ch_readraw", 1, 2, f_ch_readraw}, 8149 {"ch_sendexpr", 2, 3, f_ch_sendexpr}, 8150 {"ch_sendraw", 2, 3, f_ch_sendraw}, 8151 {"ch_setoptions", 2, 2, f_ch_setoptions}, 8152 {"ch_status", 1, 1, f_ch_status}, 8153 #endif 8154 {"changenr", 0, 0, f_changenr}, 8155 {"char2nr", 1, 2, f_char2nr}, 8156 {"cindent", 1, 1, f_cindent}, 8157 {"clearmatches", 0, 0, f_clearmatches}, 8158 {"col", 1, 1, f_col}, 8159 #if defined(FEAT_INS_EXPAND) 8160 {"complete", 2, 2, f_complete}, 8161 {"complete_add", 1, 1, f_complete_add}, 8162 {"complete_check", 0, 0, f_complete_check}, 8163 #endif 8164 {"confirm", 1, 4, f_confirm}, 8165 {"copy", 1, 1, f_copy}, 8166 #ifdef FEAT_FLOAT 8167 {"cos", 1, 1, f_cos}, 8168 {"cosh", 1, 1, f_cosh}, 8169 #endif 8170 {"count", 2, 4, f_count}, 8171 {"cscope_connection",0,3, f_cscope_connection}, 8172 {"cursor", 1, 3, f_cursor}, 8173 {"deepcopy", 1, 2, f_deepcopy}, 8174 {"delete", 1, 2, f_delete}, 8175 {"did_filetype", 0, 0, f_did_filetype}, 8176 {"diff_filler", 1, 1, f_diff_filler}, 8177 {"diff_hlID", 2, 2, f_diff_hlID}, 8178 {"disable_char_avail_for_testing", 1, 1, f_disable_char_avail_for_testing}, 8179 {"empty", 1, 1, f_empty}, 8180 {"escape", 2, 2, f_escape}, 8181 {"eval", 1, 1, f_eval}, 8182 {"eventhandler", 0, 0, f_eventhandler}, 8183 {"executable", 1, 1, f_executable}, 8184 {"exepath", 1, 1, f_exepath}, 8185 {"exists", 1, 1, f_exists}, 8186 #ifdef FEAT_FLOAT 8187 {"exp", 1, 1, f_exp}, 8188 #endif 8189 {"expand", 1, 3, f_expand}, 8190 {"extend", 2, 3, f_extend}, 8191 {"feedkeys", 1, 2, f_feedkeys}, 8192 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 8193 {"filereadable", 1, 1, f_filereadable}, 8194 {"filewritable", 1, 1, f_filewritable}, 8195 {"filter", 2, 2, f_filter}, 8196 {"finddir", 1, 3, f_finddir}, 8197 {"findfile", 1, 3, f_findfile}, 8198 #ifdef FEAT_FLOAT 8199 {"float2nr", 1, 1, f_float2nr}, 8200 {"floor", 1, 1, f_floor}, 8201 {"fmod", 2, 2, f_fmod}, 8202 #endif 8203 {"fnameescape", 1, 1, f_fnameescape}, 8204 {"fnamemodify", 2, 2, f_fnamemodify}, 8205 {"foldclosed", 1, 1, f_foldclosed}, 8206 {"foldclosedend", 1, 1, f_foldclosedend}, 8207 {"foldlevel", 1, 1, f_foldlevel}, 8208 {"foldtext", 0, 0, f_foldtext}, 8209 {"foldtextresult", 1, 1, f_foldtextresult}, 8210 {"foreground", 0, 0, f_foreground}, 8211 {"function", 1, 3, f_function}, 8212 {"garbagecollect", 0, 1, f_garbagecollect}, 8213 {"get", 2, 3, f_get}, 8214 {"getbufline", 2, 3, f_getbufline}, 8215 {"getbufvar", 2, 3, f_getbufvar}, 8216 {"getchar", 0, 1, f_getchar}, 8217 {"getcharmod", 0, 0, f_getcharmod}, 8218 {"getcharsearch", 0, 0, f_getcharsearch}, 8219 {"getcmdline", 0, 0, f_getcmdline}, 8220 {"getcmdpos", 0, 0, f_getcmdpos}, 8221 {"getcmdtype", 0, 0, f_getcmdtype}, 8222 {"getcmdwintype", 0, 0, f_getcmdwintype}, 8223 {"getcurpos", 0, 0, f_getcurpos}, 8224 {"getcwd", 0, 2, f_getcwd}, 8225 {"getfontname", 0, 1, f_getfontname}, 8226 {"getfperm", 1, 1, f_getfperm}, 8227 {"getfsize", 1, 1, f_getfsize}, 8228 {"getftime", 1, 1, f_getftime}, 8229 {"getftype", 1, 1, f_getftype}, 8230 {"getline", 1, 2, f_getline}, 8231 {"getloclist", 1, 1, f_getqflist}, 8232 {"getmatches", 0, 0, f_getmatches}, 8233 {"getpid", 0, 0, f_getpid}, 8234 {"getpos", 1, 1, f_getpos}, 8235 {"getqflist", 0, 0, f_getqflist}, 8236 {"getreg", 0, 3, f_getreg}, 8237 {"getregtype", 0, 1, f_getregtype}, 8238 {"gettabvar", 2, 3, f_gettabvar}, 8239 {"gettabwinvar", 3, 4, f_gettabwinvar}, 8240 {"getwinposx", 0, 0, f_getwinposx}, 8241 {"getwinposy", 0, 0, f_getwinposy}, 8242 {"getwinvar", 2, 3, f_getwinvar}, 8243 {"glob", 1, 4, f_glob}, 8244 {"glob2regpat", 1, 1, f_glob2regpat}, 8245 {"globpath", 2, 5, f_globpath}, 8246 {"has", 1, 1, f_has}, 8247 {"has_key", 2, 2, f_has_key}, 8248 {"haslocaldir", 0, 2, f_haslocaldir}, 8249 {"hasmapto", 1, 3, f_hasmapto}, 8250 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 8251 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 8252 {"histadd", 2, 2, f_histadd}, 8253 {"histdel", 1, 2, f_histdel}, 8254 {"histget", 1, 2, f_histget}, 8255 {"histnr", 1, 1, f_histnr}, 8256 {"hlID", 1, 1, f_hlID}, 8257 {"hlexists", 1, 1, f_hlexists}, 8258 {"hostname", 0, 0, f_hostname}, 8259 {"iconv", 3, 3, f_iconv}, 8260 {"indent", 1, 1, f_indent}, 8261 {"index", 2, 4, f_index}, 8262 {"input", 1, 3, f_input}, 8263 {"inputdialog", 1, 3, f_inputdialog}, 8264 {"inputlist", 1, 1, f_inputlist}, 8265 {"inputrestore", 0, 0, f_inputrestore}, 8266 {"inputsave", 0, 0, f_inputsave}, 8267 {"inputsecret", 1, 2, f_inputsecret}, 8268 {"insert", 2, 3, f_insert}, 8269 {"invert", 1, 1, f_invert}, 8270 {"isdirectory", 1, 1, f_isdirectory}, 8271 {"islocked", 1, 1, f_islocked}, 8272 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 8273 {"isnan", 1, 1, f_isnan}, 8274 #endif 8275 {"items", 1, 1, f_items}, 8276 #ifdef FEAT_JOB_CHANNEL 8277 {"job_getchannel", 1, 1, f_job_getchannel}, 8278 {"job_info", 1, 1, f_job_info}, 8279 {"job_setoptions", 2, 2, f_job_setoptions}, 8280 {"job_start", 1, 2, f_job_start}, 8281 {"job_status", 1, 1, f_job_status}, 8282 {"job_stop", 1, 2, f_job_stop}, 8283 #endif 8284 {"join", 1, 2, f_join}, 8285 {"js_decode", 1, 1, f_js_decode}, 8286 {"js_encode", 1, 1, f_js_encode}, 8287 {"json_decode", 1, 1, f_json_decode}, 8288 {"json_encode", 1, 1, f_json_encode}, 8289 {"keys", 1, 1, f_keys}, 8290 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 8291 {"len", 1, 1, f_len}, 8292 {"libcall", 3, 3, f_libcall}, 8293 {"libcallnr", 3, 3, f_libcallnr}, 8294 {"line", 1, 1, f_line}, 8295 {"line2byte", 1, 1, f_line2byte}, 8296 {"lispindent", 1, 1, f_lispindent}, 8297 {"localtime", 0, 0, f_localtime}, 8298 #ifdef FEAT_FLOAT 8299 {"log", 1, 1, f_log}, 8300 {"log10", 1, 1, f_log10}, 8301 #endif 8302 #ifdef FEAT_LUA 8303 {"luaeval", 1, 2, f_luaeval}, 8304 #endif 8305 {"map", 2, 2, f_map}, 8306 {"maparg", 1, 4, f_maparg}, 8307 {"mapcheck", 1, 3, f_mapcheck}, 8308 {"match", 2, 4, f_match}, 8309 {"matchadd", 2, 5, f_matchadd}, 8310 {"matchaddpos", 2, 5, f_matchaddpos}, 8311 {"matcharg", 1, 1, f_matcharg}, 8312 {"matchdelete", 1, 1, f_matchdelete}, 8313 {"matchend", 2, 4, f_matchend}, 8314 {"matchlist", 2, 4, f_matchlist}, 8315 {"matchstr", 2, 4, f_matchstr}, 8316 {"max", 1, 1, f_max}, 8317 {"min", 1, 1, f_min}, 8318 #ifdef vim_mkdir 8319 {"mkdir", 1, 3, f_mkdir}, 8320 #endif 8321 {"mode", 0, 1, f_mode}, 8322 #ifdef FEAT_MZSCHEME 8323 {"mzeval", 1, 1, f_mzeval}, 8324 #endif 8325 {"nextnonblank", 1, 1, f_nextnonblank}, 8326 {"nr2char", 1, 2, f_nr2char}, 8327 {"or", 2, 2, f_or}, 8328 {"pathshorten", 1, 1, f_pathshorten}, 8329 #ifdef FEAT_PERL 8330 {"perleval", 1, 1, f_perleval}, 8331 #endif 8332 #ifdef FEAT_FLOAT 8333 {"pow", 2, 2, f_pow}, 8334 #endif 8335 {"prevnonblank", 1, 1, f_prevnonblank}, 8336 {"printf", 2, 19, f_printf}, 8337 {"pumvisible", 0, 0, f_pumvisible}, 8338 #ifdef FEAT_PYTHON3 8339 {"py3eval", 1, 1, f_py3eval}, 8340 #endif 8341 #ifdef FEAT_PYTHON 8342 {"pyeval", 1, 1, f_pyeval}, 8343 #endif 8344 {"range", 1, 3, f_range}, 8345 {"readfile", 1, 3, f_readfile}, 8346 {"reltime", 0, 2, f_reltime}, 8347 #ifdef FEAT_FLOAT 8348 {"reltimefloat", 1, 1, f_reltimefloat}, 8349 #endif 8350 {"reltimestr", 1, 1, f_reltimestr}, 8351 {"remote_expr", 2, 3, f_remote_expr}, 8352 {"remote_foreground", 1, 1, f_remote_foreground}, 8353 {"remote_peek", 1, 2, f_remote_peek}, 8354 {"remote_read", 1, 1, f_remote_read}, 8355 {"remote_send", 2, 3, f_remote_send}, 8356 {"remove", 2, 3, f_remove}, 8357 {"rename", 2, 2, f_rename}, 8358 {"repeat", 2, 2, f_repeat}, 8359 {"resolve", 1, 1, f_resolve}, 8360 {"reverse", 1, 1, f_reverse}, 8361 #ifdef FEAT_FLOAT 8362 {"round", 1, 1, f_round}, 8363 #endif 8364 {"screenattr", 2, 2, f_screenattr}, 8365 {"screenchar", 2, 2, f_screenchar}, 8366 {"screencol", 0, 0, f_screencol}, 8367 {"screenrow", 0, 0, f_screenrow}, 8368 {"search", 1, 4, f_search}, 8369 {"searchdecl", 1, 3, f_searchdecl}, 8370 {"searchpair", 3, 7, f_searchpair}, 8371 {"searchpairpos", 3, 7, f_searchpairpos}, 8372 {"searchpos", 1, 4, f_searchpos}, 8373 {"server2client", 2, 2, f_server2client}, 8374 {"serverlist", 0, 0, f_serverlist}, 8375 {"setbufvar", 3, 3, f_setbufvar}, 8376 {"setcharsearch", 1, 1, f_setcharsearch}, 8377 {"setcmdpos", 1, 1, f_setcmdpos}, 8378 {"setfperm", 2, 2, f_setfperm}, 8379 {"setline", 2, 2, f_setline}, 8380 {"setloclist", 2, 3, f_setloclist}, 8381 {"setmatches", 1, 1, f_setmatches}, 8382 {"setpos", 2, 2, f_setpos}, 8383 {"setqflist", 1, 2, f_setqflist}, 8384 {"setreg", 2, 3, f_setreg}, 8385 {"settabvar", 3, 3, f_settabvar}, 8386 {"settabwinvar", 4, 4, f_settabwinvar}, 8387 {"setwinvar", 3, 3, f_setwinvar}, 8388 #ifdef FEAT_CRYPT 8389 {"sha256", 1, 1, f_sha256}, 8390 #endif 8391 {"shellescape", 1, 2, f_shellescape}, 8392 {"shiftwidth", 0, 0, f_shiftwidth}, 8393 {"simplify", 1, 1, f_simplify}, 8394 #ifdef FEAT_FLOAT 8395 {"sin", 1, 1, f_sin}, 8396 {"sinh", 1, 1, f_sinh}, 8397 #endif 8398 {"sort", 1, 3, f_sort}, 8399 {"soundfold", 1, 1, f_soundfold}, 8400 {"spellbadword", 0, 1, f_spellbadword}, 8401 {"spellsuggest", 1, 3, f_spellsuggest}, 8402 {"split", 1, 3, f_split}, 8403 #ifdef FEAT_FLOAT 8404 {"sqrt", 1, 1, f_sqrt}, 8405 {"str2float", 1, 1, f_str2float}, 8406 #endif 8407 {"str2nr", 1, 2, f_str2nr}, 8408 {"strchars", 1, 2, f_strchars}, 8409 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 8410 #ifdef HAVE_STRFTIME 8411 {"strftime", 1, 2, f_strftime}, 8412 #endif 8413 {"stridx", 2, 3, f_stridx}, 8414 {"string", 1, 1, f_string}, 8415 {"strlen", 1, 1, f_strlen}, 8416 {"strpart", 2, 3, f_strpart}, 8417 {"strridx", 2, 3, f_strridx}, 8418 {"strtrans", 1, 1, f_strtrans}, 8419 {"strwidth", 1, 1, f_strwidth}, 8420 {"submatch", 1, 2, f_submatch}, 8421 {"substitute", 4, 4, f_substitute}, 8422 {"synID", 3, 3, f_synID}, 8423 {"synIDattr", 2, 3, f_synIDattr}, 8424 {"synIDtrans", 1, 1, f_synIDtrans}, 8425 {"synconcealed", 2, 2, f_synconcealed}, 8426 {"synstack", 2, 2, f_synstack}, 8427 {"system", 1, 2, f_system}, 8428 {"systemlist", 1, 2, f_systemlist}, 8429 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 8430 {"tabpagenr", 0, 1, f_tabpagenr}, 8431 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 8432 {"tagfiles", 0, 0, f_tagfiles}, 8433 {"taglist", 1, 1, f_taglist}, 8434 #ifdef FEAT_FLOAT 8435 {"tan", 1, 1, f_tan}, 8436 {"tanh", 1, 1, f_tanh}, 8437 #endif 8438 {"tempname", 0, 0, f_tempname}, 8439 {"test", 1, 1, f_test}, 8440 #ifdef FEAT_TIMERS 8441 {"timer_start", 2, 3, f_timer_start}, 8442 {"timer_stop", 1, 1, f_timer_stop}, 8443 #endif 8444 {"tolower", 1, 1, f_tolower}, 8445 {"toupper", 1, 1, f_toupper}, 8446 {"tr", 3, 3, f_tr}, 8447 #ifdef FEAT_FLOAT 8448 {"trunc", 1, 1, f_trunc}, 8449 #endif 8450 {"type", 1, 1, f_type}, 8451 {"undofile", 1, 1, f_undofile}, 8452 {"undotree", 0, 0, f_undotree}, 8453 {"uniq", 1, 3, f_uniq}, 8454 {"values", 1, 1, f_values}, 8455 {"virtcol", 1, 1, f_virtcol}, 8456 {"visualmode", 0, 1, f_visualmode}, 8457 {"wildmenumode", 0, 0, f_wildmenumode}, 8458 {"win_findbuf", 1, 1, f_win_findbuf}, 8459 {"win_getid", 0, 2, f_win_getid}, 8460 {"win_gotoid", 1, 1, f_win_gotoid}, 8461 {"win_id2tabwin", 1, 1, f_win_id2tabwin}, 8462 {"win_id2win", 1, 1, f_win_id2win}, 8463 {"winbufnr", 1, 1, f_winbufnr}, 8464 {"wincol", 0, 0, f_wincol}, 8465 {"winheight", 1, 1, f_winheight}, 8466 {"winline", 0, 0, f_winline}, 8467 {"winnr", 0, 1, f_winnr}, 8468 {"winrestcmd", 0, 0, f_winrestcmd}, 8469 {"winrestview", 1, 1, f_winrestview}, 8470 {"winsaveview", 0, 0, f_winsaveview}, 8471 {"winwidth", 1, 1, f_winwidth}, 8472 {"wordcount", 0, 0, f_wordcount}, 8473 {"writefile", 2, 3, f_writefile}, 8474 {"xor", 2, 2, f_xor}, 8475 }; 8476 8477 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 8478 8479 /* 8480 * Function given to ExpandGeneric() to obtain the list of internal 8481 * or user defined function names. 8482 */ 8483 char_u * 8484 get_function_name(expand_T *xp, int idx) 8485 { 8486 static int intidx = -1; 8487 char_u *name; 8488 8489 if (idx == 0) 8490 intidx = -1; 8491 if (intidx < 0) 8492 { 8493 name = get_user_func_name(xp, idx); 8494 if (name != NULL) 8495 return name; 8496 } 8497 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 8498 { 8499 STRCPY(IObuff, functions[intidx].f_name); 8500 STRCAT(IObuff, "("); 8501 if (functions[intidx].f_max_argc == 0) 8502 STRCAT(IObuff, ")"); 8503 return IObuff; 8504 } 8505 8506 return NULL; 8507 } 8508 8509 /* 8510 * Function given to ExpandGeneric() to obtain the list of internal or 8511 * user defined variable or function names. 8512 */ 8513 char_u * 8514 get_expr_name(expand_T *xp, int idx) 8515 { 8516 static int intidx = -1; 8517 char_u *name; 8518 8519 if (idx == 0) 8520 intidx = -1; 8521 if (intidx < 0) 8522 { 8523 name = get_function_name(xp, idx); 8524 if (name != NULL) 8525 return name; 8526 } 8527 return get_user_var_name(xp, ++intidx); 8528 } 8529 8530 #endif /* FEAT_CMDL_COMPL */ 8531 8532 #if defined(EBCDIC) || defined(PROTO) 8533 /* 8534 * Compare struct fst by function name. 8535 */ 8536 static int 8537 compare_func_name(const void *s1, const void *s2) 8538 { 8539 struct fst *p1 = (struct fst *)s1; 8540 struct fst *p2 = (struct fst *)s2; 8541 8542 return STRCMP(p1->f_name, p2->f_name); 8543 } 8544 8545 /* 8546 * Sort the function table by function name. 8547 * The sorting of the table above is ASCII dependant. 8548 * On machines using EBCDIC we have to sort it. 8549 */ 8550 static void 8551 sortFunctions(void) 8552 { 8553 int funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8554 8555 qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name); 8556 } 8557 #endif 8558 8559 8560 /* 8561 * Find internal function in table above. 8562 * Return index, or -1 if not found 8563 */ 8564 static int 8565 find_internal_func( 8566 char_u *name) /* name of the function */ 8567 { 8568 int first = 0; 8569 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8570 int cmp; 8571 int x; 8572 8573 /* 8574 * Find the function name in the table. Binary search. 8575 */ 8576 while (first <= last) 8577 { 8578 x = first + ((unsigned)(last - first) >> 1); 8579 cmp = STRCMP(name, functions[x].f_name); 8580 if (cmp < 0) 8581 last = x - 1; 8582 else if (cmp > 0) 8583 first = x + 1; 8584 else 8585 return x; 8586 } 8587 return -1; 8588 } 8589 8590 /* 8591 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 8592 * name it contains, otherwise return "name". 8593 * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set 8594 * "partialp". 8595 */ 8596 static char_u * 8597 deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload) 8598 { 8599 dictitem_T *v; 8600 int cc; 8601 8602 if (partialp != NULL) 8603 *partialp = NULL; 8604 8605 cc = name[*lenp]; 8606 name[*lenp] = NUL; 8607 v = find_var(name, NULL, no_autoload); 8608 name[*lenp] = cc; 8609 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 8610 { 8611 if (v->di_tv.vval.v_string == NULL) 8612 { 8613 *lenp = 0; 8614 return (char_u *)""; /* just in case */ 8615 } 8616 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 8617 return v->di_tv.vval.v_string; 8618 } 8619 8620 if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) 8621 { 8622 partial_T *pt = v->di_tv.vval.v_partial; 8623 8624 if (pt == NULL) 8625 { 8626 *lenp = 0; 8627 return (char_u *)""; /* just in case */ 8628 } 8629 if (partialp != NULL) 8630 *partialp = pt; 8631 *lenp = (int)STRLEN(pt->pt_name); 8632 return pt->pt_name; 8633 } 8634 8635 return name; 8636 } 8637 8638 /* 8639 * Allocate a variable for the result of a function. 8640 * Return OK or FAIL. 8641 */ 8642 static int 8643 get_func_tv( 8644 char_u *name, /* name of the function */ 8645 int len, /* length of "name" */ 8646 typval_T *rettv, 8647 char_u **arg, /* argument, pointing to the '(' */ 8648 linenr_T firstline, /* first line of range */ 8649 linenr_T lastline, /* last line of range */ 8650 int *doesrange, /* return: function handled range */ 8651 int evaluate, 8652 partial_T *partial, /* for extra arguments */ 8653 dict_T *selfdict) /* Dictionary for "self" */ 8654 { 8655 char_u *argp; 8656 int ret = OK; 8657 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 8658 int argcount = 0; /* number of arguments found */ 8659 8660 /* 8661 * Get the arguments. 8662 */ 8663 argp = *arg; 8664 while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) 8665 { 8666 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 8667 if (*argp == ')' || *argp == ',' || *argp == NUL) 8668 break; 8669 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 8670 { 8671 ret = FAIL; 8672 break; 8673 } 8674 ++argcount; 8675 if (*argp != ',') 8676 break; 8677 } 8678 if (*argp == ')') 8679 ++argp; 8680 else 8681 ret = FAIL; 8682 8683 if (ret == OK) 8684 ret = call_func(name, len, rettv, argcount, argvars, 8685 firstline, lastline, doesrange, evaluate, partial, selfdict); 8686 else if (!aborting()) 8687 { 8688 if (argcount == MAX_FUNC_ARGS) 8689 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 8690 else 8691 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 8692 } 8693 8694 while (--argcount >= 0) 8695 clear_tv(&argvars[argcount]); 8696 8697 *arg = skipwhite(argp); 8698 return ret; 8699 } 8700 8701 #define ERROR_UNKNOWN 0 8702 #define ERROR_TOOMANY 1 8703 #define ERROR_TOOFEW 2 8704 #define ERROR_SCRIPT 3 8705 #define ERROR_DICT 4 8706 #define ERROR_NONE 5 8707 #define ERROR_OTHER 6 8708 #define FLEN_FIXED 40 8709 8710 /* 8711 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8712 * Change <SNR>123_name() to K_SNR 123_name(). 8713 * Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory 8714 * (slow). 8715 */ 8716 static char_u * 8717 fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) 8718 { 8719 int llen; 8720 char_u *fname; 8721 int i; 8722 8723 llen = eval_fname_script(name); 8724 if (llen > 0) 8725 { 8726 fname_buf[0] = K_SPECIAL; 8727 fname_buf[1] = KS_EXTRA; 8728 fname_buf[2] = (int)KE_SNR; 8729 i = 3; 8730 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8731 { 8732 if (current_SID <= 0) 8733 *error = ERROR_SCRIPT; 8734 else 8735 { 8736 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8737 i = (int)STRLEN(fname_buf); 8738 } 8739 } 8740 if (i + STRLEN(name + llen) < FLEN_FIXED) 8741 { 8742 STRCPY(fname_buf + i, name + llen); 8743 fname = fname_buf; 8744 } 8745 else 8746 { 8747 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8748 if (fname == NULL) 8749 *error = ERROR_OTHER; 8750 else 8751 { 8752 *tofree = fname; 8753 mch_memmove(fname, fname_buf, (size_t)i); 8754 STRCPY(fname + i, name + llen); 8755 } 8756 } 8757 } 8758 else 8759 fname = name; 8760 return fname; 8761 } 8762 8763 /* 8764 * Call a function with its resolved parameters 8765 * Return FAIL when the function can't be called, OK otherwise. 8766 * Also returns OK when an error was encountered while executing the function. 8767 */ 8768 int 8769 call_func( 8770 char_u *funcname, /* name of the function */ 8771 int len, /* length of "name" */ 8772 typval_T *rettv, /* return value goes here */ 8773 int argcount_in, /* number of "argvars" */ 8774 typval_T *argvars_in, /* vars for arguments, must have "argcount" 8775 PLUS ONE elements! */ 8776 linenr_T firstline, /* first line of range */ 8777 linenr_T lastline, /* last line of range */ 8778 int *doesrange, /* return: function handled range */ 8779 int evaluate, 8780 partial_T *partial, /* optional, can be NULL */ 8781 dict_T *selfdict_in) /* Dictionary for "self" */ 8782 { 8783 int ret = FAIL; 8784 int error = ERROR_NONE; 8785 int i; 8786 ufunc_T *fp; 8787 char_u fname_buf[FLEN_FIXED + 1]; 8788 char_u *tofree = NULL; 8789 char_u *fname; 8790 char_u *name; 8791 int argcount = argcount_in; 8792 typval_T *argvars = argvars_in; 8793 dict_T *selfdict = selfdict_in; 8794 typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */ 8795 int argv_clear = 0; 8796 8797 /* Make a copy of the name, if it comes from a funcref variable it could 8798 * be changed or deleted in the called function. */ 8799 name = vim_strnsave(funcname, len); 8800 if (name == NULL) 8801 return ret; 8802 8803 fname = fname_trans_sid(name, fname_buf, &tofree, &error); 8804 8805 *doesrange = FALSE; 8806 8807 if (partial != NULL) 8808 { 8809 if (partial->pt_dict != NULL) 8810 { 8811 /* When the function has a partial with a dict and there is a dict 8812 * argument, use the dict argument. That is backwards compatible. 8813 */ 8814 if (selfdict_in == NULL) 8815 selfdict = partial->pt_dict; 8816 } 8817 if (error == ERROR_NONE && partial->pt_argc > 0) 8818 { 8819 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear) 8820 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]); 8821 for (i = 0; i < argcount_in; ++i) 8822 argv[i + argv_clear] = argvars_in[i]; 8823 argvars = argv; 8824 argcount = partial->pt_argc + argcount_in; 8825 } 8826 } 8827 8828 8829 /* execute the function if no errors detected and executing */ 8830 if (evaluate && error == ERROR_NONE) 8831 { 8832 char_u *rfname = fname; 8833 8834 /* Ignore "g:" before a function name. */ 8835 if (fname[0] == 'g' && fname[1] == ':') 8836 rfname = fname + 2; 8837 8838 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8839 rettv->vval.v_number = 0; 8840 error = ERROR_UNKNOWN; 8841 8842 if (!builtin_function(rfname, -1)) 8843 { 8844 /* 8845 * User defined function. 8846 */ 8847 fp = find_func(rfname); 8848 8849 #ifdef FEAT_AUTOCMD 8850 /* Trigger FuncUndefined event, may load the function. */ 8851 if (fp == NULL 8852 && apply_autocmds(EVENT_FUNCUNDEFINED, 8853 rfname, rfname, TRUE, NULL) 8854 && !aborting()) 8855 { 8856 /* executed an autocommand, search for the function again */ 8857 fp = find_func(rfname); 8858 } 8859 #endif 8860 /* Try loading a package. */ 8861 if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) 8862 { 8863 /* loaded a package, search for the function again */ 8864 fp = find_func(rfname); 8865 } 8866 8867 if (fp != NULL) 8868 { 8869 if (fp->uf_flags & FC_RANGE) 8870 *doesrange = TRUE; 8871 if (argcount < fp->uf_args.ga_len) 8872 error = ERROR_TOOFEW; 8873 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8874 error = ERROR_TOOMANY; 8875 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8876 error = ERROR_DICT; 8877 else 8878 { 8879 int did_save_redo = FALSE; 8880 8881 /* 8882 * Call the user function. 8883 * Save and restore search patterns, script variables and 8884 * redo buffer. 8885 */ 8886 save_search_patterns(); 8887 #ifdef FEAT_INS_EXPAND 8888 if (!ins_compl_active()) 8889 #endif 8890 { 8891 saveRedobuff(); 8892 did_save_redo = TRUE; 8893 } 8894 ++fp->uf_calls; 8895 call_user_func(fp, argcount, argvars, rettv, 8896 firstline, lastline, 8897 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8898 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8899 && fp->uf_refcount <= 0) 8900 /* Function was unreferenced while being used, free it 8901 * now. */ 8902 func_free(fp); 8903 if (did_save_redo) 8904 restoreRedobuff(); 8905 restore_search_patterns(); 8906 error = ERROR_NONE; 8907 } 8908 } 8909 } 8910 else 8911 { 8912 /* 8913 * Find the function name in the table, call its implementation. 8914 */ 8915 i = find_internal_func(fname); 8916 if (i >= 0) 8917 { 8918 if (argcount < functions[i].f_min_argc) 8919 error = ERROR_TOOFEW; 8920 else if (argcount > functions[i].f_max_argc) 8921 error = ERROR_TOOMANY; 8922 else 8923 { 8924 argvars[argcount].v_type = VAR_UNKNOWN; 8925 functions[i].f_func(argvars, rettv); 8926 error = ERROR_NONE; 8927 } 8928 } 8929 } 8930 /* 8931 * The function call (or "FuncUndefined" autocommand sequence) might 8932 * have been aborted by an error, an interrupt, or an explicitly thrown 8933 * exception that has not been caught so far. This situation can be 8934 * tested for by calling aborting(). For an error in an internal 8935 * function or for the "E132" error in call_user_func(), however, the 8936 * throw point at which the "force_abort" flag (temporarily reset by 8937 * emsg()) is normally updated has not been reached yet. We need to 8938 * update that flag first to make aborting() reliable. 8939 */ 8940 update_force_abort(); 8941 } 8942 if (error == ERROR_NONE) 8943 ret = OK; 8944 8945 /* 8946 * Report an error unless the argument evaluation or function call has been 8947 * cancelled due to an aborting error, an interrupt, or an exception. 8948 */ 8949 if (!aborting()) 8950 { 8951 switch (error) 8952 { 8953 case ERROR_UNKNOWN: 8954 emsg_funcname(N_("E117: Unknown function: %s"), name); 8955 break; 8956 case ERROR_TOOMANY: 8957 emsg_funcname(e_toomanyarg, name); 8958 break; 8959 case ERROR_TOOFEW: 8960 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 8961 name); 8962 break; 8963 case ERROR_SCRIPT: 8964 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 8965 name); 8966 break; 8967 case ERROR_DICT: 8968 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 8969 name); 8970 break; 8971 } 8972 } 8973 8974 while (argv_clear > 0) 8975 clear_tv(&argv[--argv_clear]); 8976 vim_free(tofree); 8977 vim_free(name); 8978 8979 return ret; 8980 } 8981 8982 /* 8983 * Give an error message with a function name. Handle <SNR> things. 8984 * "ermsg" is to be passed without translation, use N_() instead of _(). 8985 */ 8986 static void 8987 emsg_funcname(char *ermsg, char_u *name) 8988 { 8989 char_u *p; 8990 8991 if (*name == K_SPECIAL) 8992 p = concat_str((char_u *)"<SNR>", name + 3); 8993 else 8994 p = name; 8995 EMSG2(_(ermsg), p); 8996 if (p != name) 8997 vim_free(p); 8998 } 8999 9000 /* 9001 * Return TRUE for a non-zero Number and a non-empty String. 9002 */ 9003 static int 9004 non_zero_arg(typval_T *argvars) 9005 { 9006 return ((argvars[0].v_type == VAR_NUMBER 9007 && argvars[0].vval.v_number != 0) 9008 || (argvars[0].v_type == VAR_STRING 9009 && argvars[0].vval.v_string != NULL 9010 && *argvars[0].vval.v_string != NUL)); 9011 } 9012 9013 /********************************************* 9014 * Implementation of the built-in functions 9015 */ 9016 9017 #ifdef FEAT_FLOAT 9018 static int get_float_arg(typval_T *argvars, float_T *f); 9019 9020 /* 9021 * Get the float value of "argvars[0]" into "f". 9022 * Returns FAIL when the argument is not a Number or Float. 9023 */ 9024 static int 9025 get_float_arg(typval_T *argvars, float_T *f) 9026 { 9027 if (argvars[0].v_type == VAR_FLOAT) 9028 { 9029 *f = argvars[0].vval.v_float; 9030 return OK; 9031 } 9032 if (argvars[0].v_type == VAR_NUMBER) 9033 { 9034 *f = (float_T)argvars[0].vval.v_number; 9035 return OK; 9036 } 9037 EMSG(_("E808: Number or Float required")); 9038 return FAIL; 9039 } 9040 9041 /* 9042 * "abs(expr)" function 9043 */ 9044 static void 9045 f_abs(typval_T *argvars, typval_T *rettv) 9046 { 9047 if (argvars[0].v_type == VAR_FLOAT) 9048 { 9049 rettv->v_type = VAR_FLOAT; 9050 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 9051 } 9052 else 9053 { 9054 varnumber_T n; 9055 int error = FALSE; 9056 9057 n = get_tv_number_chk(&argvars[0], &error); 9058 if (error) 9059 rettv->vval.v_number = -1; 9060 else if (n > 0) 9061 rettv->vval.v_number = n; 9062 else 9063 rettv->vval.v_number = -n; 9064 } 9065 } 9066 9067 /* 9068 * "acos()" function 9069 */ 9070 static void 9071 f_acos(typval_T *argvars, typval_T *rettv) 9072 { 9073 float_T f = 0.0; 9074 9075 rettv->v_type = VAR_FLOAT; 9076 if (get_float_arg(argvars, &f) == OK) 9077 rettv->vval.v_float = acos(f); 9078 else 9079 rettv->vval.v_float = 0.0; 9080 } 9081 #endif 9082 9083 /* 9084 * "add(list, item)" function 9085 */ 9086 static void 9087 f_add(typval_T *argvars, typval_T *rettv) 9088 { 9089 list_T *l; 9090 9091 rettv->vval.v_number = 1; /* Default: Failed */ 9092 if (argvars[0].v_type == VAR_LIST) 9093 { 9094 if ((l = argvars[0].vval.v_list) != NULL 9095 && !tv_check_lock(l->lv_lock, 9096 (char_u *)N_("add() argument"), TRUE) 9097 && list_append_tv(l, &argvars[1]) == OK) 9098 copy_tv(&argvars[0], rettv); 9099 } 9100 else 9101 EMSG(_(e_listreq)); 9102 } 9103 9104 /* 9105 * "alloc_fail(id, countdown, repeat)" function 9106 */ 9107 static void 9108 f_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED) 9109 { 9110 if (argvars[0].v_type != VAR_NUMBER 9111 || argvars[0].vval.v_number <= 0 9112 || argvars[1].v_type != VAR_NUMBER 9113 || argvars[1].vval.v_number < 0 9114 || argvars[2].v_type != VAR_NUMBER) 9115 EMSG(_(e_invarg)); 9116 else 9117 { 9118 alloc_fail_id = argvars[0].vval.v_number; 9119 if (alloc_fail_id >= aid_last) 9120 EMSG(_(e_invarg)); 9121 alloc_fail_countdown = argvars[1].vval.v_number; 9122 alloc_fail_repeat = argvars[2].vval.v_number; 9123 did_outofmem_msg = FALSE; 9124 } 9125 } 9126 9127 /* 9128 * "and(expr, expr)" function 9129 */ 9130 static void 9131 f_and(typval_T *argvars, typval_T *rettv) 9132 { 9133 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 9134 & get_tv_number_chk(&argvars[1], NULL); 9135 } 9136 9137 /* 9138 * "append(lnum, string/list)" function 9139 */ 9140 static void 9141 f_append(typval_T *argvars, typval_T *rettv) 9142 { 9143 long lnum; 9144 char_u *line; 9145 list_T *l = NULL; 9146 listitem_T *li = NULL; 9147 typval_T *tv; 9148 long added = 0; 9149 9150 /* When coming here from Insert mode, sync undo, so that this can be 9151 * undone separately from what was previously inserted. */ 9152 if (u_sync_once == 2) 9153 { 9154 u_sync_once = 1; /* notify that u_sync() was called */ 9155 u_sync(TRUE); 9156 } 9157 9158 lnum = get_tv_lnum(argvars); 9159 if (lnum >= 0 9160 && lnum <= curbuf->b_ml.ml_line_count 9161 && u_save(lnum, lnum + 1) == OK) 9162 { 9163 if (argvars[1].v_type == VAR_LIST) 9164 { 9165 l = argvars[1].vval.v_list; 9166 if (l == NULL) 9167 return; 9168 li = l->lv_first; 9169 } 9170 for (;;) 9171 { 9172 if (l == NULL) 9173 tv = &argvars[1]; /* append a string */ 9174 else if (li == NULL) 9175 break; /* end of list */ 9176 else 9177 tv = &li->li_tv; /* append item from list */ 9178 line = get_tv_string_chk(tv); 9179 if (line == NULL) /* type error */ 9180 { 9181 rettv->vval.v_number = 1; /* Failed */ 9182 break; 9183 } 9184 ml_append(lnum + added, line, (colnr_T)0, FALSE); 9185 ++added; 9186 if (l == NULL) 9187 break; 9188 li = li->li_next; 9189 } 9190 9191 appended_lines_mark(lnum, added); 9192 if (curwin->w_cursor.lnum > lnum) 9193 curwin->w_cursor.lnum += added; 9194 } 9195 else 9196 rettv->vval.v_number = 1; /* Failed */ 9197 } 9198 9199 /* 9200 * "argc()" function 9201 */ 9202 static void 9203 f_argc(typval_T *argvars UNUSED, typval_T *rettv) 9204 { 9205 rettv->vval.v_number = ARGCOUNT; 9206 } 9207 9208 /* 9209 * "argidx()" function 9210 */ 9211 static void 9212 f_argidx(typval_T *argvars UNUSED, typval_T *rettv) 9213 { 9214 rettv->vval.v_number = curwin->w_arg_idx; 9215 } 9216 9217 /* 9218 * "arglistid()" function 9219 */ 9220 static void 9221 f_arglistid(typval_T *argvars, typval_T *rettv) 9222 { 9223 win_T *wp; 9224 9225 rettv->vval.v_number = -1; 9226 wp = find_tabwin(&argvars[0], &argvars[1]); 9227 if (wp != NULL) 9228 rettv->vval.v_number = wp->w_alist->id; 9229 } 9230 9231 /* 9232 * "argv(nr)" function 9233 */ 9234 static void 9235 f_argv(typval_T *argvars, typval_T *rettv) 9236 { 9237 int idx; 9238 9239 if (argvars[0].v_type != VAR_UNKNOWN) 9240 { 9241 idx = get_tv_number_chk(&argvars[0], NULL); 9242 if (idx >= 0 && idx < ARGCOUNT) 9243 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 9244 else 9245 rettv->vval.v_string = NULL; 9246 rettv->v_type = VAR_STRING; 9247 } 9248 else if (rettv_list_alloc(rettv) == OK) 9249 for (idx = 0; idx < ARGCOUNT; ++idx) 9250 list_append_string(rettv->vval.v_list, 9251 alist_name(&ARGLIST[idx]), -1); 9252 } 9253 9254 static void prepare_assert_error(garray_T*gap); 9255 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); 9256 static void assert_error(garray_T *gap); 9257 static void assert_bool(typval_T *argvars, int isTrue); 9258 9259 /* 9260 * Prepare "gap" for an assert error and add the sourcing position. 9261 */ 9262 static void 9263 prepare_assert_error(garray_T *gap) 9264 { 9265 char buf[NUMBUFLEN]; 9266 9267 ga_init2(gap, 1, 100); 9268 if (sourcing_name != NULL) 9269 { 9270 ga_concat(gap, sourcing_name); 9271 if (sourcing_lnum > 0) 9272 ga_concat(gap, (char_u *)" "); 9273 } 9274 if (sourcing_lnum > 0) 9275 { 9276 sprintf(buf, "line %ld", (long)sourcing_lnum); 9277 ga_concat(gap, (char_u *)buf); 9278 } 9279 if (sourcing_name != NULL || sourcing_lnum > 0) 9280 ga_concat(gap, (char_u *)": "); 9281 } 9282 9283 /* 9284 * Append "str" to "gap", escaping unprintable characters. 9285 * Changes NL to \n, CR to \r, etc. 9286 */ 9287 static void 9288 ga_concat_esc(garray_T *gap, char_u *str) 9289 { 9290 char_u *p; 9291 char_u buf[NUMBUFLEN]; 9292 9293 if (str == NULL) 9294 { 9295 ga_concat(gap, (char_u *)"NULL"); 9296 return; 9297 } 9298 9299 for (p = str; *p != NUL; ++p) 9300 switch (*p) 9301 { 9302 case BS: ga_concat(gap, (char_u *)"\\b"); break; 9303 case ESC: ga_concat(gap, (char_u *)"\\e"); break; 9304 case FF: ga_concat(gap, (char_u *)"\\f"); break; 9305 case NL: ga_concat(gap, (char_u *)"\\n"); break; 9306 case TAB: ga_concat(gap, (char_u *)"\\t"); break; 9307 case CAR: ga_concat(gap, (char_u *)"\\r"); break; 9308 case '\\': ga_concat(gap, (char_u *)"\\\\"); break; 9309 default: 9310 if (*p < ' ') 9311 { 9312 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); 9313 ga_concat(gap, buf); 9314 } 9315 else 9316 ga_append(gap, *p); 9317 break; 9318 } 9319 } 9320 9321 /* 9322 * Fill "gap" with information about an assert error. 9323 */ 9324 static void 9325 fill_assert_error( 9326 garray_T *gap, 9327 typval_T *opt_msg_tv, 9328 char_u *exp_str, 9329 typval_T *exp_tv, 9330 typval_T *got_tv) 9331 { 9332 char_u numbuf[NUMBUFLEN]; 9333 char_u *tofree; 9334 9335 if (opt_msg_tv->v_type != VAR_UNKNOWN) 9336 { 9337 ga_concat(gap, tv2string(opt_msg_tv, &tofree, numbuf, 0)); 9338 vim_free(tofree); 9339 } 9340 else 9341 { 9342 ga_concat(gap, (char_u *)"Expected "); 9343 if (exp_str == NULL) 9344 { 9345 ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); 9346 vim_free(tofree); 9347 } 9348 else 9349 ga_concat_esc(gap, exp_str); 9350 ga_concat(gap, (char_u *)" but got "); 9351 ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); 9352 vim_free(tofree); 9353 } 9354 } 9355 9356 /* 9357 * Add an assert error to v:errors. 9358 */ 9359 static void 9360 assert_error(garray_T *gap) 9361 { 9362 struct vimvar *vp = &vimvars[VV_ERRORS]; 9363 9364 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) 9365 /* Make sure v:errors is a list. */ 9366 set_vim_var_list(VV_ERRORS, list_alloc()); 9367 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); 9368 } 9369 9370 /* 9371 * "assert_equal(expected, actual[, msg])" function 9372 */ 9373 static void 9374 f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED) 9375 { 9376 garray_T ga; 9377 9378 if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)) 9379 { 9380 prepare_assert_error(&ga); 9381 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1]); 9382 assert_error(&ga); 9383 ga_clear(&ga); 9384 } 9385 } 9386 9387 /* 9388 * "assert_exception(string[, msg])" function 9389 */ 9390 static void 9391 f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED) 9392 { 9393 garray_T ga; 9394 char *error; 9395 9396 error = (char *)get_tv_string_chk(&argvars[0]); 9397 if (vimvars[VV_EXCEPTION].vv_str == NULL) 9398 { 9399 prepare_assert_error(&ga); 9400 ga_concat(&ga, (char_u *)"v:exception is not set"); 9401 assert_error(&ga); 9402 ga_clear(&ga); 9403 } 9404 else if (error != NULL 9405 && strstr((char *)vimvars[VV_EXCEPTION].vv_str, error) == NULL) 9406 { 9407 prepare_assert_error(&ga); 9408 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], 9409 &vimvars[VV_EXCEPTION].vv_tv); 9410 assert_error(&ga); 9411 ga_clear(&ga); 9412 } 9413 } 9414 9415 /* 9416 * "assert_fails(cmd [, error])" function 9417 */ 9418 static void 9419 f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED) 9420 { 9421 char_u *cmd = get_tv_string_chk(&argvars[0]); 9422 garray_T ga; 9423 9424 called_emsg = FALSE; 9425 suppress_errthrow = TRUE; 9426 emsg_silent = TRUE; 9427 do_cmdline_cmd(cmd); 9428 if (!called_emsg) 9429 { 9430 prepare_assert_error(&ga); 9431 ga_concat(&ga, (char_u *)"command did not fail: "); 9432 ga_concat(&ga, cmd); 9433 assert_error(&ga); 9434 ga_clear(&ga); 9435 } 9436 else if (argvars[1].v_type != VAR_UNKNOWN) 9437 { 9438 char_u buf[NUMBUFLEN]; 9439 char *error = (char *)get_tv_string_buf_chk(&argvars[1], buf); 9440 9441 if (error == NULL 9442 || strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL) 9443 { 9444 prepare_assert_error(&ga); 9445 fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], 9446 &vimvars[VV_ERRMSG].vv_tv); 9447 assert_error(&ga); 9448 ga_clear(&ga); 9449 } 9450 } 9451 9452 called_emsg = FALSE; 9453 suppress_errthrow = FALSE; 9454 emsg_silent = FALSE; 9455 emsg_on_display = FALSE; 9456 set_vim_var_string(VV_ERRMSG, NULL, 0); 9457 } 9458 9459 /* 9460 * Common for assert_true() and assert_false(). 9461 */ 9462 static void 9463 assert_bool(typval_T *argvars, int isTrue) 9464 { 9465 int error = FALSE; 9466 garray_T ga; 9467 9468 if (argvars[0].v_type == VAR_SPECIAL 9469 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) 9470 return; 9471 if (argvars[0].v_type != VAR_NUMBER 9472 || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue 9473 || error) 9474 { 9475 prepare_assert_error(&ga); 9476 fill_assert_error(&ga, &argvars[1], 9477 (char_u *)(isTrue ? "True" : "False"), 9478 NULL, &argvars[0]); 9479 assert_error(&ga); 9480 ga_clear(&ga); 9481 } 9482 } 9483 9484 /* 9485 * "assert_false(actual[, msg])" function 9486 */ 9487 static void 9488 f_assert_false(typval_T *argvars, typval_T *rettv UNUSED) 9489 { 9490 assert_bool(argvars, FALSE); 9491 } 9492 9493 /* 9494 * "assert_true(actual[, msg])" function 9495 */ 9496 static void 9497 f_assert_true(typval_T *argvars, typval_T *rettv UNUSED) 9498 { 9499 assert_bool(argvars, TRUE); 9500 } 9501 9502 #ifdef FEAT_FLOAT 9503 /* 9504 * "asin()" function 9505 */ 9506 static void 9507 f_asin(typval_T *argvars, typval_T *rettv) 9508 { 9509 float_T f = 0.0; 9510 9511 rettv->v_type = VAR_FLOAT; 9512 if (get_float_arg(argvars, &f) == OK) 9513 rettv->vval.v_float = asin(f); 9514 else 9515 rettv->vval.v_float = 0.0; 9516 } 9517 9518 /* 9519 * "atan()" function 9520 */ 9521 static void 9522 f_atan(typval_T *argvars, typval_T *rettv) 9523 { 9524 float_T f = 0.0; 9525 9526 rettv->v_type = VAR_FLOAT; 9527 if (get_float_arg(argvars, &f) == OK) 9528 rettv->vval.v_float = atan(f); 9529 else 9530 rettv->vval.v_float = 0.0; 9531 } 9532 9533 /* 9534 * "atan2()" function 9535 */ 9536 static void 9537 f_atan2(typval_T *argvars, typval_T *rettv) 9538 { 9539 float_T fx = 0.0, fy = 0.0; 9540 9541 rettv->v_type = VAR_FLOAT; 9542 if (get_float_arg(argvars, &fx) == OK 9543 && get_float_arg(&argvars[1], &fy) == OK) 9544 rettv->vval.v_float = atan2(fx, fy); 9545 else 9546 rettv->vval.v_float = 0.0; 9547 } 9548 #endif 9549 9550 /* 9551 * "browse(save, title, initdir, default)" function 9552 */ 9553 static void 9554 f_browse(typval_T *argvars UNUSED, typval_T *rettv) 9555 { 9556 #ifdef FEAT_BROWSE 9557 int save; 9558 char_u *title; 9559 char_u *initdir; 9560 char_u *defname; 9561 char_u buf[NUMBUFLEN]; 9562 char_u buf2[NUMBUFLEN]; 9563 int error = FALSE; 9564 9565 save = get_tv_number_chk(&argvars[0], &error); 9566 title = get_tv_string_chk(&argvars[1]); 9567 initdir = get_tv_string_buf_chk(&argvars[2], buf); 9568 defname = get_tv_string_buf_chk(&argvars[3], buf2); 9569 9570 if (error || title == NULL || initdir == NULL || defname == NULL) 9571 rettv->vval.v_string = NULL; 9572 else 9573 rettv->vval.v_string = 9574 do_browse(save ? BROWSE_SAVE : 0, 9575 title, defname, NULL, initdir, NULL, curbuf); 9576 #else 9577 rettv->vval.v_string = NULL; 9578 #endif 9579 rettv->v_type = VAR_STRING; 9580 } 9581 9582 /* 9583 * "browsedir(title, initdir)" function 9584 */ 9585 static void 9586 f_browsedir(typval_T *argvars UNUSED, typval_T *rettv) 9587 { 9588 #ifdef FEAT_BROWSE 9589 char_u *title; 9590 char_u *initdir; 9591 char_u buf[NUMBUFLEN]; 9592 9593 title = get_tv_string_chk(&argvars[0]); 9594 initdir = get_tv_string_buf_chk(&argvars[1], buf); 9595 9596 if (title == NULL || initdir == NULL) 9597 rettv->vval.v_string = NULL; 9598 else 9599 rettv->vval.v_string = do_browse(BROWSE_DIR, 9600 title, NULL, NULL, initdir, NULL, curbuf); 9601 #else 9602 rettv->vval.v_string = NULL; 9603 #endif 9604 rettv->v_type = VAR_STRING; 9605 } 9606 9607 static buf_T *find_buffer(typval_T *avar); 9608 9609 /* 9610 * Find a buffer by number or exact name. 9611 */ 9612 static buf_T * 9613 find_buffer(typval_T *avar) 9614 { 9615 buf_T *buf = NULL; 9616 9617 if (avar->v_type == VAR_NUMBER) 9618 buf = buflist_findnr((int)avar->vval.v_number); 9619 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 9620 { 9621 buf = buflist_findname_exp(avar->vval.v_string); 9622 if (buf == NULL) 9623 { 9624 /* No full path name match, try a match with a URL or a "nofile" 9625 * buffer, these don't use the full path. */ 9626 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 9627 if (buf->b_fname != NULL 9628 && (path_with_url(buf->b_fname) 9629 #ifdef FEAT_QUICKFIX 9630 || bt_nofile(buf) 9631 #endif 9632 ) 9633 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 9634 break; 9635 } 9636 } 9637 return buf; 9638 } 9639 9640 /* 9641 * "bufexists(expr)" function 9642 */ 9643 static void 9644 f_bufexists(typval_T *argvars, typval_T *rettv) 9645 { 9646 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 9647 } 9648 9649 /* 9650 * "buflisted(expr)" function 9651 */ 9652 static void 9653 f_buflisted(typval_T *argvars, typval_T *rettv) 9654 { 9655 buf_T *buf; 9656 9657 buf = find_buffer(&argvars[0]); 9658 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 9659 } 9660 9661 /* 9662 * "bufloaded(expr)" function 9663 */ 9664 static void 9665 f_bufloaded(typval_T *argvars, typval_T *rettv) 9666 { 9667 buf_T *buf; 9668 9669 buf = find_buffer(&argvars[0]); 9670 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 9671 } 9672 9673 buf_T * 9674 buflist_find_by_name(char_u *name, int curtab_only) 9675 { 9676 int save_magic; 9677 char_u *save_cpo; 9678 buf_T *buf; 9679 9680 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 9681 save_magic = p_magic; 9682 p_magic = TRUE; 9683 save_cpo = p_cpo; 9684 p_cpo = (char_u *)""; 9685 9686 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 9687 TRUE, FALSE, curtab_only)); 9688 9689 p_magic = save_magic; 9690 p_cpo = save_cpo; 9691 return buf; 9692 } 9693 9694 /* 9695 * Get buffer by number or pattern. 9696 */ 9697 static buf_T * 9698 get_buf_tv(typval_T *tv, int curtab_only) 9699 { 9700 char_u *name = tv->vval.v_string; 9701 buf_T *buf; 9702 9703 if (tv->v_type == VAR_NUMBER) 9704 return buflist_findnr((int)tv->vval.v_number); 9705 if (tv->v_type != VAR_STRING) 9706 return NULL; 9707 if (name == NULL || *name == NUL) 9708 return curbuf; 9709 if (name[0] == '$' && name[1] == NUL) 9710 return lastbuf; 9711 9712 buf = buflist_find_by_name(name, curtab_only); 9713 9714 /* If not found, try expanding the name, like done for bufexists(). */ 9715 if (buf == NULL) 9716 buf = find_buffer(tv); 9717 9718 return buf; 9719 } 9720 9721 /* 9722 * "bufname(expr)" function 9723 */ 9724 static void 9725 f_bufname(typval_T *argvars, typval_T *rettv) 9726 { 9727 buf_T *buf; 9728 9729 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9730 ++emsg_off; 9731 buf = get_buf_tv(&argvars[0], FALSE); 9732 rettv->v_type = VAR_STRING; 9733 if (buf != NULL && buf->b_fname != NULL) 9734 rettv->vval.v_string = vim_strsave(buf->b_fname); 9735 else 9736 rettv->vval.v_string = NULL; 9737 --emsg_off; 9738 } 9739 9740 /* 9741 * "bufnr(expr)" function 9742 */ 9743 static void 9744 f_bufnr(typval_T *argvars, typval_T *rettv) 9745 { 9746 buf_T *buf; 9747 int error = FALSE; 9748 char_u *name; 9749 9750 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9751 ++emsg_off; 9752 buf = get_buf_tv(&argvars[0], FALSE); 9753 --emsg_off; 9754 9755 /* If the buffer isn't found and the second argument is not zero create a 9756 * new buffer. */ 9757 if (buf == NULL 9758 && argvars[1].v_type != VAR_UNKNOWN 9759 && get_tv_number_chk(&argvars[1], &error) != 0 9760 && !error 9761 && (name = get_tv_string_chk(&argvars[0])) != NULL 9762 && !error) 9763 buf = buflist_new(name, NULL, (linenr_T)1, 0); 9764 9765 if (buf != NULL) 9766 rettv->vval.v_number = buf->b_fnum; 9767 else 9768 rettv->vval.v_number = -1; 9769 } 9770 9771 /* 9772 * "bufwinnr(nr)" function 9773 */ 9774 static void 9775 f_bufwinnr(typval_T *argvars, typval_T *rettv) 9776 { 9777 #ifdef FEAT_WINDOWS 9778 win_T *wp; 9779 int winnr = 0; 9780 #endif 9781 buf_T *buf; 9782 9783 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9784 ++emsg_off; 9785 buf = get_buf_tv(&argvars[0], TRUE); 9786 #ifdef FEAT_WINDOWS 9787 for (wp = firstwin; wp; wp = wp->w_next) 9788 { 9789 ++winnr; 9790 if (wp->w_buffer == buf) 9791 break; 9792 } 9793 rettv->vval.v_number = (wp != NULL ? winnr : -1); 9794 #else 9795 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 9796 #endif 9797 --emsg_off; 9798 } 9799 9800 /* 9801 * "byte2line(byte)" function 9802 */ 9803 static void 9804 f_byte2line(typval_T *argvars UNUSED, typval_T *rettv) 9805 { 9806 #ifndef FEAT_BYTEOFF 9807 rettv->vval.v_number = -1; 9808 #else 9809 long boff = 0; 9810 9811 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 9812 if (boff < 0) 9813 rettv->vval.v_number = -1; 9814 else 9815 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 9816 (linenr_T)0, &boff); 9817 #endif 9818 } 9819 9820 static void 9821 byteidx(typval_T *argvars, typval_T *rettv, int comp UNUSED) 9822 { 9823 #ifdef FEAT_MBYTE 9824 char_u *t; 9825 #endif 9826 char_u *str; 9827 long idx; 9828 9829 str = get_tv_string_chk(&argvars[0]); 9830 idx = get_tv_number_chk(&argvars[1], NULL); 9831 rettv->vval.v_number = -1; 9832 if (str == NULL || idx < 0) 9833 return; 9834 9835 #ifdef FEAT_MBYTE 9836 t = str; 9837 for ( ; idx > 0; idx--) 9838 { 9839 if (*t == NUL) /* EOL reached */ 9840 return; 9841 if (enc_utf8 && comp) 9842 t += utf_ptr2len(t); 9843 else 9844 t += (*mb_ptr2len)(t); 9845 } 9846 rettv->vval.v_number = (varnumber_T)(t - str); 9847 #else 9848 if ((size_t)idx <= STRLEN(str)) 9849 rettv->vval.v_number = idx; 9850 #endif 9851 } 9852 9853 /* 9854 * "byteidx()" function 9855 */ 9856 static void 9857 f_byteidx(typval_T *argvars, typval_T *rettv) 9858 { 9859 byteidx(argvars, rettv, FALSE); 9860 } 9861 9862 /* 9863 * "byteidxcomp()" function 9864 */ 9865 static void 9866 f_byteidxcomp(typval_T *argvars, typval_T *rettv) 9867 { 9868 byteidx(argvars, rettv, TRUE); 9869 } 9870 9871 int 9872 func_call( 9873 char_u *name, 9874 typval_T *args, 9875 partial_T *partial, 9876 dict_T *selfdict, 9877 typval_T *rettv) 9878 { 9879 listitem_T *item; 9880 typval_T argv[MAX_FUNC_ARGS + 1]; 9881 int argc = 0; 9882 int dummy; 9883 int r = 0; 9884 9885 for (item = args->vval.v_list->lv_first; item != NULL; 9886 item = item->li_next) 9887 { 9888 if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) 9889 { 9890 EMSG(_("E699: Too many arguments")); 9891 break; 9892 } 9893 /* Make a copy of each argument. This is needed to be able to set 9894 * v_lock to VAR_FIXED in the copy without changing the original list. 9895 */ 9896 copy_tv(&item->li_tv, &argv[argc++]); 9897 } 9898 9899 if (item == NULL) 9900 r = call_func(name, (int)STRLEN(name), rettv, argc, argv, 9901 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 9902 &dummy, TRUE, partial, selfdict); 9903 9904 /* Free the arguments. */ 9905 while (argc > 0) 9906 clear_tv(&argv[--argc]); 9907 9908 return r; 9909 } 9910 9911 /* 9912 * "call(func, arglist [, dict])" function 9913 */ 9914 static void 9915 f_call(typval_T *argvars, typval_T *rettv) 9916 { 9917 char_u *func; 9918 partial_T *partial = NULL; 9919 dict_T *selfdict = NULL; 9920 9921 if (argvars[1].v_type != VAR_LIST) 9922 { 9923 EMSG(_(e_listreq)); 9924 return; 9925 } 9926 if (argvars[1].vval.v_list == NULL) 9927 return; 9928 9929 if (argvars[0].v_type == VAR_FUNC) 9930 func = argvars[0].vval.v_string; 9931 else if (argvars[0].v_type == VAR_PARTIAL) 9932 { 9933 partial = argvars[0].vval.v_partial; 9934 func = partial->pt_name; 9935 } 9936 else 9937 func = get_tv_string(&argvars[0]); 9938 if (*func == NUL) 9939 return; /* type error or empty name */ 9940 9941 if (argvars[2].v_type != VAR_UNKNOWN) 9942 { 9943 if (argvars[2].v_type != VAR_DICT) 9944 { 9945 EMSG(_(e_dictreq)); 9946 return; 9947 } 9948 selfdict = argvars[2].vval.v_dict; 9949 } 9950 9951 (void)func_call(func, &argvars[1], partial, selfdict, rettv); 9952 } 9953 9954 #ifdef FEAT_FLOAT 9955 /* 9956 * "ceil({float})" function 9957 */ 9958 static void 9959 f_ceil(typval_T *argvars, typval_T *rettv) 9960 { 9961 float_T f = 0.0; 9962 9963 rettv->v_type = VAR_FLOAT; 9964 if (get_float_arg(argvars, &f) == OK) 9965 rettv->vval.v_float = ceil(f); 9966 else 9967 rettv->vval.v_float = 0.0; 9968 } 9969 #endif 9970 9971 #ifdef FEAT_JOB_CHANNEL 9972 /* 9973 * "ch_close()" function 9974 */ 9975 static void 9976 f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) 9977 { 9978 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 9979 9980 if (channel != NULL) 9981 { 9982 channel_close(channel, FALSE); 9983 channel_clear(channel); 9984 } 9985 } 9986 9987 /* 9988 * "ch_getbufnr()" function 9989 */ 9990 static void 9991 f_ch_getbufnr(typval_T *argvars, typval_T *rettv) 9992 { 9993 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 9994 9995 rettv->vval.v_number = -1; 9996 if (channel != NULL) 9997 { 9998 char_u *what = get_tv_string(&argvars[1]); 9999 int part; 10000 10001 if (STRCMP(what, "err") == 0) 10002 part = PART_ERR; 10003 else if (STRCMP(what, "out") == 0) 10004 part = PART_OUT; 10005 else if (STRCMP(what, "in") == 0) 10006 part = PART_IN; 10007 else 10008 part = PART_SOCK; 10009 if (channel->ch_part[part].ch_buffer != NULL) 10010 rettv->vval.v_number = channel->ch_part[part].ch_buffer->b_fnum; 10011 } 10012 } 10013 10014 /* 10015 * "ch_getjob()" function 10016 */ 10017 static void 10018 f_ch_getjob(typval_T *argvars, typval_T *rettv) 10019 { 10020 channel_T *channel = get_channel_arg(&argvars[0], TRUE); 10021 10022 if (channel != NULL) 10023 { 10024 rettv->v_type = VAR_JOB; 10025 rettv->vval.v_job = channel->ch_job; 10026 if (channel->ch_job != NULL) 10027 ++channel->ch_job->jv_refcount; 10028 } 10029 } 10030 10031 /* 10032 * "ch_log()" function 10033 */ 10034 static void 10035 f_ch_log(typval_T *argvars, typval_T *rettv UNUSED) 10036 { 10037 char_u *msg = get_tv_string(&argvars[0]); 10038 channel_T *channel = NULL; 10039 10040 if (argvars[1].v_type != VAR_UNKNOWN) 10041 channel = get_channel_arg(&argvars[1], TRUE); 10042 10043 ch_log(channel, (char *)msg); 10044 } 10045 10046 /* 10047 * "ch_logfile()" function 10048 */ 10049 static void 10050 f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) 10051 { 10052 char_u *fname; 10053 char_u *opt = (char_u *)""; 10054 char_u buf[NUMBUFLEN]; 10055 10056 fname = get_tv_string(&argvars[0]); 10057 if (argvars[1].v_type == VAR_STRING) 10058 opt = get_tv_string_buf(&argvars[1], buf); 10059 ch_logfile(fname, opt); 10060 } 10061 10062 /* 10063 * "ch_open()" function 10064 */ 10065 static void 10066 f_ch_open(typval_T *argvars, typval_T *rettv) 10067 { 10068 rettv->v_type = VAR_CHANNEL; 10069 rettv->vval.v_channel = channel_open_func(argvars); 10070 } 10071 10072 /* 10073 * "ch_read()" function 10074 */ 10075 static void 10076 f_ch_read(typval_T *argvars, typval_T *rettv) 10077 { 10078 common_channel_read(argvars, rettv, FALSE); 10079 } 10080 10081 /* 10082 * "ch_readraw()" function 10083 */ 10084 static void 10085 f_ch_readraw(typval_T *argvars, typval_T *rettv) 10086 { 10087 common_channel_read(argvars, rettv, TRUE); 10088 } 10089 10090 /* 10091 * "ch_evalexpr()" function 10092 */ 10093 static void 10094 f_ch_evalexpr(typval_T *argvars, typval_T *rettv) 10095 { 10096 ch_expr_common(argvars, rettv, TRUE); 10097 } 10098 10099 /* 10100 * "ch_sendexpr()" function 10101 */ 10102 static void 10103 f_ch_sendexpr(typval_T *argvars, typval_T *rettv) 10104 { 10105 ch_expr_common(argvars, rettv, FALSE); 10106 } 10107 10108 /* 10109 * "ch_evalraw()" function 10110 */ 10111 static void 10112 f_ch_evalraw(typval_T *argvars, typval_T *rettv) 10113 { 10114 ch_raw_common(argvars, rettv, TRUE); 10115 } 10116 10117 /* 10118 * "ch_sendraw()" function 10119 */ 10120 static void 10121 f_ch_sendraw(typval_T *argvars, typval_T *rettv) 10122 { 10123 ch_raw_common(argvars, rettv, FALSE); 10124 } 10125 10126 /* 10127 * "ch_setoptions()" function 10128 */ 10129 static void 10130 f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED) 10131 { 10132 channel_T *channel; 10133 jobopt_T opt; 10134 10135 channel = get_channel_arg(&argvars[0], TRUE); 10136 if (channel == NULL) 10137 return; 10138 clear_job_options(&opt); 10139 if (get_job_options(&argvars[1], &opt, 10140 JO_CB_ALL + JO_TIMEOUT_ALL + JO_MODE_ALL) == FAIL) 10141 return; 10142 channel_set_options(channel, &opt); 10143 } 10144 10145 /* 10146 * "ch_status()" function 10147 */ 10148 static void 10149 f_ch_status(typval_T *argvars, typval_T *rettv) 10150 { 10151 channel_T *channel; 10152 10153 /* return an empty string by default */ 10154 rettv->v_type = VAR_STRING; 10155 rettv->vval.v_string = NULL; 10156 10157 channel = get_channel_arg(&argvars[0], FALSE); 10158 rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel)); 10159 } 10160 #endif 10161 10162 /* 10163 * "changenr()" function 10164 */ 10165 static void 10166 f_changenr(typval_T *argvars UNUSED, typval_T *rettv) 10167 { 10168 rettv->vval.v_number = curbuf->b_u_seq_cur; 10169 } 10170 10171 /* 10172 * "char2nr(string)" function 10173 */ 10174 static void 10175 f_char2nr(typval_T *argvars, typval_T *rettv) 10176 { 10177 #ifdef FEAT_MBYTE 10178 if (has_mbyte) 10179 { 10180 int utf8 = 0; 10181 10182 if (argvars[1].v_type != VAR_UNKNOWN) 10183 utf8 = get_tv_number_chk(&argvars[1], NULL); 10184 10185 if (utf8) 10186 rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0])); 10187 else 10188 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 10189 } 10190 else 10191 #endif 10192 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 10193 } 10194 10195 /* 10196 * "cindent(lnum)" function 10197 */ 10198 static void 10199 f_cindent(typval_T *argvars UNUSED, typval_T *rettv) 10200 { 10201 #ifdef FEAT_CINDENT 10202 pos_T pos; 10203 linenr_T lnum; 10204 10205 pos = curwin->w_cursor; 10206 lnum = get_tv_lnum(argvars); 10207 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10208 { 10209 curwin->w_cursor.lnum = lnum; 10210 rettv->vval.v_number = get_c_indent(); 10211 curwin->w_cursor = pos; 10212 } 10213 else 10214 #endif 10215 rettv->vval.v_number = -1; 10216 } 10217 10218 /* 10219 * "clearmatches()" function 10220 */ 10221 static void 10222 f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10223 { 10224 #ifdef FEAT_SEARCH_EXTRA 10225 clear_matches(curwin); 10226 #endif 10227 } 10228 10229 /* 10230 * "col(string)" function 10231 */ 10232 static void 10233 f_col(typval_T *argvars, typval_T *rettv) 10234 { 10235 colnr_T col = 0; 10236 pos_T *fp; 10237 int fnum = curbuf->b_fnum; 10238 10239 fp = var2fpos(&argvars[0], FALSE, &fnum); 10240 if (fp != NULL && fnum == curbuf->b_fnum) 10241 { 10242 if (fp->col == MAXCOL) 10243 { 10244 /* '> can be MAXCOL, get the length of the line then */ 10245 if (fp->lnum <= curbuf->b_ml.ml_line_count) 10246 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 10247 else 10248 col = MAXCOL; 10249 } 10250 else 10251 { 10252 col = fp->col + 1; 10253 #ifdef FEAT_VIRTUALEDIT 10254 /* col(".") when the cursor is on the NUL at the end of the line 10255 * because of "coladd" can be seen as an extra column. */ 10256 if (virtual_active() && fp == &curwin->w_cursor) 10257 { 10258 char_u *p = ml_get_cursor(); 10259 10260 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 10261 curwin->w_virtcol - curwin->w_cursor.coladd)) 10262 { 10263 # ifdef FEAT_MBYTE 10264 int l; 10265 10266 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 10267 col += l; 10268 # else 10269 if (*p != NUL && p[1] == NUL) 10270 ++col; 10271 # endif 10272 } 10273 } 10274 #endif 10275 } 10276 } 10277 rettv->vval.v_number = col; 10278 } 10279 10280 #if defined(FEAT_INS_EXPAND) 10281 /* 10282 * "complete()" function 10283 */ 10284 static void 10285 f_complete(typval_T *argvars, typval_T *rettv UNUSED) 10286 { 10287 int startcol; 10288 10289 if ((State & INSERT) == 0) 10290 { 10291 EMSG(_("E785: complete() can only be used in Insert mode")); 10292 return; 10293 } 10294 10295 /* Check for undo allowed here, because if something was already inserted 10296 * the line was already saved for undo and this check isn't done. */ 10297 if (!undo_allowed()) 10298 return; 10299 10300 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 10301 { 10302 EMSG(_(e_invarg)); 10303 return; 10304 } 10305 10306 startcol = get_tv_number_chk(&argvars[0], NULL); 10307 if (startcol <= 0) 10308 return; 10309 10310 set_completion(startcol - 1, argvars[1].vval.v_list); 10311 } 10312 10313 /* 10314 * "complete_add()" function 10315 */ 10316 static void 10317 f_complete_add(typval_T *argvars, typval_T *rettv) 10318 { 10319 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 10320 } 10321 10322 /* 10323 * "complete_check()" function 10324 */ 10325 static void 10326 f_complete_check(typval_T *argvars UNUSED, typval_T *rettv) 10327 { 10328 int saved = RedrawingDisabled; 10329 10330 RedrawingDisabled = 0; 10331 ins_compl_check_keys(0); 10332 rettv->vval.v_number = compl_interrupted; 10333 RedrawingDisabled = saved; 10334 } 10335 #endif 10336 10337 /* 10338 * "confirm(message, buttons[, default [, type]])" function 10339 */ 10340 static void 10341 f_confirm(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10342 { 10343 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 10344 char_u *message; 10345 char_u *buttons = NULL; 10346 char_u buf[NUMBUFLEN]; 10347 char_u buf2[NUMBUFLEN]; 10348 int def = 1; 10349 int type = VIM_GENERIC; 10350 char_u *typestr; 10351 int error = FALSE; 10352 10353 message = get_tv_string_chk(&argvars[0]); 10354 if (message == NULL) 10355 error = TRUE; 10356 if (argvars[1].v_type != VAR_UNKNOWN) 10357 { 10358 buttons = get_tv_string_buf_chk(&argvars[1], buf); 10359 if (buttons == NULL) 10360 error = TRUE; 10361 if (argvars[2].v_type != VAR_UNKNOWN) 10362 { 10363 def = get_tv_number_chk(&argvars[2], &error); 10364 if (argvars[3].v_type != VAR_UNKNOWN) 10365 { 10366 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 10367 if (typestr == NULL) 10368 error = TRUE; 10369 else 10370 { 10371 switch (TOUPPER_ASC(*typestr)) 10372 { 10373 case 'E': type = VIM_ERROR; break; 10374 case 'Q': type = VIM_QUESTION; break; 10375 case 'I': type = VIM_INFO; break; 10376 case 'W': type = VIM_WARNING; break; 10377 case 'G': type = VIM_GENERIC; break; 10378 } 10379 } 10380 } 10381 } 10382 } 10383 10384 if (buttons == NULL || *buttons == NUL) 10385 buttons = (char_u *)_("&Ok"); 10386 10387 if (!error) 10388 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 10389 def, NULL, FALSE); 10390 #endif 10391 } 10392 10393 /* 10394 * "copy()" function 10395 */ 10396 static void 10397 f_copy(typval_T *argvars, typval_T *rettv) 10398 { 10399 item_copy(&argvars[0], rettv, FALSE, 0); 10400 } 10401 10402 #ifdef FEAT_FLOAT 10403 /* 10404 * "cos()" function 10405 */ 10406 static void 10407 f_cos(typval_T *argvars, typval_T *rettv) 10408 { 10409 float_T f = 0.0; 10410 10411 rettv->v_type = VAR_FLOAT; 10412 if (get_float_arg(argvars, &f) == OK) 10413 rettv->vval.v_float = cos(f); 10414 else 10415 rettv->vval.v_float = 0.0; 10416 } 10417 10418 /* 10419 * "cosh()" function 10420 */ 10421 static void 10422 f_cosh(typval_T *argvars, typval_T *rettv) 10423 { 10424 float_T f = 0.0; 10425 10426 rettv->v_type = VAR_FLOAT; 10427 if (get_float_arg(argvars, &f) == OK) 10428 rettv->vval.v_float = cosh(f); 10429 else 10430 rettv->vval.v_float = 0.0; 10431 } 10432 #endif 10433 10434 /* 10435 * "count()" function 10436 */ 10437 static void 10438 f_count(typval_T *argvars, typval_T *rettv) 10439 { 10440 long n = 0; 10441 int ic = FALSE; 10442 10443 if (argvars[0].v_type == VAR_LIST) 10444 { 10445 listitem_T *li; 10446 list_T *l; 10447 long idx; 10448 10449 if ((l = argvars[0].vval.v_list) != NULL) 10450 { 10451 li = l->lv_first; 10452 if (argvars[2].v_type != VAR_UNKNOWN) 10453 { 10454 int error = FALSE; 10455 10456 ic = get_tv_number_chk(&argvars[2], &error); 10457 if (argvars[3].v_type != VAR_UNKNOWN) 10458 { 10459 idx = get_tv_number_chk(&argvars[3], &error); 10460 if (!error) 10461 { 10462 li = list_find(l, idx); 10463 if (li == NULL) 10464 EMSGN(_(e_listidx), idx); 10465 } 10466 } 10467 if (error) 10468 li = NULL; 10469 } 10470 10471 for ( ; li != NULL; li = li->li_next) 10472 if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE)) 10473 ++n; 10474 } 10475 } 10476 else if (argvars[0].v_type == VAR_DICT) 10477 { 10478 int todo; 10479 dict_T *d; 10480 hashitem_T *hi; 10481 10482 if ((d = argvars[0].vval.v_dict) != NULL) 10483 { 10484 int error = FALSE; 10485 10486 if (argvars[2].v_type != VAR_UNKNOWN) 10487 { 10488 ic = get_tv_number_chk(&argvars[2], &error); 10489 if (argvars[3].v_type != VAR_UNKNOWN) 10490 EMSG(_(e_invarg)); 10491 } 10492 10493 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 10494 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 10495 { 10496 if (!HASHITEM_EMPTY(hi)) 10497 { 10498 --todo; 10499 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE)) 10500 ++n; 10501 } 10502 } 10503 } 10504 } 10505 else 10506 EMSG2(_(e_listdictarg), "count()"); 10507 rettv->vval.v_number = n; 10508 } 10509 10510 /* 10511 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 10512 * 10513 * Checks the existence of a cscope connection. 10514 */ 10515 static void 10516 f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10517 { 10518 #ifdef FEAT_CSCOPE 10519 int num = 0; 10520 char_u *dbpath = NULL; 10521 char_u *prepend = NULL; 10522 char_u buf[NUMBUFLEN]; 10523 10524 if (argvars[0].v_type != VAR_UNKNOWN 10525 && argvars[1].v_type != VAR_UNKNOWN) 10526 { 10527 num = (int)get_tv_number(&argvars[0]); 10528 dbpath = get_tv_string(&argvars[1]); 10529 if (argvars[2].v_type != VAR_UNKNOWN) 10530 prepend = get_tv_string_buf(&argvars[2], buf); 10531 } 10532 10533 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 10534 #endif 10535 } 10536 10537 /* 10538 * "cursor(lnum, col)" function, or 10539 * "cursor(list)" 10540 * 10541 * Moves the cursor to the specified line and column. 10542 * Returns 0 when the position could be set, -1 otherwise. 10543 */ 10544 static void 10545 f_cursor(typval_T *argvars, typval_T *rettv) 10546 { 10547 long line, col; 10548 #ifdef FEAT_VIRTUALEDIT 10549 long coladd = 0; 10550 #endif 10551 int set_curswant = TRUE; 10552 10553 rettv->vval.v_number = -1; 10554 if (argvars[1].v_type == VAR_UNKNOWN) 10555 { 10556 pos_T pos; 10557 colnr_T curswant = -1; 10558 10559 if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL) 10560 { 10561 EMSG(_(e_invarg)); 10562 return; 10563 } 10564 line = pos.lnum; 10565 col = pos.col; 10566 #ifdef FEAT_VIRTUALEDIT 10567 coladd = pos.coladd; 10568 #endif 10569 if (curswant >= 0) 10570 { 10571 curwin->w_curswant = curswant - 1; 10572 set_curswant = FALSE; 10573 } 10574 } 10575 else 10576 { 10577 line = get_tv_lnum(argvars); 10578 col = get_tv_number_chk(&argvars[1], NULL); 10579 #ifdef FEAT_VIRTUALEDIT 10580 if (argvars[2].v_type != VAR_UNKNOWN) 10581 coladd = get_tv_number_chk(&argvars[2], NULL); 10582 #endif 10583 } 10584 if (line < 0 || col < 0 10585 #ifdef FEAT_VIRTUALEDIT 10586 || coladd < 0 10587 #endif 10588 ) 10589 return; /* type error; errmsg already given */ 10590 if (line > 0) 10591 curwin->w_cursor.lnum = line; 10592 if (col > 0) 10593 curwin->w_cursor.col = col - 1; 10594 #ifdef FEAT_VIRTUALEDIT 10595 curwin->w_cursor.coladd = coladd; 10596 #endif 10597 10598 /* Make sure the cursor is in a valid position. */ 10599 check_cursor(); 10600 #ifdef FEAT_MBYTE 10601 /* Correct cursor for multi-byte character. */ 10602 if (has_mbyte) 10603 mb_adjust_cursor(); 10604 #endif 10605 10606 curwin->w_set_curswant = set_curswant; 10607 rettv->vval.v_number = 0; 10608 } 10609 10610 /* 10611 * "deepcopy()" function 10612 */ 10613 static void 10614 f_deepcopy(typval_T *argvars, typval_T *rettv) 10615 { 10616 int noref = 0; 10617 10618 if (argvars[1].v_type != VAR_UNKNOWN) 10619 noref = get_tv_number_chk(&argvars[1], NULL); 10620 if (noref < 0 || noref > 1) 10621 EMSG(_(e_invarg)); 10622 else 10623 { 10624 current_copyID += COPYID_INC; 10625 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 10626 } 10627 } 10628 10629 /* 10630 * "delete()" function 10631 */ 10632 static void 10633 f_delete(typval_T *argvars, typval_T *rettv) 10634 { 10635 char_u nbuf[NUMBUFLEN]; 10636 char_u *name; 10637 char_u *flags; 10638 10639 rettv->vval.v_number = -1; 10640 if (check_restricted() || check_secure()) 10641 return; 10642 10643 name = get_tv_string(&argvars[0]); 10644 if (name == NULL || *name == NUL) 10645 { 10646 EMSG(_(e_invarg)); 10647 return; 10648 } 10649 10650 if (argvars[1].v_type != VAR_UNKNOWN) 10651 flags = get_tv_string_buf(&argvars[1], nbuf); 10652 else 10653 flags = (char_u *)""; 10654 10655 if (*flags == NUL) 10656 /* delete a file */ 10657 rettv->vval.v_number = mch_remove(name) == 0 ? 0 : -1; 10658 else if (STRCMP(flags, "d") == 0) 10659 /* delete an empty directory */ 10660 rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1; 10661 else if (STRCMP(flags, "rf") == 0) 10662 /* delete a directory recursively */ 10663 rettv->vval.v_number = delete_recursive(name); 10664 else 10665 EMSG2(_(e_invexpr2), flags); 10666 } 10667 10668 /* 10669 * "did_filetype()" function 10670 */ 10671 static void 10672 f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10673 { 10674 #ifdef FEAT_AUTOCMD 10675 rettv->vval.v_number = did_filetype; 10676 #endif 10677 } 10678 10679 /* 10680 * "diff_filler()" function 10681 */ 10682 static void 10683 f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10684 { 10685 #ifdef FEAT_DIFF 10686 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 10687 #endif 10688 } 10689 10690 /* 10691 * "diff_hlID()" function 10692 */ 10693 static void 10694 f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 10695 { 10696 #ifdef FEAT_DIFF 10697 linenr_T lnum = get_tv_lnum(argvars); 10698 static linenr_T prev_lnum = 0; 10699 static int changedtick = 0; 10700 static int fnum = 0; 10701 static int change_start = 0; 10702 static int change_end = 0; 10703 static hlf_T hlID = (hlf_T)0; 10704 int filler_lines; 10705 int col; 10706 10707 if (lnum < 0) /* ignore type error in {lnum} arg */ 10708 lnum = 0; 10709 if (lnum != prev_lnum 10710 || changedtick != curbuf->b_changedtick 10711 || fnum != curbuf->b_fnum) 10712 { 10713 /* New line, buffer, change: need to get the values. */ 10714 filler_lines = diff_check(curwin, lnum); 10715 if (filler_lines < 0) 10716 { 10717 if (filler_lines == -1) 10718 { 10719 change_start = MAXCOL; 10720 change_end = -1; 10721 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 10722 hlID = HLF_ADD; /* added line */ 10723 else 10724 hlID = HLF_CHD; /* changed line */ 10725 } 10726 else 10727 hlID = HLF_ADD; /* added line */ 10728 } 10729 else 10730 hlID = (hlf_T)0; 10731 prev_lnum = lnum; 10732 changedtick = curbuf->b_changedtick; 10733 fnum = curbuf->b_fnum; 10734 } 10735 10736 if (hlID == HLF_CHD || hlID == HLF_TXD) 10737 { 10738 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 10739 if (col >= change_start && col <= change_end) 10740 hlID = HLF_TXD; /* changed text */ 10741 else 10742 hlID = HLF_CHD; /* changed line */ 10743 } 10744 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 10745 #endif 10746 } 10747 10748 /* 10749 * "disable_char_avail_for_testing({expr})" function 10750 */ 10751 static void 10752 f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv UNUSED) 10753 { 10754 disable_char_avail_for_testing = get_tv_number(&argvars[0]); 10755 } 10756 10757 /* 10758 * "empty({expr})" function 10759 */ 10760 static void 10761 f_empty(typval_T *argvars, typval_T *rettv) 10762 { 10763 int n = FALSE; 10764 10765 switch (argvars[0].v_type) 10766 { 10767 case VAR_STRING: 10768 case VAR_FUNC: 10769 n = argvars[0].vval.v_string == NULL 10770 || *argvars[0].vval.v_string == NUL; 10771 break; 10772 case VAR_PARTIAL: 10773 n = FALSE; 10774 break; 10775 case VAR_NUMBER: 10776 n = argvars[0].vval.v_number == 0; 10777 break; 10778 case VAR_FLOAT: 10779 #ifdef FEAT_FLOAT 10780 n = argvars[0].vval.v_float == 0.0; 10781 break; 10782 #endif 10783 case VAR_LIST: 10784 n = argvars[0].vval.v_list == NULL 10785 || argvars[0].vval.v_list->lv_first == NULL; 10786 break; 10787 case VAR_DICT: 10788 n = argvars[0].vval.v_dict == NULL 10789 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 10790 break; 10791 case VAR_SPECIAL: 10792 n = argvars[0].vval.v_number != VVAL_TRUE; 10793 break; 10794 10795 case VAR_JOB: 10796 #ifdef FEAT_JOB_CHANNEL 10797 n = argvars[0].vval.v_job == NULL 10798 || argvars[0].vval.v_job->jv_status != JOB_STARTED; 10799 break; 10800 #endif 10801 case VAR_CHANNEL: 10802 #ifdef FEAT_JOB_CHANNEL 10803 n = argvars[0].vval.v_channel == NULL 10804 || !channel_is_open(argvars[0].vval.v_channel); 10805 break; 10806 #endif 10807 case VAR_UNKNOWN: 10808 EMSG2(_(e_intern2), "f_empty(UNKNOWN)"); 10809 n = TRUE; 10810 break; 10811 } 10812 10813 rettv->vval.v_number = n; 10814 } 10815 10816 /* 10817 * "escape({string}, {chars})" function 10818 */ 10819 static void 10820 f_escape(typval_T *argvars, typval_T *rettv) 10821 { 10822 char_u buf[NUMBUFLEN]; 10823 10824 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 10825 get_tv_string_buf(&argvars[1], buf)); 10826 rettv->v_type = VAR_STRING; 10827 } 10828 10829 /* 10830 * "eval()" function 10831 */ 10832 static void 10833 f_eval(typval_T *argvars, typval_T *rettv) 10834 { 10835 char_u *s, *p; 10836 10837 s = get_tv_string_chk(&argvars[0]); 10838 if (s != NULL) 10839 s = skipwhite(s); 10840 10841 p = s; 10842 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 10843 { 10844 if (p != NULL && !aborting()) 10845 EMSG2(_(e_invexpr2), p); 10846 need_clr_eos = FALSE; 10847 rettv->v_type = VAR_NUMBER; 10848 rettv->vval.v_number = 0; 10849 } 10850 else if (*s != NUL) 10851 EMSG(_(e_trailing)); 10852 } 10853 10854 /* 10855 * "eventhandler()" function 10856 */ 10857 static void 10858 f_eventhandler(typval_T *argvars UNUSED, typval_T *rettv) 10859 { 10860 rettv->vval.v_number = vgetc_busy; 10861 } 10862 10863 /* 10864 * "executable()" function 10865 */ 10866 static void 10867 f_executable(typval_T *argvars, typval_T *rettv) 10868 { 10869 char_u *name = get_tv_string(&argvars[0]); 10870 10871 /* Check in $PATH and also check directly if there is a directory name. */ 10872 rettv->vval.v_number = mch_can_exe(name, NULL, TRUE) 10873 || (gettail(name) != name && mch_can_exe(name, NULL, FALSE)); 10874 } 10875 10876 /* 10877 * "exepath()" function 10878 */ 10879 static void 10880 f_exepath(typval_T *argvars, typval_T *rettv) 10881 { 10882 char_u *p = NULL; 10883 10884 (void)mch_can_exe(get_tv_string(&argvars[0]), &p, TRUE); 10885 rettv->v_type = VAR_STRING; 10886 rettv->vval.v_string = p; 10887 } 10888 10889 /* 10890 * "exists()" function 10891 */ 10892 static void 10893 f_exists(typval_T *argvars, typval_T *rettv) 10894 { 10895 char_u *p; 10896 char_u *name; 10897 int n = FALSE; 10898 int len = 0; 10899 10900 p = get_tv_string(&argvars[0]); 10901 if (*p == '$') /* environment variable */ 10902 { 10903 /* first try "normal" environment variables (fast) */ 10904 if (mch_getenv(p + 1) != NULL) 10905 n = TRUE; 10906 else 10907 { 10908 /* try expanding things like $VIM and ${HOME} */ 10909 p = expand_env_save(p); 10910 if (p != NULL && *p != '$') 10911 n = TRUE; 10912 vim_free(p); 10913 } 10914 } 10915 else if (*p == '&' || *p == '+') /* option */ 10916 { 10917 n = (get_option_tv(&p, NULL, TRUE) == OK); 10918 if (*skipwhite(p) != NUL) 10919 n = FALSE; /* trailing garbage */ 10920 } 10921 else if (*p == '*') /* internal or user defined function */ 10922 { 10923 n = function_exists(p + 1); 10924 } 10925 else if (*p == ':') 10926 { 10927 n = cmd_exists(p + 1); 10928 } 10929 else if (*p == '#') 10930 { 10931 #ifdef FEAT_AUTOCMD 10932 if (p[1] == '#') 10933 n = autocmd_supported(p + 2); 10934 else 10935 n = au_exists(p + 1); 10936 #endif 10937 } 10938 else /* internal variable */ 10939 { 10940 char_u *tofree; 10941 typval_T tv; 10942 10943 /* get_name_len() takes care of expanding curly braces */ 10944 name = p; 10945 len = get_name_len(&p, &tofree, TRUE, FALSE); 10946 if (len > 0) 10947 { 10948 if (tofree != NULL) 10949 name = tofree; 10950 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK); 10951 if (n) 10952 { 10953 /* handle d.key, l[idx], f(expr) */ 10954 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 10955 if (n) 10956 clear_tv(&tv); 10957 } 10958 } 10959 if (*p != NUL) 10960 n = FALSE; 10961 10962 vim_free(tofree); 10963 } 10964 10965 rettv->vval.v_number = n; 10966 } 10967 10968 #ifdef FEAT_FLOAT 10969 /* 10970 * "exp()" function 10971 */ 10972 static void 10973 f_exp(typval_T *argvars, typval_T *rettv) 10974 { 10975 float_T f = 0.0; 10976 10977 rettv->v_type = VAR_FLOAT; 10978 if (get_float_arg(argvars, &f) == OK) 10979 rettv->vval.v_float = exp(f); 10980 else 10981 rettv->vval.v_float = 0.0; 10982 } 10983 #endif 10984 10985 /* 10986 * "expand()" function 10987 */ 10988 static void 10989 f_expand(typval_T *argvars, typval_T *rettv) 10990 { 10991 char_u *s; 10992 int len; 10993 char_u *errormsg; 10994 int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 10995 expand_T xpc; 10996 int error = FALSE; 10997 char_u *result; 10998 10999 rettv->v_type = VAR_STRING; 11000 if (argvars[1].v_type != VAR_UNKNOWN 11001 && argvars[2].v_type != VAR_UNKNOWN 11002 && get_tv_number_chk(&argvars[2], &error) 11003 && !error) 11004 { 11005 rettv->v_type = VAR_LIST; 11006 rettv->vval.v_list = NULL; 11007 } 11008 11009 s = get_tv_string(&argvars[0]); 11010 if (*s == '%' || *s == '#' || *s == '<') 11011 { 11012 ++emsg_off; 11013 result = eval_vars(s, s, &len, NULL, &errormsg, NULL); 11014 --emsg_off; 11015 if (rettv->v_type == VAR_LIST) 11016 { 11017 if (rettv_list_alloc(rettv) != FAIL && result != NULL) 11018 list_append_string(rettv->vval.v_list, result, -1); 11019 else 11020 vim_free(result); 11021 } 11022 else 11023 rettv->vval.v_string = result; 11024 } 11025 else 11026 { 11027 /* When the optional second argument is non-zero, don't remove matches 11028 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11029 if (argvars[1].v_type != VAR_UNKNOWN 11030 && get_tv_number_chk(&argvars[1], &error)) 11031 options |= WILD_KEEP_ALL; 11032 if (!error) 11033 { 11034 ExpandInit(&xpc); 11035 xpc.xp_context = EXPAND_FILES; 11036 if (p_wic) 11037 options += WILD_ICASE; 11038 if (rettv->v_type == VAR_STRING) 11039 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, 11040 options, WILD_ALL); 11041 else if (rettv_list_alloc(rettv) != FAIL) 11042 { 11043 int i; 11044 11045 ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP); 11046 for (i = 0; i < xpc.xp_numfiles; i++) 11047 list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); 11048 ExpandCleanup(&xpc); 11049 } 11050 } 11051 else 11052 rettv->vval.v_string = NULL; 11053 } 11054 } 11055 11056 /* 11057 * Go over all entries in "d2" and add them to "d1". 11058 * When "action" is "error" then a duplicate key is an error. 11059 * When "action" is "force" then a duplicate key is overwritten. 11060 * Otherwise duplicate keys are ignored ("action" is "keep"). 11061 */ 11062 void 11063 dict_extend(dict_T *d1, dict_T *d2, char_u *action) 11064 { 11065 dictitem_T *di1; 11066 hashitem_T *hi2; 11067 int todo; 11068 char_u *arg_errmsg = (char_u *)N_("extend() argument"); 11069 11070 todo = (int)d2->dv_hashtab.ht_used; 11071 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 11072 { 11073 if (!HASHITEM_EMPTY(hi2)) 11074 { 11075 --todo; 11076 di1 = dict_find(d1, hi2->hi_key, -1); 11077 if (d1->dv_scope != 0) 11078 { 11079 /* Disallow replacing a builtin function in l: and g:. 11080 * Check the key to be valid when adding to any 11081 * scope. */ 11082 if (d1->dv_scope == VAR_DEF_SCOPE 11083 && HI2DI(hi2)->di_tv.v_type == VAR_FUNC 11084 && var_check_func_name(hi2->hi_key, 11085 di1 == NULL)) 11086 break; 11087 if (!valid_varname(hi2->hi_key)) 11088 break; 11089 } 11090 if (di1 == NULL) 11091 { 11092 di1 = dictitem_copy(HI2DI(hi2)); 11093 if (di1 != NULL && dict_add(d1, di1) == FAIL) 11094 dictitem_free(di1); 11095 } 11096 else if (*action == 'e') 11097 { 11098 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 11099 break; 11100 } 11101 else if (*action == 'f' && HI2DI(hi2) != di1) 11102 { 11103 if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE) 11104 || var_check_ro(di1->di_flags, arg_errmsg, TRUE)) 11105 break; 11106 clear_tv(&di1->di_tv); 11107 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 11108 } 11109 } 11110 } 11111 } 11112 11113 /* 11114 * "extend(list, list [, idx])" function 11115 * "extend(dict, dict [, action])" function 11116 */ 11117 static void 11118 f_extend(typval_T *argvars, typval_T *rettv) 11119 { 11120 char_u *arg_errmsg = (char_u *)N_("extend() argument"); 11121 11122 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 11123 { 11124 list_T *l1, *l2; 11125 listitem_T *item; 11126 long before; 11127 int error = FALSE; 11128 11129 l1 = argvars[0].vval.v_list; 11130 l2 = argvars[1].vval.v_list; 11131 if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, TRUE) 11132 && l2 != NULL) 11133 { 11134 if (argvars[2].v_type != VAR_UNKNOWN) 11135 { 11136 before = get_tv_number_chk(&argvars[2], &error); 11137 if (error) 11138 return; /* type error; errmsg already given */ 11139 11140 if (before == l1->lv_len) 11141 item = NULL; 11142 else 11143 { 11144 item = list_find(l1, before); 11145 if (item == NULL) 11146 { 11147 EMSGN(_(e_listidx), before); 11148 return; 11149 } 11150 } 11151 } 11152 else 11153 item = NULL; 11154 list_extend(l1, l2, item); 11155 11156 copy_tv(&argvars[0], rettv); 11157 } 11158 } 11159 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 11160 { 11161 dict_T *d1, *d2; 11162 char_u *action; 11163 int i; 11164 11165 d1 = argvars[0].vval.v_dict; 11166 d2 = argvars[1].vval.v_dict; 11167 if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE) 11168 && d2 != NULL) 11169 { 11170 /* Check the third argument. */ 11171 if (argvars[2].v_type != VAR_UNKNOWN) 11172 { 11173 static char *(av[]) = {"keep", "force", "error"}; 11174 11175 action = get_tv_string_chk(&argvars[2]); 11176 if (action == NULL) 11177 return; /* type error; errmsg already given */ 11178 for (i = 0; i < 3; ++i) 11179 if (STRCMP(action, av[i]) == 0) 11180 break; 11181 if (i == 3) 11182 { 11183 EMSG2(_(e_invarg2), action); 11184 return; 11185 } 11186 } 11187 else 11188 action = (char_u *)"force"; 11189 11190 dict_extend(d1, d2, action); 11191 11192 copy_tv(&argvars[0], rettv); 11193 } 11194 } 11195 else 11196 EMSG2(_(e_listdictarg), "extend()"); 11197 } 11198 11199 /* 11200 * "feedkeys()" function 11201 */ 11202 static void 11203 f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED) 11204 { 11205 int remap = TRUE; 11206 int insert = FALSE; 11207 char_u *keys, *flags; 11208 char_u nbuf[NUMBUFLEN]; 11209 int typed = FALSE; 11210 int execute = FALSE; 11211 char_u *keys_esc; 11212 11213 /* This is not allowed in the sandbox. If the commands would still be 11214 * executed in the sandbox it would be OK, but it probably happens later, 11215 * when "sandbox" is no longer set. */ 11216 if (check_secure()) 11217 return; 11218 11219 keys = get_tv_string(&argvars[0]); 11220 11221 if (argvars[1].v_type != VAR_UNKNOWN) 11222 { 11223 flags = get_tv_string_buf(&argvars[1], nbuf); 11224 for ( ; *flags != NUL; ++flags) 11225 { 11226 switch (*flags) 11227 { 11228 case 'n': remap = FALSE; break; 11229 case 'm': remap = TRUE; break; 11230 case 't': typed = TRUE; break; 11231 case 'i': insert = TRUE; break; 11232 case 'x': execute = TRUE; break; 11233 } 11234 } 11235 } 11236 11237 if (*keys != NUL || execute) 11238 { 11239 /* Need to escape K_SPECIAL and CSI before putting the string in the 11240 * typeahead buffer. */ 11241 keys_esc = vim_strsave_escape_csi(keys); 11242 if (keys_esc != NULL) 11243 { 11244 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 11245 insert ? 0 : typebuf.tb_len, !typed, FALSE); 11246 vim_free(keys_esc); 11247 if (vgetc_busy) 11248 typebuf_was_filled = TRUE; 11249 if (execute) 11250 { 11251 int save_msg_scroll = msg_scroll; 11252 11253 /* Avoid a 1 second delay when the keys start Insert mode. */ 11254 msg_scroll = FALSE; 11255 exec_normal(TRUE); 11256 msg_scroll |= save_msg_scroll; 11257 } 11258 } 11259 } 11260 } 11261 11262 /* 11263 * "filereadable()" function 11264 */ 11265 static void 11266 f_filereadable(typval_T *argvars, typval_T *rettv) 11267 { 11268 int fd; 11269 char_u *p; 11270 int n; 11271 11272 #ifndef O_NONBLOCK 11273 # define O_NONBLOCK 0 11274 #endif 11275 p = get_tv_string(&argvars[0]); 11276 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 11277 O_RDONLY | O_NONBLOCK, 0)) >= 0) 11278 { 11279 n = TRUE; 11280 close(fd); 11281 } 11282 else 11283 n = FALSE; 11284 11285 rettv->vval.v_number = n; 11286 } 11287 11288 /* 11289 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 11290 * rights to write into. 11291 */ 11292 static void 11293 f_filewritable(typval_T *argvars, typval_T *rettv) 11294 { 11295 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 11296 } 11297 11298 static void 11299 findfilendir( 11300 typval_T *argvars UNUSED, 11301 typval_T *rettv, 11302 int find_what UNUSED) 11303 { 11304 #ifdef FEAT_SEARCHPATH 11305 char_u *fname; 11306 char_u *fresult = NULL; 11307 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 11308 char_u *p; 11309 char_u pathbuf[NUMBUFLEN]; 11310 int count = 1; 11311 int first = TRUE; 11312 int error = FALSE; 11313 #endif 11314 11315 rettv->vval.v_string = NULL; 11316 rettv->v_type = VAR_STRING; 11317 11318 #ifdef FEAT_SEARCHPATH 11319 fname = get_tv_string(&argvars[0]); 11320 11321 if (argvars[1].v_type != VAR_UNKNOWN) 11322 { 11323 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 11324 if (p == NULL) 11325 error = TRUE; 11326 else 11327 { 11328 if (*p != NUL) 11329 path = p; 11330 11331 if (argvars[2].v_type != VAR_UNKNOWN) 11332 count = get_tv_number_chk(&argvars[2], &error); 11333 } 11334 } 11335 11336 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 11337 error = TRUE; 11338 11339 if (*fname != NUL && !error) 11340 { 11341 do 11342 { 11343 if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) 11344 vim_free(fresult); 11345 fresult = find_file_in_path_option(first ? fname : NULL, 11346 first ? (int)STRLEN(fname) : 0, 11347 0, first, path, 11348 find_what, 11349 curbuf->b_ffname, 11350 find_what == FINDFILE_DIR 11351 ? (char_u *)"" : curbuf->b_p_sua); 11352 first = FALSE; 11353 11354 if (fresult != NULL && rettv->v_type == VAR_LIST) 11355 list_append_string(rettv->vval.v_list, fresult, -1); 11356 11357 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 11358 } 11359 11360 if (rettv->v_type == VAR_STRING) 11361 rettv->vval.v_string = fresult; 11362 #endif 11363 } 11364 11365 static void filter_map(typval_T *argvars, typval_T *rettv, int map); 11366 static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp); 11367 11368 /* 11369 * Implementation of map() and filter(). 11370 */ 11371 static void 11372 filter_map(typval_T *argvars, typval_T *rettv, int map) 11373 { 11374 char_u buf[NUMBUFLEN]; 11375 char_u *expr; 11376 listitem_T *li, *nli; 11377 list_T *l = NULL; 11378 dictitem_T *di; 11379 hashtab_T *ht; 11380 hashitem_T *hi; 11381 dict_T *d = NULL; 11382 typval_T save_val; 11383 typval_T save_key; 11384 int rem; 11385 int todo; 11386 char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); 11387 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument") 11388 : N_("filter() argument")); 11389 int save_did_emsg; 11390 int idx = 0; 11391 11392 if (argvars[0].v_type == VAR_LIST) 11393 { 11394 if ((l = argvars[0].vval.v_list) == NULL 11395 || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE))) 11396 return; 11397 } 11398 else if (argvars[0].v_type == VAR_DICT) 11399 { 11400 if ((d = argvars[0].vval.v_dict) == NULL 11401 || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TRUE))) 11402 return; 11403 } 11404 else 11405 { 11406 EMSG2(_(e_listdictarg), ermsg); 11407 return; 11408 } 11409 11410 expr = get_tv_string_buf_chk(&argvars[1], buf); 11411 /* On type errors, the preceding call has already displayed an error 11412 * message. Avoid a misleading error message for an empty string that 11413 * was not passed as argument. */ 11414 if (expr != NULL) 11415 { 11416 prepare_vimvar(VV_VAL, &save_val); 11417 expr = skipwhite(expr); 11418 11419 /* We reset "did_emsg" to be able to detect whether an error 11420 * occurred during evaluation of the expression. */ 11421 save_did_emsg = did_emsg; 11422 did_emsg = FALSE; 11423 11424 prepare_vimvar(VV_KEY, &save_key); 11425 if (argvars[0].v_type == VAR_DICT) 11426 { 11427 vimvars[VV_KEY].vv_type = VAR_STRING; 11428 11429 ht = &d->dv_hashtab; 11430 hash_lock(ht); 11431 todo = (int)ht->ht_used; 11432 for (hi = ht->ht_array; todo > 0; ++hi) 11433 { 11434 if (!HASHITEM_EMPTY(hi)) 11435 { 11436 int r; 11437 11438 --todo; 11439 di = HI2DI(hi); 11440 if (map && 11441 (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TRUE) 11442 || var_check_ro(di->di_flags, arg_errmsg, TRUE))) 11443 break; 11444 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 11445 r = filter_map_one(&di->di_tv, expr, map, &rem); 11446 clear_tv(&vimvars[VV_KEY].vv_tv); 11447 if (r == FAIL || did_emsg) 11448 break; 11449 if (!map && rem) 11450 { 11451 if (var_check_fixed(di->di_flags, arg_errmsg, TRUE) 11452 || var_check_ro(di->di_flags, arg_errmsg, TRUE)) 11453 break; 11454 dictitem_remove(d, di); 11455 } 11456 } 11457 } 11458 hash_unlock(ht); 11459 } 11460 else 11461 { 11462 vimvars[VV_KEY].vv_type = VAR_NUMBER; 11463 11464 for (li = l->lv_first; li != NULL; li = nli) 11465 { 11466 if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) 11467 break; 11468 nli = li->li_next; 11469 vimvars[VV_KEY].vv_nr = idx; 11470 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 11471 || did_emsg) 11472 break; 11473 if (!map && rem) 11474 listitem_remove(l, li); 11475 ++idx; 11476 } 11477 } 11478 11479 restore_vimvar(VV_KEY, &save_key); 11480 restore_vimvar(VV_VAL, &save_val); 11481 11482 did_emsg |= save_did_emsg; 11483 } 11484 11485 copy_tv(&argvars[0], rettv); 11486 } 11487 11488 static int 11489 filter_map_one(typval_T *tv, char_u *expr, int map, int *remp) 11490 { 11491 typval_T rettv; 11492 char_u *s; 11493 int retval = FAIL; 11494 11495 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 11496 s = expr; 11497 if (eval1(&s, &rettv, TRUE) == FAIL) 11498 goto theend; 11499 if (*s != NUL) /* check for trailing chars after expr */ 11500 { 11501 EMSG2(_(e_invexpr2), s); 11502 clear_tv(&rettv); 11503 goto theend; 11504 } 11505 if (map) 11506 { 11507 /* map(): replace the list item value */ 11508 clear_tv(tv); 11509 rettv.v_lock = 0; 11510 *tv = rettv; 11511 } 11512 else 11513 { 11514 int error = FALSE; 11515 11516 /* filter(): when expr is zero remove the item */ 11517 *remp = (get_tv_number_chk(&rettv, &error) == 0); 11518 clear_tv(&rettv); 11519 /* On type error, nothing has been removed; return FAIL to stop the 11520 * loop. The error message was given by get_tv_number_chk(). */ 11521 if (error) 11522 goto theend; 11523 } 11524 retval = OK; 11525 theend: 11526 clear_tv(&vimvars[VV_VAL].vv_tv); 11527 return retval; 11528 } 11529 11530 /* 11531 * "filter()" function 11532 */ 11533 static void 11534 f_filter(typval_T *argvars, typval_T *rettv) 11535 { 11536 filter_map(argvars, rettv, FALSE); 11537 } 11538 11539 /* 11540 * "finddir({fname}[, {path}[, {count}]])" function 11541 */ 11542 static void 11543 f_finddir(typval_T *argvars, typval_T *rettv) 11544 { 11545 findfilendir(argvars, rettv, FINDFILE_DIR); 11546 } 11547 11548 /* 11549 * "findfile({fname}[, {path}[, {count}]])" function 11550 */ 11551 static void 11552 f_findfile(typval_T *argvars, typval_T *rettv) 11553 { 11554 findfilendir(argvars, rettv, FINDFILE_FILE); 11555 } 11556 11557 #ifdef FEAT_FLOAT 11558 /* 11559 * "float2nr({float})" function 11560 */ 11561 static void 11562 f_float2nr(typval_T *argvars, typval_T *rettv) 11563 { 11564 float_T f = 0.0; 11565 11566 if (get_float_arg(argvars, &f) == OK) 11567 { 11568 if (f < -0x7fffffff) 11569 rettv->vval.v_number = -0x7fffffff; 11570 else if (f > 0x7fffffff) 11571 rettv->vval.v_number = 0x7fffffff; 11572 else 11573 rettv->vval.v_number = (varnumber_T)f; 11574 } 11575 } 11576 11577 /* 11578 * "floor({float})" function 11579 */ 11580 static void 11581 f_floor(typval_T *argvars, typval_T *rettv) 11582 { 11583 float_T f = 0.0; 11584 11585 rettv->v_type = VAR_FLOAT; 11586 if (get_float_arg(argvars, &f) == OK) 11587 rettv->vval.v_float = floor(f); 11588 else 11589 rettv->vval.v_float = 0.0; 11590 } 11591 11592 /* 11593 * "fmod()" function 11594 */ 11595 static void 11596 f_fmod(typval_T *argvars, typval_T *rettv) 11597 { 11598 float_T fx = 0.0, fy = 0.0; 11599 11600 rettv->v_type = VAR_FLOAT; 11601 if (get_float_arg(argvars, &fx) == OK 11602 && get_float_arg(&argvars[1], &fy) == OK) 11603 rettv->vval.v_float = fmod(fx, fy); 11604 else 11605 rettv->vval.v_float = 0.0; 11606 } 11607 #endif 11608 11609 /* 11610 * "fnameescape({string})" function 11611 */ 11612 static void 11613 f_fnameescape(typval_T *argvars, typval_T *rettv) 11614 { 11615 rettv->vval.v_string = vim_strsave_fnameescape( 11616 get_tv_string(&argvars[0]), FALSE); 11617 rettv->v_type = VAR_STRING; 11618 } 11619 11620 /* 11621 * "fnamemodify({fname}, {mods})" function 11622 */ 11623 static void 11624 f_fnamemodify(typval_T *argvars, typval_T *rettv) 11625 { 11626 char_u *fname; 11627 char_u *mods; 11628 int usedlen = 0; 11629 int len; 11630 char_u *fbuf = NULL; 11631 char_u buf[NUMBUFLEN]; 11632 11633 fname = get_tv_string_chk(&argvars[0]); 11634 mods = get_tv_string_buf_chk(&argvars[1], buf); 11635 if (fname == NULL || mods == NULL) 11636 fname = NULL; 11637 else 11638 { 11639 len = (int)STRLEN(fname); 11640 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 11641 } 11642 11643 rettv->v_type = VAR_STRING; 11644 if (fname == NULL) 11645 rettv->vval.v_string = NULL; 11646 else 11647 rettv->vval.v_string = vim_strnsave(fname, len); 11648 vim_free(fbuf); 11649 } 11650 11651 static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end); 11652 11653 /* 11654 * "foldclosed()" function 11655 */ 11656 static void 11657 foldclosed_both( 11658 typval_T *argvars UNUSED, 11659 typval_T *rettv, 11660 int end UNUSED) 11661 { 11662 #ifdef FEAT_FOLDING 11663 linenr_T lnum; 11664 linenr_T first, last; 11665 11666 lnum = get_tv_lnum(argvars); 11667 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11668 { 11669 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 11670 { 11671 if (end) 11672 rettv->vval.v_number = (varnumber_T)last; 11673 else 11674 rettv->vval.v_number = (varnumber_T)first; 11675 return; 11676 } 11677 } 11678 #endif 11679 rettv->vval.v_number = -1; 11680 } 11681 11682 /* 11683 * "foldclosed()" function 11684 */ 11685 static void 11686 f_foldclosed(typval_T *argvars, typval_T *rettv) 11687 { 11688 foldclosed_both(argvars, rettv, FALSE); 11689 } 11690 11691 /* 11692 * "foldclosedend()" function 11693 */ 11694 static void 11695 f_foldclosedend(typval_T *argvars, typval_T *rettv) 11696 { 11697 foldclosed_both(argvars, rettv, TRUE); 11698 } 11699 11700 /* 11701 * "foldlevel()" function 11702 */ 11703 static void 11704 f_foldlevel(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 11705 { 11706 #ifdef FEAT_FOLDING 11707 linenr_T lnum; 11708 11709 lnum = get_tv_lnum(argvars); 11710 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11711 rettv->vval.v_number = foldLevel(lnum); 11712 #endif 11713 } 11714 11715 /* 11716 * "foldtext()" function 11717 */ 11718 static void 11719 f_foldtext(typval_T *argvars UNUSED, typval_T *rettv) 11720 { 11721 #ifdef FEAT_FOLDING 11722 linenr_T lnum; 11723 char_u *s; 11724 char_u *r; 11725 int len; 11726 char *txt; 11727 #endif 11728 11729 rettv->v_type = VAR_STRING; 11730 rettv->vval.v_string = NULL; 11731 #ifdef FEAT_FOLDING 11732 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 11733 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 11734 <= curbuf->b_ml.ml_line_count 11735 && vimvars[VV_FOLDDASHES].vv_str != NULL) 11736 { 11737 /* Find first non-empty line in the fold. */ 11738 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 11739 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 11740 { 11741 if (!linewhite(lnum)) 11742 break; 11743 ++lnum; 11744 } 11745 11746 /* Find interesting text in this line. */ 11747 s = skipwhite(ml_get(lnum)); 11748 /* skip C comment-start */ 11749 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 11750 { 11751 s = skipwhite(s + 2); 11752 if (*skipwhite(s) == NUL 11753 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 11754 { 11755 s = skipwhite(ml_get(lnum + 1)); 11756 if (*s == '*') 11757 s = skipwhite(s + 1); 11758 } 11759 } 11760 txt = _("+-%s%3ld lines: "); 11761 r = alloc((unsigned)(STRLEN(txt) 11762 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 11763 + 20 /* for %3ld */ 11764 + STRLEN(s))); /* concatenated */ 11765 if (r != NULL) 11766 { 11767 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 11768 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 11769 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 11770 len = (int)STRLEN(r); 11771 STRCAT(r, s); 11772 /* remove 'foldmarker' and 'commentstring' */ 11773 foldtext_cleanup(r + len); 11774 rettv->vval.v_string = r; 11775 } 11776 } 11777 #endif 11778 } 11779 11780 /* 11781 * "foldtextresult(lnum)" function 11782 */ 11783 static void 11784 f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv) 11785 { 11786 #ifdef FEAT_FOLDING 11787 linenr_T lnum; 11788 char_u *text; 11789 char_u buf[51]; 11790 foldinfo_T foldinfo; 11791 int fold_count; 11792 #endif 11793 11794 rettv->v_type = VAR_STRING; 11795 rettv->vval.v_string = NULL; 11796 #ifdef FEAT_FOLDING 11797 lnum = get_tv_lnum(argvars); 11798 /* treat illegal types and illegal string values for {lnum} the same */ 11799 if (lnum < 0) 11800 lnum = 0; 11801 fold_count = foldedCount(curwin, lnum, &foldinfo); 11802 if (fold_count > 0) 11803 { 11804 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 11805 &foldinfo, buf); 11806 if (text == buf) 11807 text = vim_strsave(text); 11808 rettv->vval.v_string = text; 11809 } 11810 #endif 11811 } 11812 11813 /* 11814 * "foreground()" function 11815 */ 11816 static void 11817 f_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 11818 { 11819 #ifdef FEAT_GUI 11820 if (gui.in_use) 11821 gui_mch_set_foreground(); 11822 #else 11823 # ifdef WIN32 11824 win32_set_foreground(); 11825 # endif 11826 #endif 11827 } 11828 11829 /* 11830 * "function()" function 11831 */ 11832 static void 11833 f_function(typval_T *argvars, typval_T *rettv) 11834 { 11835 char_u *s; 11836 char_u *name; 11837 int use_string = FALSE; 11838 partial_T *arg_pt = NULL; 11839 11840 if (argvars[0].v_type == VAR_FUNC) 11841 { 11842 /* function(MyFunc, [arg], dict) */ 11843 s = argvars[0].vval.v_string; 11844 } 11845 else if (argvars[0].v_type == VAR_PARTIAL 11846 && argvars[0].vval.v_partial != NULL) 11847 { 11848 /* function(dict.MyFunc, [arg]) */ 11849 arg_pt = argvars[0].vval.v_partial; 11850 s = arg_pt->pt_name; 11851 } 11852 else 11853 { 11854 /* function('MyFunc', [arg], dict) */ 11855 s = get_tv_string(&argvars[0]); 11856 use_string = TRUE; 11857 } 11858 11859 if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s))) 11860 EMSG2(_(e_invarg2), s); 11861 /* Don't check an autoload name for existence here. */ 11862 else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL 11863 && !function_exists(s)) 11864 EMSG2(_("E700: Unknown function: %s"), s); 11865 else 11866 { 11867 int dict_idx = 0; 11868 int arg_idx = 0; 11869 list_T *list = NULL; 11870 11871 if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0) 11872 { 11873 char sid_buf[25]; 11874 int off = *s == 's' ? 2 : 5; 11875 11876 /* Expand s: and <SID> into <SNR>nr_, so that the function can 11877 * also be called from another script. Using trans_function_name() 11878 * would also work, but some plugins depend on the name being 11879 * printable text. */ 11880 sprintf(sid_buf, "<SNR>%ld_", (long)current_SID); 11881 name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); 11882 if (name != NULL) 11883 { 11884 STRCPY(name, sid_buf); 11885 STRCAT(name, s + off); 11886 } 11887 } 11888 else 11889 name = vim_strsave(s); 11890 11891 if (argvars[1].v_type != VAR_UNKNOWN) 11892 { 11893 if (argvars[2].v_type != VAR_UNKNOWN) 11894 { 11895 /* function(name, [args], dict) */ 11896 arg_idx = 1; 11897 dict_idx = 2; 11898 } 11899 else if (argvars[1].v_type == VAR_DICT) 11900 /* function(name, dict) */ 11901 dict_idx = 1; 11902 else 11903 /* function(name, [args]) */ 11904 arg_idx = 1; 11905 if (dict_idx > 0) 11906 { 11907 if (argvars[dict_idx].v_type != VAR_DICT) 11908 { 11909 EMSG(_("E922: expected a dict")); 11910 vim_free(name); 11911 return; 11912 } 11913 if (argvars[dict_idx].vval.v_dict == NULL) 11914 dict_idx = 0; 11915 } 11916 if (arg_idx > 0) 11917 { 11918 if (argvars[arg_idx].v_type != VAR_LIST) 11919 { 11920 EMSG(_("E923: Second argument of function() must be a list or a dict")); 11921 vim_free(name); 11922 return; 11923 } 11924 list = argvars[arg_idx].vval.v_list; 11925 if (list == NULL || list->lv_len == 0) 11926 arg_idx = 0; 11927 } 11928 } 11929 if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL) 11930 { 11931 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); 11932 11933 /* result is a VAR_PARTIAL */ 11934 if (pt == NULL) 11935 vim_free(name); 11936 else 11937 { 11938 if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0)) 11939 { 11940 listitem_T *li; 11941 int i = 0; 11942 int arg_len = 0; 11943 int lv_len = 0; 11944 11945 if (arg_pt != NULL) 11946 arg_len = arg_pt->pt_argc; 11947 if (list != NULL) 11948 lv_len = list->lv_len; 11949 pt->pt_argc = arg_len + lv_len; 11950 pt->pt_argv = (typval_T *)alloc( 11951 sizeof(typval_T) * pt->pt_argc); 11952 if (pt->pt_argv == NULL) 11953 { 11954 vim_free(pt); 11955 vim_free(name); 11956 return; 11957 } 11958 else 11959 { 11960 for (i = 0; i < arg_len; i++) 11961 copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]); 11962 if (lv_len > 0) 11963 for (li = list->lv_first; li != NULL; 11964 li = li->li_next) 11965 copy_tv(&li->li_tv, &pt->pt_argv[i++]); 11966 } 11967 } 11968 11969 /* For "function(dict.func, [], dict)" and "func" is a partial 11970 * use "dict". That is backwards compatible. */ 11971 if (dict_idx > 0) 11972 { 11973 pt->pt_dict = argvars[dict_idx].vval.v_dict; 11974 ++pt->pt_dict->dv_refcount; 11975 } 11976 else if (arg_pt != NULL) 11977 { 11978 pt->pt_dict = arg_pt->pt_dict; 11979 if (pt->pt_dict != NULL) 11980 ++pt->pt_dict->dv_refcount; 11981 } 11982 11983 pt->pt_refcount = 1; 11984 pt->pt_name = name; 11985 func_ref(pt->pt_name); 11986 } 11987 rettv->v_type = VAR_PARTIAL; 11988 rettv->vval.v_partial = pt; 11989 } 11990 else 11991 { 11992 /* result is a VAR_FUNC */ 11993 rettv->v_type = VAR_FUNC; 11994 rettv->vval.v_string = name; 11995 func_ref(name); 11996 } 11997 } 11998 } 11999 12000 static void 12001 partial_free(partial_T *pt) 12002 { 12003 int i; 12004 12005 for (i = 0; i < pt->pt_argc; ++i) 12006 clear_tv(&pt->pt_argv[i]); 12007 vim_free(pt->pt_argv); 12008 func_unref(pt->pt_name); 12009 vim_free(pt->pt_name); 12010 vim_free(pt); 12011 } 12012 12013 /* 12014 * Unreference a closure: decrement the reference count and free it when it 12015 * becomes zero. 12016 */ 12017 void 12018 partial_unref(partial_T *pt) 12019 { 12020 if (pt != NULL && --pt->pt_refcount <= 0) 12021 partial_free(pt); 12022 } 12023 12024 /* 12025 * "garbagecollect()" function 12026 */ 12027 static void 12028 f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED) 12029 { 12030 /* This is postponed until we are back at the toplevel, because we may be 12031 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 12032 want_garbage_collect = TRUE; 12033 12034 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 12035 garbage_collect_at_exit = TRUE; 12036 } 12037 12038 /* 12039 * "get()" function 12040 */ 12041 static void 12042 f_get(typval_T *argvars, typval_T *rettv) 12043 { 12044 listitem_T *li; 12045 list_T *l; 12046 dictitem_T *di; 12047 dict_T *d; 12048 typval_T *tv = NULL; 12049 12050 if (argvars[0].v_type == VAR_LIST) 12051 { 12052 if ((l = argvars[0].vval.v_list) != NULL) 12053 { 12054 int error = FALSE; 12055 12056 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 12057 if (!error && li != NULL) 12058 tv = &li->li_tv; 12059 } 12060 } 12061 else if (argvars[0].v_type == VAR_DICT) 12062 { 12063 if ((d = argvars[0].vval.v_dict) != NULL) 12064 { 12065 di = dict_find(d, get_tv_string(&argvars[1]), -1); 12066 if (di != NULL) 12067 tv = &di->di_tv; 12068 } 12069 } 12070 else 12071 EMSG2(_(e_listdictarg), "get()"); 12072 12073 if (tv == NULL) 12074 { 12075 if (argvars[2].v_type != VAR_UNKNOWN) 12076 copy_tv(&argvars[2], rettv); 12077 } 12078 else 12079 copy_tv(tv, rettv); 12080 } 12081 12082 static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv); 12083 12084 /* 12085 * Get line or list of lines from buffer "buf" into "rettv". 12086 * Return a range (from start to end) of lines in rettv from the specified 12087 * buffer. 12088 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 12089 */ 12090 static void 12091 get_buffer_lines( 12092 buf_T *buf, 12093 linenr_T start, 12094 linenr_T end, 12095 int retlist, 12096 typval_T *rettv) 12097 { 12098 char_u *p; 12099 12100 rettv->v_type = VAR_STRING; 12101 rettv->vval.v_string = NULL; 12102 if (retlist && rettv_list_alloc(rettv) == FAIL) 12103 return; 12104 12105 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 12106 return; 12107 12108 if (!retlist) 12109 { 12110 if (start >= 1 && start <= buf->b_ml.ml_line_count) 12111 p = ml_get_buf(buf, start, FALSE); 12112 else 12113 p = (char_u *)""; 12114 rettv->vval.v_string = vim_strsave(p); 12115 } 12116 else 12117 { 12118 if (end < start) 12119 return; 12120 12121 if (start < 1) 12122 start = 1; 12123 if (end > buf->b_ml.ml_line_count) 12124 end = buf->b_ml.ml_line_count; 12125 while (start <= end) 12126 if (list_append_string(rettv->vval.v_list, 12127 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 12128 break; 12129 } 12130 } 12131 12132 /* 12133 * "getbufline()" function 12134 */ 12135 static void 12136 f_getbufline(typval_T *argvars, typval_T *rettv) 12137 { 12138 linenr_T lnum; 12139 linenr_T end; 12140 buf_T *buf; 12141 12142 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 12143 ++emsg_off; 12144 buf = get_buf_tv(&argvars[0], FALSE); 12145 --emsg_off; 12146 12147 lnum = get_tv_lnum_buf(&argvars[1], buf); 12148 if (argvars[2].v_type == VAR_UNKNOWN) 12149 end = lnum; 12150 else 12151 end = get_tv_lnum_buf(&argvars[2], buf); 12152 12153 get_buffer_lines(buf, lnum, end, TRUE, rettv); 12154 } 12155 12156 /* 12157 * "getbufvar()" function 12158 */ 12159 static void 12160 f_getbufvar(typval_T *argvars, typval_T *rettv) 12161 { 12162 buf_T *buf; 12163 buf_T *save_curbuf; 12164 char_u *varname; 12165 dictitem_T *v; 12166 int done = FALSE; 12167 12168 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 12169 varname = get_tv_string_chk(&argvars[1]); 12170 ++emsg_off; 12171 buf = get_buf_tv(&argvars[0], FALSE); 12172 12173 rettv->v_type = VAR_STRING; 12174 rettv->vval.v_string = NULL; 12175 12176 if (buf != NULL && varname != NULL) 12177 { 12178 /* set curbuf to be our buf, temporarily */ 12179 save_curbuf = curbuf; 12180 curbuf = buf; 12181 12182 if (*varname == '&') /* buffer-local-option */ 12183 { 12184 if (get_option_tv(&varname, rettv, TRUE) == OK) 12185 done = TRUE; 12186 } 12187 else if (STRCMP(varname, "changedtick") == 0) 12188 { 12189 rettv->v_type = VAR_NUMBER; 12190 rettv->vval.v_number = curbuf->b_changedtick; 12191 done = TRUE; 12192 } 12193 else 12194 { 12195 /* Look up the variable. */ 12196 /* Let getbufvar({nr}, "") return the "b:" dictionary. */ 12197 v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 12198 'b', varname, FALSE); 12199 if (v != NULL) 12200 { 12201 copy_tv(&v->di_tv, rettv); 12202 done = TRUE; 12203 } 12204 } 12205 12206 /* restore previous notion of curbuf */ 12207 curbuf = save_curbuf; 12208 } 12209 12210 if (!done && argvars[2].v_type != VAR_UNKNOWN) 12211 /* use the default value */ 12212 copy_tv(&argvars[2], rettv); 12213 12214 --emsg_off; 12215 } 12216 12217 /* 12218 * "getchar()" function 12219 */ 12220 static void 12221 f_getchar(typval_T *argvars, typval_T *rettv) 12222 { 12223 varnumber_T n; 12224 int error = FALSE; 12225 12226 /* Position the cursor. Needed after a message that ends in a space. */ 12227 windgoto(msg_row, msg_col); 12228 12229 ++no_mapping; 12230 ++allow_keys; 12231 for (;;) 12232 { 12233 if (argvars[0].v_type == VAR_UNKNOWN) 12234 /* getchar(): blocking wait. */ 12235 n = safe_vgetc(); 12236 else if (get_tv_number_chk(&argvars[0], &error) == 1) 12237 /* getchar(1): only check if char avail */ 12238 n = vpeekc_any(); 12239 else if (error || vpeekc_any() == NUL) 12240 /* illegal argument or getchar(0) and no char avail: return zero */ 12241 n = 0; 12242 else 12243 /* getchar(0) and char avail: return char */ 12244 n = safe_vgetc(); 12245 12246 if (n == K_IGNORE) 12247 continue; 12248 break; 12249 } 12250 --no_mapping; 12251 --allow_keys; 12252 12253 vimvars[VV_MOUSE_WIN].vv_nr = 0; 12254 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 12255 vimvars[VV_MOUSE_COL].vv_nr = 0; 12256 12257 rettv->vval.v_number = n; 12258 if (IS_SPECIAL(n) || mod_mask != 0) 12259 { 12260 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 12261 int i = 0; 12262 12263 /* Turn a special key into three bytes, plus modifier. */ 12264 if (mod_mask != 0) 12265 { 12266 temp[i++] = K_SPECIAL; 12267 temp[i++] = KS_MODIFIER; 12268 temp[i++] = mod_mask; 12269 } 12270 if (IS_SPECIAL(n)) 12271 { 12272 temp[i++] = K_SPECIAL; 12273 temp[i++] = K_SECOND(n); 12274 temp[i++] = K_THIRD(n); 12275 } 12276 #ifdef FEAT_MBYTE 12277 else if (has_mbyte) 12278 i += (*mb_char2bytes)(n, temp + i); 12279 #endif 12280 else 12281 temp[i++] = n; 12282 temp[i++] = NUL; 12283 rettv->v_type = VAR_STRING; 12284 rettv->vval.v_string = vim_strsave(temp); 12285 12286 #ifdef FEAT_MOUSE 12287 if (is_mouse_key(n)) 12288 { 12289 int row = mouse_row; 12290 int col = mouse_col; 12291 win_T *win; 12292 linenr_T lnum; 12293 # ifdef FEAT_WINDOWS 12294 win_T *wp; 12295 # endif 12296 int winnr = 1; 12297 12298 if (row >= 0 && col >= 0) 12299 { 12300 /* Find the window at the mouse coordinates and compute the 12301 * text position. */ 12302 win = mouse_find_win(&row, &col); 12303 (void)mouse_comp_pos(win, &row, &col, &lnum); 12304 # ifdef FEAT_WINDOWS 12305 for (wp = firstwin; wp != win; wp = wp->w_next) 12306 ++winnr; 12307 # endif 12308 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 12309 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 12310 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 12311 } 12312 } 12313 #endif 12314 } 12315 } 12316 12317 /* 12318 * "getcharmod()" function 12319 */ 12320 static void 12321 f_getcharmod(typval_T *argvars UNUSED, typval_T *rettv) 12322 { 12323 rettv->vval.v_number = mod_mask; 12324 } 12325 12326 /* 12327 * "getcharsearch()" function 12328 */ 12329 static void 12330 f_getcharsearch(typval_T *argvars UNUSED, typval_T *rettv) 12331 { 12332 if (rettv_dict_alloc(rettv) != FAIL) 12333 { 12334 dict_T *dict = rettv->vval.v_dict; 12335 12336 dict_add_nr_str(dict, "char", 0L, last_csearch()); 12337 dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL); 12338 dict_add_nr_str(dict, "until", last_csearch_until(), NULL); 12339 } 12340 } 12341 12342 /* 12343 * "getcmdline()" function 12344 */ 12345 static void 12346 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv) 12347 { 12348 rettv->v_type = VAR_STRING; 12349 rettv->vval.v_string = get_cmdline_str(); 12350 } 12351 12352 /* 12353 * "getcmdpos()" function 12354 */ 12355 static void 12356 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv) 12357 { 12358 rettv->vval.v_number = get_cmdline_pos() + 1; 12359 } 12360 12361 /* 12362 * "getcmdtype()" function 12363 */ 12364 static void 12365 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv) 12366 { 12367 rettv->v_type = VAR_STRING; 12368 rettv->vval.v_string = alloc(2); 12369 if (rettv->vval.v_string != NULL) 12370 { 12371 rettv->vval.v_string[0] = get_cmdline_type(); 12372 rettv->vval.v_string[1] = NUL; 12373 } 12374 } 12375 12376 /* 12377 * "getcmdwintype()" function 12378 */ 12379 static void 12380 f_getcmdwintype(typval_T *argvars UNUSED, typval_T *rettv) 12381 { 12382 rettv->v_type = VAR_STRING; 12383 rettv->vval.v_string = NULL; 12384 #ifdef FEAT_CMDWIN 12385 rettv->vval.v_string = alloc(2); 12386 if (rettv->vval.v_string != NULL) 12387 { 12388 rettv->vval.v_string[0] = cmdwin_type; 12389 rettv->vval.v_string[1] = NUL; 12390 } 12391 #endif 12392 } 12393 12394 /* 12395 * "getcwd()" function 12396 */ 12397 static void 12398 f_getcwd(typval_T *argvars, typval_T *rettv) 12399 { 12400 win_T *wp = NULL; 12401 char_u *cwd; 12402 12403 rettv->v_type = VAR_STRING; 12404 rettv->vval.v_string = NULL; 12405 12406 wp = find_tabwin(&argvars[0], &argvars[1]); 12407 if (wp != NULL) 12408 { 12409 if (wp->w_localdir != NULL) 12410 rettv->vval.v_string = vim_strsave(wp->w_localdir); 12411 else if(globaldir != NULL) 12412 rettv->vval.v_string = vim_strsave(globaldir); 12413 else 12414 { 12415 cwd = alloc(MAXPATHL); 12416 if (cwd != NULL) 12417 { 12418 if (mch_dirname(cwd, MAXPATHL) != FAIL) 12419 rettv->vval.v_string = vim_strsave(cwd); 12420 vim_free(cwd); 12421 } 12422 } 12423 #ifdef BACKSLASH_IN_FILENAME 12424 if (rettv->vval.v_string != NULL) 12425 slash_adjust(rettv->vval.v_string); 12426 #endif 12427 } 12428 } 12429 12430 /* 12431 * "getfontname()" function 12432 */ 12433 static void 12434 f_getfontname(typval_T *argvars UNUSED, typval_T *rettv) 12435 { 12436 rettv->v_type = VAR_STRING; 12437 rettv->vval.v_string = NULL; 12438 #ifdef FEAT_GUI 12439 if (gui.in_use) 12440 { 12441 GuiFont font; 12442 char_u *name = NULL; 12443 12444 if (argvars[0].v_type == VAR_UNKNOWN) 12445 { 12446 /* Get the "Normal" font. Either the name saved by 12447 * hl_set_font_name() or from the font ID. */ 12448 font = gui.norm_font; 12449 name = hl_get_font_name(); 12450 } 12451 else 12452 { 12453 name = get_tv_string(&argvars[0]); 12454 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 12455 return; 12456 font = gui_mch_get_font(name, FALSE); 12457 if (font == NOFONT) 12458 return; /* Invalid font name, return empty string. */ 12459 } 12460 rettv->vval.v_string = gui_mch_get_fontname(font, name); 12461 if (argvars[0].v_type != VAR_UNKNOWN) 12462 gui_mch_free_font(font); 12463 } 12464 #endif 12465 } 12466 12467 /* 12468 * "getfperm({fname})" function 12469 */ 12470 static void 12471 f_getfperm(typval_T *argvars, typval_T *rettv) 12472 { 12473 char_u *fname; 12474 struct stat st; 12475 char_u *perm = NULL; 12476 char_u flags[] = "rwx"; 12477 int i; 12478 12479 fname = get_tv_string(&argvars[0]); 12480 12481 rettv->v_type = VAR_STRING; 12482 if (mch_stat((char *)fname, &st) >= 0) 12483 { 12484 perm = vim_strsave((char_u *)"---------"); 12485 if (perm != NULL) 12486 { 12487 for (i = 0; i < 9; i++) 12488 { 12489 if (st.st_mode & (1 << (8 - i))) 12490 perm[i] = flags[i % 3]; 12491 } 12492 } 12493 } 12494 rettv->vval.v_string = perm; 12495 } 12496 12497 /* 12498 * "getfsize({fname})" function 12499 */ 12500 static void 12501 f_getfsize(typval_T *argvars, typval_T *rettv) 12502 { 12503 char_u *fname; 12504 struct stat st; 12505 12506 fname = get_tv_string(&argvars[0]); 12507 12508 rettv->v_type = VAR_NUMBER; 12509 12510 if (mch_stat((char *)fname, &st) >= 0) 12511 { 12512 if (mch_isdir(fname)) 12513 rettv->vval.v_number = 0; 12514 else 12515 { 12516 rettv->vval.v_number = (varnumber_T)st.st_size; 12517 12518 /* non-perfect check for overflow */ 12519 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 12520 rettv->vval.v_number = -2; 12521 } 12522 } 12523 else 12524 rettv->vval.v_number = -1; 12525 } 12526 12527 /* 12528 * "getftime({fname})" function 12529 */ 12530 static void 12531 f_getftime(typval_T *argvars, typval_T *rettv) 12532 { 12533 char_u *fname; 12534 struct stat st; 12535 12536 fname = get_tv_string(&argvars[0]); 12537 12538 if (mch_stat((char *)fname, &st) >= 0) 12539 rettv->vval.v_number = (varnumber_T)st.st_mtime; 12540 else 12541 rettv->vval.v_number = -1; 12542 } 12543 12544 /* 12545 * "getftype({fname})" function 12546 */ 12547 static void 12548 f_getftype(typval_T *argvars, typval_T *rettv) 12549 { 12550 char_u *fname; 12551 struct stat st; 12552 char_u *type = NULL; 12553 char *t; 12554 12555 fname = get_tv_string(&argvars[0]); 12556 12557 rettv->v_type = VAR_STRING; 12558 if (mch_lstat((char *)fname, &st) >= 0) 12559 { 12560 #ifdef S_ISREG 12561 if (S_ISREG(st.st_mode)) 12562 t = "file"; 12563 else if (S_ISDIR(st.st_mode)) 12564 t = "dir"; 12565 # ifdef S_ISLNK 12566 else if (S_ISLNK(st.st_mode)) 12567 t = "link"; 12568 # endif 12569 # ifdef S_ISBLK 12570 else if (S_ISBLK(st.st_mode)) 12571 t = "bdev"; 12572 # endif 12573 # ifdef S_ISCHR 12574 else if (S_ISCHR(st.st_mode)) 12575 t = "cdev"; 12576 # endif 12577 # ifdef S_ISFIFO 12578 else if (S_ISFIFO(st.st_mode)) 12579 t = "fifo"; 12580 # endif 12581 # ifdef S_ISSOCK 12582 else if (S_ISSOCK(st.st_mode)) 12583 t = "fifo"; 12584 # endif 12585 else 12586 t = "other"; 12587 #else 12588 # ifdef S_IFMT 12589 switch (st.st_mode & S_IFMT) 12590 { 12591 case S_IFREG: t = "file"; break; 12592 case S_IFDIR: t = "dir"; break; 12593 # ifdef S_IFLNK 12594 case S_IFLNK: t = "link"; break; 12595 # endif 12596 # ifdef S_IFBLK 12597 case S_IFBLK: t = "bdev"; break; 12598 # endif 12599 # ifdef S_IFCHR 12600 case S_IFCHR: t = "cdev"; break; 12601 # endif 12602 # ifdef S_IFIFO 12603 case S_IFIFO: t = "fifo"; break; 12604 # endif 12605 # ifdef S_IFSOCK 12606 case S_IFSOCK: t = "socket"; break; 12607 # endif 12608 default: t = "other"; 12609 } 12610 # else 12611 if (mch_isdir(fname)) 12612 t = "dir"; 12613 else 12614 t = "file"; 12615 # endif 12616 #endif 12617 type = vim_strsave((char_u *)t); 12618 } 12619 rettv->vval.v_string = type; 12620 } 12621 12622 /* 12623 * "getline(lnum, [end])" function 12624 */ 12625 static void 12626 f_getline(typval_T *argvars, typval_T *rettv) 12627 { 12628 linenr_T lnum; 12629 linenr_T end; 12630 int retlist; 12631 12632 lnum = get_tv_lnum(argvars); 12633 if (argvars[1].v_type == VAR_UNKNOWN) 12634 { 12635 end = 0; 12636 retlist = FALSE; 12637 } 12638 else 12639 { 12640 end = get_tv_lnum(&argvars[1]); 12641 retlist = TRUE; 12642 } 12643 12644 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 12645 } 12646 12647 /* 12648 * "getmatches()" function 12649 */ 12650 static void 12651 f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 12652 { 12653 #ifdef FEAT_SEARCH_EXTRA 12654 dict_T *dict; 12655 matchitem_T *cur = curwin->w_match_head; 12656 int i; 12657 12658 if (rettv_list_alloc(rettv) == OK) 12659 { 12660 while (cur != NULL) 12661 { 12662 dict = dict_alloc(); 12663 if (dict == NULL) 12664 return; 12665 if (cur->match.regprog == NULL) 12666 { 12667 /* match added with matchaddpos() */ 12668 for (i = 0; i < MAXPOSMATCH; ++i) 12669 { 12670 llpos_T *llpos; 12671 char buf[6]; 12672 list_T *l; 12673 12674 llpos = &cur->pos.pos[i]; 12675 if (llpos->lnum == 0) 12676 break; 12677 l = list_alloc(); 12678 if (l == NULL) 12679 break; 12680 list_append_number(l, (varnumber_T)llpos->lnum); 12681 if (llpos->col > 0) 12682 { 12683 list_append_number(l, (varnumber_T)llpos->col); 12684 list_append_number(l, (varnumber_T)llpos->len); 12685 } 12686 sprintf(buf, "pos%d", i + 1); 12687 dict_add_list(dict, buf, l); 12688 } 12689 } 12690 else 12691 { 12692 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 12693 } 12694 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 12695 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 12696 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 12697 # ifdef FEAT_CONCEAL 12698 if (cur->conceal_char) 12699 { 12700 char_u buf[MB_MAXBYTES + 1]; 12701 12702 buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL; 12703 dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf); 12704 } 12705 # endif 12706 list_append_dict(rettv->vval.v_list, dict); 12707 cur = cur->next; 12708 } 12709 } 12710 #endif 12711 } 12712 12713 /* 12714 * "getpid()" function 12715 */ 12716 static void 12717 f_getpid(typval_T *argvars UNUSED, typval_T *rettv) 12718 { 12719 rettv->vval.v_number = mch_get_pid(); 12720 } 12721 12722 static void getpos_both(typval_T *argvars, typval_T *rettv, int getcurpos); 12723 12724 /* 12725 * "getcurpos()" function 12726 */ 12727 static void 12728 f_getcurpos(typval_T *argvars, typval_T *rettv) 12729 { 12730 getpos_both(argvars, rettv, TRUE); 12731 } 12732 12733 /* 12734 * "getpos(string)" function 12735 */ 12736 static void 12737 f_getpos(typval_T *argvars, typval_T *rettv) 12738 { 12739 getpos_both(argvars, rettv, FALSE); 12740 } 12741 12742 static void 12743 getpos_both( 12744 typval_T *argvars, 12745 typval_T *rettv, 12746 int getcurpos) 12747 { 12748 pos_T *fp; 12749 list_T *l; 12750 int fnum = -1; 12751 12752 if (rettv_list_alloc(rettv) == OK) 12753 { 12754 l = rettv->vval.v_list; 12755 if (getcurpos) 12756 fp = &curwin->w_cursor; 12757 else 12758 fp = var2fpos(&argvars[0], TRUE, &fnum); 12759 if (fnum != -1) 12760 list_append_number(l, (varnumber_T)fnum); 12761 else 12762 list_append_number(l, (varnumber_T)0); 12763 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 12764 : (varnumber_T)0); 12765 list_append_number(l, (fp != NULL) 12766 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 12767 : (varnumber_T)0); 12768 list_append_number(l, 12769 #ifdef FEAT_VIRTUALEDIT 12770 (fp != NULL) ? (varnumber_T)fp->coladd : 12771 #endif 12772 (varnumber_T)0); 12773 if (getcurpos) 12774 { 12775 update_curswant(); 12776 list_append_number(l, curwin->w_curswant == MAXCOL ? 12777 (varnumber_T)MAXCOL : (varnumber_T)curwin->w_curswant + 1); 12778 } 12779 } 12780 else 12781 rettv->vval.v_number = FALSE; 12782 } 12783 12784 /* 12785 * "getqflist()" and "getloclist()" functions 12786 */ 12787 static void 12788 f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 12789 { 12790 #ifdef FEAT_QUICKFIX 12791 win_T *wp; 12792 #endif 12793 12794 #ifdef FEAT_QUICKFIX 12795 if (rettv_list_alloc(rettv) == OK) 12796 { 12797 wp = NULL; 12798 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 12799 { 12800 wp = find_win_by_nr(&argvars[0], NULL); 12801 if (wp == NULL) 12802 return; 12803 } 12804 12805 (void)get_errorlist(wp, rettv->vval.v_list); 12806 } 12807 #endif 12808 } 12809 12810 /* 12811 * "getreg()" function 12812 */ 12813 static void 12814 f_getreg(typval_T *argvars, typval_T *rettv) 12815 { 12816 char_u *strregname; 12817 int regname; 12818 int arg2 = FALSE; 12819 int return_list = FALSE; 12820 int error = FALSE; 12821 12822 if (argvars[0].v_type != VAR_UNKNOWN) 12823 { 12824 strregname = get_tv_string_chk(&argvars[0]); 12825 error = strregname == NULL; 12826 if (argvars[1].v_type != VAR_UNKNOWN) 12827 { 12828 arg2 = get_tv_number_chk(&argvars[1], &error); 12829 if (!error && argvars[2].v_type != VAR_UNKNOWN) 12830 return_list = get_tv_number_chk(&argvars[2], &error); 12831 } 12832 } 12833 else 12834 strregname = vimvars[VV_REG].vv_str; 12835 12836 if (error) 12837 return; 12838 12839 regname = (strregname == NULL ? '"' : *strregname); 12840 if (regname == 0) 12841 regname = '"'; 12842 12843 if (return_list) 12844 { 12845 rettv->v_type = VAR_LIST; 12846 rettv->vval.v_list = (list_T *)get_reg_contents(regname, 12847 (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST); 12848 if (rettv->vval.v_list != NULL) 12849 ++rettv->vval.v_list->lv_refcount; 12850 } 12851 else 12852 { 12853 rettv->v_type = VAR_STRING; 12854 rettv->vval.v_string = get_reg_contents(regname, 12855 arg2 ? GREG_EXPR_SRC : 0); 12856 } 12857 } 12858 12859 /* 12860 * "getregtype()" function 12861 */ 12862 static void 12863 f_getregtype(typval_T *argvars, typval_T *rettv) 12864 { 12865 char_u *strregname; 12866 int regname; 12867 char_u buf[NUMBUFLEN + 2]; 12868 long reglen = 0; 12869 12870 if (argvars[0].v_type != VAR_UNKNOWN) 12871 { 12872 strregname = get_tv_string_chk(&argvars[0]); 12873 if (strregname == NULL) /* type error; errmsg already given */ 12874 { 12875 rettv->v_type = VAR_STRING; 12876 rettv->vval.v_string = NULL; 12877 return; 12878 } 12879 } 12880 else 12881 /* Default to v:register */ 12882 strregname = vimvars[VV_REG].vv_str; 12883 12884 regname = (strregname == NULL ? '"' : *strregname); 12885 if (regname == 0) 12886 regname = '"'; 12887 12888 buf[0] = NUL; 12889 buf[1] = NUL; 12890 switch (get_reg_type(regname, ®len)) 12891 { 12892 case MLINE: buf[0] = 'V'; break; 12893 case MCHAR: buf[0] = 'v'; break; 12894 case MBLOCK: 12895 buf[0] = Ctrl_V; 12896 sprintf((char *)buf + 1, "%ld", reglen + 1); 12897 break; 12898 } 12899 rettv->v_type = VAR_STRING; 12900 rettv->vval.v_string = vim_strsave(buf); 12901 } 12902 12903 /* 12904 * "gettabvar()" function 12905 */ 12906 static void 12907 f_gettabvar(typval_T *argvars, typval_T *rettv) 12908 { 12909 win_T *oldcurwin; 12910 tabpage_T *tp, *oldtabpage; 12911 dictitem_T *v; 12912 char_u *varname; 12913 int done = FALSE; 12914 12915 rettv->v_type = VAR_STRING; 12916 rettv->vval.v_string = NULL; 12917 12918 varname = get_tv_string_chk(&argvars[1]); 12919 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 12920 if (tp != NULL && varname != NULL) 12921 { 12922 /* Set tp to be our tabpage, temporarily. Also set the window to the 12923 * first window in the tabpage, otherwise the window is not valid. */ 12924 if (switch_win(&oldcurwin, &oldtabpage, 12925 tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE) 12926 == OK) 12927 { 12928 /* look up the variable */ 12929 /* Let gettabvar({nr}, "") return the "t:" dictionary. */ 12930 v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); 12931 if (v != NULL) 12932 { 12933 copy_tv(&v->di_tv, rettv); 12934 done = TRUE; 12935 } 12936 } 12937 12938 /* restore previous notion of curwin */ 12939 restore_win(oldcurwin, oldtabpage, TRUE); 12940 } 12941 12942 if (!done && argvars[2].v_type != VAR_UNKNOWN) 12943 copy_tv(&argvars[2], rettv); 12944 } 12945 12946 /* 12947 * "gettabwinvar()" function 12948 */ 12949 static void 12950 f_gettabwinvar(typval_T *argvars, typval_T *rettv) 12951 { 12952 getwinvar(argvars, rettv, 1); 12953 } 12954 12955 /* 12956 * "getwinposx()" function 12957 */ 12958 static void 12959 f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv) 12960 { 12961 rettv->vval.v_number = -1; 12962 #ifdef FEAT_GUI 12963 if (gui.in_use) 12964 { 12965 int x, y; 12966 12967 if (gui_mch_get_winpos(&x, &y) == OK) 12968 rettv->vval.v_number = x; 12969 } 12970 #endif 12971 } 12972 12973 /* 12974 * "win_findbuf()" function 12975 */ 12976 static void 12977 f_win_findbuf(typval_T *argvars, typval_T *rettv) 12978 { 12979 if (rettv_list_alloc(rettv) != FAIL) 12980 win_findbuf(argvars, rettv->vval.v_list); 12981 } 12982 12983 /* 12984 * "win_getid()" function 12985 */ 12986 static void 12987 f_win_getid(typval_T *argvars, typval_T *rettv) 12988 { 12989 rettv->vval.v_number = win_getid(argvars); 12990 } 12991 12992 /* 12993 * "win_gotoid()" function 12994 */ 12995 static void 12996 f_win_gotoid(typval_T *argvars, typval_T *rettv) 12997 { 12998 rettv->vval.v_number = win_gotoid(argvars); 12999 } 13000 13001 /* 13002 * "win_id2tabwin()" function 13003 */ 13004 static void 13005 f_win_id2tabwin(typval_T *argvars, typval_T *rettv) 13006 { 13007 if (rettv_list_alloc(rettv) != FAIL) 13008 win_id2tabwin(argvars, rettv->vval.v_list); 13009 } 13010 13011 /* 13012 * "win_id2win()" function 13013 */ 13014 static void 13015 f_win_id2win(typval_T *argvars, typval_T *rettv) 13016 { 13017 rettv->vval.v_number = win_id2win(argvars); 13018 } 13019 13020 /* 13021 * "getwinposy()" function 13022 */ 13023 static void 13024 f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv) 13025 { 13026 rettv->vval.v_number = -1; 13027 #ifdef FEAT_GUI 13028 if (gui.in_use) 13029 { 13030 int x, y; 13031 13032 if (gui_mch_get_winpos(&x, &y) == OK) 13033 rettv->vval.v_number = y; 13034 } 13035 #endif 13036 } 13037 13038 /* 13039 * Find window specified by "vp" in tabpage "tp". 13040 */ 13041 static win_T * 13042 find_win_by_nr( 13043 typval_T *vp, 13044 tabpage_T *tp UNUSED) /* NULL for current tab page */ 13045 { 13046 #ifdef FEAT_WINDOWS 13047 win_T *wp; 13048 #endif 13049 int nr; 13050 13051 nr = get_tv_number_chk(vp, NULL); 13052 13053 #ifdef FEAT_WINDOWS 13054 if (nr < 0) 13055 return NULL; 13056 if (nr == 0) 13057 return curwin; 13058 13059 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 13060 wp != NULL; wp = wp->w_next) 13061 if (--nr <= 0) 13062 break; 13063 return wp; 13064 #else 13065 if (nr == 0 || nr == 1) 13066 return curwin; 13067 return NULL; 13068 #endif 13069 } 13070 13071 /* 13072 * Find window specified by "wvp" in tabpage "tvp". 13073 */ 13074 static win_T * 13075 find_tabwin( 13076 typval_T *wvp, /* VAR_UNKNOWN for current window */ 13077 typval_T *tvp) /* VAR_UNKNOWN for current tab page */ 13078 { 13079 win_T *wp = NULL; 13080 tabpage_T *tp = NULL; 13081 long n; 13082 13083 if (wvp->v_type != VAR_UNKNOWN) 13084 { 13085 if (tvp->v_type != VAR_UNKNOWN) 13086 { 13087 n = get_tv_number(tvp); 13088 if (n >= 0) 13089 tp = find_tabpage(n); 13090 } 13091 else 13092 tp = curtab; 13093 13094 if (tp != NULL) 13095 wp = find_win_by_nr(wvp, tp); 13096 } 13097 else 13098 wp = curwin; 13099 13100 return wp; 13101 } 13102 13103 /* 13104 * "getwinvar()" function 13105 */ 13106 static void 13107 f_getwinvar(typval_T *argvars, typval_T *rettv) 13108 { 13109 getwinvar(argvars, rettv, 0); 13110 } 13111 13112 /* 13113 * getwinvar() and gettabwinvar() 13114 */ 13115 static void 13116 getwinvar( 13117 typval_T *argvars, 13118 typval_T *rettv, 13119 int off) /* 1 for gettabwinvar() */ 13120 { 13121 win_T *win; 13122 char_u *varname; 13123 dictitem_T *v; 13124 tabpage_T *tp = NULL; 13125 int done = FALSE; 13126 #ifdef FEAT_WINDOWS 13127 win_T *oldcurwin; 13128 tabpage_T *oldtabpage; 13129 int need_switch_win; 13130 #endif 13131 13132 #ifdef FEAT_WINDOWS 13133 if (off == 1) 13134 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 13135 else 13136 tp = curtab; 13137 #endif 13138 win = find_win_by_nr(&argvars[off], tp); 13139 varname = get_tv_string_chk(&argvars[off + 1]); 13140 ++emsg_off; 13141 13142 rettv->v_type = VAR_STRING; 13143 rettv->vval.v_string = NULL; 13144 13145 if (win != NULL && varname != NULL) 13146 { 13147 #ifdef FEAT_WINDOWS 13148 /* Set curwin to be our win, temporarily. Also set the tabpage, 13149 * otherwise the window is not valid. Only do this when needed, 13150 * autocommands get blocked. */ 13151 need_switch_win = !(tp == curtab && win == curwin); 13152 if (!need_switch_win 13153 || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) 13154 #endif 13155 { 13156 if (*varname == '&') /* window-local-option */ 13157 { 13158 if (get_option_tv(&varname, rettv, 1) == OK) 13159 done = TRUE; 13160 } 13161 else 13162 { 13163 /* Look up the variable. */ 13164 /* Let getwinvar({nr}, "") return the "w:" dictionary. */ 13165 v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', 13166 varname, FALSE); 13167 if (v != NULL) 13168 { 13169 copy_tv(&v->di_tv, rettv); 13170 done = TRUE; 13171 } 13172 } 13173 } 13174 13175 #ifdef FEAT_WINDOWS 13176 if (need_switch_win) 13177 /* restore previous notion of curwin */ 13178 restore_win(oldcurwin, oldtabpage, TRUE); 13179 #endif 13180 } 13181 13182 if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) 13183 /* use the default return value */ 13184 copy_tv(&argvars[off + 2], rettv); 13185 13186 --emsg_off; 13187 } 13188 13189 /* 13190 * "glob()" function 13191 */ 13192 static void 13193 f_glob(typval_T *argvars, typval_T *rettv) 13194 { 13195 int options = WILD_SILENT|WILD_USE_NL; 13196 expand_T xpc; 13197 int error = FALSE; 13198 13199 /* When the optional second argument is non-zero, don't remove matches 13200 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 13201 rettv->v_type = VAR_STRING; 13202 if (argvars[1].v_type != VAR_UNKNOWN) 13203 { 13204 if (get_tv_number_chk(&argvars[1], &error)) 13205 options |= WILD_KEEP_ALL; 13206 if (argvars[2].v_type != VAR_UNKNOWN) 13207 { 13208 if (get_tv_number_chk(&argvars[2], &error)) 13209 { 13210 rettv->v_type = VAR_LIST; 13211 rettv->vval.v_list = NULL; 13212 } 13213 if (argvars[3].v_type != VAR_UNKNOWN 13214 && get_tv_number_chk(&argvars[3], &error)) 13215 options |= WILD_ALLLINKS; 13216 } 13217 } 13218 if (!error) 13219 { 13220 ExpandInit(&xpc); 13221 xpc.xp_context = EXPAND_FILES; 13222 if (p_wic) 13223 options += WILD_ICASE; 13224 if (rettv->v_type == VAR_STRING) 13225 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 13226 NULL, options, WILD_ALL); 13227 else if (rettv_list_alloc(rettv) != FAIL) 13228 { 13229 int i; 13230 13231 ExpandOne(&xpc, get_tv_string(&argvars[0]), 13232 NULL, options, WILD_ALL_KEEP); 13233 for (i = 0; i < xpc.xp_numfiles; i++) 13234 list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); 13235 13236 ExpandCleanup(&xpc); 13237 } 13238 } 13239 else 13240 rettv->vval.v_string = NULL; 13241 } 13242 13243 /* 13244 * "globpath()" function 13245 */ 13246 static void 13247 f_globpath(typval_T *argvars, typval_T *rettv) 13248 { 13249 int flags = 0; 13250 char_u buf1[NUMBUFLEN]; 13251 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 13252 int error = FALSE; 13253 garray_T ga; 13254 int i; 13255 13256 /* When the optional second argument is non-zero, don't remove matches 13257 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 13258 rettv->v_type = VAR_STRING; 13259 if (argvars[2].v_type != VAR_UNKNOWN) 13260 { 13261 if (get_tv_number_chk(&argvars[2], &error)) 13262 flags |= WILD_KEEP_ALL; 13263 if (argvars[3].v_type != VAR_UNKNOWN) 13264 { 13265 if (get_tv_number_chk(&argvars[3], &error)) 13266 { 13267 rettv->v_type = VAR_LIST; 13268 rettv->vval.v_list = NULL; 13269 } 13270 if (argvars[4].v_type != VAR_UNKNOWN 13271 && get_tv_number_chk(&argvars[4], &error)) 13272 flags |= WILD_ALLLINKS; 13273 } 13274 } 13275 if (file != NULL && !error) 13276 { 13277 ga_init2(&ga, (int)sizeof(char_u *), 10); 13278 globpath(get_tv_string(&argvars[0]), file, &ga, flags); 13279 if (rettv->v_type == VAR_STRING) 13280 rettv->vval.v_string = ga_concat_strings(&ga, "\n"); 13281 else if (rettv_list_alloc(rettv) != FAIL) 13282 for (i = 0; i < ga.ga_len; ++i) 13283 list_append_string(rettv->vval.v_list, 13284 ((char_u **)(ga.ga_data))[i], -1); 13285 ga_clear_strings(&ga); 13286 } 13287 else 13288 rettv->vval.v_string = NULL; 13289 } 13290 13291 /* 13292 * "glob2regpat()" function 13293 */ 13294 static void 13295 f_glob2regpat(typval_T *argvars, typval_T *rettv) 13296 { 13297 char_u *pat = get_tv_string_chk(&argvars[0]); 13298 13299 rettv->v_type = VAR_STRING; 13300 rettv->vval.v_string = (pat == NULL) 13301 ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, FALSE); 13302 } 13303 13304 /* 13305 * "has()" function 13306 */ 13307 static void 13308 f_has(typval_T *argvars, typval_T *rettv) 13309 { 13310 int i; 13311 char_u *name; 13312 int n = FALSE; 13313 static char *(has_list[]) = 13314 { 13315 #ifdef AMIGA 13316 "amiga", 13317 # ifdef FEAT_ARP 13318 "arp", 13319 # endif 13320 #endif 13321 #ifdef __BEOS__ 13322 "beos", 13323 #endif 13324 #ifdef MACOS 13325 "mac", 13326 #endif 13327 #if defined(MACOS_X_UNIX) 13328 "macunix", /* built with 'darwin' enabled */ 13329 #endif 13330 #if defined(__APPLE__) && __APPLE__ == 1 13331 "osx", /* built with or without 'darwin' enabled */ 13332 #endif 13333 #ifdef __QNX__ 13334 "qnx", 13335 #endif 13336 #ifdef UNIX 13337 "unix", 13338 #endif 13339 #ifdef VMS 13340 "vms", 13341 #endif 13342 #ifdef WIN32 13343 "win32", 13344 #endif 13345 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 13346 "win32unix", 13347 #endif 13348 #if defined(WIN64) || defined(_WIN64) 13349 "win64", 13350 #endif 13351 #ifdef EBCDIC 13352 "ebcdic", 13353 #endif 13354 #ifndef CASE_INSENSITIVE_FILENAME 13355 "fname_case", 13356 #endif 13357 #ifdef HAVE_ACL 13358 "acl", 13359 #endif 13360 #ifdef FEAT_ARABIC 13361 "arabic", 13362 #endif 13363 #ifdef FEAT_AUTOCMD 13364 "autocmd", 13365 #endif 13366 #ifdef FEAT_BEVAL 13367 "balloon_eval", 13368 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 13369 "balloon_multiline", 13370 # endif 13371 #endif 13372 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 13373 "builtin_terms", 13374 # ifdef ALL_BUILTIN_TCAPS 13375 "all_builtin_terms", 13376 # endif 13377 #endif 13378 #if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \ 13379 || defined(FEAT_GUI_W32) \ 13380 || defined(FEAT_GUI_MOTIF)) 13381 "browsefilter", 13382 #endif 13383 #ifdef FEAT_BYTEOFF 13384 "byte_offset", 13385 #endif 13386 #ifdef FEAT_JOB_CHANNEL 13387 "channel", 13388 #endif 13389 #ifdef FEAT_CINDENT 13390 "cindent", 13391 #endif 13392 #ifdef FEAT_CLIENTSERVER 13393 "clientserver", 13394 #endif 13395 #ifdef FEAT_CLIPBOARD 13396 "clipboard", 13397 #endif 13398 #ifdef FEAT_CMDL_COMPL 13399 "cmdline_compl", 13400 #endif 13401 #ifdef FEAT_CMDHIST 13402 "cmdline_hist", 13403 #endif 13404 #ifdef FEAT_COMMENTS 13405 "comments", 13406 #endif 13407 #ifdef FEAT_CONCEAL 13408 "conceal", 13409 #endif 13410 #ifdef FEAT_CRYPT 13411 "cryptv", 13412 "crypt-blowfish", 13413 "crypt-blowfish2", 13414 #endif 13415 #ifdef FEAT_CSCOPE 13416 "cscope", 13417 #endif 13418 #ifdef FEAT_CURSORBIND 13419 "cursorbind", 13420 #endif 13421 #ifdef CURSOR_SHAPE 13422 "cursorshape", 13423 #endif 13424 #ifdef DEBUG 13425 "debug", 13426 #endif 13427 #ifdef FEAT_CON_DIALOG 13428 "dialog_con", 13429 #endif 13430 #ifdef FEAT_GUI_DIALOG 13431 "dialog_gui", 13432 #endif 13433 #ifdef FEAT_DIFF 13434 "diff", 13435 #endif 13436 #ifdef FEAT_DIGRAPHS 13437 "digraphs", 13438 #endif 13439 #ifdef FEAT_DIRECTX 13440 "directx", 13441 #endif 13442 #ifdef FEAT_DND 13443 "dnd", 13444 #endif 13445 #ifdef FEAT_EMACS_TAGS 13446 "emacs_tags", 13447 #endif 13448 "eval", /* always present, of course! */ 13449 "ex_extra", /* graduated feature */ 13450 #ifdef FEAT_SEARCH_EXTRA 13451 "extra_search", 13452 #endif 13453 #ifdef FEAT_FKMAP 13454 "farsi", 13455 #endif 13456 #ifdef FEAT_SEARCHPATH 13457 "file_in_path", 13458 #endif 13459 #ifdef FEAT_FILTERPIPE 13460 "filterpipe", 13461 #endif 13462 #ifdef FEAT_FIND_ID 13463 "find_in_path", 13464 #endif 13465 #ifdef FEAT_FLOAT 13466 "float", 13467 #endif 13468 #ifdef FEAT_FOLDING 13469 "folding", 13470 #endif 13471 #ifdef FEAT_FOOTER 13472 "footer", 13473 #endif 13474 #if !defined(USE_SYSTEM) && defined(UNIX) 13475 "fork", 13476 #endif 13477 #ifdef FEAT_GETTEXT 13478 "gettext", 13479 #endif 13480 #ifdef FEAT_GUI 13481 "gui", 13482 #endif 13483 #ifdef FEAT_GUI_ATHENA 13484 # ifdef FEAT_GUI_NEXTAW 13485 "gui_neXtaw", 13486 # else 13487 "gui_athena", 13488 # endif 13489 #endif 13490 #ifdef FEAT_GUI_GTK 13491 "gui_gtk", 13492 # ifdef USE_GTK3 13493 "gui_gtk3", 13494 # else 13495 "gui_gtk2", 13496 # endif 13497 #endif 13498 #ifdef FEAT_GUI_GNOME 13499 "gui_gnome", 13500 #endif 13501 #ifdef FEAT_GUI_MAC 13502 "gui_mac", 13503 #endif 13504 #ifdef FEAT_GUI_MOTIF 13505 "gui_motif", 13506 #endif 13507 #ifdef FEAT_GUI_PHOTON 13508 "gui_photon", 13509 #endif 13510 #ifdef FEAT_GUI_W32 13511 "gui_win32", 13512 #endif 13513 #ifdef FEAT_HANGULIN 13514 "hangul_input", 13515 #endif 13516 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 13517 "iconv", 13518 #endif 13519 #ifdef FEAT_INS_EXPAND 13520 "insert_expand", 13521 #endif 13522 #ifdef FEAT_JOB_CHANNEL 13523 "job", 13524 #endif 13525 #ifdef FEAT_JUMPLIST 13526 "jumplist", 13527 #endif 13528 #ifdef FEAT_KEYMAP 13529 "keymap", 13530 #endif 13531 #ifdef FEAT_LANGMAP 13532 "langmap", 13533 #endif 13534 #ifdef FEAT_LIBCALL 13535 "libcall", 13536 #endif 13537 #ifdef FEAT_LINEBREAK 13538 "linebreak", 13539 #endif 13540 #ifdef FEAT_LISP 13541 "lispindent", 13542 #endif 13543 #ifdef FEAT_LISTCMDS 13544 "listcmds", 13545 #endif 13546 #ifdef FEAT_LOCALMAP 13547 "localmap", 13548 #endif 13549 #ifdef FEAT_LUA 13550 # ifndef DYNAMIC_LUA 13551 "lua", 13552 # endif 13553 #endif 13554 #ifdef FEAT_MENU 13555 "menu", 13556 #endif 13557 #ifdef FEAT_SESSION 13558 "mksession", 13559 #endif 13560 #ifdef FEAT_MODIFY_FNAME 13561 "modify_fname", 13562 #endif 13563 #ifdef FEAT_MOUSE 13564 "mouse", 13565 #endif 13566 #ifdef FEAT_MOUSESHAPE 13567 "mouseshape", 13568 #endif 13569 #if defined(UNIX) || defined(VMS) 13570 # ifdef FEAT_MOUSE_DEC 13571 "mouse_dec", 13572 # endif 13573 # ifdef FEAT_MOUSE_GPM 13574 "mouse_gpm", 13575 # endif 13576 # ifdef FEAT_MOUSE_JSB 13577 "mouse_jsbterm", 13578 # endif 13579 # ifdef FEAT_MOUSE_NET 13580 "mouse_netterm", 13581 # endif 13582 # ifdef FEAT_MOUSE_PTERM 13583 "mouse_pterm", 13584 # endif 13585 # ifdef FEAT_MOUSE_SGR 13586 "mouse_sgr", 13587 # endif 13588 # ifdef FEAT_SYSMOUSE 13589 "mouse_sysmouse", 13590 # endif 13591 # ifdef FEAT_MOUSE_URXVT 13592 "mouse_urxvt", 13593 # endif 13594 # ifdef FEAT_MOUSE_XTERM 13595 "mouse_xterm", 13596 # endif 13597 #endif 13598 #ifdef FEAT_MBYTE 13599 "multi_byte", 13600 #endif 13601 #ifdef FEAT_MBYTE_IME 13602 "multi_byte_ime", 13603 #endif 13604 #ifdef FEAT_MULTI_LANG 13605 "multi_lang", 13606 #endif 13607 #ifdef FEAT_MZSCHEME 13608 #ifndef DYNAMIC_MZSCHEME 13609 "mzscheme", 13610 #endif 13611 #endif 13612 #ifdef FEAT_OLE 13613 "ole", 13614 #endif 13615 "packages", 13616 #ifdef FEAT_PATH_EXTRA 13617 "path_extra", 13618 #endif 13619 #ifdef FEAT_PERL 13620 #ifndef DYNAMIC_PERL 13621 "perl", 13622 #endif 13623 #endif 13624 #ifdef FEAT_PERSISTENT_UNDO 13625 "persistent_undo", 13626 #endif 13627 #ifdef FEAT_PYTHON 13628 #ifndef DYNAMIC_PYTHON 13629 "python", 13630 #endif 13631 #endif 13632 #ifdef FEAT_PYTHON3 13633 #ifndef DYNAMIC_PYTHON3 13634 "python3", 13635 #endif 13636 #endif 13637 #ifdef FEAT_POSTSCRIPT 13638 "postscript", 13639 #endif 13640 #ifdef FEAT_PRINTER 13641 "printer", 13642 #endif 13643 #ifdef FEAT_PROFILE 13644 "profile", 13645 #endif 13646 #ifdef FEAT_RELTIME 13647 "reltime", 13648 #endif 13649 #ifdef FEAT_QUICKFIX 13650 "quickfix", 13651 #endif 13652 #ifdef FEAT_RIGHTLEFT 13653 "rightleft", 13654 #endif 13655 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 13656 "ruby", 13657 #endif 13658 #ifdef FEAT_SCROLLBIND 13659 "scrollbind", 13660 #endif 13661 #ifdef FEAT_CMDL_INFO 13662 "showcmd", 13663 "cmdline_info", 13664 #endif 13665 #ifdef FEAT_SIGNS 13666 "signs", 13667 #endif 13668 #ifdef FEAT_SMARTINDENT 13669 "smartindent", 13670 #endif 13671 #ifdef STARTUPTIME 13672 "startuptime", 13673 #endif 13674 #ifdef FEAT_STL_OPT 13675 "statusline", 13676 #endif 13677 #ifdef FEAT_SUN_WORKSHOP 13678 "sun_workshop", 13679 #endif 13680 #ifdef FEAT_NETBEANS_INTG 13681 "netbeans_intg", 13682 #endif 13683 #ifdef FEAT_SPELL 13684 "spell", 13685 #endif 13686 #ifdef FEAT_SYN_HL 13687 "syntax", 13688 #endif 13689 #if defined(USE_SYSTEM) || !defined(UNIX) 13690 "system", 13691 #endif 13692 #ifdef FEAT_TAG_BINS 13693 "tag_binary", 13694 #endif 13695 #ifdef FEAT_TAG_OLDSTATIC 13696 "tag_old_static", 13697 #endif 13698 #ifdef FEAT_TAG_ANYWHITE 13699 "tag_any_white", 13700 #endif 13701 #ifdef FEAT_TCL 13702 # ifndef DYNAMIC_TCL 13703 "tcl", 13704 # endif 13705 #endif 13706 #ifdef TERMINFO 13707 "terminfo", 13708 #endif 13709 #ifdef FEAT_TERMRESPONSE 13710 "termresponse", 13711 #endif 13712 #ifdef FEAT_TEXTOBJ 13713 "textobjects", 13714 #endif 13715 #ifdef HAVE_TGETENT 13716 "tgetent", 13717 #endif 13718 #ifdef FEAT_TIMERS 13719 "timers", 13720 #endif 13721 #ifdef FEAT_TITLE 13722 "title", 13723 #endif 13724 #ifdef FEAT_TOOLBAR 13725 "toolbar", 13726 #endif 13727 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) 13728 "unnamedplus", 13729 #endif 13730 #ifdef FEAT_USR_CMDS 13731 "user-commands", /* was accidentally included in 5.4 */ 13732 "user_commands", 13733 #endif 13734 #ifdef FEAT_VIMINFO 13735 "viminfo", 13736 #endif 13737 #ifdef FEAT_VERTSPLIT 13738 "vertsplit", 13739 #endif 13740 #ifdef FEAT_VIRTUALEDIT 13741 "virtualedit", 13742 #endif 13743 "visual", 13744 #ifdef FEAT_VISUALEXTRA 13745 "visualextra", 13746 #endif 13747 #ifdef FEAT_VREPLACE 13748 "vreplace", 13749 #endif 13750 #ifdef FEAT_WILDIGN 13751 "wildignore", 13752 #endif 13753 #ifdef FEAT_WILDMENU 13754 "wildmenu", 13755 #endif 13756 #ifdef FEAT_WINDOWS 13757 "windows", 13758 #endif 13759 #ifdef FEAT_WAK 13760 "winaltkeys", 13761 #endif 13762 #ifdef FEAT_WRITEBACKUP 13763 "writebackup", 13764 #endif 13765 #ifdef FEAT_XIM 13766 "xim", 13767 #endif 13768 #ifdef FEAT_XFONTSET 13769 "xfontset", 13770 #endif 13771 #ifdef FEAT_XPM_W32 13772 "xpm", 13773 "xpm_w32", /* for backward compatibility */ 13774 #else 13775 # if defined(HAVE_XPM) 13776 "xpm", 13777 # endif 13778 #endif 13779 #ifdef USE_XSMP 13780 "xsmp", 13781 #endif 13782 #ifdef USE_XSMP_INTERACT 13783 "xsmp_interact", 13784 #endif 13785 #ifdef FEAT_XCLIPBOARD 13786 "xterm_clipboard", 13787 #endif 13788 #ifdef FEAT_XTERM_SAVE 13789 "xterm_save", 13790 #endif 13791 #if defined(UNIX) && defined(FEAT_X11) 13792 "X11", 13793 #endif 13794 NULL 13795 }; 13796 13797 name = get_tv_string(&argvars[0]); 13798 for (i = 0; has_list[i] != NULL; ++i) 13799 if (STRICMP(name, has_list[i]) == 0) 13800 { 13801 n = TRUE; 13802 break; 13803 } 13804 13805 if (n == FALSE) 13806 { 13807 if (STRNICMP(name, "patch", 5) == 0) 13808 { 13809 if (name[5] == '-' 13810 && STRLEN(name) > 11 13811 && vim_isdigit(name[6]) 13812 && vim_isdigit(name[8]) 13813 && vim_isdigit(name[10])) 13814 { 13815 int major = atoi((char *)name + 6); 13816 int minor = atoi((char *)name + 8); 13817 13818 /* Expect "patch-9.9.01234". */ 13819 n = (major < VIM_VERSION_MAJOR 13820 || (major == VIM_VERSION_MAJOR 13821 && (minor < VIM_VERSION_MINOR 13822 || (minor == VIM_VERSION_MINOR 13823 && has_patch(atoi((char *)name + 10)))))); 13824 } 13825 else 13826 n = has_patch(atoi((char *)name + 5)); 13827 } 13828 else if (STRICMP(name, "vim_starting") == 0) 13829 n = (starting != 0); 13830 #ifdef FEAT_MBYTE 13831 else if (STRICMP(name, "multi_byte_encoding") == 0) 13832 n = has_mbyte; 13833 #endif 13834 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 13835 else if (STRICMP(name, "balloon_multiline") == 0) 13836 n = multiline_balloon_available(); 13837 #endif 13838 #ifdef DYNAMIC_TCL 13839 else if (STRICMP(name, "tcl") == 0) 13840 n = tcl_enabled(FALSE); 13841 #endif 13842 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 13843 else if (STRICMP(name, "iconv") == 0) 13844 n = iconv_enabled(FALSE); 13845 #endif 13846 #ifdef DYNAMIC_LUA 13847 else if (STRICMP(name, "lua") == 0) 13848 n = lua_enabled(FALSE); 13849 #endif 13850 #ifdef DYNAMIC_MZSCHEME 13851 else if (STRICMP(name, "mzscheme") == 0) 13852 n = mzscheme_enabled(FALSE); 13853 #endif 13854 #ifdef DYNAMIC_RUBY 13855 else if (STRICMP(name, "ruby") == 0) 13856 n = ruby_enabled(FALSE); 13857 #endif 13858 #ifdef FEAT_PYTHON 13859 #ifdef DYNAMIC_PYTHON 13860 else if (STRICMP(name, "python") == 0) 13861 n = python_enabled(FALSE); 13862 #endif 13863 #endif 13864 #ifdef FEAT_PYTHON3 13865 #ifdef DYNAMIC_PYTHON3 13866 else if (STRICMP(name, "python3") == 0) 13867 n = python3_enabled(FALSE); 13868 #endif 13869 #endif 13870 #ifdef DYNAMIC_PERL 13871 else if (STRICMP(name, "perl") == 0) 13872 n = perl_enabled(FALSE); 13873 #endif 13874 #ifdef FEAT_GUI 13875 else if (STRICMP(name, "gui_running") == 0) 13876 n = (gui.in_use || gui.starting); 13877 # ifdef FEAT_GUI_W32 13878 else if (STRICMP(name, "gui_win32s") == 0) 13879 n = gui_is_win32s(); 13880 # endif 13881 # ifdef FEAT_BROWSE 13882 else if (STRICMP(name, "browse") == 0) 13883 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 13884 # endif 13885 #endif 13886 #ifdef FEAT_SYN_HL 13887 else if (STRICMP(name, "syntax_items") == 0) 13888 n = syntax_present(curwin); 13889 #endif 13890 #if defined(WIN3264) 13891 else if (STRICMP(name, "win95") == 0) 13892 n = mch_windows95(); 13893 #endif 13894 #ifdef FEAT_NETBEANS_INTG 13895 else if (STRICMP(name, "netbeans_enabled") == 0) 13896 n = netbeans_active(); 13897 #endif 13898 } 13899 13900 rettv->vval.v_number = n; 13901 } 13902 13903 /* 13904 * "has_key()" function 13905 */ 13906 static void 13907 f_has_key(typval_T *argvars, typval_T *rettv) 13908 { 13909 if (argvars[0].v_type != VAR_DICT) 13910 { 13911 EMSG(_(e_dictreq)); 13912 return; 13913 } 13914 if (argvars[0].vval.v_dict == NULL) 13915 return; 13916 13917 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 13918 get_tv_string(&argvars[1]), -1) != NULL; 13919 } 13920 13921 /* 13922 * "haslocaldir()" function 13923 */ 13924 static void 13925 f_haslocaldir(typval_T *argvars, typval_T *rettv) 13926 { 13927 win_T *wp = NULL; 13928 13929 wp = find_tabwin(&argvars[0], &argvars[1]); 13930 rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL); 13931 } 13932 13933 /* 13934 * "hasmapto()" function 13935 */ 13936 static void 13937 f_hasmapto(typval_T *argvars, typval_T *rettv) 13938 { 13939 char_u *name; 13940 char_u *mode; 13941 char_u buf[NUMBUFLEN]; 13942 int abbr = FALSE; 13943 13944 name = get_tv_string(&argvars[0]); 13945 if (argvars[1].v_type == VAR_UNKNOWN) 13946 mode = (char_u *)"nvo"; 13947 else 13948 { 13949 mode = get_tv_string_buf(&argvars[1], buf); 13950 if (argvars[2].v_type != VAR_UNKNOWN) 13951 abbr = get_tv_number(&argvars[2]); 13952 } 13953 13954 if (map_to_exists(name, mode, abbr)) 13955 rettv->vval.v_number = TRUE; 13956 else 13957 rettv->vval.v_number = FALSE; 13958 } 13959 13960 /* 13961 * "histadd()" function 13962 */ 13963 static void 13964 f_histadd(typval_T *argvars UNUSED, typval_T *rettv) 13965 { 13966 #ifdef FEAT_CMDHIST 13967 int histype; 13968 char_u *str; 13969 char_u buf[NUMBUFLEN]; 13970 #endif 13971 13972 rettv->vval.v_number = FALSE; 13973 if (check_restricted() || check_secure()) 13974 return; 13975 #ifdef FEAT_CMDHIST 13976 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 13977 histype = str != NULL ? get_histtype(str) : -1; 13978 if (histype >= 0) 13979 { 13980 str = get_tv_string_buf(&argvars[1], buf); 13981 if (*str != NUL) 13982 { 13983 init_history(); 13984 add_to_history(histype, str, FALSE, NUL); 13985 rettv->vval.v_number = TRUE; 13986 return; 13987 } 13988 } 13989 #endif 13990 } 13991 13992 /* 13993 * "histdel()" function 13994 */ 13995 static void 13996 f_histdel(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 13997 { 13998 #ifdef FEAT_CMDHIST 13999 int n; 14000 char_u buf[NUMBUFLEN]; 14001 char_u *str; 14002 14003 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 14004 if (str == NULL) 14005 n = 0; 14006 else if (argvars[1].v_type == VAR_UNKNOWN) 14007 /* only one argument: clear entire history */ 14008 n = clr_history(get_histtype(str)); 14009 else if (argvars[1].v_type == VAR_NUMBER) 14010 /* index given: remove that entry */ 14011 n = del_history_idx(get_histtype(str), 14012 (int)get_tv_number(&argvars[1])); 14013 else 14014 /* string given: remove all matching entries */ 14015 n = del_history_entry(get_histtype(str), 14016 get_tv_string_buf(&argvars[1], buf)); 14017 rettv->vval.v_number = n; 14018 #endif 14019 } 14020 14021 /* 14022 * "histget()" function 14023 */ 14024 static void 14025 f_histget(typval_T *argvars UNUSED, typval_T *rettv) 14026 { 14027 #ifdef FEAT_CMDHIST 14028 int type; 14029 int idx; 14030 char_u *str; 14031 14032 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 14033 if (str == NULL) 14034 rettv->vval.v_string = NULL; 14035 else 14036 { 14037 type = get_histtype(str); 14038 if (argvars[1].v_type == VAR_UNKNOWN) 14039 idx = get_history_idx(type); 14040 else 14041 idx = (int)get_tv_number_chk(&argvars[1], NULL); 14042 /* -1 on type error */ 14043 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 14044 } 14045 #else 14046 rettv->vval.v_string = NULL; 14047 #endif 14048 rettv->v_type = VAR_STRING; 14049 } 14050 14051 /* 14052 * "histnr()" function 14053 */ 14054 static void 14055 f_histnr(typval_T *argvars UNUSED, typval_T *rettv) 14056 { 14057 int i; 14058 14059 #ifdef FEAT_CMDHIST 14060 char_u *history = get_tv_string_chk(&argvars[0]); 14061 14062 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 14063 if (i >= HIST_CMD && i < HIST_COUNT) 14064 i = get_history_idx(i); 14065 else 14066 #endif 14067 i = -1; 14068 rettv->vval.v_number = i; 14069 } 14070 14071 /* 14072 * "highlightID(name)" function 14073 */ 14074 static void 14075 f_hlID(typval_T *argvars, typval_T *rettv) 14076 { 14077 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 14078 } 14079 14080 /* 14081 * "highlight_exists()" function 14082 */ 14083 static void 14084 f_hlexists(typval_T *argvars, typval_T *rettv) 14085 { 14086 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 14087 } 14088 14089 /* 14090 * "hostname()" function 14091 */ 14092 static void 14093 f_hostname(typval_T *argvars UNUSED, typval_T *rettv) 14094 { 14095 char_u hostname[256]; 14096 14097 mch_get_host_name(hostname, 256); 14098 rettv->v_type = VAR_STRING; 14099 rettv->vval.v_string = vim_strsave(hostname); 14100 } 14101 14102 /* 14103 * iconv() function 14104 */ 14105 static void 14106 f_iconv(typval_T *argvars UNUSED, typval_T *rettv) 14107 { 14108 #ifdef FEAT_MBYTE 14109 char_u buf1[NUMBUFLEN]; 14110 char_u buf2[NUMBUFLEN]; 14111 char_u *from, *to, *str; 14112 vimconv_T vimconv; 14113 #endif 14114 14115 rettv->v_type = VAR_STRING; 14116 rettv->vval.v_string = NULL; 14117 14118 #ifdef FEAT_MBYTE 14119 str = get_tv_string(&argvars[0]); 14120 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 14121 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 14122 vimconv.vc_type = CONV_NONE; 14123 convert_setup(&vimconv, from, to); 14124 14125 /* If the encodings are equal, no conversion needed. */ 14126 if (vimconv.vc_type == CONV_NONE) 14127 rettv->vval.v_string = vim_strsave(str); 14128 else 14129 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 14130 14131 convert_setup(&vimconv, NULL, NULL); 14132 vim_free(from); 14133 vim_free(to); 14134 #endif 14135 } 14136 14137 /* 14138 * "indent()" function 14139 */ 14140 static void 14141 f_indent(typval_T *argvars, typval_T *rettv) 14142 { 14143 linenr_T lnum; 14144 14145 lnum = get_tv_lnum(argvars); 14146 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 14147 rettv->vval.v_number = get_indent_lnum(lnum); 14148 else 14149 rettv->vval.v_number = -1; 14150 } 14151 14152 /* 14153 * "index()" function 14154 */ 14155 static void 14156 f_index(typval_T *argvars, typval_T *rettv) 14157 { 14158 list_T *l; 14159 listitem_T *item; 14160 long idx = 0; 14161 int ic = FALSE; 14162 14163 rettv->vval.v_number = -1; 14164 if (argvars[0].v_type != VAR_LIST) 14165 { 14166 EMSG(_(e_listreq)); 14167 return; 14168 } 14169 l = argvars[0].vval.v_list; 14170 if (l != NULL) 14171 { 14172 item = l->lv_first; 14173 if (argvars[2].v_type != VAR_UNKNOWN) 14174 { 14175 int error = FALSE; 14176 14177 /* Start at specified item. Use the cached index that list_find() 14178 * sets, so that a negative number also works. */ 14179 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 14180 idx = l->lv_idx; 14181 if (argvars[3].v_type != VAR_UNKNOWN) 14182 ic = get_tv_number_chk(&argvars[3], &error); 14183 if (error) 14184 item = NULL; 14185 } 14186 14187 for ( ; item != NULL; item = item->li_next, ++idx) 14188 if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) 14189 { 14190 rettv->vval.v_number = idx; 14191 break; 14192 } 14193 } 14194 } 14195 14196 static int inputsecret_flag = 0; 14197 14198 static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog); 14199 14200 /* 14201 * This function is used by f_input() and f_inputdialog() functions. The third 14202 * argument to f_input() specifies the type of completion to use at the 14203 * prompt. The third argument to f_inputdialog() specifies the value to return 14204 * when the user cancels the prompt. 14205 */ 14206 static void 14207 get_user_input( 14208 typval_T *argvars, 14209 typval_T *rettv, 14210 int inputdialog) 14211 { 14212 char_u *prompt = get_tv_string_chk(&argvars[0]); 14213 char_u *p = NULL; 14214 int c; 14215 char_u buf[NUMBUFLEN]; 14216 int cmd_silent_save = cmd_silent; 14217 char_u *defstr = (char_u *)""; 14218 int xp_type = EXPAND_NOTHING; 14219 char_u *xp_arg = NULL; 14220 14221 rettv->v_type = VAR_STRING; 14222 rettv->vval.v_string = NULL; 14223 14224 #ifdef NO_CONSOLE_INPUT 14225 /* While starting up, there is no place to enter text. */ 14226 if (no_console_input()) 14227 return; 14228 #endif 14229 14230 cmd_silent = FALSE; /* Want to see the prompt. */ 14231 if (prompt != NULL) 14232 { 14233 /* Only the part of the message after the last NL is considered as 14234 * prompt for the command line */ 14235 p = vim_strrchr(prompt, '\n'); 14236 if (p == NULL) 14237 p = prompt; 14238 else 14239 { 14240 ++p; 14241 c = *p; 14242 *p = NUL; 14243 msg_start(); 14244 msg_clr_eos(); 14245 msg_puts_attr(prompt, echo_attr); 14246 msg_didout = FALSE; 14247 msg_starthere(); 14248 *p = c; 14249 } 14250 cmdline_row = msg_row; 14251 14252 if (argvars[1].v_type != VAR_UNKNOWN) 14253 { 14254 defstr = get_tv_string_buf_chk(&argvars[1], buf); 14255 if (defstr != NULL) 14256 stuffReadbuffSpec(defstr); 14257 14258 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 14259 { 14260 char_u *xp_name; 14261 int xp_namelen; 14262 long argt; 14263 14264 /* input() with a third argument: completion */ 14265 rettv->vval.v_string = NULL; 14266 14267 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 14268 if (xp_name == NULL) 14269 return; 14270 14271 xp_namelen = (int)STRLEN(xp_name); 14272 14273 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 14274 &xp_arg) == FAIL) 14275 return; 14276 } 14277 } 14278 14279 if (defstr != NULL) 14280 { 14281 int save_ex_normal_busy = ex_normal_busy; 14282 ex_normal_busy = 0; 14283 rettv->vval.v_string = 14284 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 14285 xp_type, xp_arg); 14286 ex_normal_busy = save_ex_normal_busy; 14287 } 14288 if (inputdialog && rettv->vval.v_string == NULL 14289 && argvars[1].v_type != VAR_UNKNOWN 14290 && argvars[2].v_type != VAR_UNKNOWN) 14291 rettv->vval.v_string = vim_strsave(get_tv_string_buf( 14292 &argvars[2], buf)); 14293 14294 vim_free(xp_arg); 14295 14296 /* since the user typed this, no need to wait for return */ 14297 need_wait_return = FALSE; 14298 msg_didout = FALSE; 14299 } 14300 cmd_silent = cmd_silent_save; 14301 } 14302 14303 /* 14304 * "input()" function 14305 * Also handles inputsecret() when inputsecret is set. 14306 */ 14307 static void 14308 f_input(typval_T *argvars, typval_T *rettv) 14309 { 14310 get_user_input(argvars, rettv, FALSE); 14311 } 14312 14313 /* 14314 * "inputdialog()" function 14315 */ 14316 static void 14317 f_inputdialog(typval_T *argvars, typval_T *rettv) 14318 { 14319 #if defined(FEAT_GUI_TEXTDIALOG) 14320 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 14321 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 14322 { 14323 char_u *message; 14324 char_u buf[NUMBUFLEN]; 14325 char_u *defstr = (char_u *)""; 14326 14327 message = get_tv_string_chk(&argvars[0]); 14328 if (argvars[1].v_type != VAR_UNKNOWN 14329 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 14330 vim_strncpy(IObuff, defstr, IOSIZE - 1); 14331 else 14332 IObuff[0] = NUL; 14333 if (message != NULL && defstr != NULL 14334 && do_dialog(VIM_QUESTION, NULL, message, 14335 (char_u *)_("&OK\n&Cancel"), 1, IObuff, FALSE) == 1) 14336 rettv->vval.v_string = vim_strsave(IObuff); 14337 else 14338 { 14339 if (message != NULL && defstr != NULL 14340 && argvars[1].v_type != VAR_UNKNOWN 14341 && argvars[2].v_type != VAR_UNKNOWN) 14342 rettv->vval.v_string = vim_strsave( 14343 get_tv_string_buf(&argvars[2], buf)); 14344 else 14345 rettv->vval.v_string = NULL; 14346 } 14347 rettv->v_type = VAR_STRING; 14348 } 14349 else 14350 #endif 14351 get_user_input(argvars, rettv, TRUE); 14352 } 14353 14354 /* 14355 * "inputlist()" function 14356 */ 14357 static void 14358 f_inputlist(typval_T *argvars, typval_T *rettv) 14359 { 14360 listitem_T *li; 14361 int selected; 14362 int mouse_used; 14363 14364 #ifdef NO_CONSOLE_INPUT 14365 /* While starting up, there is no place to enter text. */ 14366 if (no_console_input()) 14367 return; 14368 #endif 14369 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 14370 { 14371 EMSG2(_(e_listarg), "inputlist()"); 14372 return; 14373 } 14374 14375 msg_start(); 14376 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 14377 lines_left = Rows; /* avoid more prompt */ 14378 msg_scroll = TRUE; 14379 msg_clr_eos(); 14380 14381 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 14382 { 14383 msg_puts(get_tv_string(&li->li_tv)); 14384 msg_putchar('\n'); 14385 } 14386 14387 /* Ask for choice. */ 14388 selected = prompt_for_number(&mouse_used); 14389 if (mouse_used) 14390 selected -= lines_left; 14391 14392 rettv->vval.v_number = selected; 14393 } 14394 14395 14396 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 14397 14398 /* 14399 * "inputrestore()" function 14400 */ 14401 static void 14402 f_inputrestore(typval_T *argvars UNUSED, typval_T *rettv) 14403 { 14404 if (ga_userinput.ga_len > 0) 14405 { 14406 --ga_userinput.ga_len; 14407 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 14408 + ga_userinput.ga_len); 14409 /* default return is zero == OK */ 14410 } 14411 else if (p_verbose > 1) 14412 { 14413 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 14414 rettv->vval.v_number = 1; /* Failed */ 14415 } 14416 } 14417 14418 /* 14419 * "inputsave()" function 14420 */ 14421 static void 14422 f_inputsave(typval_T *argvars UNUSED, typval_T *rettv) 14423 { 14424 /* Add an entry to the stack of typeahead storage. */ 14425 if (ga_grow(&ga_userinput, 1) == OK) 14426 { 14427 save_typeahead((tasave_T *)(ga_userinput.ga_data) 14428 + ga_userinput.ga_len); 14429 ++ga_userinput.ga_len; 14430 /* default return is zero == OK */ 14431 } 14432 else 14433 rettv->vval.v_number = 1; /* Failed */ 14434 } 14435 14436 /* 14437 * "inputsecret()" function 14438 */ 14439 static void 14440 f_inputsecret(typval_T *argvars, typval_T *rettv) 14441 { 14442 ++cmdline_star; 14443 ++inputsecret_flag; 14444 f_input(argvars, rettv); 14445 --cmdline_star; 14446 --inputsecret_flag; 14447 } 14448 14449 /* 14450 * "insert()" function 14451 */ 14452 static void 14453 f_insert(typval_T *argvars, typval_T *rettv) 14454 { 14455 long before = 0; 14456 listitem_T *item; 14457 list_T *l; 14458 int error = FALSE; 14459 14460 if (argvars[0].v_type != VAR_LIST) 14461 EMSG2(_(e_listarg), "insert()"); 14462 else if ((l = argvars[0].vval.v_list) != NULL 14463 && !tv_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE)) 14464 { 14465 if (argvars[2].v_type != VAR_UNKNOWN) 14466 before = get_tv_number_chk(&argvars[2], &error); 14467 if (error) 14468 return; /* type error; errmsg already given */ 14469 14470 if (before == l->lv_len) 14471 item = NULL; 14472 else 14473 { 14474 item = list_find(l, before); 14475 if (item == NULL) 14476 { 14477 EMSGN(_(e_listidx), before); 14478 l = NULL; 14479 } 14480 } 14481 if (l != NULL) 14482 { 14483 list_insert_tv(l, &argvars[1], item); 14484 copy_tv(&argvars[0], rettv); 14485 } 14486 } 14487 } 14488 14489 /* 14490 * "invert(expr)" function 14491 */ 14492 static void 14493 f_invert(typval_T *argvars, typval_T *rettv) 14494 { 14495 rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL); 14496 } 14497 14498 /* 14499 * "isdirectory()" function 14500 */ 14501 static void 14502 f_isdirectory(typval_T *argvars, typval_T *rettv) 14503 { 14504 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 14505 } 14506 14507 /* 14508 * "islocked()" function 14509 */ 14510 static void 14511 f_islocked(typval_T *argvars, typval_T *rettv) 14512 { 14513 lval_T lv; 14514 char_u *end; 14515 dictitem_T *di; 14516 14517 rettv->vval.v_number = -1; 14518 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, 14519 GLV_NO_AUTOLOAD, FNE_CHECK_START); 14520 if (end != NULL && lv.ll_name != NULL) 14521 { 14522 if (*end != NUL) 14523 EMSG(_(e_trailing)); 14524 else 14525 { 14526 if (lv.ll_tv == NULL) 14527 { 14528 if (check_changedtick(lv.ll_name)) 14529 rettv->vval.v_number = 1; /* always locked */ 14530 else 14531 { 14532 di = find_var(lv.ll_name, NULL, TRUE); 14533 if (di != NULL) 14534 { 14535 /* Consider a variable locked when: 14536 * 1. the variable itself is locked 14537 * 2. the value of the variable is locked. 14538 * 3. the List or Dict value is locked. 14539 */ 14540 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 14541 || tv_islocked(&di->di_tv)); 14542 } 14543 } 14544 } 14545 else if (lv.ll_range) 14546 EMSG(_("E786: Range not allowed")); 14547 else if (lv.ll_newkey != NULL) 14548 EMSG2(_(e_dictkey), lv.ll_newkey); 14549 else if (lv.ll_list != NULL) 14550 /* List item. */ 14551 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 14552 else 14553 /* Dictionary item. */ 14554 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 14555 } 14556 } 14557 14558 clear_lval(&lv); 14559 } 14560 14561 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 14562 /* 14563 * "isnan()" function 14564 */ 14565 static void 14566 f_isnan(typval_T *argvars, typval_T *rettv) 14567 { 14568 rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT 14569 && isnan(argvars[0].vval.v_float); 14570 } 14571 #endif 14572 14573 static void dict_list(typval_T *argvars, typval_T *rettv, int what); 14574 14575 /* 14576 * Turn a dict into a list: 14577 * "what" == 0: list of keys 14578 * "what" == 1: list of values 14579 * "what" == 2: list of items 14580 */ 14581 static void 14582 dict_list(typval_T *argvars, typval_T *rettv, int what) 14583 { 14584 list_T *l2; 14585 dictitem_T *di; 14586 hashitem_T *hi; 14587 listitem_T *li; 14588 listitem_T *li2; 14589 dict_T *d; 14590 int todo; 14591 14592 if (argvars[0].v_type != VAR_DICT) 14593 { 14594 EMSG(_(e_dictreq)); 14595 return; 14596 } 14597 if ((d = argvars[0].vval.v_dict) == NULL) 14598 return; 14599 14600 if (rettv_list_alloc(rettv) == FAIL) 14601 return; 14602 14603 todo = (int)d->dv_hashtab.ht_used; 14604 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 14605 { 14606 if (!HASHITEM_EMPTY(hi)) 14607 { 14608 --todo; 14609 di = HI2DI(hi); 14610 14611 li = listitem_alloc(); 14612 if (li == NULL) 14613 break; 14614 list_append(rettv->vval.v_list, li); 14615 14616 if (what == 0) 14617 { 14618 /* keys() */ 14619 li->li_tv.v_type = VAR_STRING; 14620 li->li_tv.v_lock = 0; 14621 li->li_tv.vval.v_string = vim_strsave(di->di_key); 14622 } 14623 else if (what == 1) 14624 { 14625 /* values() */ 14626 copy_tv(&di->di_tv, &li->li_tv); 14627 } 14628 else 14629 { 14630 /* items() */ 14631 l2 = list_alloc(); 14632 li->li_tv.v_type = VAR_LIST; 14633 li->li_tv.v_lock = 0; 14634 li->li_tv.vval.v_list = l2; 14635 if (l2 == NULL) 14636 break; 14637 ++l2->lv_refcount; 14638 14639 li2 = listitem_alloc(); 14640 if (li2 == NULL) 14641 break; 14642 list_append(l2, li2); 14643 li2->li_tv.v_type = VAR_STRING; 14644 li2->li_tv.v_lock = 0; 14645 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 14646 14647 li2 = listitem_alloc(); 14648 if (li2 == NULL) 14649 break; 14650 list_append(l2, li2); 14651 copy_tv(&di->di_tv, &li2->li_tv); 14652 } 14653 } 14654 } 14655 } 14656 14657 /* 14658 * "items(dict)" function 14659 */ 14660 static void 14661 f_items(typval_T *argvars, typval_T *rettv) 14662 { 14663 dict_list(argvars, rettv, 2); 14664 } 14665 14666 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) 14667 /* 14668 * Get the job from the argument. 14669 * Returns NULL if the job is invalid. 14670 */ 14671 static job_T * 14672 get_job_arg(typval_T *tv) 14673 { 14674 job_T *job; 14675 14676 if (tv->v_type != VAR_JOB) 14677 { 14678 EMSG2(_(e_invarg2), get_tv_string(tv)); 14679 return NULL; 14680 } 14681 job = tv->vval.v_job; 14682 14683 if (job == NULL) 14684 EMSG(_("E916: not a valid job")); 14685 return job; 14686 } 14687 14688 /* 14689 * "job_getchannel()" function 14690 */ 14691 static void 14692 f_job_getchannel(typval_T *argvars, typval_T *rettv) 14693 { 14694 job_T *job = get_job_arg(&argvars[0]); 14695 14696 if (job != NULL) 14697 { 14698 rettv->v_type = VAR_CHANNEL; 14699 rettv->vval.v_channel = job->jv_channel; 14700 if (job->jv_channel != NULL) 14701 ++job->jv_channel->ch_refcount; 14702 } 14703 } 14704 14705 /* 14706 * "job_info()" function 14707 */ 14708 static void 14709 f_job_info(typval_T *argvars, typval_T *rettv) 14710 { 14711 job_T *job = get_job_arg(&argvars[0]); 14712 14713 if (job != NULL && rettv_dict_alloc(rettv) != FAIL) 14714 job_info(job, rettv->vval.v_dict); 14715 } 14716 14717 /* 14718 * "job_setoptions()" function 14719 */ 14720 static void 14721 f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED) 14722 { 14723 job_T *job = get_job_arg(&argvars[0]); 14724 jobopt_T opt; 14725 14726 if (job == NULL) 14727 return; 14728 clear_job_options(&opt); 14729 if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB) == FAIL) 14730 return; 14731 job_set_options(job, &opt); 14732 } 14733 14734 /* 14735 * "job_start()" function 14736 */ 14737 static void 14738 f_job_start(typval_T *argvars, typval_T *rettv) 14739 { 14740 rettv->v_type = VAR_JOB; 14741 rettv->vval.v_job = job_start(argvars); 14742 } 14743 14744 /* 14745 * "job_status()" function 14746 */ 14747 static void 14748 f_job_status(typval_T *argvars, typval_T *rettv) 14749 { 14750 job_T *job = get_job_arg(&argvars[0]); 14751 14752 if (job != NULL) 14753 { 14754 rettv->v_type = VAR_STRING; 14755 rettv->vval.v_string = vim_strsave((char_u *)job_status(job)); 14756 } 14757 } 14758 14759 /* 14760 * "job_stop()" function 14761 */ 14762 static void 14763 f_job_stop(typval_T *argvars, typval_T *rettv) 14764 { 14765 job_T *job = get_job_arg(&argvars[0]); 14766 14767 if (job != NULL) 14768 rettv->vval.v_number = job_stop(job, argvars); 14769 } 14770 #endif 14771 14772 /* 14773 * "join()" function 14774 */ 14775 static void 14776 f_join(typval_T *argvars, typval_T *rettv) 14777 { 14778 garray_T ga; 14779 char_u *sep; 14780 14781 if (argvars[0].v_type != VAR_LIST) 14782 { 14783 EMSG(_(e_listreq)); 14784 return; 14785 } 14786 if (argvars[0].vval.v_list == NULL) 14787 return; 14788 if (argvars[1].v_type == VAR_UNKNOWN) 14789 sep = (char_u *)" "; 14790 else 14791 sep = get_tv_string_chk(&argvars[1]); 14792 14793 rettv->v_type = VAR_STRING; 14794 14795 if (sep != NULL) 14796 { 14797 ga_init2(&ga, (int)sizeof(char), 80); 14798 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 14799 ga_append(&ga, NUL); 14800 rettv->vval.v_string = (char_u *)ga.ga_data; 14801 } 14802 else 14803 rettv->vval.v_string = NULL; 14804 } 14805 14806 /* 14807 * "js_decode()" function 14808 */ 14809 static void 14810 f_js_decode(typval_T *argvars, typval_T *rettv) 14811 { 14812 js_read_T reader; 14813 14814 reader.js_buf = get_tv_string(&argvars[0]); 14815 reader.js_fill = NULL; 14816 reader.js_used = 0; 14817 if (json_decode_all(&reader, rettv, JSON_JS) != OK) 14818 EMSG(_(e_invarg)); 14819 } 14820 14821 /* 14822 * "js_encode()" function 14823 */ 14824 static void 14825 f_js_encode(typval_T *argvars, typval_T *rettv) 14826 { 14827 rettv->v_type = VAR_STRING; 14828 rettv->vval.v_string = json_encode(&argvars[0], JSON_JS); 14829 } 14830 14831 /* 14832 * "json_decode()" function 14833 */ 14834 static void 14835 f_json_decode(typval_T *argvars, typval_T *rettv) 14836 { 14837 js_read_T reader; 14838 14839 reader.js_buf = get_tv_string(&argvars[0]); 14840 reader.js_fill = NULL; 14841 reader.js_used = 0; 14842 if (json_decode_all(&reader, rettv, 0) != OK) 14843 EMSG(_(e_invarg)); 14844 } 14845 14846 /* 14847 * "json_encode()" function 14848 */ 14849 static void 14850 f_json_encode(typval_T *argvars, typval_T *rettv) 14851 { 14852 rettv->v_type = VAR_STRING; 14853 rettv->vval.v_string = json_encode(&argvars[0], 0); 14854 } 14855 14856 /* 14857 * "keys()" function 14858 */ 14859 static void 14860 f_keys(typval_T *argvars, typval_T *rettv) 14861 { 14862 dict_list(argvars, rettv, 0); 14863 } 14864 14865 /* 14866 * "last_buffer_nr()" function. 14867 */ 14868 static void 14869 f_last_buffer_nr(typval_T *argvars UNUSED, typval_T *rettv) 14870 { 14871 int n = 0; 14872 buf_T *buf; 14873 14874 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 14875 if (n < buf->b_fnum) 14876 n = buf->b_fnum; 14877 14878 rettv->vval.v_number = n; 14879 } 14880 14881 /* 14882 * "len()" function 14883 */ 14884 static void 14885 f_len(typval_T *argvars, typval_T *rettv) 14886 { 14887 switch (argvars[0].v_type) 14888 { 14889 case VAR_STRING: 14890 case VAR_NUMBER: 14891 rettv->vval.v_number = (varnumber_T)STRLEN( 14892 get_tv_string(&argvars[0])); 14893 break; 14894 case VAR_LIST: 14895 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 14896 break; 14897 case VAR_DICT: 14898 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 14899 break; 14900 case VAR_UNKNOWN: 14901 case VAR_SPECIAL: 14902 case VAR_FLOAT: 14903 case VAR_FUNC: 14904 case VAR_PARTIAL: 14905 case VAR_JOB: 14906 case VAR_CHANNEL: 14907 EMSG(_("E701: Invalid type for len()")); 14908 break; 14909 } 14910 } 14911 14912 static void libcall_common(typval_T *argvars, typval_T *rettv, int type); 14913 14914 static void 14915 libcall_common(typval_T *argvars, typval_T *rettv, int type) 14916 { 14917 #ifdef FEAT_LIBCALL 14918 char_u *string_in; 14919 char_u **string_result; 14920 int nr_result; 14921 #endif 14922 14923 rettv->v_type = type; 14924 if (type != VAR_NUMBER) 14925 rettv->vval.v_string = NULL; 14926 14927 if (check_restricted() || check_secure()) 14928 return; 14929 14930 #ifdef FEAT_LIBCALL 14931 /* The first two args must be strings, otherwise its meaningless */ 14932 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 14933 { 14934 string_in = NULL; 14935 if (argvars[2].v_type == VAR_STRING) 14936 string_in = argvars[2].vval.v_string; 14937 if (type == VAR_NUMBER) 14938 string_result = NULL; 14939 else 14940 string_result = &rettv->vval.v_string; 14941 if (mch_libcall(argvars[0].vval.v_string, 14942 argvars[1].vval.v_string, 14943 string_in, 14944 argvars[2].vval.v_number, 14945 string_result, 14946 &nr_result) == OK 14947 && type == VAR_NUMBER) 14948 rettv->vval.v_number = nr_result; 14949 } 14950 #endif 14951 } 14952 14953 /* 14954 * "libcall()" function 14955 */ 14956 static void 14957 f_libcall(typval_T *argvars, typval_T *rettv) 14958 { 14959 libcall_common(argvars, rettv, VAR_STRING); 14960 } 14961 14962 /* 14963 * "libcallnr()" function 14964 */ 14965 static void 14966 f_libcallnr(typval_T *argvars, typval_T *rettv) 14967 { 14968 libcall_common(argvars, rettv, VAR_NUMBER); 14969 } 14970 14971 /* 14972 * "line(string)" function 14973 */ 14974 static void 14975 f_line(typval_T *argvars, typval_T *rettv) 14976 { 14977 linenr_T lnum = 0; 14978 pos_T *fp; 14979 int fnum; 14980 14981 fp = var2fpos(&argvars[0], TRUE, &fnum); 14982 if (fp != NULL) 14983 lnum = fp->lnum; 14984 rettv->vval.v_number = lnum; 14985 } 14986 14987 /* 14988 * "line2byte(lnum)" function 14989 */ 14990 static void 14991 f_line2byte(typval_T *argvars UNUSED, typval_T *rettv) 14992 { 14993 #ifndef FEAT_BYTEOFF 14994 rettv->vval.v_number = -1; 14995 #else 14996 linenr_T lnum; 14997 14998 lnum = get_tv_lnum(argvars); 14999 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 15000 rettv->vval.v_number = -1; 15001 else 15002 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 15003 if (rettv->vval.v_number >= 0) 15004 ++rettv->vval.v_number; 15005 #endif 15006 } 15007 15008 /* 15009 * "lispindent(lnum)" function 15010 */ 15011 static void 15012 f_lispindent(typval_T *argvars UNUSED, typval_T *rettv) 15013 { 15014 #ifdef FEAT_LISP 15015 pos_T pos; 15016 linenr_T lnum; 15017 15018 pos = curwin->w_cursor; 15019 lnum = get_tv_lnum(argvars); 15020 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 15021 { 15022 curwin->w_cursor.lnum = lnum; 15023 rettv->vval.v_number = get_lisp_indent(); 15024 curwin->w_cursor = pos; 15025 } 15026 else 15027 #endif 15028 rettv->vval.v_number = -1; 15029 } 15030 15031 /* 15032 * "localtime()" function 15033 */ 15034 static void 15035 f_localtime(typval_T *argvars UNUSED, typval_T *rettv) 15036 { 15037 rettv->vval.v_number = (varnumber_T)time(NULL); 15038 } 15039 15040 static void get_maparg(typval_T *argvars, typval_T *rettv, int exact); 15041 15042 static void 15043 get_maparg(typval_T *argvars, typval_T *rettv, int exact) 15044 { 15045 char_u *keys; 15046 char_u *which; 15047 char_u buf[NUMBUFLEN]; 15048 char_u *keys_buf = NULL; 15049 char_u *rhs; 15050 int mode; 15051 int abbr = FALSE; 15052 int get_dict = FALSE; 15053 mapblock_T *mp; 15054 int buffer_local; 15055 15056 /* return empty string for failure */ 15057 rettv->v_type = VAR_STRING; 15058 rettv->vval.v_string = NULL; 15059 15060 keys = get_tv_string(&argvars[0]); 15061 if (*keys == NUL) 15062 return; 15063 15064 if (argvars[1].v_type != VAR_UNKNOWN) 15065 { 15066 which = get_tv_string_buf_chk(&argvars[1], buf); 15067 if (argvars[2].v_type != VAR_UNKNOWN) 15068 { 15069 abbr = get_tv_number(&argvars[2]); 15070 if (argvars[3].v_type != VAR_UNKNOWN) 15071 get_dict = get_tv_number(&argvars[3]); 15072 } 15073 } 15074 else 15075 which = (char_u *)""; 15076 if (which == NULL) 15077 return; 15078 15079 mode = get_map_mode(&which, 0); 15080 15081 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 15082 rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); 15083 vim_free(keys_buf); 15084 15085 if (!get_dict) 15086 { 15087 /* Return a string. */ 15088 if (rhs != NULL) 15089 rettv->vval.v_string = str2special_save(rhs, FALSE); 15090 15091 } 15092 else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL) 15093 { 15094 /* Return a dictionary. */ 15095 char_u *lhs = str2special_save(mp->m_keys, TRUE); 15096 char_u *mapmode = map_mode_to_chars(mp->m_mode); 15097 dict_T *dict = rettv->vval.v_dict; 15098 15099 dict_add_nr_str(dict, "lhs", 0L, lhs); 15100 dict_add_nr_str(dict, "rhs", 0L, mp->m_orig_str); 15101 dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL); 15102 dict_add_nr_str(dict, "expr", mp->m_expr ? 1L : 0L, NULL); 15103 dict_add_nr_str(dict, "silent", mp->m_silent ? 1L : 0L, NULL); 15104 dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL); 15105 dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL); 15106 dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL); 15107 dict_add_nr_str(dict, "mode", 0L, mapmode); 15108 15109 vim_free(lhs); 15110 vim_free(mapmode); 15111 } 15112 } 15113 15114 #ifdef FEAT_FLOAT 15115 /* 15116 * "log()" function 15117 */ 15118 static void 15119 f_log(typval_T *argvars, typval_T *rettv) 15120 { 15121 float_T f = 0.0; 15122 15123 rettv->v_type = VAR_FLOAT; 15124 if (get_float_arg(argvars, &f) == OK) 15125 rettv->vval.v_float = log(f); 15126 else 15127 rettv->vval.v_float = 0.0; 15128 } 15129 15130 /* 15131 * "log10()" function 15132 */ 15133 static void 15134 f_log10(typval_T *argvars, typval_T *rettv) 15135 { 15136 float_T f = 0.0; 15137 15138 rettv->v_type = VAR_FLOAT; 15139 if (get_float_arg(argvars, &f) == OK) 15140 rettv->vval.v_float = log10(f); 15141 else 15142 rettv->vval.v_float = 0.0; 15143 } 15144 #endif 15145 15146 #ifdef FEAT_LUA 15147 /* 15148 * "luaeval()" function 15149 */ 15150 static void 15151 f_luaeval(typval_T *argvars, typval_T *rettv) 15152 { 15153 char_u *str; 15154 char_u buf[NUMBUFLEN]; 15155 15156 str = get_tv_string_buf(&argvars[0], buf); 15157 do_luaeval(str, argvars + 1, rettv); 15158 } 15159 #endif 15160 15161 /* 15162 * "map()" function 15163 */ 15164 static void 15165 f_map(typval_T *argvars, typval_T *rettv) 15166 { 15167 filter_map(argvars, rettv, TRUE); 15168 } 15169 15170 /* 15171 * "maparg()" function 15172 */ 15173 static void 15174 f_maparg(typval_T *argvars, typval_T *rettv) 15175 { 15176 get_maparg(argvars, rettv, TRUE); 15177 } 15178 15179 /* 15180 * "mapcheck()" function 15181 */ 15182 static void 15183 f_mapcheck(typval_T *argvars, typval_T *rettv) 15184 { 15185 get_maparg(argvars, rettv, FALSE); 15186 } 15187 15188 static void find_some_match(typval_T *argvars, typval_T *rettv, int start); 15189 15190 static void 15191 find_some_match(typval_T *argvars, typval_T *rettv, int type) 15192 { 15193 char_u *str = NULL; 15194 long len = 0; 15195 char_u *expr = NULL; 15196 char_u *pat; 15197 regmatch_T regmatch; 15198 char_u patbuf[NUMBUFLEN]; 15199 char_u strbuf[NUMBUFLEN]; 15200 char_u *save_cpo; 15201 long start = 0; 15202 long nth = 1; 15203 colnr_T startcol = 0; 15204 int match = 0; 15205 list_T *l = NULL; 15206 listitem_T *li = NULL; 15207 long idx = 0; 15208 char_u *tofree = NULL; 15209 15210 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15211 save_cpo = p_cpo; 15212 p_cpo = (char_u *)""; 15213 15214 rettv->vval.v_number = -1; 15215 if (type == 3) 15216 { 15217 /* return empty list when there are no matches */ 15218 if (rettv_list_alloc(rettv) == FAIL) 15219 goto theend; 15220 } 15221 else if (type == 2) 15222 { 15223 rettv->v_type = VAR_STRING; 15224 rettv->vval.v_string = NULL; 15225 } 15226 15227 if (argvars[0].v_type == VAR_LIST) 15228 { 15229 if ((l = argvars[0].vval.v_list) == NULL) 15230 goto theend; 15231 li = l->lv_first; 15232 } 15233 else 15234 { 15235 expr = str = get_tv_string(&argvars[0]); 15236 len = (long)STRLEN(str); 15237 } 15238 15239 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 15240 if (pat == NULL) 15241 goto theend; 15242 15243 if (argvars[2].v_type != VAR_UNKNOWN) 15244 { 15245 int error = FALSE; 15246 15247 start = get_tv_number_chk(&argvars[2], &error); 15248 if (error) 15249 goto theend; 15250 if (l != NULL) 15251 { 15252 li = list_find(l, start); 15253 if (li == NULL) 15254 goto theend; 15255 idx = l->lv_idx; /* use the cached index */ 15256 } 15257 else 15258 { 15259 if (start < 0) 15260 start = 0; 15261 if (start > len) 15262 goto theend; 15263 /* When "count" argument is there ignore matches before "start", 15264 * otherwise skip part of the string. Differs when pattern is "^" 15265 * or "\<". */ 15266 if (argvars[3].v_type != VAR_UNKNOWN) 15267 startcol = start; 15268 else 15269 { 15270 str += start; 15271 len -= start; 15272 } 15273 } 15274 15275 if (argvars[3].v_type != VAR_UNKNOWN) 15276 nth = get_tv_number_chk(&argvars[3], &error); 15277 if (error) 15278 goto theend; 15279 } 15280 15281 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 15282 if (regmatch.regprog != NULL) 15283 { 15284 regmatch.rm_ic = p_ic; 15285 15286 for (;;) 15287 { 15288 if (l != NULL) 15289 { 15290 if (li == NULL) 15291 { 15292 match = FALSE; 15293 break; 15294 } 15295 vim_free(tofree); 15296 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 15297 if (str == NULL) 15298 break; 15299 } 15300 15301 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 15302 15303 if (match && --nth <= 0) 15304 break; 15305 if (l == NULL && !match) 15306 break; 15307 15308 /* Advance to just after the match. */ 15309 if (l != NULL) 15310 { 15311 li = li->li_next; 15312 ++idx; 15313 } 15314 else 15315 { 15316 #ifdef FEAT_MBYTE 15317 startcol = (colnr_T)(regmatch.startp[0] 15318 + (*mb_ptr2len)(regmatch.startp[0]) - str); 15319 #else 15320 startcol = (colnr_T)(regmatch.startp[0] + 1 - str); 15321 #endif 15322 if (startcol > (colnr_T)len 15323 || str + startcol <= regmatch.startp[0]) 15324 { 15325 match = FALSE; 15326 break; 15327 } 15328 } 15329 } 15330 15331 if (match) 15332 { 15333 if (type == 3) 15334 { 15335 int i; 15336 15337 /* return list with matched string and submatches */ 15338 for (i = 0; i < NSUBEXP; ++i) 15339 { 15340 if (regmatch.endp[i] == NULL) 15341 { 15342 if (list_append_string(rettv->vval.v_list, 15343 (char_u *)"", 0) == FAIL) 15344 break; 15345 } 15346 else if (list_append_string(rettv->vval.v_list, 15347 regmatch.startp[i], 15348 (int)(regmatch.endp[i] - regmatch.startp[i])) 15349 == FAIL) 15350 break; 15351 } 15352 } 15353 else if (type == 2) 15354 { 15355 /* return matched string */ 15356 if (l != NULL) 15357 copy_tv(&li->li_tv, rettv); 15358 else 15359 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 15360 (int)(regmatch.endp[0] - regmatch.startp[0])); 15361 } 15362 else if (l != NULL) 15363 rettv->vval.v_number = idx; 15364 else 15365 { 15366 if (type != 0) 15367 rettv->vval.v_number = 15368 (varnumber_T)(regmatch.startp[0] - str); 15369 else 15370 rettv->vval.v_number = 15371 (varnumber_T)(regmatch.endp[0] - str); 15372 rettv->vval.v_number += (varnumber_T)(str - expr); 15373 } 15374 } 15375 vim_regfree(regmatch.regprog); 15376 } 15377 15378 theend: 15379 vim_free(tofree); 15380 p_cpo = save_cpo; 15381 } 15382 15383 /* 15384 * "match()" function 15385 */ 15386 static void 15387 f_match(typval_T *argvars, typval_T *rettv) 15388 { 15389 find_some_match(argvars, rettv, 1); 15390 } 15391 15392 /* 15393 * "matchadd()" function 15394 */ 15395 static void 15396 f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 15397 { 15398 #ifdef FEAT_SEARCH_EXTRA 15399 char_u buf[NUMBUFLEN]; 15400 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 15401 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 15402 int prio = 10; /* default priority */ 15403 int id = -1; 15404 int error = FALSE; 15405 char_u *conceal_char = NULL; 15406 15407 rettv->vval.v_number = -1; 15408 15409 if (grp == NULL || pat == NULL) 15410 return; 15411 if (argvars[2].v_type != VAR_UNKNOWN) 15412 { 15413 prio = get_tv_number_chk(&argvars[2], &error); 15414 if (argvars[3].v_type != VAR_UNKNOWN) 15415 { 15416 id = get_tv_number_chk(&argvars[3], &error); 15417 if (argvars[4].v_type != VAR_UNKNOWN) 15418 { 15419 if (argvars[4].v_type != VAR_DICT) 15420 { 15421 EMSG(_(e_dictreq)); 15422 return; 15423 } 15424 if (dict_find(argvars[4].vval.v_dict, 15425 (char_u *)"conceal", -1) != NULL) 15426 conceal_char = get_dict_string(argvars[4].vval.v_dict, 15427 (char_u *)"conceal", FALSE); 15428 } 15429 } 15430 } 15431 if (error == TRUE) 15432 return; 15433 if (id >= 1 && id <= 3) 15434 { 15435 EMSGN("E798: ID is reserved for \":match\": %ld", id); 15436 return; 15437 } 15438 15439 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL, 15440 conceal_char); 15441 #endif 15442 } 15443 15444 /* 15445 * "matchaddpos()" function 15446 */ 15447 static void 15448 f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 15449 { 15450 #ifdef FEAT_SEARCH_EXTRA 15451 char_u buf[NUMBUFLEN]; 15452 char_u *group; 15453 int prio = 10; 15454 int id = -1; 15455 int error = FALSE; 15456 list_T *l; 15457 char_u *conceal_char = NULL; 15458 15459 rettv->vval.v_number = -1; 15460 15461 group = get_tv_string_buf_chk(&argvars[0], buf); 15462 if (group == NULL) 15463 return; 15464 15465 if (argvars[1].v_type != VAR_LIST) 15466 { 15467 EMSG2(_(e_listarg), "matchaddpos()"); 15468 return; 15469 } 15470 l = argvars[1].vval.v_list; 15471 if (l == NULL) 15472 return; 15473 15474 if (argvars[2].v_type != VAR_UNKNOWN) 15475 { 15476 prio = get_tv_number_chk(&argvars[2], &error); 15477 if (argvars[3].v_type != VAR_UNKNOWN) 15478 { 15479 id = get_tv_number_chk(&argvars[3], &error); 15480 if (argvars[4].v_type != VAR_UNKNOWN) 15481 { 15482 if (argvars[4].v_type != VAR_DICT) 15483 { 15484 EMSG(_(e_dictreq)); 15485 return; 15486 } 15487 if (dict_find(argvars[4].vval.v_dict, 15488 (char_u *)"conceal", -1) != NULL) 15489 conceal_char = get_dict_string(argvars[4].vval.v_dict, 15490 (char_u *)"conceal", FALSE); 15491 } 15492 } 15493 } 15494 if (error == TRUE) 15495 return; 15496 15497 /* id == 3 is ok because matchaddpos() is supposed to substitute :3match */ 15498 if (id == 1 || id == 2) 15499 { 15500 EMSGN("E798: ID is reserved for \":match\": %ld", id); 15501 return; 15502 } 15503 15504 rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l, 15505 conceal_char); 15506 #endif 15507 } 15508 15509 /* 15510 * "matcharg()" function 15511 */ 15512 static void 15513 f_matcharg(typval_T *argvars UNUSED, typval_T *rettv) 15514 { 15515 if (rettv_list_alloc(rettv) == OK) 15516 { 15517 #ifdef FEAT_SEARCH_EXTRA 15518 int id = get_tv_number(&argvars[0]); 15519 matchitem_T *m; 15520 15521 if (id >= 1 && id <= 3) 15522 { 15523 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 15524 { 15525 list_append_string(rettv->vval.v_list, 15526 syn_id2name(m->hlg_id), -1); 15527 list_append_string(rettv->vval.v_list, m->pattern, -1); 15528 } 15529 else 15530 { 15531 list_append_string(rettv->vval.v_list, NULL, -1); 15532 list_append_string(rettv->vval.v_list, NULL, -1); 15533 } 15534 } 15535 #endif 15536 } 15537 } 15538 15539 /* 15540 * "matchdelete()" function 15541 */ 15542 static void 15543 f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 15544 { 15545 #ifdef FEAT_SEARCH_EXTRA 15546 rettv->vval.v_number = match_delete(curwin, 15547 (int)get_tv_number(&argvars[0]), TRUE); 15548 #endif 15549 } 15550 15551 /* 15552 * "matchend()" function 15553 */ 15554 static void 15555 f_matchend(typval_T *argvars, typval_T *rettv) 15556 { 15557 find_some_match(argvars, rettv, 0); 15558 } 15559 15560 /* 15561 * "matchlist()" function 15562 */ 15563 static void 15564 f_matchlist(typval_T *argvars, typval_T *rettv) 15565 { 15566 find_some_match(argvars, rettv, 3); 15567 } 15568 15569 /* 15570 * "matchstr()" function 15571 */ 15572 static void 15573 f_matchstr(typval_T *argvars, typval_T *rettv) 15574 { 15575 find_some_match(argvars, rettv, 2); 15576 } 15577 15578 static void max_min(typval_T *argvars, typval_T *rettv, int domax); 15579 15580 static void 15581 max_min(typval_T *argvars, typval_T *rettv, int domax) 15582 { 15583 long n = 0; 15584 long i; 15585 int error = FALSE; 15586 15587 if (argvars[0].v_type == VAR_LIST) 15588 { 15589 list_T *l; 15590 listitem_T *li; 15591 15592 l = argvars[0].vval.v_list; 15593 if (l != NULL) 15594 { 15595 li = l->lv_first; 15596 if (li != NULL) 15597 { 15598 n = get_tv_number_chk(&li->li_tv, &error); 15599 for (;;) 15600 { 15601 li = li->li_next; 15602 if (li == NULL) 15603 break; 15604 i = get_tv_number_chk(&li->li_tv, &error); 15605 if (domax ? i > n : i < n) 15606 n = i; 15607 } 15608 } 15609 } 15610 } 15611 else if (argvars[0].v_type == VAR_DICT) 15612 { 15613 dict_T *d; 15614 int first = TRUE; 15615 hashitem_T *hi; 15616 int todo; 15617 15618 d = argvars[0].vval.v_dict; 15619 if (d != NULL) 15620 { 15621 todo = (int)d->dv_hashtab.ht_used; 15622 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 15623 { 15624 if (!HASHITEM_EMPTY(hi)) 15625 { 15626 --todo; 15627 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 15628 if (first) 15629 { 15630 n = i; 15631 first = FALSE; 15632 } 15633 else if (domax ? i > n : i < n) 15634 n = i; 15635 } 15636 } 15637 } 15638 } 15639 else 15640 EMSG(_(e_listdictarg)); 15641 rettv->vval.v_number = error ? 0 : n; 15642 } 15643 15644 /* 15645 * "max()" function 15646 */ 15647 static void 15648 f_max(typval_T *argvars, typval_T *rettv) 15649 { 15650 max_min(argvars, rettv, TRUE); 15651 } 15652 15653 /* 15654 * "min()" function 15655 */ 15656 static void 15657 f_min(typval_T *argvars, typval_T *rettv) 15658 { 15659 max_min(argvars, rettv, FALSE); 15660 } 15661 15662 static int mkdir_recurse(char_u *dir, int prot); 15663 15664 /* 15665 * Create the directory in which "dir" is located, and higher levels when 15666 * needed. 15667 */ 15668 static int 15669 mkdir_recurse(char_u *dir, int prot) 15670 { 15671 char_u *p; 15672 char_u *updir; 15673 int r = FAIL; 15674 15675 /* Get end of directory name in "dir". 15676 * We're done when it's "/" or "c:/". */ 15677 p = gettail_sep(dir); 15678 if (p <= get_past_head(dir)) 15679 return OK; 15680 15681 /* If the directory exists we're done. Otherwise: create it.*/ 15682 updir = vim_strnsave(dir, (int)(p - dir)); 15683 if (updir == NULL) 15684 return FAIL; 15685 if (mch_isdir(updir)) 15686 r = OK; 15687 else if (mkdir_recurse(updir, prot) == OK) 15688 r = vim_mkdir_emsg(updir, prot); 15689 vim_free(updir); 15690 return r; 15691 } 15692 15693 #ifdef vim_mkdir 15694 /* 15695 * "mkdir()" function 15696 */ 15697 static void 15698 f_mkdir(typval_T *argvars, typval_T *rettv) 15699 { 15700 char_u *dir; 15701 char_u buf[NUMBUFLEN]; 15702 int prot = 0755; 15703 15704 rettv->vval.v_number = FAIL; 15705 if (check_restricted() || check_secure()) 15706 return; 15707 15708 dir = get_tv_string_buf(&argvars[0], buf); 15709 if (*dir == NUL) 15710 rettv->vval.v_number = FAIL; 15711 else 15712 { 15713 if (*gettail(dir) == NUL) 15714 /* remove trailing slashes */ 15715 *gettail_sep(dir) = NUL; 15716 15717 if (argvars[1].v_type != VAR_UNKNOWN) 15718 { 15719 if (argvars[2].v_type != VAR_UNKNOWN) 15720 prot = get_tv_number_chk(&argvars[2], NULL); 15721 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 15722 mkdir_recurse(dir, prot); 15723 } 15724 rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); 15725 } 15726 } 15727 #endif 15728 15729 /* 15730 * "mode()" function 15731 */ 15732 static void 15733 f_mode(typval_T *argvars, typval_T *rettv) 15734 { 15735 char_u buf[3]; 15736 15737 buf[1] = NUL; 15738 buf[2] = NUL; 15739 15740 if (VIsual_active) 15741 { 15742 if (VIsual_select) 15743 buf[0] = VIsual_mode + 's' - 'v'; 15744 else 15745 buf[0] = VIsual_mode; 15746 } 15747 else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 15748 || State == CONFIRM) 15749 { 15750 buf[0] = 'r'; 15751 if (State == ASKMORE) 15752 buf[1] = 'm'; 15753 else if (State == CONFIRM) 15754 buf[1] = '?'; 15755 } 15756 else if (State == EXTERNCMD) 15757 buf[0] = '!'; 15758 else if (State & INSERT) 15759 { 15760 #ifdef FEAT_VREPLACE 15761 if (State & VREPLACE_FLAG) 15762 { 15763 buf[0] = 'R'; 15764 buf[1] = 'v'; 15765 } 15766 else 15767 #endif 15768 if (State & REPLACE_FLAG) 15769 buf[0] = 'R'; 15770 else 15771 buf[0] = 'i'; 15772 } 15773 else if (State & CMDLINE) 15774 { 15775 buf[0] = 'c'; 15776 if (exmode_active) 15777 buf[1] = 'v'; 15778 } 15779 else if (exmode_active) 15780 { 15781 buf[0] = 'c'; 15782 buf[1] = 'e'; 15783 } 15784 else 15785 { 15786 buf[0] = 'n'; 15787 if (finish_op) 15788 buf[1] = 'o'; 15789 } 15790 15791 /* Clear out the minor mode when the argument is not a non-zero number or 15792 * non-empty string. */ 15793 if (!non_zero_arg(&argvars[0])) 15794 buf[1] = NUL; 15795 15796 rettv->vval.v_string = vim_strsave(buf); 15797 rettv->v_type = VAR_STRING; 15798 } 15799 15800 #if defined(FEAT_MZSCHEME) || defined(PROTO) 15801 /* 15802 * "mzeval()" function 15803 */ 15804 static void 15805 f_mzeval(typval_T *argvars, typval_T *rettv) 15806 { 15807 char_u *str; 15808 char_u buf[NUMBUFLEN]; 15809 15810 str = get_tv_string_buf(&argvars[0], buf); 15811 do_mzeval(str, rettv); 15812 } 15813 15814 void 15815 mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv) 15816 { 15817 typval_T argvars[3]; 15818 15819 argvars[0].v_type = VAR_STRING; 15820 argvars[0].vval.v_string = name; 15821 copy_tv(args, &argvars[1]); 15822 argvars[2].v_type = VAR_UNKNOWN; 15823 f_call(argvars, rettv); 15824 clear_tv(&argvars[1]); 15825 } 15826 #endif 15827 15828 /* 15829 * "nextnonblank()" function 15830 */ 15831 static void 15832 f_nextnonblank(typval_T *argvars, typval_T *rettv) 15833 { 15834 linenr_T lnum; 15835 15836 for (lnum = get_tv_lnum(argvars); ; ++lnum) 15837 { 15838 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 15839 { 15840 lnum = 0; 15841 break; 15842 } 15843 if (*skipwhite(ml_get(lnum)) != NUL) 15844 break; 15845 } 15846 rettv->vval.v_number = lnum; 15847 } 15848 15849 /* 15850 * "nr2char()" function 15851 */ 15852 static void 15853 f_nr2char(typval_T *argvars, typval_T *rettv) 15854 { 15855 char_u buf[NUMBUFLEN]; 15856 15857 #ifdef FEAT_MBYTE 15858 if (has_mbyte) 15859 { 15860 int utf8 = 0; 15861 15862 if (argvars[1].v_type != VAR_UNKNOWN) 15863 utf8 = get_tv_number_chk(&argvars[1], NULL); 15864 if (utf8) 15865 buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 15866 else 15867 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 15868 } 15869 else 15870 #endif 15871 { 15872 buf[0] = (char_u)get_tv_number(&argvars[0]); 15873 buf[1] = NUL; 15874 } 15875 rettv->v_type = VAR_STRING; 15876 rettv->vval.v_string = vim_strsave(buf); 15877 } 15878 15879 /* 15880 * "or(expr, expr)" function 15881 */ 15882 static void 15883 f_or(typval_T *argvars, typval_T *rettv) 15884 { 15885 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 15886 | get_tv_number_chk(&argvars[1], NULL); 15887 } 15888 15889 /* 15890 * "pathshorten()" function 15891 */ 15892 static void 15893 f_pathshorten(typval_T *argvars, typval_T *rettv) 15894 { 15895 char_u *p; 15896 15897 rettv->v_type = VAR_STRING; 15898 p = get_tv_string_chk(&argvars[0]); 15899 if (p == NULL) 15900 rettv->vval.v_string = NULL; 15901 else 15902 { 15903 p = vim_strsave(p); 15904 rettv->vval.v_string = p; 15905 if (p != NULL) 15906 shorten_dir(p); 15907 } 15908 } 15909 15910 #ifdef FEAT_PERL 15911 /* 15912 * "perleval()" function 15913 */ 15914 static void 15915 f_perleval(typval_T *argvars, typval_T *rettv) 15916 { 15917 char_u *str; 15918 char_u buf[NUMBUFLEN]; 15919 15920 str = get_tv_string_buf(&argvars[0], buf); 15921 do_perleval(str, rettv); 15922 } 15923 #endif 15924 15925 #ifdef FEAT_FLOAT 15926 /* 15927 * "pow()" function 15928 */ 15929 static void 15930 f_pow(typval_T *argvars, typval_T *rettv) 15931 { 15932 float_T fx = 0.0, fy = 0.0; 15933 15934 rettv->v_type = VAR_FLOAT; 15935 if (get_float_arg(argvars, &fx) == OK 15936 && get_float_arg(&argvars[1], &fy) == OK) 15937 rettv->vval.v_float = pow(fx, fy); 15938 else 15939 rettv->vval.v_float = 0.0; 15940 } 15941 #endif 15942 15943 /* 15944 * "prevnonblank()" function 15945 */ 15946 static void 15947 f_prevnonblank(typval_T *argvars, typval_T *rettv) 15948 { 15949 linenr_T lnum; 15950 15951 lnum = get_tv_lnum(argvars); 15952 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 15953 lnum = 0; 15954 else 15955 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 15956 --lnum; 15957 rettv->vval.v_number = lnum; 15958 } 15959 15960 /* This dummy va_list is here because: 15961 * - passing a NULL pointer doesn't work when va_list isn't a pointer 15962 * - locally in the function results in a "used before set" warning 15963 * - using va_start() to initialize it gives "function with fixed args" error */ 15964 static va_list ap; 15965 15966 /* 15967 * "printf()" function 15968 */ 15969 static void 15970 f_printf(typval_T *argvars, typval_T *rettv) 15971 { 15972 char_u buf[NUMBUFLEN]; 15973 int len; 15974 char_u *s; 15975 int saved_did_emsg = did_emsg; 15976 char *fmt; 15977 15978 rettv->v_type = VAR_STRING; 15979 rettv->vval.v_string = NULL; 15980 15981 /* Get the required length, allocate the buffer and do it for real. */ 15982 did_emsg = FALSE; 15983 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 15984 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 15985 if (!did_emsg) 15986 { 15987 s = alloc(len + 1); 15988 if (s != NULL) 15989 { 15990 rettv->vval.v_string = s; 15991 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 15992 } 15993 } 15994 did_emsg |= saved_did_emsg; 15995 } 15996 15997 /* 15998 * "pumvisible()" function 15999 */ 16000 static void 16001 f_pumvisible(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 16002 { 16003 #ifdef FEAT_INS_EXPAND 16004 if (pum_visible()) 16005 rettv->vval.v_number = 1; 16006 #endif 16007 } 16008 16009 #ifdef FEAT_PYTHON3 16010 /* 16011 * "py3eval()" function 16012 */ 16013 static void 16014 f_py3eval(typval_T *argvars, typval_T *rettv) 16015 { 16016 char_u *str; 16017 char_u buf[NUMBUFLEN]; 16018 16019 str = get_tv_string_buf(&argvars[0], buf); 16020 do_py3eval(str, rettv); 16021 } 16022 #endif 16023 16024 #ifdef FEAT_PYTHON 16025 /* 16026 * "pyeval()" function 16027 */ 16028 static void 16029 f_pyeval(typval_T *argvars, typval_T *rettv) 16030 { 16031 char_u *str; 16032 char_u buf[NUMBUFLEN]; 16033 16034 str = get_tv_string_buf(&argvars[0], buf); 16035 do_pyeval(str, rettv); 16036 } 16037 #endif 16038 16039 /* 16040 * "range()" function 16041 */ 16042 static void 16043 f_range(typval_T *argvars, typval_T *rettv) 16044 { 16045 long start; 16046 long end; 16047 long stride = 1; 16048 long i; 16049 int error = FALSE; 16050 16051 start = get_tv_number_chk(&argvars[0], &error); 16052 if (argvars[1].v_type == VAR_UNKNOWN) 16053 { 16054 end = start - 1; 16055 start = 0; 16056 } 16057 else 16058 { 16059 end = get_tv_number_chk(&argvars[1], &error); 16060 if (argvars[2].v_type != VAR_UNKNOWN) 16061 stride = get_tv_number_chk(&argvars[2], &error); 16062 } 16063 16064 if (error) 16065 return; /* type error; errmsg already given */ 16066 if (stride == 0) 16067 EMSG(_("E726: Stride is zero")); 16068 else if (stride > 0 ? end + 1 < start : end - 1 > start) 16069 EMSG(_("E727: Start past end")); 16070 else 16071 { 16072 if (rettv_list_alloc(rettv) == OK) 16073 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 16074 if (list_append_number(rettv->vval.v_list, 16075 (varnumber_T)i) == FAIL) 16076 break; 16077 } 16078 } 16079 16080 /* 16081 * "readfile()" function 16082 */ 16083 static void 16084 f_readfile(typval_T *argvars, typval_T *rettv) 16085 { 16086 int binary = FALSE; 16087 int failed = FALSE; 16088 char_u *fname; 16089 FILE *fd; 16090 char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */ 16091 int io_size = sizeof(buf); 16092 int readlen; /* size of last fread() */ 16093 char_u *prev = NULL; /* previously read bytes, if any */ 16094 long prevlen = 0; /* length of data in prev */ 16095 long prevsize = 0; /* size of prev buffer */ 16096 long maxline = MAXLNUM; 16097 long cnt = 0; 16098 char_u *p; /* position in buf */ 16099 char_u *start; /* start of current line */ 16100 16101 if (argvars[1].v_type != VAR_UNKNOWN) 16102 { 16103 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 16104 binary = TRUE; 16105 if (argvars[2].v_type != VAR_UNKNOWN) 16106 maxline = get_tv_number(&argvars[2]); 16107 } 16108 16109 if (rettv_list_alloc(rettv) == FAIL) 16110 return; 16111 16112 /* Always open the file in binary mode, library functions have a mind of 16113 * their own about CR-LF conversion. */ 16114 fname = get_tv_string(&argvars[0]); 16115 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 16116 { 16117 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 16118 return; 16119 } 16120 16121 while (cnt < maxline || maxline < 0) 16122 { 16123 readlen = (int)fread(buf, 1, io_size, fd); 16124 16125 /* This for loop processes what was read, but is also entered at end 16126 * of file so that either: 16127 * - an incomplete line gets written 16128 * - a "binary" file gets an empty line at the end if it ends in a 16129 * newline. */ 16130 for (p = buf, start = buf; 16131 p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary)); 16132 ++p) 16133 { 16134 if (*p == '\n' || readlen <= 0) 16135 { 16136 listitem_T *li; 16137 char_u *s = NULL; 16138 long_u len = p - start; 16139 16140 /* Finished a line. Remove CRs before NL. */ 16141 if (readlen > 0 && !binary) 16142 { 16143 while (len > 0 && start[len - 1] == '\r') 16144 --len; 16145 /* removal may cross back to the "prev" string */ 16146 if (len == 0) 16147 while (prevlen > 0 && prev[prevlen - 1] == '\r') 16148 --prevlen; 16149 } 16150 if (prevlen == 0) 16151 s = vim_strnsave(start, (int)len); 16152 else 16153 { 16154 /* Change "prev" buffer to be the right size. This way 16155 * the bytes are only copied once, and very long lines are 16156 * allocated only once. */ 16157 if ((s = vim_realloc(prev, prevlen + len + 1)) != NULL) 16158 { 16159 mch_memmove(s + prevlen, start, len); 16160 s[prevlen + len] = NUL; 16161 prev = NULL; /* the list will own the string */ 16162 prevlen = prevsize = 0; 16163 } 16164 } 16165 if (s == NULL) 16166 { 16167 do_outofmem_msg((long_u) prevlen + len + 1); 16168 failed = TRUE; 16169 break; 16170 } 16171 16172 if ((li = listitem_alloc()) == NULL) 16173 { 16174 vim_free(s); 16175 failed = TRUE; 16176 break; 16177 } 16178 li->li_tv.v_type = VAR_STRING; 16179 li->li_tv.v_lock = 0; 16180 li->li_tv.vval.v_string = s; 16181 list_append(rettv->vval.v_list, li); 16182 16183 start = p + 1; /* step over newline */ 16184 if ((++cnt >= maxline && maxline >= 0) || readlen <= 0) 16185 break; 16186 } 16187 else if (*p == NUL) 16188 *p = '\n'; 16189 #ifdef FEAT_MBYTE 16190 /* Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this 16191 * when finding the BF and check the previous two bytes. */ 16192 else if (*p == 0xbf && enc_utf8 && !binary) 16193 { 16194 /* Find the two bytes before the 0xbf. If p is at buf, or buf 16195 * + 1, these may be in the "prev" string. */ 16196 char_u back1 = p >= buf + 1 ? p[-1] 16197 : prevlen >= 1 ? prev[prevlen - 1] : NUL; 16198 char_u back2 = p >= buf + 2 ? p[-2] 16199 : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1] 16200 : prevlen >= 2 ? prev[prevlen - 2] : NUL; 16201 16202 if (back2 == 0xef && back1 == 0xbb) 16203 { 16204 char_u *dest = p - 2; 16205 16206 /* Usually a BOM is at the beginning of a file, and so at 16207 * the beginning of a line; then we can just step over it. 16208 */ 16209 if (start == dest) 16210 start = p + 1; 16211 else 16212 { 16213 /* have to shuffle buf to close gap */ 16214 int adjust_prevlen = 0; 16215 16216 if (dest < buf) 16217 { 16218 adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */ 16219 dest = buf; 16220 } 16221 if (readlen > p - buf + 1) 16222 mch_memmove(dest, p + 1, readlen - (p - buf) - 1); 16223 readlen -= 3 - adjust_prevlen; 16224 prevlen -= adjust_prevlen; 16225 p = dest - 1; 16226 } 16227 } 16228 } 16229 #endif 16230 } /* for */ 16231 16232 if (failed || (cnt >= maxline && maxline >= 0) || readlen <= 0) 16233 break; 16234 if (start < p) 16235 { 16236 /* There's part of a line in buf, store it in "prev". */ 16237 if (p - start + prevlen >= prevsize) 16238 { 16239 /* need bigger "prev" buffer */ 16240 char_u *newprev; 16241 16242 /* A common use case is ordinary text files and "prev" gets a 16243 * fragment of a line, so the first allocation is made 16244 * small, to avoid repeatedly 'allocing' large and 16245 * 'reallocing' small. */ 16246 if (prevsize == 0) 16247 prevsize = (long)(p - start); 16248 else 16249 { 16250 long grow50pc = (prevsize * 3) / 2; 16251 long growmin = (long)((p - start) * 2 + prevlen); 16252 prevsize = grow50pc > growmin ? grow50pc : growmin; 16253 } 16254 newprev = prev == NULL ? alloc(prevsize) 16255 : vim_realloc(prev, prevsize); 16256 if (newprev == NULL) 16257 { 16258 do_outofmem_msg((long_u)prevsize); 16259 failed = TRUE; 16260 break; 16261 } 16262 prev = newprev; 16263 } 16264 /* Add the line part to end of "prev". */ 16265 mch_memmove(prev + prevlen, start, p - start); 16266 prevlen += (long)(p - start); 16267 } 16268 } /* while */ 16269 16270 /* 16271 * For a negative line count use only the lines at the end of the file, 16272 * free the rest. 16273 */ 16274 if (!failed && maxline < 0) 16275 while (cnt > -maxline) 16276 { 16277 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 16278 --cnt; 16279 } 16280 16281 if (failed) 16282 { 16283 list_free(rettv->vval.v_list, TRUE); 16284 /* readfile doc says an empty list is returned on error */ 16285 rettv->vval.v_list = list_alloc(); 16286 } 16287 16288 vim_free(prev); 16289 fclose(fd); 16290 } 16291 16292 #if defined(FEAT_RELTIME) 16293 static int list2proftime(typval_T *arg, proftime_T *tm); 16294 16295 /* 16296 * Convert a List to proftime_T. 16297 * Return FAIL when there is something wrong. 16298 */ 16299 static int 16300 list2proftime(typval_T *arg, proftime_T *tm) 16301 { 16302 long n1, n2; 16303 int error = FALSE; 16304 16305 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 16306 || arg->vval.v_list->lv_len != 2) 16307 return FAIL; 16308 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 16309 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 16310 # ifdef WIN3264 16311 tm->HighPart = n1; 16312 tm->LowPart = n2; 16313 # else 16314 tm->tv_sec = n1; 16315 tm->tv_usec = n2; 16316 # endif 16317 return error ? FAIL : OK; 16318 } 16319 #endif /* FEAT_RELTIME */ 16320 16321 /* 16322 * "reltime()" function 16323 */ 16324 static void 16325 f_reltime(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 16326 { 16327 #ifdef FEAT_RELTIME 16328 proftime_T res; 16329 proftime_T start; 16330 16331 if (argvars[0].v_type == VAR_UNKNOWN) 16332 { 16333 /* No arguments: get current time. */ 16334 profile_start(&res); 16335 } 16336 else if (argvars[1].v_type == VAR_UNKNOWN) 16337 { 16338 if (list2proftime(&argvars[0], &res) == FAIL) 16339 return; 16340 profile_end(&res); 16341 } 16342 else 16343 { 16344 /* Two arguments: compute the difference. */ 16345 if (list2proftime(&argvars[0], &start) == FAIL 16346 || list2proftime(&argvars[1], &res) == FAIL) 16347 return; 16348 profile_sub(&res, &start); 16349 } 16350 16351 if (rettv_list_alloc(rettv) == OK) 16352 { 16353 long n1, n2; 16354 16355 # ifdef WIN3264 16356 n1 = res.HighPart; 16357 n2 = res.LowPart; 16358 # else 16359 n1 = res.tv_sec; 16360 n2 = res.tv_usec; 16361 # endif 16362 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 16363 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 16364 } 16365 #endif 16366 } 16367 16368 #ifdef FEAT_FLOAT 16369 /* 16370 * "reltimefloat()" function 16371 */ 16372 static void 16373 f_reltimefloat(typval_T *argvars UNUSED, typval_T *rettv) 16374 { 16375 # ifdef FEAT_RELTIME 16376 proftime_T tm; 16377 # endif 16378 16379 rettv->v_type = VAR_FLOAT; 16380 rettv->vval.v_float = 0; 16381 # ifdef FEAT_RELTIME 16382 if (list2proftime(&argvars[0], &tm) == OK) 16383 rettv->vval.v_float = profile_float(&tm); 16384 # endif 16385 } 16386 #endif 16387 16388 /* 16389 * "reltimestr()" function 16390 */ 16391 static void 16392 f_reltimestr(typval_T *argvars UNUSED, typval_T *rettv) 16393 { 16394 #ifdef FEAT_RELTIME 16395 proftime_T tm; 16396 #endif 16397 16398 rettv->v_type = VAR_STRING; 16399 rettv->vval.v_string = NULL; 16400 #ifdef FEAT_RELTIME 16401 if (list2proftime(&argvars[0], &tm) == OK) 16402 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 16403 #endif 16404 } 16405 16406 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 16407 static void make_connection(void); 16408 static int check_connection(void); 16409 16410 static void 16411 make_connection(void) 16412 { 16413 if (X_DISPLAY == NULL 16414 # ifdef FEAT_GUI 16415 && !gui.in_use 16416 # endif 16417 ) 16418 { 16419 x_force_connect = TRUE; 16420 setup_term_clip(); 16421 x_force_connect = FALSE; 16422 } 16423 } 16424 16425 static int 16426 check_connection(void) 16427 { 16428 make_connection(); 16429 if (X_DISPLAY == NULL) 16430 { 16431 EMSG(_("E240: No connection to Vim server")); 16432 return FAIL; 16433 } 16434 return OK; 16435 } 16436 #endif 16437 16438 #ifdef FEAT_CLIENTSERVER 16439 static void remote_common(typval_T *argvars, typval_T *rettv, int expr); 16440 16441 static void 16442 remote_common(typval_T *argvars, typval_T *rettv, int expr) 16443 { 16444 char_u *server_name; 16445 char_u *keys; 16446 char_u *r = NULL; 16447 char_u buf[NUMBUFLEN]; 16448 # ifdef WIN32 16449 HWND w; 16450 # else 16451 Window w; 16452 # endif 16453 16454 if (check_restricted() || check_secure()) 16455 return; 16456 16457 # ifdef FEAT_X11 16458 if (check_connection() == FAIL) 16459 return; 16460 # endif 16461 16462 server_name = get_tv_string_chk(&argvars[0]); 16463 if (server_name == NULL) 16464 return; /* type error; errmsg already given */ 16465 keys = get_tv_string_buf(&argvars[1], buf); 16466 # ifdef WIN32 16467 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 16468 # else 16469 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 16470 < 0) 16471 # endif 16472 { 16473 if (r != NULL) 16474 EMSG(r); /* sending worked but evaluation failed */ 16475 else 16476 EMSG2(_("E241: Unable to send to %s"), server_name); 16477 return; 16478 } 16479 16480 rettv->vval.v_string = r; 16481 16482 if (argvars[2].v_type != VAR_UNKNOWN) 16483 { 16484 dictitem_T v; 16485 char_u str[30]; 16486 char_u *idvar; 16487 16488 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 16489 v.di_tv.v_type = VAR_STRING; 16490 v.di_tv.vval.v_string = vim_strsave(str); 16491 idvar = get_tv_string_chk(&argvars[2]); 16492 if (idvar != NULL) 16493 set_var(idvar, &v.di_tv, FALSE); 16494 vim_free(v.di_tv.vval.v_string); 16495 } 16496 } 16497 #endif 16498 16499 /* 16500 * "remote_expr()" function 16501 */ 16502 static void 16503 f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv) 16504 { 16505 rettv->v_type = VAR_STRING; 16506 rettv->vval.v_string = NULL; 16507 #ifdef FEAT_CLIENTSERVER 16508 remote_common(argvars, rettv, TRUE); 16509 #endif 16510 } 16511 16512 /* 16513 * "remote_foreground()" function 16514 */ 16515 static void 16516 f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 16517 { 16518 #ifdef FEAT_CLIENTSERVER 16519 # ifdef WIN32 16520 /* On Win32 it's done in this application. */ 16521 { 16522 char_u *server_name = get_tv_string_chk(&argvars[0]); 16523 16524 if (server_name != NULL) 16525 serverForeground(server_name); 16526 } 16527 # else 16528 /* Send a foreground() expression to the server. */ 16529 argvars[1].v_type = VAR_STRING; 16530 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 16531 argvars[2].v_type = VAR_UNKNOWN; 16532 remote_common(argvars, rettv, TRUE); 16533 vim_free(argvars[1].vval.v_string); 16534 # endif 16535 #endif 16536 } 16537 16538 static void 16539 f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) 16540 { 16541 #ifdef FEAT_CLIENTSERVER 16542 dictitem_T v; 16543 char_u *s = NULL; 16544 # ifdef WIN32 16545 long_u n = 0; 16546 # endif 16547 char_u *serverid; 16548 16549 if (check_restricted() || check_secure()) 16550 { 16551 rettv->vval.v_number = -1; 16552 return; 16553 } 16554 serverid = get_tv_string_chk(&argvars[0]); 16555 if (serverid == NULL) 16556 { 16557 rettv->vval.v_number = -1; 16558 return; /* type error; errmsg already given */ 16559 } 16560 # ifdef WIN32 16561 sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); 16562 if (n == 0) 16563 rettv->vval.v_number = -1; 16564 else 16565 { 16566 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 16567 rettv->vval.v_number = (s != NULL); 16568 } 16569 # else 16570 if (check_connection() == FAIL) 16571 return; 16572 16573 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 16574 serverStrToWin(serverid), &s); 16575 # endif 16576 16577 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 16578 { 16579 char_u *retvar; 16580 16581 v.di_tv.v_type = VAR_STRING; 16582 v.di_tv.vval.v_string = vim_strsave(s); 16583 retvar = get_tv_string_chk(&argvars[1]); 16584 if (retvar != NULL) 16585 set_var(retvar, &v.di_tv, FALSE); 16586 vim_free(v.di_tv.vval.v_string); 16587 } 16588 #else 16589 rettv->vval.v_number = -1; 16590 #endif 16591 } 16592 16593 static void 16594 f_remote_read(typval_T *argvars UNUSED, typval_T *rettv) 16595 { 16596 char_u *r = NULL; 16597 16598 #ifdef FEAT_CLIENTSERVER 16599 char_u *serverid = get_tv_string_chk(&argvars[0]); 16600 16601 if (serverid != NULL && !check_restricted() && !check_secure()) 16602 { 16603 # ifdef WIN32 16604 /* The server's HWND is encoded in the 'id' parameter */ 16605 long_u n = 0; 16606 16607 sscanf((char *)serverid, SCANF_HEX_LONG_U, &n); 16608 if (n != 0) 16609 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 16610 if (r == NULL) 16611 # else 16612 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 16613 serverStrToWin(serverid), &r, FALSE) < 0) 16614 # endif 16615 EMSG(_("E277: Unable to read a server reply")); 16616 } 16617 #endif 16618 rettv->v_type = VAR_STRING; 16619 rettv->vval.v_string = r; 16620 } 16621 16622 /* 16623 * "remote_send()" function 16624 */ 16625 static void 16626 f_remote_send(typval_T *argvars UNUSED, typval_T *rettv) 16627 { 16628 rettv->v_type = VAR_STRING; 16629 rettv->vval.v_string = NULL; 16630 #ifdef FEAT_CLIENTSERVER 16631 remote_common(argvars, rettv, FALSE); 16632 #endif 16633 } 16634 16635 /* 16636 * "remove()" function 16637 */ 16638 static void 16639 f_remove(typval_T *argvars, typval_T *rettv) 16640 { 16641 list_T *l; 16642 listitem_T *item, *item2; 16643 listitem_T *li; 16644 long idx; 16645 long end; 16646 char_u *key; 16647 dict_T *d; 16648 dictitem_T *di; 16649 char_u *arg_errmsg = (char_u *)N_("remove() argument"); 16650 16651 if (argvars[0].v_type == VAR_DICT) 16652 { 16653 if (argvars[2].v_type != VAR_UNKNOWN) 16654 EMSG2(_(e_toomanyarg), "remove()"); 16655 else if ((d = argvars[0].vval.v_dict) != NULL 16656 && !tv_check_lock(d->dv_lock, arg_errmsg, TRUE)) 16657 { 16658 key = get_tv_string_chk(&argvars[1]); 16659 if (key != NULL) 16660 { 16661 di = dict_find(d, key, -1); 16662 if (di == NULL) 16663 EMSG2(_(e_dictkey), key); 16664 else if (!var_check_fixed(di->di_flags, arg_errmsg, TRUE) 16665 && !var_check_ro(di->di_flags, arg_errmsg, TRUE)) 16666 { 16667 *rettv = di->di_tv; 16668 init_tv(&di->di_tv); 16669 dictitem_remove(d, di); 16670 } 16671 } 16672 } 16673 } 16674 else if (argvars[0].v_type != VAR_LIST) 16675 EMSG2(_(e_listdictarg), "remove()"); 16676 else if ((l = argvars[0].vval.v_list) != NULL 16677 && !tv_check_lock(l->lv_lock, arg_errmsg, TRUE)) 16678 { 16679 int error = FALSE; 16680 16681 idx = get_tv_number_chk(&argvars[1], &error); 16682 if (error) 16683 ; /* type error: do nothing, errmsg already given */ 16684 else if ((item = list_find(l, idx)) == NULL) 16685 EMSGN(_(e_listidx), idx); 16686 else 16687 { 16688 if (argvars[2].v_type == VAR_UNKNOWN) 16689 { 16690 /* Remove one item, return its value. */ 16691 vimlist_remove(l, item, item); 16692 *rettv = item->li_tv; 16693 vim_free(item); 16694 } 16695 else 16696 { 16697 /* Remove range of items, return list with values. */ 16698 end = get_tv_number_chk(&argvars[2], &error); 16699 if (error) 16700 ; /* type error: do nothing */ 16701 else if ((item2 = list_find(l, end)) == NULL) 16702 EMSGN(_(e_listidx), end); 16703 else 16704 { 16705 int cnt = 0; 16706 16707 for (li = item; li != NULL; li = li->li_next) 16708 { 16709 ++cnt; 16710 if (li == item2) 16711 break; 16712 } 16713 if (li == NULL) /* didn't find "item2" after "item" */ 16714 EMSG(_(e_invrange)); 16715 else 16716 { 16717 vimlist_remove(l, item, item2); 16718 if (rettv_list_alloc(rettv) == OK) 16719 { 16720 l = rettv->vval.v_list; 16721 l->lv_first = item; 16722 l->lv_last = item2; 16723 item->li_prev = NULL; 16724 item2->li_next = NULL; 16725 l->lv_len = cnt; 16726 } 16727 } 16728 } 16729 } 16730 } 16731 } 16732 } 16733 16734 /* 16735 * "rename({from}, {to})" function 16736 */ 16737 static void 16738 f_rename(typval_T *argvars, typval_T *rettv) 16739 { 16740 char_u buf[NUMBUFLEN]; 16741 16742 if (check_restricted() || check_secure()) 16743 rettv->vval.v_number = -1; 16744 else 16745 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 16746 get_tv_string_buf(&argvars[1], buf)); 16747 } 16748 16749 /* 16750 * "repeat()" function 16751 */ 16752 static void 16753 f_repeat(typval_T *argvars, typval_T *rettv) 16754 { 16755 char_u *p; 16756 int n; 16757 int slen; 16758 int len; 16759 char_u *r; 16760 int i; 16761 16762 n = get_tv_number(&argvars[1]); 16763 if (argvars[0].v_type == VAR_LIST) 16764 { 16765 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 16766 while (n-- > 0) 16767 if (list_extend(rettv->vval.v_list, 16768 argvars[0].vval.v_list, NULL) == FAIL) 16769 break; 16770 } 16771 else 16772 { 16773 p = get_tv_string(&argvars[0]); 16774 rettv->v_type = VAR_STRING; 16775 rettv->vval.v_string = NULL; 16776 16777 slen = (int)STRLEN(p); 16778 len = slen * n; 16779 if (len <= 0) 16780 return; 16781 16782 r = alloc(len + 1); 16783 if (r != NULL) 16784 { 16785 for (i = 0; i < n; i++) 16786 mch_memmove(r + i * slen, p, (size_t)slen); 16787 r[len] = NUL; 16788 } 16789 16790 rettv->vval.v_string = r; 16791 } 16792 } 16793 16794 /* 16795 * "resolve()" function 16796 */ 16797 static void 16798 f_resolve(typval_T *argvars, typval_T *rettv) 16799 { 16800 char_u *p; 16801 #ifdef HAVE_READLINK 16802 char_u *buf = NULL; 16803 #endif 16804 16805 p = get_tv_string(&argvars[0]); 16806 #ifdef FEAT_SHORTCUT 16807 { 16808 char_u *v = NULL; 16809 16810 v = mch_resolve_shortcut(p); 16811 if (v != NULL) 16812 rettv->vval.v_string = v; 16813 else 16814 rettv->vval.v_string = vim_strsave(p); 16815 } 16816 #else 16817 # ifdef HAVE_READLINK 16818 { 16819 char_u *cpy; 16820 int len; 16821 char_u *remain = NULL; 16822 char_u *q; 16823 int is_relative_to_current = FALSE; 16824 int has_trailing_pathsep = FALSE; 16825 int limit = 100; 16826 16827 p = vim_strsave(p); 16828 16829 if (p[0] == '.' && (vim_ispathsep(p[1]) 16830 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 16831 is_relative_to_current = TRUE; 16832 16833 len = STRLEN(p); 16834 if (len > 0 && after_pathsep(p, p + len)) 16835 { 16836 has_trailing_pathsep = TRUE; 16837 p[len - 1] = NUL; /* the trailing slash breaks readlink() */ 16838 } 16839 16840 q = getnextcomp(p); 16841 if (*q != NUL) 16842 { 16843 /* Separate the first path component in "p", and keep the 16844 * remainder (beginning with the path separator). */ 16845 remain = vim_strsave(q - 1); 16846 q[-1] = NUL; 16847 } 16848 16849 buf = alloc(MAXPATHL + 1); 16850 if (buf == NULL) 16851 goto fail; 16852 16853 for (;;) 16854 { 16855 for (;;) 16856 { 16857 len = readlink((char *)p, (char *)buf, MAXPATHL); 16858 if (len <= 0) 16859 break; 16860 buf[len] = NUL; 16861 16862 if (limit-- == 0) 16863 { 16864 vim_free(p); 16865 vim_free(remain); 16866 EMSG(_("E655: Too many symbolic links (cycle?)")); 16867 rettv->vval.v_string = NULL; 16868 goto fail; 16869 } 16870 16871 /* Ensure that the result will have a trailing path separator 16872 * if the argument has one. */ 16873 if (remain == NULL && has_trailing_pathsep) 16874 add_pathsep(buf); 16875 16876 /* Separate the first path component in the link value and 16877 * concatenate the remainders. */ 16878 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 16879 if (*q != NUL) 16880 { 16881 if (remain == NULL) 16882 remain = vim_strsave(q - 1); 16883 else 16884 { 16885 cpy = concat_str(q - 1, remain); 16886 if (cpy != NULL) 16887 { 16888 vim_free(remain); 16889 remain = cpy; 16890 } 16891 } 16892 q[-1] = NUL; 16893 } 16894 16895 q = gettail(p); 16896 if (q > p && *q == NUL) 16897 { 16898 /* Ignore trailing path separator. */ 16899 q[-1] = NUL; 16900 q = gettail(p); 16901 } 16902 if (q > p && !mch_isFullName(buf)) 16903 { 16904 /* symlink is relative to directory of argument */ 16905 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 16906 if (cpy != NULL) 16907 { 16908 STRCPY(cpy, p); 16909 STRCPY(gettail(cpy), buf); 16910 vim_free(p); 16911 p = cpy; 16912 } 16913 } 16914 else 16915 { 16916 vim_free(p); 16917 p = vim_strsave(buf); 16918 } 16919 } 16920 16921 if (remain == NULL) 16922 break; 16923 16924 /* Append the first path component of "remain" to "p". */ 16925 q = getnextcomp(remain + 1); 16926 len = q - remain - (*q != NUL); 16927 cpy = vim_strnsave(p, STRLEN(p) + len); 16928 if (cpy != NULL) 16929 { 16930 STRNCAT(cpy, remain, len); 16931 vim_free(p); 16932 p = cpy; 16933 } 16934 /* Shorten "remain". */ 16935 if (*q != NUL) 16936 STRMOVE(remain, q - 1); 16937 else 16938 { 16939 vim_free(remain); 16940 remain = NULL; 16941 } 16942 } 16943 16944 /* If the result is a relative path name, make it explicitly relative to 16945 * the current directory if and only if the argument had this form. */ 16946 if (!vim_ispathsep(*p)) 16947 { 16948 if (is_relative_to_current 16949 && *p != NUL 16950 && !(p[0] == '.' 16951 && (p[1] == NUL 16952 || vim_ispathsep(p[1]) 16953 || (p[1] == '.' 16954 && (p[2] == NUL 16955 || vim_ispathsep(p[2])))))) 16956 { 16957 /* Prepend "./". */ 16958 cpy = concat_str((char_u *)"./", p); 16959 if (cpy != NULL) 16960 { 16961 vim_free(p); 16962 p = cpy; 16963 } 16964 } 16965 else if (!is_relative_to_current) 16966 { 16967 /* Strip leading "./". */ 16968 q = p; 16969 while (q[0] == '.' && vim_ispathsep(q[1])) 16970 q += 2; 16971 if (q > p) 16972 STRMOVE(p, p + 2); 16973 } 16974 } 16975 16976 /* Ensure that the result will have no trailing path separator 16977 * if the argument had none. But keep "/" or "//". */ 16978 if (!has_trailing_pathsep) 16979 { 16980 q = p + STRLEN(p); 16981 if (after_pathsep(p, q)) 16982 *gettail_sep(p) = NUL; 16983 } 16984 16985 rettv->vval.v_string = p; 16986 } 16987 # else 16988 rettv->vval.v_string = vim_strsave(p); 16989 # endif 16990 #endif 16991 16992 simplify_filename(rettv->vval.v_string); 16993 16994 #ifdef HAVE_READLINK 16995 fail: 16996 vim_free(buf); 16997 #endif 16998 rettv->v_type = VAR_STRING; 16999 } 17000 17001 /* 17002 * "reverse({list})" function 17003 */ 17004 static void 17005 f_reverse(typval_T *argvars, typval_T *rettv) 17006 { 17007 list_T *l; 17008 listitem_T *li, *ni; 17009 17010 if (argvars[0].v_type != VAR_LIST) 17011 EMSG2(_(e_listarg), "reverse()"); 17012 else if ((l = argvars[0].vval.v_list) != NULL 17013 && !tv_check_lock(l->lv_lock, 17014 (char_u *)N_("reverse() argument"), TRUE)) 17015 { 17016 li = l->lv_last; 17017 l->lv_first = l->lv_last = NULL; 17018 l->lv_len = 0; 17019 while (li != NULL) 17020 { 17021 ni = li->li_prev; 17022 list_append(l, li); 17023 li = ni; 17024 } 17025 rettv->vval.v_list = l; 17026 rettv->v_type = VAR_LIST; 17027 ++l->lv_refcount; 17028 l->lv_idx = l->lv_len - l->lv_idx - 1; 17029 } 17030 } 17031 17032 #define SP_NOMOVE 0x01 /* don't move cursor */ 17033 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 17034 #define SP_RETCOUNT 0x04 /* return matchcount */ 17035 #define SP_SETPCMARK 0x08 /* set previous context mark */ 17036 #define SP_START 0x10 /* accept match at start position */ 17037 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 17038 #define SP_END 0x40 /* leave cursor at end of match */ 17039 #define SP_COLUMN 0x80 /* start at cursor column */ 17040 17041 static int get_search_arg(typval_T *varp, int *flagsp); 17042 17043 /* 17044 * Get flags for a search function. 17045 * Possibly sets "p_ws". 17046 * Returns BACKWARD, FORWARD or zero (for an error). 17047 */ 17048 static int 17049 get_search_arg(typval_T *varp, int *flagsp) 17050 { 17051 int dir = FORWARD; 17052 char_u *flags; 17053 char_u nbuf[NUMBUFLEN]; 17054 int mask; 17055 17056 if (varp->v_type != VAR_UNKNOWN) 17057 { 17058 flags = get_tv_string_buf_chk(varp, nbuf); 17059 if (flags == NULL) 17060 return 0; /* type error; errmsg already given */ 17061 while (*flags != NUL) 17062 { 17063 switch (*flags) 17064 { 17065 case 'b': dir = BACKWARD; break; 17066 case 'w': p_ws = TRUE; break; 17067 case 'W': p_ws = FALSE; break; 17068 default: mask = 0; 17069 if (flagsp != NULL) 17070 switch (*flags) 17071 { 17072 case 'c': mask = SP_START; break; 17073 case 'e': mask = SP_END; break; 17074 case 'm': mask = SP_RETCOUNT; break; 17075 case 'n': mask = SP_NOMOVE; break; 17076 case 'p': mask = SP_SUBPAT; break; 17077 case 'r': mask = SP_REPEAT; break; 17078 case 's': mask = SP_SETPCMARK; break; 17079 case 'z': mask = SP_COLUMN; break; 17080 } 17081 if (mask == 0) 17082 { 17083 EMSG2(_(e_invarg2), flags); 17084 dir = 0; 17085 } 17086 else 17087 *flagsp |= mask; 17088 } 17089 if (dir == 0) 17090 break; 17091 ++flags; 17092 } 17093 } 17094 return dir; 17095 } 17096 17097 /* 17098 * Shared by search() and searchpos() functions. 17099 */ 17100 static int 17101 search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) 17102 { 17103 int flags; 17104 char_u *pat; 17105 pos_T pos; 17106 pos_T save_cursor; 17107 int save_p_ws = p_ws; 17108 int dir; 17109 int retval = 0; /* default: FAIL */ 17110 long lnum_stop = 0; 17111 proftime_T tm; 17112 #ifdef FEAT_RELTIME 17113 long time_limit = 0; 17114 #endif 17115 int options = SEARCH_KEEP; 17116 int subpatnum; 17117 17118 pat = get_tv_string(&argvars[0]); 17119 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 17120 if (dir == 0) 17121 goto theend; 17122 flags = *flagsp; 17123 if (flags & SP_START) 17124 options |= SEARCH_START; 17125 if (flags & SP_END) 17126 options |= SEARCH_END; 17127 if (flags & SP_COLUMN) 17128 options |= SEARCH_COL; 17129 17130 /* Optional arguments: line number to stop searching and timeout. */ 17131 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 17132 { 17133 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 17134 if (lnum_stop < 0) 17135 goto theend; 17136 #ifdef FEAT_RELTIME 17137 if (argvars[3].v_type != VAR_UNKNOWN) 17138 { 17139 time_limit = get_tv_number_chk(&argvars[3], NULL); 17140 if (time_limit < 0) 17141 goto theend; 17142 } 17143 #endif 17144 } 17145 17146 #ifdef FEAT_RELTIME 17147 /* Set the time limit, if there is one. */ 17148 profile_setlimit(time_limit, &tm); 17149 #endif 17150 17151 /* 17152 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 17153 * Check to make sure only those flags are set. 17154 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 17155 * flags cannot be set. Check for that condition also. 17156 */ 17157 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 17158 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 17159 { 17160 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 17161 goto theend; 17162 } 17163 17164 pos = save_cursor = curwin->w_cursor; 17165 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 17166 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 17167 if (subpatnum != FAIL) 17168 { 17169 if (flags & SP_SUBPAT) 17170 retval = subpatnum; 17171 else 17172 retval = pos.lnum; 17173 if (flags & SP_SETPCMARK) 17174 setpcmark(); 17175 curwin->w_cursor = pos; 17176 if (match_pos != NULL) 17177 { 17178 /* Store the match cursor position */ 17179 match_pos->lnum = pos.lnum; 17180 match_pos->col = pos.col + 1; 17181 } 17182 /* "/$" will put the cursor after the end of the line, may need to 17183 * correct that here */ 17184 check_cursor(); 17185 } 17186 17187 /* If 'n' flag is used: restore cursor position. */ 17188 if (flags & SP_NOMOVE) 17189 curwin->w_cursor = save_cursor; 17190 else 17191 curwin->w_set_curswant = TRUE; 17192 theend: 17193 p_ws = save_p_ws; 17194 17195 return retval; 17196 } 17197 17198 #ifdef FEAT_FLOAT 17199 17200 /* 17201 * round() is not in C90, use ceil() or floor() instead. 17202 */ 17203 float_T 17204 vim_round(float_T f) 17205 { 17206 return f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 17207 } 17208 17209 /* 17210 * "round({float})" function 17211 */ 17212 static void 17213 f_round(typval_T *argvars, typval_T *rettv) 17214 { 17215 float_T f = 0.0; 17216 17217 rettv->v_type = VAR_FLOAT; 17218 if (get_float_arg(argvars, &f) == OK) 17219 rettv->vval.v_float = vim_round(f); 17220 else 17221 rettv->vval.v_float = 0.0; 17222 } 17223 #endif 17224 17225 /* 17226 * "screenattr()" function 17227 */ 17228 static void 17229 f_screenattr(typval_T *argvars, typval_T *rettv) 17230 { 17231 int row; 17232 int col; 17233 int c; 17234 17235 row = get_tv_number_chk(&argvars[0], NULL) - 1; 17236 col = get_tv_number_chk(&argvars[1], NULL) - 1; 17237 if (row < 0 || row >= screen_Rows 17238 || col < 0 || col >= screen_Columns) 17239 c = -1; 17240 else 17241 c = ScreenAttrs[LineOffset[row] + col]; 17242 rettv->vval.v_number = c; 17243 } 17244 17245 /* 17246 * "screenchar()" function 17247 */ 17248 static void 17249 f_screenchar(typval_T *argvars, typval_T *rettv) 17250 { 17251 int row; 17252 int col; 17253 int off; 17254 int c; 17255 17256 row = get_tv_number_chk(&argvars[0], NULL) - 1; 17257 col = get_tv_number_chk(&argvars[1], NULL) - 1; 17258 if (row < 0 || row >= screen_Rows 17259 || col < 0 || col >= screen_Columns) 17260 c = -1; 17261 else 17262 { 17263 off = LineOffset[row] + col; 17264 #ifdef FEAT_MBYTE 17265 if (enc_utf8 && ScreenLinesUC[off] != 0) 17266 c = ScreenLinesUC[off]; 17267 else 17268 #endif 17269 c = ScreenLines[off]; 17270 } 17271 rettv->vval.v_number = c; 17272 } 17273 17274 /* 17275 * "screencol()" function 17276 * 17277 * First column is 1 to be consistent with virtcol(). 17278 */ 17279 static void 17280 f_screencol(typval_T *argvars UNUSED, typval_T *rettv) 17281 { 17282 rettv->vval.v_number = screen_screencol() + 1; 17283 } 17284 17285 /* 17286 * "screenrow()" function 17287 */ 17288 static void 17289 f_screenrow(typval_T *argvars UNUSED, typval_T *rettv) 17290 { 17291 rettv->vval.v_number = screen_screenrow() + 1; 17292 } 17293 17294 /* 17295 * "search()" function 17296 */ 17297 static void 17298 f_search(typval_T *argvars, typval_T *rettv) 17299 { 17300 int flags = 0; 17301 17302 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 17303 } 17304 17305 /* 17306 * "searchdecl()" function 17307 */ 17308 static void 17309 f_searchdecl(typval_T *argvars, typval_T *rettv) 17310 { 17311 int locally = 1; 17312 int thisblock = 0; 17313 int error = FALSE; 17314 char_u *name; 17315 17316 rettv->vval.v_number = 1; /* default: FAIL */ 17317 17318 name = get_tv_string_chk(&argvars[0]); 17319 if (argvars[1].v_type != VAR_UNKNOWN) 17320 { 17321 locally = get_tv_number_chk(&argvars[1], &error) == 0; 17322 if (!error && argvars[2].v_type != VAR_UNKNOWN) 17323 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 17324 } 17325 if (!error && name != NULL) 17326 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 17327 locally, thisblock, SEARCH_KEEP) == FAIL; 17328 } 17329 17330 /* 17331 * Used by searchpair() and searchpairpos() 17332 */ 17333 static int 17334 searchpair_cmn(typval_T *argvars, pos_T *match_pos) 17335 { 17336 char_u *spat, *mpat, *epat; 17337 char_u *skip; 17338 int save_p_ws = p_ws; 17339 int dir; 17340 int flags = 0; 17341 char_u nbuf1[NUMBUFLEN]; 17342 char_u nbuf2[NUMBUFLEN]; 17343 char_u nbuf3[NUMBUFLEN]; 17344 int retval = 0; /* default: FAIL */ 17345 long lnum_stop = 0; 17346 long time_limit = 0; 17347 17348 /* Get the three pattern arguments: start, middle, end. */ 17349 spat = get_tv_string_chk(&argvars[0]); 17350 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 17351 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 17352 if (spat == NULL || mpat == NULL || epat == NULL) 17353 goto theend; /* type error */ 17354 17355 /* Handle the optional fourth argument: flags */ 17356 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 17357 if (dir == 0) 17358 goto theend; 17359 17360 /* Don't accept SP_END or SP_SUBPAT. 17361 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 17362 */ 17363 if ((flags & (SP_END | SP_SUBPAT)) != 0 17364 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 17365 { 17366 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 17367 goto theend; 17368 } 17369 17370 /* Using 'r' implies 'W', otherwise it doesn't work. */ 17371 if (flags & SP_REPEAT) 17372 p_ws = FALSE; 17373 17374 /* Optional fifth argument: skip expression */ 17375 if (argvars[3].v_type == VAR_UNKNOWN 17376 || argvars[4].v_type == VAR_UNKNOWN) 17377 skip = (char_u *)""; 17378 else 17379 { 17380 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 17381 if (argvars[5].v_type != VAR_UNKNOWN) 17382 { 17383 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 17384 if (lnum_stop < 0) 17385 goto theend; 17386 #ifdef FEAT_RELTIME 17387 if (argvars[6].v_type != VAR_UNKNOWN) 17388 { 17389 time_limit = get_tv_number_chk(&argvars[6], NULL); 17390 if (time_limit < 0) 17391 goto theend; 17392 } 17393 #endif 17394 } 17395 } 17396 if (skip == NULL) 17397 goto theend; /* type error */ 17398 17399 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 17400 match_pos, lnum_stop, time_limit); 17401 17402 theend: 17403 p_ws = save_p_ws; 17404 17405 return retval; 17406 } 17407 17408 /* 17409 * "searchpair()" function 17410 */ 17411 static void 17412 f_searchpair(typval_T *argvars, typval_T *rettv) 17413 { 17414 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 17415 } 17416 17417 /* 17418 * "searchpairpos()" function 17419 */ 17420 static void 17421 f_searchpairpos(typval_T *argvars, typval_T *rettv) 17422 { 17423 pos_T match_pos; 17424 int lnum = 0; 17425 int col = 0; 17426 17427 if (rettv_list_alloc(rettv) == FAIL) 17428 return; 17429 17430 if (searchpair_cmn(argvars, &match_pos) > 0) 17431 { 17432 lnum = match_pos.lnum; 17433 col = match_pos.col; 17434 } 17435 17436 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 17437 list_append_number(rettv->vval.v_list, (varnumber_T)col); 17438 } 17439 17440 /* 17441 * Search for a start/middle/end thing. 17442 * Used by searchpair(), see its documentation for the details. 17443 * Returns 0 or -1 for no match, 17444 */ 17445 long 17446 do_searchpair( 17447 char_u *spat, /* start pattern */ 17448 char_u *mpat, /* middle pattern */ 17449 char_u *epat, /* end pattern */ 17450 int dir, /* BACKWARD or FORWARD */ 17451 char_u *skip, /* skip expression */ 17452 int flags, /* SP_SETPCMARK and other SP_ values */ 17453 pos_T *match_pos, 17454 linenr_T lnum_stop, /* stop at this line if not zero */ 17455 long time_limit UNUSED) /* stop after this many msec */ 17456 { 17457 char_u *save_cpo; 17458 char_u *pat, *pat2 = NULL, *pat3 = NULL; 17459 long retval = 0; 17460 pos_T pos; 17461 pos_T firstpos; 17462 pos_T foundpos; 17463 pos_T save_cursor; 17464 pos_T save_pos; 17465 int n; 17466 int r; 17467 int nest = 1; 17468 int err; 17469 int options = SEARCH_KEEP; 17470 proftime_T tm; 17471 17472 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 17473 save_cpo = p_cpo; 17474 p_cpo = empty_option; 17475 17476 #ifdef FEAT_RELTIME 17477 /* Set the time limit, if there is one. */ 17478 profile_setlimit(time_limit, &tm); 17479 #endif 17480 17481 /* Make two search patterns: start/end (pat2, for in nested pairs) and 17482 * start/middle/end (pat3, for the top pair). */ 17483 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 17484 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 17485 if (pat2 == NULL || pat3 == NULL) 17486 goto theend; 17487 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 17488 if (*mpat == NUL) 17489 STRCPY(pat3, pat2); 17490 else 17491 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 17492 spat, epat, mpat); 17493 if (flags & SP_START) 17494 options |= SEARCH_START; 17495 17496 save_cursor = curwin->w_cursor; 17497 pos = curwin->w_cursor; 17498 clearpos(&firstpos); 17499 clearpos(&foundpos); 17500 pat = pat3; 17501 for (;;) 17502 { 17503 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 17504 options, RE_SEARCH, lnum_stop, &tm); 17505 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 17506 /* didn't find it or found the first match again: FAIL */ 17507 break; 17508 17509 if (firstpos.lnum == 0) 17510 firstpos = pos; 17511 if (equalpos(pos, foundpos)) 17512 { 17513 /* Found the same position again. Can happen with a pattern that 17514 * has "\zs" at the end and searching backwards. Advance one 17515 * character and try again. */ 17516 if (dir == BACKWARD) 17517 decl(&pos); 17518 else 17519 incl(&pos); 17520 } 17521 foundpos = pos; 17522 17523 /* clear the start flag to avoid getting stuck here */ 17524 options &= ~SEARCH_START; 17525 17526 /* If the skip pattern matches, ignore this match. */ 17527 if (*skip != NUL) 17528 { 17529 save_pos = curwin->w_cursor; 17530 curwin->w_cursor = pos; 17531 r = eval_to_bool(skip, &err, NULL, FALSE); 17532 curwin->w_cursor = save_pos; 17533 if (err) 17534 { 17535 /* Evaluating {skip} caused an error, break here. */ 17536 curwin->w_cursor = save_cursor; 17537 retval = -1; 17538 break; 17539 } 17540 if (r) 17541 continue; 17542 } 17543 17544 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 17545 { 17546 /* Found end when searching backwards or start when searching 17547 * forward: nested pair. */ 17548 ++nest; 17549 pat = pat2; /* nested, don't search for middle */ 17550 } 17551 else 17552 { 17553 /* Found end when searching forward or start when searching 17554 * backward: end of (nested) pair; or found middle in outer pair. */ 17555 if (--nest == 1) 17556 pat = pat3; /* outer level, search for middle */ 17557 } 17558 17559 if (nest == 0) 17560 { 17561 /* Found the match: return matchcount or line number. */ 17562 if (flags & SP_RETCOUNT) 17563 ++retval; 17564 else 17565 retval = pos.lnum; 17566 if (flags & SP_SETPCMARK) 17567 setpcmark(); 17568 curwin->w_cursor = pos; 17569 if (!(flags & SP_REPEAT)) 17570 break; 17571 nest = 1; /* search for next unmatched */ 17572 } 17573 } 17574 17575 if (match_pos != NULL) 17576 { 17577 /* Store the match cursor position */ 17578 match_pos->lnum = curwin->w_cursor.lnum; 17579 match_pos->col = curwin->w_cursor.col + 1; 17580 } 17581 17582 /* If 'n' flag is used or search failed: restore cursor position. */ 17583 if ((flags & SP_NOMOVE) || retval == 0) 17584 curwin->w_cursor = save_cursor; 17585 17586 theend: 17587 vim_free(pat2); 17588 vim_free(pat3); 17589 if (p_cpo == empty_option) 17590 p_cpo = save_cpo; 17591 else 17592 /* Darn, evaluating the {skip} expression changed the value. */ 17593 free_string_option(save_cpo); 17594 17595 return retval; 17596 } 17597 17598 /* 17599 * "searchpos()" function 17600 */ 17601 static void 17602 f_searchpos(typval_T *argvars, typval_T *rettv) 17603 { 17604 pos_T match_pos; 17605 int lnum = 0; 17606 int col = 0; 17607 int n; 17608 int flags = 0; 17609 17610 if (rettv_list_alloc(rettv) == FAIL) 17611 return; 17612 17613 n = search_cmn(argvars, &match_pos, &flags); 17614 if (n > 0) 17615 { 17616 lnum = match_pos.lnum; 17617 col = match_pos.col; 17618 } 17619 17620 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 17621 list_append_number(rettv->vval.v_list, (varnumber_T)col); 17622 if (flags & SP_SUBPAT) 17623 list_append_number(rettv->vval.v_list, (varnumber_T)n); 17624 } 17625 17626 static void 17627 f_server2client(typval_T *argvars UNUSED, typval_T *rettv) 17628 { 17629 #ifdef FEAT_CLIENTSERVER 17630 char_u buf[NUMBUFLEN]; 17631 char_u *server = get_tv_string_chk(&argvars[0]); 17632 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 17633 17634 rettv->vval.v_number = -1; 17635 if (server == NULL || reply == NULL) 17636 return; 17637 if (check_restricted() || check_secure()) 17638 return; 17639 # ifdef FEAT_X11 17640 if (check_connection() == FAIL) 17641 return; 17642 # endif 17643 17644 if (serverSendReply(server, reply) < 0) 17645 { 17646 EMSG(_("E258: Unable to send to client")); 17647 return; 17648 } 17649 rettv->vval.v_number = 0; 17650 #else 17651 rettv->vval.v_number = -1; 17652 #endif 17653 } 17654 17655 static void 17656 f_serverlist(typval_T *argvars UNUSED, typval_T *rettv) 17657 { 17658 char_u *r = NULL; 17659 17660 #ifdef FEAT_CLIENTSERVER 17661 # ifdef WIN32 17662 r = serverGetVimNames(); 17663 # else 17664 make_connection(); 17665 if (X_DISPLAY != NULL) 17666 r = serverGetVimNames(X_DISPLAY); 17667 # endif 17668 #endif 17669 rettv->v_type = VAR_STRING; 17670 rettv->vval.v_string = r; 17671 } 17672 17673 /* 17674 * "setbufvar()" function 17675 */ 17676 static void 17677 f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) 17678 { 17679 buf_T *buf; 17680 aco_save_T aco; 17681 char_u *varname, *bufvarname; 17682 typval_T *varp; 17683 char_u nbuf[NUMBUFLEN]; 17684 17685 if (check_restricted() || check_secure()) 17686 return; 17687 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 17688 varname = get_tv_string_chk(&argvars[1]); 17689 buf = get_buf_tv(&argvars[0], FALSE); 17690 varp = &argvars[2]; 17691 17692 if (buf != NULL && varname != NULL && varp != NULL) 17693 { 17694 /* set curbuf to be our buf, temporarily */ 17695 aucmd_prepbuf(&aco, buf); 17696 17697 if (*varname == '&') 17698 { 17699 long numval; 17700 char_u *strval; 17701 int error = FALSE; 17702 17703 ++varname; 17704 numval = get_tv_number_chk(varp, &error); 17705 strval = get_tv_string_buf_chk(varp, nbuf); 17706 if (!error && strval != NULL) 17707 set_option_value(varname, numval, strval, OPT_LOCAL); 17708 } 17709 else 17710 { 17711 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 17712 if (bufvarname != NULL) 17713 { 17714 STRCPY(bufvarname, "b:"); 17715 STRCPY(bufvarname + 2, varname); 17716 set_var(bufvarname, varp, TRUE); 17717 vim_free(bufvarname); 17718 } 17719 } 17720 17721 /* reset notion of buffer */ 17722 aucmd_restbuf(&aco); 17723 } 17724 } 17725 17726 static void 17727 f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) 17728 { 17729 dict_T *d; 17730 dictitem_T *di; 17731 char_u *csearch; 17732 17733 if (argvars[0].v_type != VAR_DICT) 17734 { 17735 EMSG(_(e_dictreq)); 17736 return; 17737 } 17738 17739 if ((d = argvars[0].vval.v_dict) != NULL) 17740 { 17741 csearch = get_dict_string(d, (char_u *)"char", FALSE); 17742 if (csearch != NULL) 17743 { 17744 #ifdef FEAT_MBYTE 17745 if (enc_utf8) 17746 { 17747 int pcc[MAX_MCO]; 17748 int c = utfc_ptr2char(csearch, pcc); 17749 17750 set_last_csearch(c, csearch, utfc_ptr2len(csearch)); 17751 } 17752 else 17753 #endif 17754 set_last_csearch(PTR2CHAR(csearch), 17755 csearch, MB_PTR2LEN(csearch)); 17756 } 17757 17758 di = dict_find(d, (char_u *)"forward", -1); 17759 if (di != NULL) 17760 set_csearch_direction(get_tv_number(&di->di_tv) 17761 ? FORWARD : BACKWARD); 17762 17763 di = dict_find(d, (char_u *)"until", -1); 17764 if (di != NULL) 17765 set_csearch_until(!!get_tv_number(&di->di_tv)); 17766 } 17767 } 17768 17769 /* 17770 * "setcmdpos()" function 17771 */ 17772 static void 17773 f_setcmdpos(typval_T *argvars, typval_T *rettv) 17774 { 17775 int pos = (int)get_tv_number(&argvars[0]) - 1; 17776 17777 if (pos >= 0) 17778 rettv->vval.v_number = set_cmdline_pos(pos); 17779 } 17780 17781 /* 17782 * "setfperm({fname}, {mode})" function 17783 */ 17784 static void 17785 f_setfperm(typval_T *argvars, typval_T *rettv) 17786 { 17787 char_u *fname; 17788 char_u modebuf[NUMBUFLEN]; 17789 char_u *mode_str; 17790 int i; 17791 int mask; 17792 int mode = 0; 17793 17794 rettv->vval.v_number = 0; 17795 fname = get_tv_string_chk(&argvars[0]); 17796 if (fname == NULL) 17797 return; 17798 mode_str = get_tv_string_buf_chk(&argvars[1], modebuf); 17799 if (mode_str == NULL) 17800 return; 17801 if (STRLEN(mode_str) != 9) 17802 { 17803 EMSG2(_(e_invarg2), mode_str); 17804 return; 17805 } 17806 17807 mask = 1; 17808 for (i = 8; i >= 0; --i) 17809 { 17810 if (mode_str[i] != '-') 17811 mode |= mask; 17812 mask = mask << 1; 17813 } 17814 rettv->vval.v_number = mch_setperm(fname, mode) == OK; 17815 } 17816 17817 /* 17818 * "setline()" function 17819 */ 17820 static void 17821 f_setline(typval_T *argvars, typval_T *rettv) 17822 { 17823 linenr_T lnum; 17824 char_u *line = NULL; 17825 list_T *l = NULL; 17826 listitem_T *li = NULL; 17827 long added = 0; 17828 linenr_T lcount = curbuf->b_ml.ml_line_count; 17829 17830 lnum = get_tv_lnum(&argvars[0]); 17831 if (argvars[1].v_type == VAR_LIST) 17832 { 17833 l = argvars[1].vval.v_list; 17834 li = l->lv_first; 17835 } 17836 else 17837 line = get_tv_string_chk(&argvars[1]); 17838 17839 /* default result is zero == OK */ 17840 for (;;) 17841 { 17842 if (l != NULL) 17843 { 17844 /* list argument, get next string */ 17845 if (li == NULL) 17846 break; 17847 line = get_tv_string_chk(&li->li_tv); 17848 li = li->li_next; 17849 } 17850 17851 rettv->vval.v_number = 1; /* FAIL */ 17852 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 17853 break; 17854 17855 /* When coming here from Insert mode, sync undo, so that this can be 17856 * undone separately from what was previously inserted. */ 17857 if (u_sync_once == 2) 17858 { 17859 u_sync_once = 1; /* notify that u_sync() was called */ 17860 u_sync(TRUE); 17861 } 17862 17863 if (lnum <= curbuf->b_ml.ml_line_count) 17864 { 17865 /* existing line, replace it */ 17866 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 17867 { 17868 changed_bytes(lnum, 0); 17869 if (lnum == curwin->w_cursor.lnum) 17870 check_cursor_col(); 17871 rettv->vval.v_number = 0; /* OK */ 17872 } 17873 } 17874 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 17875 { 17876 /* lnum is one past the last line, append the line */ 17877 ++added; 17878 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 17879 rettv->vval.v_number = 0; /* OK */ 17880 } 17881 17882 if (l == NULL) /* only one string argument */ 17883 break; 17884 ++lnum; 17885 } 17886 17887 if (added > 0) 17888 appended_lines_mark(lcount, added); 17889 } 17890 17891 static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv); 17892 17893 /* 17894 * Used by "setqflist()" and "setloclist()" functions 17895 */ 17896 static void 17897 set_qf_ll_list( 17898 win_T *wp UNUSED, 17899 typval_T *list_arg UNUSED, 17900 typval_T *action_arg UNUSED, 17901 typval_T *rettv) 17902 { 17903 #ifdef FEAT_QUICKFIX 17904 char_u *act; 17905 int action = ' '; 17906 #endif 17907 17908 rettv->vval.v_number = -1; 17909 17910 #ifdef FEAT_QUICKFIX 17911 if (list_arg->v_type != VAR_LIST) 17912 EMSG(_(e_listreq)); 17913 else 17914 { 17915 list_T *l = list_arg->vval.v_list; 17916 17917 if (action_arg->v_type == VAR_STRING) 17918 { 17919 act = get_tv_string_chk(action_arg); 17920 if (act == NULL) 17921 return; /* type error; errmsg already given */ 17922 if (*act == 'a' || *act == 'r') 17923 action = *act; 17924 } 17925 17926 if (l != NULL && set_errorlist(wp, l, action, 17927 (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK) 17928 rettv->vval.v_number = 0; 17929 } 17930 #endif 17931 } 17932 17933 /* 17934 * "setloclist()" function 17935 */ 17936 static void 17937 f_setloclist(typval_T *argvars, typval_T *rettv) 17938 { 17939 win_T *win; 17940 17941 rettv->vval.v_number = -1; 17942 17943 win = find_win_by_nr(&argvars[0], NULL); 17944 if (win != NULL) 17945 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 17946 } 17947 17948 /* 17949 * "setmatches()" function 17950 */ 17951 static void 17952 f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 17953 { 17954 #ifdef FEAT_SEARCH_EXTRA 17955 list_T *l; 17956 listitem_T *li; 17957 dict_T *d; 17958 list_T *s = NULL; 17959 17960 rettv->vval.v_number = -1; 17961 if (argvars[0].v_type != VAR_LIST) 17962 { 17963 EMSG(_(e_listreq)); 17964 return; 17965 } 17966 if ((l = argvars[0].vval.v_list) != NULL) 17967 { 17968 17969 /* To some extent make sure that we are dealing with a list from 17970 * "getmatches()". */ 17971 li = l->lv_first; 17972 while (li != NULL) 17973 { 17974 if (li->li_tv.v_type != VAR_DICT 17975 || (d = li->li_tv.vval.v_dict) == NULL) 17976 { 17977 EMSG(_(e_invarg)); 17978 return; 17979 } 17980 if (!(dict_find(d, (char_u *)"group", -1) != NULL 17981 && (dict_find(d, (char_u *)"pattern", -1) != NULL 17982 || dict_find(d, (char_u *)"pos1", -1) != NULL) 17983 && dict_find(d, (char_u *)"priority", -1) != NULL 17984 && dict_find(d, (char_u *)"id", -1) != NULL)) 17985 { 17986 EMSG(_(e_invarg)); 17987 return; 17988 } 17989 li = li->li_next; 17990 } 17991 17992 clear_matches(curwin); 17993 li = l->lv_first; 17994 while (li != NULL) 17995 { 17996 int i = 0; 17997 char_u buf[5]; 17998 dictitem_T *di; 17999 char_u *group; 18000 int priority; 18001 int id; 18002 char_u *conceal; 18003 18004 d = li->li_tv.vval.v_dict; 18005 if (dict_find(d, (char_u *)"pattern", -1) == NULL) 18006 { 18007 if (s == NULL) 18008 { 18009 s = list_alloc(); 18010 if (s == NULL) 18011 return; 18012 } 18013 18014 /* match from matchaddpos() */ 18015 for (i = 1; i < 9; i++) 18016 { 18017 sprintf((char *)buf, (char *)"pos%d", i); 18018 if ((di = dict_find(d, (char_u *)buf, -1)) != NULL) 18019 { 18020 if (di->di_tv.v_type != VAR_LIST) 18021 return; 18022 18023 list_append_tv(s, &di->di_tv); 18024 s->lv_refcount++; 18025 } 18026 else 18027 break; 18028 } 18029 } 18030 18031 group = get_dict_string(d, (char_u *)"group", FALSE); 18032 priority = (int)get_dict_number(d, (char_u *)"priority"); 18033 id = (int)get_dict_number(d, (char_u *)"id"); 18034 conceal = dict_find(d, (char_u *)"conceal", -1) != NULL 18035 ? get_dict_string(d, (char_u *)"conceal", FALSE) 18036 : NULL; 18037 if (i == 0) 18038 { 18039 match_add(curwin, group, 18040 get_dict_string(d, (char_u *)"pattern", FALSE), 18041 priority, id, NULL, conceal); 18042 } 18043 else 18044 { 18045 match_add(curwin, group, NULL, priority, id, s, conceal); 18046 list_unref(s); 18047 s = NULL; 18048 } 18049 18050 li = li->li_next; 18051 } 18052 rettv->vval.v_number = 0; 18053 } 18054 #endif 18055 } 18056 18057 /* 18058 * "setpos()" function 18059 */ 18060 static void 18061 f_setpos(typval_T *argvars, typval_T *rettv) 18062 { 18063 pos_T pos; 18064 int fnum; 18065 char_u *name; 18066 colnr_T curswant = -1; 18067 18068 rettv->vval.v_number = -1; 18069 name = get_tv_string_chk(argvars); 18070 if (name != NULL) 18071 { 18072 if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) 18073 { 18074 if (--pos.col < 0) 18075 pos.col = 0; 18076 if (name[0] == '.' && name[1] == NUL) 18077 { 18078 /* set cursor */ 18079 if (fnum == curbuf->b_fnum) 18080 { 18081 curwin->w_cursor = pos; 18082 if (curswant >= 0) 18083 { 18084 curwin->w_curswant = curswant - 1; 18085 curwin->w_set_curswant = FALSE; 18086 } 18087 check_cursor(); 18088 rettv->vval.v_number = 0; 18089 } 18090 else 18091 EMSG(_(e_invarg)); 18092 } 18093 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 18094 { 18095 /* set mark */ 18096 if (setmark_pos(name[1], &pos, fnum) == OK) 18097 rettv->vval.v_number = 0; 18098 } 18099 else 18100 EMSG(_(e_invarg)); 18101 } 18102 } 18103 } 18104 18105 /* 18106 * "setqflist()" function 18107 */ 18108 static void 18109 f_setqflist(typval_T *argvars, typval_T *rettv) 18110 { 18111 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 18112 } 18113 18114 /* 18115 * "setreg()" function 18116 */ 18117 static void 18118 f_setreg(typval_T *argvars, typval_T *rettv) 18119 { 18120 int regname; 18121 char_u *strregname; 18122 char_u *stropt; 18123 char_u *strval; 18124 int append; 18125 char_u yank_type; 18126 long block_len; 18127 18128 block_len = -1; 18129 yank_type = MAUTO; 18130 append = FALSE; 18131 18132 strregname = get_tv_string_chk(argvars); 18133 rettv->vval.v_number = 1; /* FAIL is default */ 18134 18135 if (strregname == NULL) 18136 return; /* type error; errmsg already given */ 18137 regname = *strregname; 18138 if (regname == 0 || regname == '@') 18139 regname = '"'; 18140 18141 if (argvars[2].v_type != VAR_UNKNOWN) 18142 { 18143 stropt = get_tv_string_chk(&argvars[2]); 18144 if (stropt == NULL) 18145 return; /* type error */ 18146 for (; *stropt != NUL; ++stropt) 18147 switch (*stropt) 18148 { 18149 case 'a': case 'A': /* append */ 18150 append = TRUE; 18151 break; 18152 case 'v': case 'c': /* character-wise selection */ 18153 yank_type = MCHAR; 18154 break; 18155 case 'V': case 'l': /* line-wise selection */ 18156 yank_type = MLINE; 18157 break; 18158 case 'b': case Ctrl_V: /* block-wise selection */ 18159 yank_type = MBLOCK; 18160 if (VIM_ISDIGIT(stropt[1])) 18161 { 18162 ++stropt; 18163 block_len = getdigits(&stropt) - 1; 18164 --stropt; 18165 } 18166 break; 18167 } 18168 } 18169 18170 if (argvars[1].v_type == VAR_LIST) 18171 { 18172 char_u **lstval; 18173 char_u **allocval; 18174 char_u buf[NUMBUFLEN]; 18175 char_u **curval; 18176 char_u **curallocval; 18177 int len = argvars[1].vval.v_list->lv_len; 18178 listitem_T *li; 18179 18180 /* First half: use for pointers to result lines; second half: use for 18181 * pointers to allocated copies. */ 18182 lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2)); 18183 if (lstval == NULL) 18184 return; 18185 curval = lstval; 18186 allocval = lstval + len + 2; 18187 curallocval = allocval; 18188 18189 for (li = argvars[1].vval.v_list->lv_first; li != NULL; 18190 li = li->li_next) 18191 { 18192 strval = get_tv_string_buf_chk(&li->li_tv, buf); 18193 if (strval == NULL) 18194 goto free_lstval; 18195 if (strval == buf) 18196 { 18197 /* Need to make a copy, next get_tv_string_buf_chk() will 18198 * overwrite the string. */ 18199 strval = vim_strsave(buf); 18200 if (strval == NULL) 18201 goto free_lstval; 18202 *curallocval++ = strval; 18203 } 18204 *curval++ = strval; 18205 } 18206 *curval++ = NULL; 18207 18208 write_reg_contents_lst(regname, lstval, -1, 18209 append, yank_type, block_len); 18210 free_lstval: 18211 while (curallocval > allocval) 18212 vim_free(*--curallocval); 18213 vim_free(lstval); 18214 } 18215 else 18216 { 18217 strval = get_tv_string_chk(&argvars[1]); 18218 if (strval == NULL) 18219 return; 18220 write_reg_contents_ex(regname, strval, -1, 18221 append, yank_type, block_len); 18222 } 18223 rettv->vval.v_number = 0; 18224 } 18225 18226 /* 18227 * "settabvar()" function 18228 */ 18229 static void 18230 f_settabvar(typval_T *argvars, typval_T *rettv) 18231 { 18232 #ifdef FEAT_WINDOWS 18233 tabpage_T *save_curtab; 18234 tabpage_T *tp; 18235 #endif 18236 char_u *varname, *tabvarname; 18237 typval_T *varp; 18238 18239 rettv->vval.v_number = 0; 18240 18241 if (check_restricted() || check_secure()) 18242 return; 18243 18244 #ifdef FEAT_WINDOWS 18245 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 18246 #endif 18247 varname = get_tv_string_chk(&argvars[1]); 18248 varp = &argvars[2]; 18249 18250 if (varname != NULL && varp != NULL 18251 #ifdef FEAT_WINDOWS 18252 && tp != NULL 18253 #endif 18254 ) 18255 { 18256 #ifdef FEAT_WINDOWS 18257 save_curtab = curtab; 18258 goto_tabpage_tp(tp, FALSE, FALSE); 18259 #endif 18260 18261 tabvarname = alloc((unsigned)STRLEN(varname) + 3); 18262 if (tabvarname != NULL) 18263 { 18264 STRCPY(tabvarname, "t:"); 18265 STRCPY(tabvarname + 2, varname); 18266 set_var(tabvarname, varp, TRUE); 18267 vim_free(tabvarname); 18268 } 18269 18270 #ifdef FEAT_WINDOWS 18271 /* Restore current tabpage */ 18272 if (valid_tabpage(save_curtab)) 18273 goto_tabpage_tp(save_curtab, FALSE, FALSE); 18274 #endif 18275 } 18276 } 18277 18278 /* 18279 * "settabwinvar()" function 18280 */ 18281 static void 18282 f_settabwinvar(typval_T *argvars, typval_T *rettv) 18283 { 18284 setwinvar(argvars, rettv, 1); 18285 } 18286 18287 /* 18288 * "setwinvar()" function 18289 */ 18290 static void 18291 f_setwinvar(typval_T *argvars, typval_T *rettv) 18292 { 18293 setwinvar(argvars, rettv, 0); 18294 } 18295 18296 /* 18297 * "setwinvar()" and "settabwinvar()" functions 18298 */ 18299 18300 static void 18301 setwinvar(typval_T *argvars, typval_T *rettv UNUSED, int off) 18302 { 18303 win_T *win; 18304 #ifdef FEAT_WINDOWS 18305 win_T *save_curwin; 18306 tabpage_T *save_curtab; 18307 int need_switch_win; 18308 #endif 18309 char_u *varname, *winvarname; 18310 typval_T *varp; 18311 char_u nbuf[NUMBUFLEN]; 18312 tabpage_T *tp = NULL; 18313 18314 if (check_restricted() || check_secure()) 18315 return; 18316 18317 #ifdef FEAT_WINDOWS 18318 if (off == 1) 18319 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 18320 else 18321 tp = curtab; 18322 #endif 18323 win = find_win_by_nr(&argvars[off], tp); 18324 varname = get_tv_string_chk(&argvars[off + 1]); 18325 varp = &argvars[off + 2]; 18326 18327 if (win != NULL && varname != NULL && varp != NULL) 18328 { 18329 #ifdef FEAT_WINDOWS 18330 need_switch_win = !(tp == curtab && win == curwin); 18331 if (!need_switch_win 18332 || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) 18333 #endif 18334 { 18335 if (*varname == '&') 18336 { 18337 long numval; 18338 char_u *strval; 18339 int error = FALSE; 18340 18341 ++varname; 18342 numval = get_tv_number_chk(varp, &error); 18343 strval = get_tv_string_buf_chk(varp, nbuf); 18344 if (!error && strval != NULL) 18345 set_option_value(varname, numval, strval, OPT_LOCAL); 18346 } 18347 else 18348 { 18349 winvarname = alloc((unsigned)STRLEN(varname) + 3); 18350 if (winvarname != NULL) 18351 { 18352 STRCPY(winvarname, "w:"); 18353 STRCPY(winvarname + 2, varname); 18354 set_var(winvarname, varp, TRUE); 18355 vim_free(winvarname); 18356 } 18357 } 18358 } 18359 #ifdef FEAT_WINDOWS 18360 if (need_switch_win) 18361 restore_win(save_curwin, save_curtab, TRUE); 18362 #endif 18363 } 18364 } 18365 18366 #ifdef FEAT_CRYPT 18367 /* 18368 * "sha256({string})" function 18369 */ 18370 static void 18371 f_sha256(typval_T *argvars, typval_T *rettv) 18372 { 18373 char_u *p; 18374 18375 p = get_tv_string(&argvars[0]); 18376 rettv->vval.v_string = vim_strsave( 18377 sha256_bytes(p, (int)STRLEN(p), NULL, 0)); 18378 rettv->v_type = VAR_STRING; 18379 } 18380 #endif /* FEAT_CRYPT */ 18381 18382 /* 18383 * "shellescape({string})" function 18384 */ 18385 static void 18386 f_shellescape(typval_T *argvars, typval_T *rettv) 18387 { 18388 rettv->vval.v_string = vim_strsave_shellescape( 18389 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), TRUE); 18390 rettv->v_type = VAR_STRING; 18391 } 18392 18393 /* 18394 * shiftwidth() function 18395 */ 18396 static void 18397 f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv) 18398 { 18399 rettv->vval.v_number = get_sw_value(curbuf); 18400 } 18401 18402 /* 18403 * "simplify()" function 18404 */ 18405 static void 18406 f_simplify(typval_T *argvars, typval_T *rettv) 18407 { 18408 char_u *p; 18409 18410 p = get_tv_string(&argvars[0]); 18411 rettv->vval.v_string = vim_strsave(p); 18412 simplify_filename(rettv->vval.v_string); /* simplify in place */ 18413 rettv->v_type = VAR_STRING; 18414 } 18415 18416 #ifdef FEAT_FLOAT 18417 /* 18418 * "sin()" function 18419 */ 18420 static void 18421 f_sin(typval_T *argvars, typval_T *rettv) 18422 { 18423 float_T f = 0.0; 18424 18425 rettv->v_type = VAR_FLOAT; 18426 if (get_float_arg(argvars, &f) == OK) 18427 rettv->vval.v_float = sin(f); 18428 else 18429 rettv->vval.v_float = 0.0; 18430 } 18431 18432 /* 18433 * "sinh()" function 18434 */ 18435 static void 18436 f_sinh(typval_T *argvars, typval_T *rettv) 18437 { 18438 float_T f = 0.0; 18439 18440 rettv->v_type = VAR_FLOAT; 18441 if (get_float_arg(argvars, &f) == OK) 18442 rettv->vval.v_float = sinh(f); 18443 else 18444 rettv->vval.v_float = 0.0; 18445 } 18446 #endif 18447 18448 static int 18449 #ifdef __BORLANDC__ 18450 _RTLENTRYF 18451 #endif 18452 item_compare(const void *s1, const void *s2); 18453 static int 18454 #ifdef __BORLANDC__ 18455 _RTLENTRYF 18456 #endif 18457 item_compare2(const void *s1, const void *s2); 18458 18459 /* struct used in the array that's given to qsort() */ 18460 typedef struct 18461 { 18462 listitem_T *item; 18463 int idx; 18464 } sortItem_T; 18465 18466 /* struct storing information about current sort */ 18467 typedef struct 18468 { 18469 int item_compare_ic; 18470 int item_compare_numeric; 18471 int item_compare_numbers; 18472 #ifdef FEAT_FLOAT 18473 int item_compare_float; 18474 #endif 18475 char_u *item_compare_func; 18476 partial_T *item_compare_partial; 18477 dict_T *item_compare_selfdict; 18478 int item_compare_func_err; 18479 int item_compare_keep_zero; 18480 } sortinfo_T; 18481 static sortinfo_T *sortinfo = NULL; 18482 static void do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort); 18483 #define ITEM_COMPARE_FAIL 999 18484 18485 /* 18486 * Compare functions for f_sort() and f_uniq() below. 18487 */ 18488 static int 18489 #ifdef __BORLANDC__ 18490 _RTLENTRYF 18491 #endif 18492 item_compare(const void *s1, const void *s2) 18493 { 18494 sortItem_T *si1, *si2; 18495 typval_T *tv1, *tv2; 18496 char_u *p1, *p2; 18497 char_u *tofree1 = NULL, *tofree2 = NULL; 18498 int res; 18499 char_u numbuf1[NUMBUFLEN]; 18500 char_u numbuf2[NUMBUFLEN]; 18501 18502 si1 = (sortItem_T *)s1; 18503 si2 = (sortItem_T *)s2; 18504 tv1 = &si1->item->li_tv; 18505 tv2 = &si2->item->li_tv; 18506 18507 if (sortinfo->item_compare_numbers) 18508 { 18509 long v1 = get_tv_number(tv1); 18510 long v2 = get_tv_number(tv2); 18511 18512 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 18513 } 18514 18515 #ifdef FEAT_FLOAT 18516 if (sortinfo->item_compare_float) 18517 { 18518 float_T v1 = get_tv_float(tv1); 18519 float_T v2 = get_tv_float(tv2); 18520 18521 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 18522 } 18523 #endif 18524 18525 /* tv2string() puts quotes around a string and allocates memory. Don't do 18526 * that for string variables. Use a single quote when comparing with a 18527 * non-string to do what the docs promise. */ 18528 if (tv1->v_type == VAR_STRING) 18529 { 18530 if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) 18531 p1 = (char_u *)"'"; 18532 else 18533 p1 = tv1->vval.v_string; 18534 } 18535 else 18536 p1 = tv2string(tv1, &tofree1, numbuf1, 0); 18537 if (tv2->v_type == VAR_STRING) 18538 { 18539 if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) 18540 p2 = (char_u *)"'"; 18541 else 18542 p2 = tv2->vval.v_string; 18543 } 18544 else 18545 p2 = tv2string(tv2, &tofree2, numbuf2, 0); 18546 if (p1 == NULL) 18547 p1 = (char_u *)""; 18548 if (p2 == NULL) 18549 p2 = (char_u *)""; 18550 if (!sortinfo->item_compare_numeric) 18551 { 18552 if (sortinfo->item_compare_ic) 18553 res = STRICMP(p1, p2); 18554 else 18555 res = STRCMP(p1, p2); 18556 } 18557 else 18558 { 18559 double n1, n2; 18560 n1 = strtod((char *)p1, (char **)&p1); 18561 n2 = strtod((char *)p2, (char **)&p2); 18562 res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1; 18563 } 18564 18565 /* When the result would be zero, compare the item indexes. Makes the 18566 * sort stable. */ 18567 if (res == 0 && !sortinfo->item_compare_keep_zero) 18568 res = si1->idx > si2->idx ? 1 : -1; 18569 18570 vim_free(tofree1); 18571 vim_free(tofree2); 18572 return res; 18573 } 18574 18575 static int 18576 #ifdef __BORLANDC__ 18577 _RTLENTRYF 18578 #endif 18579 item_compare2(const void *s1, const void *s2) 18580 { 18581 sortItem_T *si1, *si2; 18582 int res; 18583 typval_T rettv; 18584 typval_T argv[3]; 18585 int dummy; 18586 char_u *func_name; 18587 partial_T *partial = sortinfo->item_compare_partial; 18588 18589 /* shortcut after failure in previous call; compare all items equal */ 18590 if (sortinfo->item_compare_func_err) 18591 return 0; 18592 18593 si1 = (sortItem_T *)s1; 18594 si2 = (sortItem_T *)s2; 18595 18596 if (partial == NULL) 18597 func_name = sortinfo->item_compare_func; 18598 else 18599 func_name = partial->pt_name; 18600 18601 /* Copy the values. This is needed to be able to set v_lock to VAR_FIXED 18602 * in the copy without changing the original list items. */ 18603 copy_tv(&si1->item->li_tv, &argv[0]); 18604 copy_tv(&si2->item->li_tv, &argv[1]); 18605 18606 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 18607 res = call_func(func_name, (int)STRLEN(func_name), 18608 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, 18609 partial, sortinfo->item_compare_selfdict); 18610 clear_tv(&argv[0]); 18611 clear_tv(&argv[1]); 18612 18613 if (res == FAIL) 18614 res = ITEM_COMPARE_FAIL; 18615 else 18616 res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err); 18617 if (sortinfo->item_compare_func_err) 18618 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 18619 clear_tv(&rettv); 18620 18621 /* When the result would be zero, compare the pointers themselves. Makes 18622 * the sort stable. */ 18623 if (res == 0 && !sortinfo->item_compare_keep_zero) 18624 res = si1->idx > si2->idx ? 1 : -1; 18625 18626 return res; 18627 } 18628 18629 /* 18630 * "sort({list})" function 18631 */ 18632 static void 18633 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort) 18634 { 18635 list_T *l; 18636 listitem_T *li; 18637 sortItem_T *ptrs; 18638 sortinfo_T *old_sortinfo; 18639 sortinfo_T info; 18640 long len; 18641 long i; 18642 18643 /* Pointer to current info struct used in compare function. Save and 18644 * restore the current one for nested calls. */ 18645 old_sortinfo = sortinfo; 18646 sortinfo = &info; 18647 18648 if (argvars[0].v_type != VAR_LIST) 18649 EMSG2(_(e_listarg), sort ? "sort()" : "uniq()"); 18650 else 18651 { 18652 l = argvars[0].vval.v_list; 18653 if (l == NULL || tv_check_lock(l->lv_lock, 18654 (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")), 18655 TRUE)) 18656 goto theend; 18657 rettv->vval.v_list = l; 18658 rettv->v_type = VAR_LIST; 18659 ++l->lv_refcount; 18660 18661 len = list_len(l); 18662 if (len <= 1) 18663 goto theend; /* short list sorts pretty quickly */ 18664 18665 info.item_compare_ic = FALSE; 18666 info.item_compare_numeric = FALSE; 18667 info.item_compare_numbers = FALSE; 18668 #ifdef FEAT_FLOAT 18669 info.item_compare_float = FALSE; 18670 #endif 18671 info.item_compare_func = NULL; 18672 info.item_compare_partial = NULL; 18673 info.item_compare_selfdict = NULL; 18674 if (argvars[1].v_type != VAR_UNKNOWN) 18675 { 18676 /* optional second argument: {func} */ 18677 if (argvars[1].v_type == VAR_FUNC) 18678 info.item_compare_func = argvars[1].vval.v_string; 18679 else if (argvars[1].v_type == VAR_PARTIAL) 18680 info.item_compare_partial = argvars[1].vval.v_partial; 18681 else 18682 { 18683 int error = FALSE; 18684 18685 i = get_tv_number_chk(&argvars[1], &error); 18686 if (error) 18687 goto theend; /* type error; errmsg already given */ 18688 if (i == 1) 18689 info.item_compare_ic = TRUE; 18690 else if (argvars[1].v_type != VAR_NUMBER) 18691 info.item_compare_func = get_tv_string(&argvars[1]); 18692 else if (i != 0) 18693 { 18694 EMSG(_(e_invarg)); 18695 goto theend; 18696 } 18697 if (info.item_compare_func != NULL) 18698 { 18699 if (*info.item_compare_func == NUL) 18700 { 18701 /* empty string means default sort */ 18702 info.item_compare_func = NULL; 18703 } 18704 else if (STRCMP(info.item_compare_func, "n") == 0) 18705 { 18706 info.item_compare_func = NULL; 18707 info.item_compare_numeric = TRUE; 18708 } 18709 else if (STRCMP(info.item_compare_func, "N") == 0) 18710 { 18711 info.item_compare_func = NULL; 18712 info.item_compare_numbers = TRUE; 18713 } 18714 #ifdef FEAT_FLOAT 18715 else if (STRCMP(info.item_compare_func, "f") == 0) 18716 { 18717 info.item_compare_func = NULL; 18718 info.item_compare_float = TRUE; 18719 } 18720 #endif 18721 else if (STRCMP(info.item_compare_func, "i") == 0) 18722 { 18723 info.item_compare_func = NULL; 18724 info.item_compare_ic = TRUE; 18725 } 18726 } 18727 } 18728 18729 if (argvars[2].v_type != VAR_UNKNOWN) 18730 { 18731 /* optional third argument: {dict} */ 18732 if (argvars[2].v_type != VAR_DICT) 18733 { 18734 EMSG(_(e_dictreq)); 18735 goto theend; 18736 } 18737 info.item_compare_selfdict = argvars[2].vval.v_dict; 18738 } 18739 } 18740 18741 /* Make an array with each entry pointing to an item in the List. */ 18742 ptrs = (sortItem_T *)alloc((int)(len * sizeof(sortItem_T))); 18743 if (ptrs == NULL) 18744 goto theend; 18745 18746 i = 0; 18747 if (sort) 18748 { 18749 /* sort(): ptrs will be the list to sort */ 18750 for (li = l->lv_first; li != NULL; li = li->li_next) 18751 { 18752 ptrs[i].item = li; 18753 ptrs[i].idx = i; 18754 ++i; 18755 } 18756 18757 info.item_compare_func_err = FALSE; 18758 info.item_compare_keep_zero = FALSE; 18759 /* test the compare function */ 18760 if ((info.item_compare_func != NULL 18761 || info.item_compare_partial != NULL) 18762 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 18763 == ITEM_COMPARE_FAIL) 18764 EMSG(_("E702: Sort compare function failed")); 18765 else 18766 { 18767 /* Sort the array with item pointers. */ 18768 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T), 18769 info.item_compare_func == NULL 18770 && info.item_compare_partial == NULL 18771 ? item_compare : item_compare2); 18772 18773 if (!info.item_compare_func_err) 18774 { 18775 /* Clear the List and append the items in sorted order. */ 18776 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 18777 l->lv_len = 0; 18778 for (i = 0; i < len; ++i) 18779 list_append(l, ptrs[i].item); 18780 } 18781 } 18782 } 18783 else 18784 { 18785 int (*item_compare_func_ptr)(const void *, const void *); 18786 18787 /* f_uniq(): ptrs will be a stack of items to remove */ 18788 info.item_compare_func_err = FALSE; 18789 info.item_compare_keep_zero = TRUE; 18790 item_compare_func_ptr = info.item_compare_func != NULL 18791 || info.item_compare_partial != NULL 18792 ? item_compare2 : item_compare; 18793 18794 for (li = l->lv_first; li != NULL && li->li_next != NULL; 18795 li = li->li_next) 18796 { 18797 if (item_compare_func_ptr((void *)&li, (void *)&li->li_next) 18798 == 0) 18799 ptrs[i++].item = li; 18800 if (info.item_compare_func_err) 18801 { 18802 EMSG(_("E882: Uniq compare function failed")); 18803 break; 18804 } 18805 } 18806 18807 if (!info.item_compare_func_err) 18808 { 18809 while (--i >= 0) 18810 { 18811 li = ptrs[i].item->li_next; 18812 ptrs[i].item->li_next = li->li_next; 18813 if (li->li_next != NULL) 18814 li->li_next->li_prev = ptrs[i].item; 18815 else 18816 l->lv_last = ptrs[i].item; 18817 list_fix_watch(l, li); 18818 listitem_free(li); 18819 l->lv_len--; 18820 } 18821 } 18822 } 18823 18824 vim_free(ptrs); 18825 } 18826 theend: 18827 sortinfo = old_sortinfo; 18828 } 18829 18830 /* 18831 * "sort({list})" function 18832 */ 18833 static void 18834 f_sort(typval_T *argvars, typval_T *rettv) 18835 { 18836 do_sort_uniq(argvars, rettv, TRUE); 18837 } 18838 18839 /* 18840 * "uniq({list})" function 18841 */ 18842 static void 18843 f_uniq(typval_T *argvars, typval_T *rettv) 18844 { 18845 do_sort_uniq(argvars, rettv, FALSE); 18846 } 18847 18848 /* 18849 * "soundfold({word})" function 18850 */ 18851 static void 18852 f_soundfold(typval_T *argvars, typval_T *rettv) 18853 { 18854 char_u *s; 18855 18856 rettv->v_type = VAR_STRING; 18857 s = get_tv_string(&argvars[0]); 18858 #ifdef FEAT_SPELL 18859 rettv->vval.v_string = eval_soundfold(s); 18860 #else 18861 rettv->vval.v_string = vim_strsave(s); 18862 #endif 18863 } 18864 18865 /* 18866 * "spellbadword()" function 18867 */ 18868 static void 18869 f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv) 18870 { 18871 char_u *word = (char_u *)""; 18872 hlf_T attr = HLF_COUNT; 18873 int len = 0; 18874 18875 if (rettv_list_alloc(rettv) == FAIL) 18876 return; 18877 18878 #ifdef FEAT_SPELL 18879 if (argvars[0].v_type == VAR_UNKNOWN) 18880 { 18881 /* Find the start and length of the badly spelled word. */ 18882 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 18883 if (len != 0) 18884 word = ml_get_cursor(); 18885 } 18886 else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) 18887 { 18888 char_u *str = get_tv_string_chk(&argvars[0]); 18889 int capcol = -1; 18890 18891 if (str != NULL) 18892 { 18893 /* Check the argument for spelling. */ 18894 while (*str != NUL) 18895 { 18896 len = spell_check(curwin, str, &attr, &capcol, FALSE); 18897 if (attr != HLF_COUNT) 18898 { 18899 word = str; 18900 break; 18901 } 18902 str += len; 18903 } 18904 } 18905 } 18906 #endif 18907 18908 list_append_string(rettv->vval.v_list, word, len); 18909 list_append_string(rettv->vval.v_list, (char_u *)( 18910 attr == HLF_SPB ? "bad" : 18911 attr == HLF_SPR ? "rare" : 18912 attr == HLF_SPL ? "local" : 18913 attr == HLF_SPC ? "caps" : 18914 ""), -1); 18915 } 18916 18917 /* 18918 * "spellsuggest()" function 18919 */ 18920 static void 18921 f_spellsuggest(typval_T *argvars UNUSED, typval_T *rettv) 18922 { 18923 #ifdef FEAT_SPELL 18924 char_u *str; 18925 int typeerr = FALSE; 18926 int maxcount; 18927 garray_T ga; 18928 int i; 18929 listitem_T *li; 18930 int need_capital = FALSE; 18931 #endif 18932 18933 if (rettv_list_alloc(rettv) == FAIL) 18934 return; 18935 18936 #ifdef FEAT_SPELL 18937 if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) 18938 { 18939 str = get_tv_string(&argvars[0]); 18940 if (argvars[1].v_type != VAR_UNKNOWN) 18941 { 18942 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 18943 if (maxcount <= 0) 18944 return; 18945 if (argvars[2].v_type != VAR_UNKNOWN) 18946 { 18947 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 18948 if (typeerr) 18949 return; 18950 } 18951 } 18952 else 18953 maxcount = 25; 18954 18955 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 18956 18957 for (i = 0; i < ga.ga_len; ++i) 18958 { 18959 str = ((char_u **)ga.ga_data)[i]; 18960 18961 li = listitem_alloc(); 18962 if (li == NULL) 18963 vim_free(str); 18964 else 18965 { 18966 li->li_tv.v_type = VAR_STRING; 18967 li->li_tv.v_lock = 0; 18968 li->li_tv.vval.v_string = str; 18969 list_append(rettv->vval.v_list, li); 18970 } 18971 } 18972 ga_clear(&ga); 18973 } 18974 #endif 18975 } 18976 18977 static void 18978 f_split(typval_T *argvars, typval_T *rettv) 18979 { 18980 char_u *str; 18981 char_u *end; 18982 char_u *pat = NULL; 18983 regmatch_T regmatch; 18984 char_u patbuf[NUMBUFLEN]; 18985 char_u *save_cpo; 18986 int match; 18987 colnr_T col = 0; 18988 int keepempty = FALSE; 18989 int typeerr = FALSE; 18990 18991 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 18992 save_cpo = p_cpo; 18993 p_cpo = (char_u *)""; 18994 18995 str = get_tv_string(&argvars[0]); 18996 if (argvars[1].v_type != VAR_UNKNOWN) 18997 { 18998 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 18999 if (pat == NULL) 19000 typeerr = TRUE; 19001 if (argvars[2].v_type != VAR_UNKNOWN) 19002 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 19003 } 19004 if (pat == NULL || *pat == NUL) 19005 pat = (char_u *)"[\\x01- ]\\+"; 19006 19007 if (rettv_list_alloc(rettv) == FAIL) 19008 return; 19009 if (typeerr) 19010 return; 19011 19012 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19013 if (regmatch.regprog != NULL) 19014 { 19015 regmatch.rm_ic = FALSE; 19016 while (*str != NUL || keepempty) 19017 { 19018 if (*str == NUL) 19019 match = FALSE; /* empty item at the end */ 19020 else 19021 match = vim_regexec_nl(®match, str, col); 19022 if (match) 19023 end = regmatch.startp[0]; 19024 else 19025 end = str + STRLEN(str); 19026 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 19027 && *str != NUL && match && end < regmatch.endp[0])) 19028 { 19029 if (list_append_string(rettv->vval.v_list, str, 19030 (int)(end - str)) == FAIL) 19031 break; 19032 } 19033 if (!match) 19034 break; 19035 /* Advance to just after the match. */ 19036 if (regmatch.endp[0] > str) 19037 col = 0; 19038 else 19039 { 19040 /* Don't get stuck at the same match. */ 19041 #ifdef FEAT_MBYTE 19042 col = (*mb_ptr2len)(regmatch.endp[0]); 19043 #else 19044 col = 1; 19045 #endif 19046 } 19047 str = regmatch.endp[0]; 19048 } 19049 19050 vim_regfree(regmatch.regprog); 19051 } 19052 19053 p_cpo = save_cpo; 19054 } 19055 19056 #ifdef FEAT_FLOAT 19057 /* 19058 * "sqrt()" function 19059 */ 19060 static void 19061 f_sqrt(typval_T *argvars, typval_T *rettv) 19062 { 19063 float_T f = 0.0; 19064 19065 rettv->v_type = VAR_FLOAT; 19066 if (get_float_arg(argvars, &f) == OK) 19067 rettv->vval.v_float = sqrt(f); 19068 else 19069 rettv->vval.v_float = 0.0; 19070 } 19071 19072 /* 19073 * "str2float()" function 19074 */ 19075 static void 19076 f_str2float(typval_T *argvars, typval_T *rettv) 19077 { 19078 char_u *p = skipwhite(get_tv_string(&argvars[0])); 19079 19080 if (*p == '+') 19081 p = skipwhite(p + 1); 19082 (void)string2float(p, &rettv->vval.v_float); 19083 rettv->v_type = VAR_FLOAT; 19084 } 19085 #endif 19086 19087 /* 19088 * "str2nr()" function 19089 */ 19090 static void 19091 f_str2nr(typval_T *argvars, typval_T *rettv) 19092 { 19093 int base = 10; 19094 char_u *p; 19095 long n; 19096 int what; 19097 19098 if (argvars[1].v_type != VAR_UNKNOWN) 19099 { 19100 base = get_tv_number(&argvars[1]); 19101 if (base != 2 && base != 8 && base != 10 && base != 16) 19102 { 19103 EMSG(_(e_invarg)); 19104 return; 19105 } 19106 } 19107 19108 p = skipwhite(get_tv_string(&argvars[0])); 19109 if (*p == '+') 19110 p = skipwhite(p + 1); 19111 switch (base) 19112 { 19113 case 2: what = STR2NR_BIN + STR2NR_FORCE; break; 19114 case 8: what = STR2NR_OCT + STR2NR_FORCE; break; 19115 case 16: what = STR2NR_HEX + STR2NR_FORCE; break; 19116 default: what = 0; 19117 } 19118 vim_str2nr(p, NULL, NULL, what, &n, NULL, 0); 19119 rettv->vval.v_number = n; 19120 } 19121 19122 #ifdef HAVE_STRFTIME 19123 /* 19124 * "strftime({format}[, {time}])" function 19125 */ 19126 static void 19127 f_strftime(typval_T *argvars, typval_T *rettv) 19128 { 19129 char_u result_buf[256]; 19130 struct tm *curtime; 19131 time_t seconds; 19132 char_u *p; 19133 19134 rettv->v_type = VAR_STRING; 19135 19136 p = get_tv_string(&argvars[0]); 19137 if (argvars[1].v_type == VAR_UNKNOWN) 19138 seconds = time(NULL); 19139 else 19140 seconds = (time_t)get_tv_number(&argvars[1]); 19141 curtime = localtime(&seconds); 19142 /* MSVC returns NULL for an invalid value of seconds. */ 19143 if (curtime == NULL) 19144 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 19145 else 19146 { 19147 # ifdef FEAT_MBYTE 19148 vimconv_T conv; 19149 char_u *enc; 19150 19151 conv.vc_type = CONV_NONE; 19152 enc = enc_locale(); 19153 convert_setup(&conv, p_enc, enc); 19154 if (conv.vc_type != CONV_NONE) 19155 p = string_convert(&conv, p, NULL); 19156 # endif 19157 if (p != NULL) 19158 (void)strftime((char *)result_buf, sizeof(result_buf), 19159 (char *)p, curtime); 19160 else 19161 result_buf[0] = NUL; 19162 19163 # ifdef FEAT_MBYTE 19164 if (conv.vc_type != CONV_NONE) 19165 vim_free(p); 19166 convert_setup(&conv, enc, p_enc); 19167 if (conv.vc_type != CONV_NONE) 19168 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 19169 else 19170 # endif 19171 rettv->vval.v_string = vim_strsave(result_buf); 19172 19173 # ifdef FEAT_MBYTE 19174 /* Release conversion descriptors */ 19175 convert_setup(&conv, NULL, NULL); 19176 vim_free(enc); 19177 # endif 19178 } 19179 } 19180 #endif 19181 19182 /* 19183 * "stridx()" function 19184 */ 19185 static void 19186 f_stridx(typval_T *argvars, typval_T *rettv) 19187 { 19188 char_u buf[NUMBUFLEN]; 19189 char_u *needle; 19190 char_u *haystack; 19191 char_u *save_haystack; 19192 char_u *pos; 19193 int start_idx; 19194 19195 needle = get_tv_string_chk(&argvars[1]); 19196 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 19197 rettv->vval.v_number = -1; 19198 if (needle == NULL || haystack == NULL) 19199 return; /* type error; errmsg already given */ 19200 19201 if (argvars[2].v_type != VAR_UNKNOWN) 19202 { 19203 int error = FALSE; 19204 19205 start_idx = get_tv_number_chk(&argvars[2], &error); 19206 if (error || start_idx >= (int)STRLEN(haystack)) 19207 return; 19208 if (start_idx >= 0) 19209 haystack += start_idx; 19210 } 19211 19212 pos = (char_u *)strstr((char *)haystack, (char *)needle); 19213 if (pos != NULL) 19214 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 19215 } 19216 19217 /* 19218 * "string()" function 19219 */ 19220 static void 19221 f_string(typval_T *argvars, typval_T *rettv) 19222 { 19223 char_u *tofree; 19224 char_u numbuf[NUMBUFLEN]; 19225 19226 rettv->v_type = VAR_STRING; 19227 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 19228 /* Make a copy if we have a value but it's not in allocated memory. */ 19229 if (rettv->vval.v_string != NULL && tofree == NULL) 19230 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 19231 } 19232 19233 /* 19234 * "strlen()" function 19235 */ 19236 static void 19237 f_strlen(typval_T *argvars, typval_T *rettv) 19238 { 19239 rettv->vval.v_number = (varnumber_T)(STRLEN( 19240 get_tv_string(&argvars[0]))); 19241 } 19242 19243 /* 19244 * "strchars()" function 19245 */ 19246 static void 19247 f_strchars(typval_T *argvars, typval_T *rettv) 19248 { 19249 char_u *s = get_tv_string(&argvars[0]); 19250 int skipcc = 0; 19251 #ifdef FEAT_MBYTE 19252 varnumber_T len = 0; 19253 int (*func_mb_ptr2char_adv)(char_u **pp); 19254 #endif 19255 19256 if (argvars[1].v_type != VAR_UNKNOWN) 19257 skipcc = get_tv_number_chk(&argvars[1], NULL); 19258 if (skipcc < 0 || skipcc > 1) 19259 EMSG(_(e_invarg)); 19260 else 19261 { 19262 #ifdef FEAT_MBYTE 19263 func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv; 19264 while (*s != NUL) 19265 { 19266 func_mb_ptr2char_adv(&s); 19267 ++len; 19268 } 19269 rettv->vval.v_number = len; 19270 #else 19271 rettv->vval.v_number = (varnumber_T)(STRLEN(s)); 19272 #endif 19273 } 19274 } 19275 19276 /* 19277 * "strdisplaywidth()" function 19278 */ 19279 static void 19280 f_strdisplaywidth(typval_T *argvars, typval_T *rettv) 19281 { 19282 char_u *s = get_tv_string(&argvars[0]); 19283 int col = 0; 19284 19285 if (argvars[1].v_type != VAR_UNKNOWN) 19286 col = get_tv_number(&argvars[1]); 19287 19288 rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col); 19289 } 19290 19291 /* 19292 * "strwidth()" function 19293 */ 19294 static void 19295 f_strwidth(typval_T *argvars, typval_T *rettv) 19296 { 19297 char_u *s = get_tv_string(&argvars[0]); 19298 19299 rettv->vval.v_number = (varnumber_T)( 19300 #ifdef FEAT_MBYTE 19301 mb_string2cells(s, -1) 19302 #else 19303 STRLEN(s) 19304 #endif 19305 ); 19306 } 19307 19308 /* 19309 * "strpart()" function 19310 */ 19311 static void 19312 f_strpart(typval_T *argvars, typval_T *rettv) 19313 { 19314 char_u *p; 19315 int n; 19316 int len; 19317 int slen; 19318 int error = FALSE; 19319 19320 p = get_tv_string(&argvars[0]); 19321 slen = (int)STRLEN(p); 19322 19323 n = get_tv_number_chk(&argvars[1], &error); 19324 if (error) 19325 len = 0; 19326 else if (argvars[2].v_type != VAR_UNKNOWN) 19327 len = get_tv_number(&argvars[2]); 19328 else 19329 len = slen - n; /* default len: all bytes that are available. */ 19330 19331 /* 19332 * Only return the overlap between the specified part and the actual 19333 * string. 19334 */ 19335 if (n < 0) 19336 { 19337 len += n; 19338 n = 0; 19339 } 19340 else if (n > slen) 19341 n = slen; 19342 if (len < 0) 19343 len = 0; 19344 else if (n + len > slen) 19345 len = slen - n; 19346 19347 rettv->v_type = VAR_STRING; 19348 rettv->vval.v_string = vim_strnsave(p + n, len); 19349 } 19350 19351 /* 19352 * "strridx()" function 19353 */ 19354 static void 19355 f_strridx(typval_T *argvars, typval_T *rettv) 19356 { 19357 char_u buf[NUMBUFLEN]; 19358 char_u *needle; 19359 char_u *haystack; 19360 char_u *rest; 19361 char_u *lastmatch = NULL; 19362 int haystack_len, end_idx; 19363 19364 needle = get_tv_string_chk(&argvars[1]); 19365 haystack = get_tv_string_buf_chk(&argvars[0], buf); 19366 19367 rettv->vval.v_number = -1; 19368 if (needle == NULL || haystack == NULL) 19369 return; /* type error; errmsg already given */ 19370 19371 haystack_len = (int)STRLEN(haystack); 19372 if (argvars[2].v_type != VAR_UNKNOWN) 19373 { 19374 /* Third argument: upper limit for index */ 19375 end_idx = get_tv_number_chk(&argvars[2], NULL); 19376 if (end_idx < 0) 19377 return; /* can never find a match */ 19378 } 19379 else 19380 end_idx = haystack_len; 19381 19382 if (*needle == NUL) 19383 { 19384 /* Empty string matches past the end. */ 19385 lastmatch = haystack + end_idx; 19386 } 19387 else 19388 { 19389 for (rest = haystack; *rest != '\0'; ++rest) 19390 { 19391 rest = (char_u *)strstr((char *)rest, (char *)needle); 19392 if (rest == NULL || rest > haystack + end_idx) 19393 break; 19394 lastmatch = rest; 19395 } 19396 } 19397 19398 if (lastmatch == NULL) 19399 rettv->vval.v_number = -1; 19400 else 19401 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 19402 } 19403 19404 /* 19405 * "strtrans()" function 19406 */ 19407 static void 19408 f_strtrans(typval_T *argvars, typval_T *rettv) 19409 { 19410 rettv->v_type = VAR_STRING; 19411 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 19412 } 19413 19414 /* 19415 * "submatch()" function 19416 */ 19417 static void 19418 f_submatch(typval_T *argvars, typval_T *rettv) 19419 { 19420 int error = FALSE; 19421 int no; 19422 int retList = 0; 19423 19424 no = (int)get_tv_number_chk(&argvars[0], &error); 19425 if (error) 19426 return; 19427 error = FALSE; 19428 if (argvars[1].v_type != VAR_UNKNOWN) 19429 retList = get_tv_number_chk(&argvars[1], &error); 19430 if (error) 19431 return; 19432 19433 if (retList == 0) 19434 { 19435 rettv->v_type = VAR_STRING; 19436 rettv->vval.v_string = reg_submatch(no); 19437 } 19438 else 19439 { 19440 rettv->v_type = VAR_LIST; 19441 rettv->vval.v_list = reg_submatch_list(no); 19442 } 19443 } 19444 19445 /* 19446 * "substitute()" function 19447 */ 19448 static void 19449 f_substitute(typval_T *argvars, typval_T *rettv) 19450 { 19451 char_u patbuf[NUMBUFLEN]; 19452 char_u subbuf[NUMBUFLEN]; 19453 char_u flagsbuf[NUMBUFLEN]; 19454 19455 char_u *str = get_tv_string_chk(&argvars[0]); 19456 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 19457 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 19458 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 19459 19460 rettv->v_type = VAR_STRING; 19461 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 19462 rettv->vval.v_string = NULL; 19463 else 19464 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 19465 } 19466 19467 /* 19468 * "synID(lnum, col, trans)" function 19469 */ 19470 static void 19471 f_synID(typval_T *argvars UNUSED, typval_T *rettv) 19472 { 19473 int id = 0; 19474 #ifdef FEAT_SYN_HL 19475 long lnum; 19476 long col; 19477 int trans; 19478 int transerr = FALSE; 19479 19480 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19481 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19482 trans = get_tv_number_chk(&argvars[2], &transerr); 19483 19484 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19485 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 19486 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 19487 #endif 19488 19489 rettv->vval.v_number = id; 19490 } 19491 19492 /* 19493 * "synIDattr(id, what [, mode])" function 19494 */ 19495 static void 19496 f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv) 19497 { 19498 char_u *p = NULL; 19499 #ifdef FEAT_SYN_HL 19500 int id; 19501 char_u *what; 19502 char_u *mode; 19503 char_u modebuf[NUMBUFLEN]; 19504 int modec; 19505 19506 id = get_tv_number(&argvars[0]); 19507 what = get_tv_string(&argvars[1]); 19508 if (argvars[2].v_type != VAR_UNKNOWN) 19509 { 19510 mode = get_tv_string_buf(&argvars[2], modebuf); 19511 modec = TOLOWER_ASC(mode[0]); 19512 if (modec != 't' && modec != 'c' && modec != 'g') 19513 modec = 0; /* replace invalid with current */ 19514 } 19515 else 19516 { 19517 #ifdef FEAT_GUI 19518 if (gui.in_use) 19519 modec = 'g'; 19520 else 19521 #endif 19522 if (t_colors > 1) 19523 modec = 'c'; 19524 else 19525 modec = 't'; 19526 } 19527 19528 19529 switch (TOLOWER_ASC(what[0])) 19530 { 19531 case 'b': 19532 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 19533 p = highlight_color(id, what, modec); 19534 else /* bold */ 19535 p = highlight_has_attr(id, HL_BOLD, modec); 19536 break; 19537 19538 case 'f': /* fg[#] or font */ 19539 p = highlight_color(id, what, modec); 19540 break; 19541 19542 case 'i': 19543 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 19544 p = highlight_has_attr(id, HL_INVERSE, modec); 19545 else /* italic */ 19546 p = highlight_has_attr(id, HL_ITALIC, modec); 19547 break; 19548 19549 case 'n': /* name */ 19550 p = get_highlight_name(NULL, id - 1); 19551 break; 19552 19553 case 'r': /* reverse */ 19554 p = highlight_has_attr(id, HL_INVERSE, modec); 19555 break; 19556 19557 case 's': 19558 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 19559 p = highlight_color(id, what, modec); 19560 else /* standout */ 19561 p = highlight_has_attr(id, HL_STANDOUT, modec); 19562 break; 19563 19564 case 'u': 19565 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 19566 /* underline */ 19567 p = highlight_has_attr(id, HL_UNDERLINE, modec); 19568 else 19569 /* undercurl */ 19570 p = highlight_has_attr(id, HL_UNDERCURL, modec); 19571 break; 19572 } 19573 19574 if (p != NULL) 19575 p = vim_strsave(p); 19576 #endif 19577 rettv->v_type = VAR_STRING; 19578 rettv->vval.v_string = p; 19579 } 19580 19581 /* 19582 * "synIDtrans(id)" function 19583 */ 19584 static void 19585 f_synIDtrans(typval_T *argvars UNUSED, typval_T *rettv) 19586 { 19587 int id; 19588 19589 #ifdef FEAT_SYN_HL 19590 id = get_tv_number(&argvars[0]); 19591 19592 if (id > 0) 19593 id = syn_get_final_id(id); 19594 else 19595 #endif 19596 id = 0; 19597 19598 rettv->vval.v_number = id; 19599 } 19600 19601 /* 19602 * "synconcealed(lnum, col)" function 19603 */ 19604 static void 19605 f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv) 19606 { 19607 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 19608 long lnum; 19609 long col; 19610 int syntax_flags = 0; 19611 int cchar; 19612 int matchid = 0; 19613 char_u str[NUMBUFLEN]; 19614 #endif 19615 19616 rettv->v_type = VAR_LIST; 19617 rettv->vval.v_list = NULL; 19618 19619 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 19620 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19621 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19622 19623 vim_memset(str, NUL, sizeof(str)); 19624 19625 if (rettv_list_alloc(rettv) != FAIL) 19626 { 19627 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19628 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 19629 && curwin->w_p_cole > 0) 19630 { 19631 (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE); 19632 syntax_flags = get_syntax_info(&matchid); 19633 19634 /* get the conceal character */ 19635 if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) 19636 { 19637 cchar = syn_get_sub_char(); 19638 if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL) 19639 cchar = lcs_conceal; 19640 if (cchar != NUL) 19641 { 19642 # ifdef FEAT_MBYTE 19643 if (has_mbyte) 19644 (*mb_char2bytes)(cchar, str); 19645 else 19646 # endif 19647 str[0] = cchar; 19648 } 19649 } 19650 } 19651 19652 list_append_number(rettv->vval.v_list, 19653 (syntax_flags & HL_CONCEAL) != 0); 19654 /* -1 to auto-determine strlen */ 19655 list_append_string(rettv->vval.v_list, str, -1); 19656 list_append_number(rettv->vval.v_list, matchid); 19657 } 19658 #endif 19659 } 19660 19661 /* 19662 * "synstack(lnum, col)" function 19663 */ 19664 static void 19665 f_synstack(typval_T *argvars UNUSED, typval_T *rettv) 19666 { 19667 #ifdef FEAT_SYN_HL 19668 long lnum; 19669 long col; 19670 int i; 19671 int id; 19672 #endif 19673 19674 rettv->v_type = VAR_LIST; 19675 rettv->vval.v_list = NULL; 19676 19677 #ifdef FEAT_SYN_HL 19678 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19679 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19680 19681 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19682 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 19683 && rettv_list_alloc(rettv) != FAIL) 19684 { 19685 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 19686 for (i = 0; ; ++i) 19687 { 19688 id = syn_get_stack_item(i); 19689 if (id < 0) 19690 break; 19691 if (list_append_number(rettv->vval.v_list, id) == FAIL) 19692 break; 19693 } 19694 } 19695 #endif 19696 } 19697 19698 static void 19699 get_cmd_output_as_rettv( 19700 typval_T *argvars, 19701 typval_T *rettv, 19702 int retlist) 19703 { 19704 char_u *res = NULL; 19705 char_u *p; 19706 char_u *infile = NULL; 19707 char_u buf[NUMBUFLEN]; 19708 int err = FALSE; 19709 FILE *fd; 19710 list_T *list = NULL; 19711 int flags = SHELL_SILENT; 19712 19713 rettv->v_type = VAR_STRING; 19714 rettv->vval.v_string = NULL; 19715 if (check_restricted() || check_secure()) 19716 goto errret; 19717 19718 if (argvars[1].v_type != VAR_UNKNOWN) 19719 { 19720 /* 19721 * Write the string to a temp file, to be used for input of the shell 19722 * command. 19723 */ 19724 if ((infile = vim_tempname('i', TRUE)) == NULL) 19725 { 19726 EMSG(_(e_notmp)); 19727 goto errret; 19728 } 19729 19730 fd = mch_fopen((char *)infile, WRITEBIN); 19731 if (fd == NULL) 19732 { 19733 EMSG2(_(e_notopen), infile); 19734 goto errret; 19735 } 19736 if (argvars[1].v_type == VAR_LIST) 19737 { 19738 if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL) 19739 err = TRUE; 19740 } 19741 else 19742 { 19743 size_t len; 19744 19745 p = get_tv_string_buf_chk(&argvars[1], buf); 19746 if (p == NULL) 19747 { 19748 fclose(fd); 19749 goto errret; /* type error; errmsg already given */ 19750 } 19751 len = STRLEN(p); 19752 if (len > 0 && fwrite(p, len, 1, fd) != 1) 19753 err = TRUE; 19754 } 19755 if (fclose(fd) != 0) 19756 err = TRUE; 19757 if (err) 19758 { 19759 EMSG(_("E677: Error writing temp file")); 19760 goto errret; 19761 } 19762 } 19763 19764 /* Omit SHELL_COOKED when invoked with ":silent". Avoids that the shell 19765 * echoes typeahead, that messes up the display. */ 19766 if (!msg_silent) 19767 flags += SHELL_COOKED; 19768 19769 if (retlist) 19770 { 19771 int len; 19772 listitem_T *li; 19773 char_u *s = NULL; 19774 char_u *start; 19775 char_u *end; 19776 int i; 19777 19778 res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, &len); 19779 if (res == NULL) 19780 goto errret; 19781 19782 list = list_alloc(); 19783 if (list == NULL) 19784 goto errret; 19785 19786 for (i = 0; i < len; ++i) 19787 { 19788 start = res + i; 19789 while (i < len && res[i] != NL) 19790 ++i; 19791 end = res + i; 19792 19793 s = alloc((unsigned)(end - start + 1)); 19794 if (s == NULL) 19795 goto errret; 19796 19797 for (p = s; start < end; ++p, ++start) 19798 *p = *start == NUL ? NL : *start; 19799 *p = NUL; 19800 19801 li = listitem_alloc(); 19802 if (li == NULL) 19803 { 19804 vim_free(s); 19805 goto errret; 19806 } 19807 li->li_tv.v_type = VAR_STRING; 19808 li->li_tv.v_lock = 0; 19809 li->li_tv.vval.v_string = s; 19810 list_append(list, li); 19811 } 19812 19813 ++list->lv_refcount; 19814 rettv->v_type = VAR_LIST; 19815 rettv->vval.v_list = list; 19816 list = NULL; 19817 } 19818 else 19819 { 19820 res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, NULL); 19821 #ifdef USE_CR 19822 /* translate <CR> into <NL> */ 19823 if (res != NULL) 19824 { 19825 char_u *s; 19826 19827 for (s = res; *s; ++s) 19828 { 19829 if (*s == CAR) 19830 *s = NL; 19831 } 19832 } 19833 #else 19834 # ifdef USE_CRNL 19835 /* translate <CR><NL> into <NL> */ 19836 if (res != NULL) 19837 { 19838 char_u *s, *d; 19839 19840 d = res; 19841 for (s = res; *s; ++s) 19842 { 19843 if (s[0] == CAR && s[1] == NL) 19844 ++s; 19845 *d++ = *s; 19846 } 19847 *d = NUL; 19848 } 19849 # endif 19850 #endif 19851 rettv->vval.v_string = res; 19852 res = NULL; 19853 } 19854 19855 errret: 19856 if (infile != NULL) 19857 { 19858 mch_remove(infile); 19859 vim_free(infile); 19860 } 19861 if (res != NULL) 19862 vim_free(res); 19863 if (list != NULL) 19864 list_free(list, TRUE); 19865 } 19866 19867 /* 19868 * "system()" function 19869 */ 19870 static void 19871 f_system(typval_T *argvars, typval_T *rettv) 19872 { 19873 get_cmd_output_as_rettv(argvars, rettv, FALSE); 19874 } 19875 19876 /* 19877 * "systemlist()" function 19878 */ 19879 static void 19880 f_systemlist(typval_T *argvars, typval_T *rettv) 19881 { 19882 get_cmd_output_as_rettv(argvars, rettv, TRUE); 19883 } 19884 19885 /* 19886 * "tabpagebuflist()" function 19887 */ 19888 static void 19889 f_tabpagebuflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 19890 { 19891 #ifdef FEAT_WINDOWS 19892 tabpage_T *tp; 19893 win_T *wp = NULL; 19894 19895 if (argvars[0].v_type == VAR_UNKNOWN) 19896 wp = firstwin; 19897 else 19898 { 19899 tp = find_tabpage((int)get_tv_number(&argvars[0])); 19900 if (tp != NULL) 19901 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 19902 } 19903 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 19904 { 19905 for (; wp != NULL; wp = wp->w_next) 19906 if (list_append_number(rettv->vval.v_list, 19907 wp->w_buffer->b_fnum) == FAIL) 19908 break; 19909 } 19910 #endif 19911 } 19912 19913 19914 /* 19915 * "tabpagenr()" function 19916 */ 19917 static void 19918 f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv) 19919 { 19920 int nr = 1; 19921 #ifdef FEAT_WINDOWS 19922 char_u *arg; 19923 19924 if (argvars[0].v_type != VAR_UNKNOWN) 19925 { 19926 arg = get_tv_string_chk(&argvars[0]); 19927 nr = 0; 19928 if (arg != NULL) 19929 { 19930 if (STRCMP(arg, "$") == 0) 19931 nr = tabpage_index(NULL) - 1; 19932 else 19933 EMSG2(_(e_invexpr2), arg); 19934 } 19935 } 19936 else 19937 nr = tabpage_index(curtab); 19938 #endif 19939 rettv->vval.v_number = nr; 19940 } 19941 19942 19943 #ifdef FEAT_WINDOWS 19944 static int get_winnr(tabpage_T *tp, typval_T *argvar); 19945 19946 /* 19947 * Common code for tabpagewinnr() and winnr(). 19948 */ 19949 static int 19950 get_winnr(tabpage_T *tp, typval_T *argvar) 19951 { 19952 win_T *twin; 19953 int nr = 1; 19954 win_T *wp; 19955 char_u *arg; 19956 19957 twin = (tp == curtab) ? curwin : tp->tp_curwin; 19958 if (argvar->v_type != VAR_UNKNOWN) 19959 { 19960 arg = get_tv_string_chk(argvar); 19961 if (arg == NULL) 19962 nr = 0; /* type error; errmsg already given */ 19963 else if (STRCMP(arg, "$") == 0) 19964 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 19965 else if (STRCMP(arg, "#") == 0) 19966 { 19967 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 19968 if (twin == NULL) 19969 nr = 0; 19970 } 19971 else 19972 { 19973 EMSG2(_(e_invexpr2), arg); 19974 nr = 0; 19975 } 19976 } 19977 19978 if (nr > 0) 19979 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 19980 wp != twin; wp = wp->w_next) 19981 { 19982 if (wp == NULL) 19983 { 19984 /* didn't find it in this tabpage */ 19985 nr = 0; 19986 break; 19987 } 19988 ++nr; 19989 } 19990 return nr; 19991 } 19992 #endif 19993 19994 /* 19995 * "tabpagewinnr()" function 19996 */ 19997 static void 19998 f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv) 19999 { 20000 int nr = 1; 20001 #ifdef FEAT_WINDOWS 20002 tabpage_T *tp; 20003 20004 tp = find_tabpage((int)get_tv_number(&argvars[0])); 20005 if (tp == NULL) 20006 nr = 0; 20007 else 20008 nr = get_winnr(tp, &argvars[1]); 20009 #endif 20010 rettv->vval.v_number = nr; 20011 } 20012 20013 20014 /* 20015 * "tagfiles()" function 20016 */ 20017 static void 20018 f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv) 20019 { 20020 char_u *fname; 20021 tagname_T tn; 20022 int first; 20023 20024 if (rettv_list_alloc(rettv) == FAIL) 20025 return; 20026 fname = alloc(MAXPATHL); 20027 if (fname == NULL) 20028 return; 20029 20030 for (first = TRUE; ; first = FALSE) 20031 if (get_tagfname(&tn, first, fname) == FAIL 20032 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 20033 break; 20034 tagname_free(&tn); 20035 vim_free(fname); 20036 } 20037 20038 /* 20039 * "taglist()" function 20040 */ 20041 static void 20042 f_taglist(typval_T *argvars, typval_T *rettv) 20043 { 20044 char_u *tag_pattern; 20045 20046 tag_pattern = get_tv_string(&argvars[0]); 20047 20048 rettv->vval.v_number = FALSE; 20049 if (*tag_pattern == NUL) 20050 return; 20051 20052 if (rettv_list_alloc(rettv) == OK) 20053 (void)get_tags(rettv->vval.v_list, tag_pattern); 20054 } 20055 20056 /* 20057 * "tempname()" function 20058 */ 20059 static void 20060 f_tempname(typval_T *argvars UNUSED, typval_T *rettv) 20061 { 20062 static int x = 'A'; 20063 20064 rettv->v_type = VAR_STRING; 20065 rettv->vval.v_string = vim_tempname(x, FALSE); 20066 20067 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 20068 * names. Skip 'I' and 'O', they are used for shell redirection. */ 20069 do 20070 { 20071 if (x == 'Z') 20072 x = '0'; 20073 else if (x == '9') 20074 x = 'A'; 20075 else 20076 { 20077 #ifdef EBCDIC 20078 if (x == 'I') 20079 x = 'J'; 20080 else if (x == 'R') 20081 x = 'S'; 20082 else 20083 #endif 20084 ++x; 20085 } 20086 } while (x == 'I' || x == 'O'); 20087 } 20088 20089 /* 20090 * "test(list)" function: Just checking the walls... 20091 */ 20092 static void 20093 f_test(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 20094 { 20095 /* Used for unit testing. Change the code below to your liking. */ 20096 #if 0 20097 listitem_T *li; 20098 list_T *l; 20099 char_u *bad, *good; 20100 20101 if (argvars[0].v_type != VAR_LIST) 20102 return; 20103 l = argvars[0].vval.v_list; 20104 if (l == NULL) 20105 return; 20106 li = l->lv_first; 20107 if (li == NULL) 20108 return; 20109 bad = get_tv_string(&li->li_tv); 20110 li = li->li_next; 20111 if (li == NULL) 20112 return; 20113 good = get_tv_string(&li->li_tv); 20114 rettv->vval.v_number = test_edit_score(bad, good); 20115 #endif 20116 } 20117 20118 #ifdef FEAT_FLOAT 20119 /* 20120 * "tan()" function 20121 */ 20122 static void 20123 f_tan(typval_T *argvars, typval_T *rettv) 20124 { 20125 float_T f = 0.0; 20126 20127 rettv->v_type = VAR_FLOAT; 20128 if (get_float_arg(argvars, &f) == OK) 20129 rettv->vval.v_float = tan(f); 20130 else 20131 rettv->vval.v_float = 0.0; 20132 } 20133 20134 /* 20135 * "tanh()" function 20136 */ 20137 static void 20138 f_tanh(typval_T *argvars, typval_T *rettv) 20139 { 20140 float_T f = 0.0; 20141 20142 rettv->v_type = VAR_FLOAT; 20143 if (get_float_arg(argvars, &f) == OK) 20144 rettv->vval.v_float = tanh(f); 20145 else 20146 rettv->vval.v_float = 0.0; 20147 } 20148 #endif 20149 20150 #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO) 20151 /* 20152 * Get a callback from "arg". It can be a Funcref or a function name. 20153 * When "arg" is zero return an empty string. 20154 * Return NULL for an invalid argument. 20155 */ 20156 char_u * 20157 get_callback(typval_T *arg, partial_T **pp) 20158 { 20159 if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) 20160 { 20161 *pp = arg->vval.v_partial; 20162 return (*pp)->pt_name; 20163 } 20164 *pp = NULL; 20165 if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) 20166 return arg->vval.v_string; 20167 if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) 20168 return (char_u *)""; 20169 EMSG(_("E921: Invalid callback argument")); 20170 return NULL; 20171 } 20172 #endif 20173 20174 #ifdef FEAT_TIMERS 20175 /* 20176 * "timer_start(time, callback [, options])" function 20177 */ 20178 static void 20179 f_timer_start(typval_T *argvars, typval_T *rettv) 20180 { 20181 long msec = get_tv_number(&argvars[0]); 20182 timer_T *timer; 20183 int repeat = 0; 20184 char_u *callback; 20185 dict_T *dict; 20186 20187 if (argvars[2].v_type != VAR_UNKNOWN) 20188 { 20189 if (argvars[2].v_type != VAR_DICT 20190 || (dict = argvars[2].vval.v_dict) == NULL) 20191 { 20192 EMSG2(_(e_invarg2), get_tv_string(&argvars[2])); 20193 return; 20194 } 20195 if (dict_find(dict, (char_u *)"repeat", -1) != NULL) 20196 repeat = get_dict_number(dict, (char_u *)"repeat"); 20197 } 20198 20199 timer = create_timer(msec, repeat); 20200 callback = get_callback(&argvars[1], &timer->tr_partial); 20201 if (callback == NULL) 20202 { 20203 stop_timer(timer); 20204 rettv->vval.v_number = -1; 20205 } 20206 else 20207 { 20208 timer->tr_callback = vim_strsave(callback); 20209 rettv->vval.v_number = timer->tr_id; 20210 } 20211 } 20212 20213 /* 20214 * "timer_stop(timer)" function 20215 */ 20216 static void 20217 f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED) 20218 { 20219 timer_T *timer = find_timer(get_tv_number(&argvars[0])); 20220 20221 if (timer != NULL) 20222 stop_timer(timer); 20223 } 20224 #endif 20225 20226 /* 20227 * "tolower(string)" function 20228 */ 20229 static void 20230 f_tolower(typval_T *argvars, typval_T *rettv) 20231 { 20232 char_u *p; 20233 20234 p = vim_strsave(get_tv_string(&argvars[0])); 20235 rettv->v_type = VAR_STRING; 20236 rettv->vval.v_string = p; 20237 20238 if (p != NULL) 20239 while (*p != NUL) 20240 { 20241 #ifdef FEAT_MBYTE 20242 int l; 20243 20244 if (enc_utf8) 20245 { 20246 int c, lc; 20247 20248 c = utf_ptr2char(p); 20249 lc = utf_tolower(c); 20250 l = utf_ptr2len(p); 20251 /* TODO: reallocate string when byte count changes. */ 20252 if (utf_char2len(lc) == l) 20253 utf_char2bytes(lc, p); 20254 p += l; 20255 } 20256 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 20257 p += l; /* skip multi-byte character */ 20258 else 20259 #endif 20260 { 20261 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 20262 ++p; 20263 } 20264 } 20265 } 20266 20267 /* 20268 * "toupper(string)" function 20269 */ 20270 static void 20271 f_toupper(typval_T *argvars, typval_T *rettv) 20272 { 20273 rettv->v_type = VAR_STRING; 20274 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 20275 } 20276 20277 /* 20278 * "tr(string, fromstr, tostr)" function 20279 */ 20280 static void 20281 f_tr(typval_T *argvars, typval_T *rettv) 20282 { 20283 char_u *in_str; 20284 char_u *fromstr; 20285 char_u *tostr; 20286 char_u *p; 20287 #ifdef FEAT_MBYTE 20288 int inlen; 20289 int fromlen; 20290 int tolen; 20291 int idx; 20292 char_u *cpstr; 20293 int cplen; 20294 int first = TRUE; 20295 #endif 20296 char_u buf[NUMBUFLEN]; 20297 char_u buf2[NUMBUFLEN]; 20298 garray_T ga; 20299 20300 in_str = get_tv_string(&argvars[0]); 20301 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 20302 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 20303 20304 /* Default return value: empty string. */ 20305 rettv->v_type = VAR_STRING; 20306 rettv->vval.v_string = NULL; 20307 if (fromstr == NULL || tostr == NULL) 20308 return; /* type error; errmsg already given */ 20309 ga_init2(&ga, (int)sizeof(char), 80); 20310 20311 #ifdef FEAT_MBYTE 20312 if (!has_mbyte) 20313 #endif 20314 /* not multi-byte: fromstr and tostr must be the same length */ 20315 if (STRLEN(fromstr) != STRLEN(tostr)) 20316 { 20317 #ifdef FEAT_MBYTE 20318 error: 20319 #endif 20320 EMSG2(_(e_invarg2), fromstr); 20321 ga_clear(&ga); 20322 return; 20323 } 20324 20325 /* fromstr and tostr have to contain the same number of chars */ 20326 while (*in_str != NUL) 20327 { 20328 #ifdef FEAT_MBYTE 20329 if (has_mbyte) 20330 { 20331 inlen = (*mb_ptr2len)(in_str); 20332 cpstr = in_str; 20333 cplen = inlen; 20334 idx = 0; 20335 for (p = fromstr; *p != NUL; p += fromlen) 20336 { 20337 fromlen = (*mb_ptr2len)(p); 20338 if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) 20339 { 20340 for (p = tostr; *p != NUL; p += tolen) 20341 { 20342 tolen = (*mb_ptr2len)(p); 20343 if (idx-- == 0) 20344 { 20345 cplen = tolen; 20346 cpstr = p; 20347 break; 20348 } 20349 } 20350 if (*p == NUL) /* tostr is shorter than fromstr */ 20351 goto error; 20352 break; 20353 } 20354 ++idx; 20355 } 20356 20357 if (first && cpstr == in_str) 20358 { 20359 /* Check that fromstr and tostr have the same number of 20360 * (multi-byte) characters. Done only once when a character 20361 * of in_str doesn't appear in fromstr. */ 20362 first = FALSE; 20363 for (p = tostr; *p != NUL; p += tolen) 20364 { 20365 tolen = (*mb_ptr2len)(p); 20366 --idx; 20367 } 20368 if (idx != 0) 20369 goto error; 20370 } 20371 20372 (void)ga_grow(&ga, cplen); 20373 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 20374 ga.ga_len += cplen; 20375 20376 in_str += inlen; 20377 } 20378 else 20379 #endif 20380 { 20381 /* When not using multi-byte chars we can do it faster. */ 20382 p = vim_strchr(fromstr, *in_str); 20383 if (p != NULL) 20384 ga_append(&ga, tostr[p - fromstr]); 20385 else 20386 ga_append(&ga, *in_str); 20387 ++in_str; 20388 } 20389 } 20390 20391 /* add a terminating NUL */ 20392 (void)ga_grow(&ga, 1); 20393 ga_append(&ga, NUL); 20394 20395 rettv->vval.v_string = ga.ga_data; 20396 } 20397 20398 #ifdef FEAT_FLOAT 20399 /* 20400 * "trunc({float})" function 20401 */ 20402 static void 20403 f_trunc(typval_T *argvars, typval_T *rettv) 20404 { 20405 float_T f = 0.0; 20406 20407 rettv->v_type = VAR_FLOAT; 20408 if (get_float_arg(argvars, &f) == OK) 20409 /* trunc() is not in C90, use floor() or ceil() instead. */ 20410 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 20411 else 20412 rettv->vval.v_float = 0.0; 20413 } 20414 #endif 20415 20416 /* 20417 * "type(expr)" function 20418 */ 20419 static void 20420 f_type(typval_T *argvars, typval_T *rettv) 20421 { 20422 int n = -1; 20423 20424 switch (argvars[0].v_type) 20425 { 20426 case VAR_NUMBER: n = 0; break; 20427 case VAR_STRING: n = 1; break; 20428 case VAR_PARTIAL: 20429 case VAR_FUNC: n = 2; break; 20430 case VAR_LIST: n = 3; break; 20431 case VAR_DICT: n = 4; break; 20432 case VAR_FLOAT: n = 5; break; 20433 case VAR_SPECIAL: 20434 if (argvars[0].vval.v_number == VVAL_FALSE 20435 || argvars[0].vval.v_number == VVAL_TRUE) 20436 n = 6; 20437 else 20438 n = 7; 20439 break; 20440 case VAR_JOB: n = 8; break; 20441 case VAR_CHANNEL: n = 9; break; 20442 case VAR_UNKNOWN: 20443 EMSG2(_(e_intern2), "f_type(UNKNOWN)"); 20444 n = -1; 20445 break; 20446 } 20447 rettv->vval.v_number = n; 20448 } 20449 20450 /* 20451 * "undofile(name)" function 20452 */ 20453 static void 20454 f_undofile(typval_T *argvars UNUSED, typval_T *rettv) 20455 { 20456 rettv->v_type = VAR_STRING; 20457 #ifdef FEAT_PERSISTENT_UNDO 20458 { 20459 char_u *fname = get_tv_string(&argvars[0]); 20460 20461 if (*fname == NUL) 20462 { 20463 /* If there is no file name there will be no undo file. */ 20464 rettv->vval.v_string = NULL; 20465 } 20466 else 20467 { 20468 char_u *ffname = FullName_save(fname, FALSE); 20469 20470 if (ffname != NULL) 20471 rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); 20472 vim_free(ffname); 20473 } 20474 } 20475 #else 20476 rettv->vval.v_string = NULL; 20477 #endif 20478 } 20479 20480 /* 20481 * "undotree()" function 20482 */ 20483 static void 20484 f_undotree(typval_T *argvars UNUSED, typval_T *rettv) 20485 { 20486 if (rettv_dict_alloc(rettv) == OK) 20487 { 20488 dict_T *dict = rettv->vval.v_dict; 20489 list_T *list; 20490 20491 dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL); 20492 dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL); 20493 dict_add_nr_str(dict, "save_last", 20494 (long)curbuf->b_u_save_nr_last, NULL); 20495 dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL); 20496 dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL); 20497 dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL); 20498 20499 list = list_alloc(); 20500 if (list != NULL) 20501 { 20502 u_eval_tree(curbuf->b_u_oldhead, list); 20503 dict_add_list(dict, "entries", list); 20504 } 20505 } 20506 } 20507 20508 /* 20509 * "values(dict)" function 20510 */ 20511 static void 20512 f_values(typval_T *argvars, typval_T *rettv) 20513 { 20514 dict_list(argvars, rettv, 1); 20515 } 20516 20517 /* 20518 * "virtcol(string)" function 20519 */ 20520 static void 20521 f_virtcol(typval_T *argvars, typval_T *rettv) 20522 { 20523 colnr_T vcol = 0; 20524 pos_T *fp; 20525 int fnum = curbuf->b_fnum; 20526 20527 fp = var2fpos(&argvars[0], FALSE, &fnum); 20528 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 20529 && fnum == curbuf->b_fnum) 20530 { 20531 getvvcol(curwin, fp, NULL, NULL, &vcol); 20532 ++vcol; 20533 } 20534 20535 rettv->vval.v_number = vcol; 20536 } 20537 20538 /* 20539 * "visualmode()" function 20540 */ 20541 static void 20542 f_visualmode(typval_T *argvars, typval_T *rettv) 20543 { 20544 char_u str[2]; 20545 20546 rettv->v_type = VAR_STRING; 20547 str[0] = curbuf->b_visual_mode_eval; 20548 str[1] = NUL; 20549 rettv->vval.v_string = vim_strsave(str); 20550 20551 /* A non-zero number or non-empty string argument: reset mode. */ 20552 if (non_zero_arg(&argvars[0])) 20553 curbuf->b_visual_mode_eval = NUL; 20554 } 20555 20556 /* 20557 * "wildmenumode()" function 20558 */ 20559 static void 20560 f_wildmenumode(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 20561 { 20562 #ifdef FEAT_WILDMENU 20563 if (wild_menu_showing) 20564 rettv->vval.v_number = 1; 20565 #endif 20566 } 20567 20568 /* 20569 * "winbufnr(nr)" function 20570 */ 20571 static void 20572 f_winbufnr(typval_T *argvars, typval_T *rettv) 20573 { 20574 win_T *wp; 20575 20576 wp = find_win_by_nr(&argvars[0], NULL); 20577 if (wp == NULL) 20578 rettv->vval.v_number = -1; 20579 else 20580 rettv->vval.v_number = wp->w_buffer->b_fnum; 20581 } 20582 20583 /* 20584 * "wincol()" function 20585 */ 20586 static void 20587 f_wincol(typval_T *argvars UNUSED, typval_T *rettv) 20588 { 20589 validate_cursor(); 20590 rettv->vval.v_number = curwin->w_wcol + 1; 20591 } 20592 20593 /* 20594 * "winheight(nr)" function 20595 */ 20596 static void 20597 f_winheight(typval_T *argvars, typval_T *rettv) 20598 { 20599 win_T *wp; 20600 20601 wp = find_win_by_nr(&argvars[0], NULL); 20602 if (wp == NULL) 20603 rettv->vval.v_number = -1; 20604 else 20605 rettv->vval.v_number = wp->w_height; 20606 } 20607 20608 /* 20609 * "winline()" function 20610 */ 20611 static void 20612 f_winline(typval_T *argvars UNUSED, typval_T *rettv) 20613 { 20614 validate_cursor(); 20615 rettv->vval.v_number = curwin->w_wrow + 1; 20616 } 20617 20618 /* 20619 * "winnr()" function 20620 */ 20621 static void 20622 f_winnr(typval_T *argvars UNUSED, typval_T *rettv) 20623 { 20624 int nr = 1; 20625 20626 #ifdef FEAT_WINDOWS 20627 nr = get_winnr(curtab, &argvars[0]); 20628 #endif 20629 rettv->vval.v_number = nr; 20630 } 20631 20632 /* 20633 * "winrestcmd()" function 20634 */ 20635 static void 20636 f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv) 20637 { 20638 #ifdef FEAT_WINDOWS 20639 win_T *wp; 20640 int winnr = 1; 20641 garray_T ga; 20642 char_u buf[50]; 20643 20644 ga_init2(&ga, (int)sizeof(char), 70); 20645 for (wp = firstwin; wp != NULL; wp = wp->w_next) 20646 { 20647 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 20648 ga_concat(&ga, buf); 20649 # ifdef FEAT_VERTSPLIT 20650 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 20651 ga_concat(&ga, buf); 20652 # endif 20653 ++winnr; 20654 } 20655 ga_append(&ga, NUL); 20656 20657 rettv->vval.v_string = ga.ga_data; 20658 #else 20659 rettv->vval.v_string = NULL; 20660 #endif 20661 rettv->v_type = VAR_STRING; 20662 } 20663 20664 /* 20665 * "winrestview()" function 20666 */ 20667 static void 20668 f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) 20669 { 20670 dict_T *dict; 20671 20672 if (argvars[0].v_type != VAR_DICT 20673 || (dict = argvars[0].vval.v_dict) == NULL) 20674 EMSG(_(e_invarg)); 20675 else 20676 { 20677 if (dict_find(dict, (char_u *)"lnum", -1) != NULL) 20678 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 20679 if (dict_find(dict, (char_u *)"col", -1) != NULL) 20680 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 20681 #ifdef FEAT_VIRTUALEDIT 20682 if (dict_find(dict, (char_u *)"coladd", -1) != NULL) 20683 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 20684 #endif 20685 if (dict_find(dict, (char_u *)"curswant", -1) != NULL) 20686 { 20687 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 20688 curwin->w_set_curswant = FALSE; 20689 } 20690 20691 if (dict_find(dict, (char_u *)"topline", -1) != NULL) 20692 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 20693 #ifdef FEAT_DIFF 20694 if (dict_find(dict, (char_u *)"topfill", -1) != NULL) 20695 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 20696 #endif 20697 if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) 20698 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 20699 if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) 20700 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 20701 20702 check_cursor(); 20703 win_new_height(curwin, curwin->w_height); 20704 # ifdef FEAT_VERTSPLIT 20705 win_new_width(curwin, W_WIDTH(curwin)); 20706 # endif 20707 changed_window_setting(); 20708 20709 if (curwin->w_topline <= 0) 20710 curwin->w_topline = 1; 20711 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 20712 curwin->w_topline = curbuf->b_ml.ml_line_count; 20713 #ifdef FEAT_DIFF 20714 check_topfill(curwin, TRUE); 20715 #endif 20716 } 20717 } 20718 20719 /* 20720 * "winsaveview()" function 20721 */ 20722 static void 20723 f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv) 20724 { 20725 dict_T *dict; 20726 20727 if (rettv_dict_alloc(rettv) == FAIL) 20728 return; 20729 dict = rettv->vval.v_dict; 20730 20731 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 20732 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 20733 #ifdef FEAT_VIRTUALEDIT 20734 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 20735 #endif 20736 update_curswant(); 20737 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 20738 20739 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 20740 #ifdef FEAT_DIFF 20741 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 20742 #endif 20743 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 20744 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 20745 } 20746 20747 /* 20748 * "winwidth(nr)" function 20749 */ 20750 static void 20751 f_winwidth(typval_T *argvars, typval_T *rettv) 20752 { 20753 win_T *wp; 20754 20755 wp = find_win_by_nr(&argvars[0], NULL); 20756 if (wp == NULL) 20757 rettv->vval.v_number = -1; 20758 else 20759 #ifdef FEAT_VERTSPLIT 20760 rettv->vval.v_number = wp->w_width; 20761 #else 20762 rettv->vval.v_number = Columns; 20763 #endif 20764 } 20765 20766 /* 20767 * "wordcount()" function 20768 */ 20769 static void 20770 f_wordcount(typval_T *argvars UNUSED, typval_T *rettv) 20771 { 20772 if (rettv_dict_alloc(rettv) == FAIL) 20773 return; 20774 cursor_pos_info(rettv->vval.v_dict); 20775 } 20776 20777 /* 20778 * Write list of strings to file 20779 */ 20780 static int 20781 write_list(FILE *fd, list_T *list, int binary) 20782 { 20783 listitem_T *li; 20784 int c; 20785 int ret = OK; 20786 char_u *s; 20787 20788 for (li = list->lv_first; li != NULL; li = li->li_next) 20789 { 20790 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 20791 { 20792 if (*s == '\n') 20793 c = putc(NUL, fd); 20794 else 20795 c = putc(*s, fd); 20796 if (c == EOF) 20797 { 20798 ret = FAIL; 20799 break; 20800 } 20801 } 20802 if (!binary || li->li_next != NULL) 20803 if (putc('\n', fd) == EOF) 20804 { 20805 ret = FAIL; 20806 break; 20807 } 20808 if (ret == FAIL) 20809 { 20810 EMSG(_(e_write)); 20811 break; 20812 } 20813 } 20814 return ret; 20815 } 20816 20817 /* 20818 * "writefile()" function 20819 */ 20820 static void 20821 f_writefile(typval_T *argvars, typval_T *rettv) 20822 { 20823 int binary = FALSE; 20824 int append = FALSE; 20825 char_u *fname; 20826 FILE *fd; 20827 int ret = 0; 20828 20829 if (check_restricted() || check_secure()) 20830 return; 20831 20832 if (argvars[0].v_type != VAR_LIST) 20833 { 20834 EMSG2(_(e_listarg), "writefile()"); 20835 return; 20836 } 20837 if (argvars[0].vval.v_list == NULL) 20838 return; 20839 20840 if (argvars[2].v_type != VAR_UNKNOWN) 20841 { 20842 if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL) 20843 binary = TRUE; 20844 if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL) 20845 append = TRUE; 20846 } 20847 20848 /* Always open the file in binary mode, library functions have a mind of 20849 * their own about CR-LF conversion. */ 20850 fname = get_tv_string(&argvars[1]); 20851 if (*fname == NUL || (fd = mch_fopen((char *)fname, 20852 append ? APPENDBIN : WRITEBIN)) == NULL) 20853 { 20854 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 20855 ret = -1; 20856 } 20857 else 20858 { 20859 if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL) 20860 ret = -1; 20861 fclose(fd); 20862 } 20863 20864 rettv->vval.v_number = ret; 20865 } 20866 20867 /* 20868 * "xor(expr, expr)" function 20869 */ 20870 static void 20871 f_xor(typval_T *argvars, typval_T *rettv) 20872 { 20873 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 20874 ^ get_tv_number_chk(&argvars[1], NULL); 20875 } 20876 20877 20878 /* 20879 * Translate a String variable into a position. 20880 * Returns NULL when there is an error. 20881 */ 20882 static pos_T * 20883 var2fpos( 20884 typval_T *varp, 20885 int dollar_lnum, /* TRUE when $ is last line */ 20886 int *fnum) /* set to fnum for '0, 'A, etc. */ 20887 { 20888 char_u *name; 20889 static pos_T pos; 20890 pos_T *pp; 20891 20892 /* Argument can be [lnum, col, coladd]. */ 20893 if (varp->v_type == VAR_LIST) 20894 { 20895 list_T *l; 20896 int len; 20897 int error = FALSE; 20898 listitem_T *li; 20899 20900 l = varp->vval.v_list; 20901 if (l == NULL) 20902 return NULL; 20903 20904 /* Get the line number */ 20905 pos.lnum = list_find_nr(l, 0L, &error); 20906 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 20907 return NULL; /* invalid line number */ 20908 20909 /* Get the column number */ 20910 pos.col = list_find_nr(l, 1L, &error); 20911 if (error) 20912 return NULL; 20913 len = (long)STRLEN(ml_get(pos.lnum)); 20914 20915 /* We accept "$" for the column number: last column. */ 20916 li = list_find(l, 1L); 20917 if (li != NULL && li->li_tv.v_type == VAR_STRING 20918 && li->li_tv.vval.v_string != NULL 20919 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 20920 pos.col = len + 1; 20921 20922 /* Accept a position up to the NUL after the line. */ 20923 if (pos.col == 0 || (int)pos.col > len + 1) 20924 return NULL; /* invalid column number */ 20925 --pos.col; 20926 20927 #ifdef FEAT_VIRTUALEDIT 20928 /* Get the virtual offset. Defaults to zero. */ 20929 pos.coladd = list_find_nr(l, 2L, &error); 20930 if (error) 20931 pos.coladd = 0; 20932 #endif 20933 20934 return &pos; 20935 } 20936 20937 name = get_tv_string_chk(varp); 20938 if (name == NULL) 20939 return NULL; 20940 if (name[0] == '.') /* cursor */ 20941 return &curwin->w_cursor; 20942 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 20943 { 20944 if (VIsual_active) 20945 return &VIsual; 20946 return &curwin->w_cursor; 20947 } 20948 if (name[0] == '\'') /* mark */ 20949 { 20950 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); 20951 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 20952 return NULL; 20953 return pp; 20954 } 20955 20956 #ifdef FEAT_VIRTUALEDIT 20957 pos.coladd = 0; 20958 #endif 20959 20960 if (name[0] == 'w' && dollar_lnum) 20961 { 20962 pos.col = 0; 20963 if (name[1] == '0') /* "w0": first visible line */ 20964 { 20965 update_topline(); 20966 pos.lnum = curwin->w_topline; 20967 return &pos; 20968 } 20969 else if (name[1] == '$') /* "w$": last visible line */ 20970 { 20971 validate_botline(); 20972 pos.lnum = curwin->w_botline - 1; 20973 return &pos; 20974 } 20975 } 20976 else if (name[0] == '$') /* last column or line */ 20977 { 20978 if (dollar_lnum) 20979 { 20980 pos.lnum = curbuf->b_ml.ml_line_count; 20981 pos.col = 0; 20982 } 20983 else 20984 { 20985 pos.lnum = curwin->w_cursor.lnum; 20986 pos.col = (colnr_T)STRLEN(ml_get_curline()); 20987 } 20988 return &pos; 20989 } 20990 return NULL; 20991 } 20992 20993 /* 20994 * Convert list in "arg" into a position and optional file number. 20995 * When "fnump" is NULL there is no file number, only 3 items. 20996 * Note that the column is passed on as-is, the caller may want to decrement 20997 * it to use 1 for the first column. 20998 * Return FAIL when conversion is not possible, doesn't check the position for 20999 * validity. 21000 */ 21001 static int 21002 list2fpos( 21003 typval_T *arg, 21004 pos_T *posp, 21005 int *fnump, 21006 colnr_T *curswantp) 21007 { 21008 list_T *l = arg->vval.v_list; 21009 long i = 0; 21010 long n; 21011 21012 /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only 21013 * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */ 21014 if (arg->v_type != VAR_LIST 21015 || l == NULL 21016 || l->lv_len < (fnump == NULL ? 2 : 3) 21017 || l->lv_len > (fnump == NULL ? 4 : 5)) 21018 return FAIL; 21019 21020 if (fnump != NULL) 21021 { 21022 n = list_find_nr(l, i++, NULL); /* fnum */ 21023 if (n < 0) 21024 return FAIL; 21025 if (n == 0) 21026 n = curbuf->b_fnum; /* current buffer */ 21027 *fnump = n; 21028 } 21029 21030 n = list_find_nr(l, i++, NULL); /* lnum */ 21031 if (n < 0) 21032 return FAIL; 21033 posp->lnum = n; 21034 21035 n = list_find_nr(l, i++, NULL); /* col */ 21036 if (n < 0) 21037 return FAIL; 21038 posp->col = n; 21039 21040 #ifdef FEAT_VIRTUALEDIT 21041 n = list_find_nr(l, i, NULL); /* off */ 21042 if (n < 0) 21043 posp->coladd = 0; 21044 else 21045 posp->coladd = n; 21046 #endif 21047 21048 if (curswantp != NULL) 21049 *curswantp = list_find_nr(l, i + 1, NULL); /* curswant */ 21050 21051 return OK; 21052 } 21053 21054 /* 21055 * Get the length of an environment variable name. 21056 * Advance "arg" to the first character after the name. 21057 * Return 0 for error. 21058 */ 21059 static int 21060 get_env_len(char_u **arg) 21061 { 21062 char_u *p; 21063 int len; 21064 21065 for (p = *arg; vim_isIDc(*p); ++p) 21066 ; 21067 if (p == *arg) /* no name found */ 21068 return 0; 21069 21070 len = (int)(p - *arg); 21071 *arg = p; 21072 return len; 21073 } 21074 21075 /* 21076 * Get the length of the name of a function or internal variable. 21077 * "arg" is advanced to the first non-white character after the name. 21078 * Return 0 if something is wrong. 21079 */ 21080 static int 21081 get_id_len(char_u **arg) 21082 { 21083 char_u *p; 21084 int len; 21085 21086 /* Find the end of the name. */ 21087 for (p = *arg; eval_isnamec(*p); ++p) 21088 { 21089 if (*p == ':') 21090 { 21091 /* "s:" is start of "s:var", but "n:" is not and can be used in 21092 * slice "[n:]". Also "xx:" is not a namespace. */ 21093 len = (int)(p - *arg); 21094 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL) 21095 || len > 1) 21096 break; 21097 } 21098 } 21099 if (p == *arg) /* no name found */ 21100 return 0; 21101 21102 len = (int)(p - *arg); 21103 *arg = skipwhite(p); 21104 21105 return len; 21106 } 21107 21108 /* 21109 * Get the length of the name of a variable or function. 21110 * Only the name is recognized, does not handle ".key" or "[idx]". 21111 * "arg" is advanced to the first non-white character after the name. 21112 * Return -1 if curly braces expansion failed. 21113 * Return 0 if something else is wrong. 21114 * If the name contains 'magic' {}'s, expand them and return the 21115 * expanded name in an allocated string via 'alias' - caller must free. 21116 */ 21117 static int 21118 get_name_len( 21119 char_u **arg, 21120 char_u **alias, 21121 int evaluate, 21122 int verbose) 21123 { 21124 int len; 21125 char_u *p; 21126 char_u *expr_start; 21127 char_u *expr_end; 21128 21129 *alias = NULL; /* default to no alias */ 21130 21131 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 21132 && (*arg)[2] == (int)KE_SNR) 21133 { 21134 /* hard coded <SNR>, already translated */ 21135 *arg += 3; 21136 return get_id_len(arg) + 3; 21137 } 21138 len = eval_fname_script(*arg); 21139 if (len > 0) 21140 { 21141 /* literal "<SID>", "s:" or "<SNR>" */ 21142 *arg += len; 21143 } 21144 21145 /* 21146 * Find the end of the name; check for {} construction. 21147 */ 21148 p = find_name_end(*arg, &expr_start, &expr_end, 21149 len > 0 ? 0 : FNE_CHECK_START); 21150 if (expr_start != NULL) 21151 { 21152 char_u *temp_string; 21153 21154 if (!evaluate) 21155 { 21156 len += (int)(p - *arg); 21157 *arg = skipwhite(p); 21158 return len; 21159 } 21160 21161 /* 21162 * Include any <SID> etc in the expanded string: 21163 * Thus the -len here. 21164 */ 21165 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 21166 if (temp_string == NULL) 21167 return -1; 21168 *alias = temp_string; 21169 *arg = skipwhite(p); 21170 return (int)STRLEN(temp_string); 21171 } 21172 21173 len += get_id_len(arg); 21174 if (len == 0 && verbose) 21175 EMSG2(_(e_invexpr2), *arg); 21176 21177 return len; 21178 } 21179 21180 /* 21181 * Find the end of a variable or function name, taking care of magic braces. 21182 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 21183 * start and end of the first magic braces item. 21184 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 21185 * Return a pointer to just after the name. Equal to "arg" if there is no 21186 * valid name. 21187 */ 21188 static char_u * 21189 find_name_end( 21190 char_u *arg, 21191 char_u **expr_start, 21192 char_u **expr_end, 21193 int flags) 21194 { 21195 int mb_nest = 0; 21196 int br_nest = 0; 21197 char_u *p; 21198 int len; 21199 21200 if (expr_start != NULL) 21201 { 21202 *expr_start = NULL; 21203 *expr_end = NULL; 21204 } 21205 21206 /* Quick check for valid starting character. */ 21207 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 21208 return arg; 21209 21210 for (p = arg; *p != NUL 21211 && (eval_isnamec(*p) 21212 || *p == '{' 21213 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 21214 || mb_nest != 0 21215 || br_nest != 0); mb_ptr_adv(p)) 21216 { 21217 if (*p == '\'') 21218 { 21219 /* skip over 'string' to avoid counting [ and ] inside it. */ 21220 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 21221 ; 21222 if (*p == NUL) 21223 break; 21224 } 21225 else if (*p == '"') 21226 { 21227 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 21228 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 21229 if (*p == '\\' && p[1] != NUL) 21230 ++p; 21231 if (*p == NUL) 21232 break; 21233 } 21234 else if (br_nest == 0 && mb_nest == 0 && *p == ':') 21235 { 21236 /* "s:" is start of "s:var", but "n:" is not and can be used in 21237 * slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. */ 21238 len = (int)(p - arg); 21239 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL) 21240 || (len > 1 && p[-1] != '}')) 21241 break; 21242 } 21243 21244 if (mb_nest == 0) 21245 { 21246 if (*p == '[') 21247 ++br_nest; 21248 else if (*p == ']') 21249 --br_nest; 21250 } 21251 21252 if (br_nest == 0) 21253 { 21254 if (*p == '{') 21255 { 21256 mb_nest++; 21257 if (expr_start != NULL && *expr_start == NULL) 21258 *expr_start = p; 21259 } 21260 else if (*p == '}') 21261 { 21262 mb_nest--; 21263 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 21264 *expr_end = p; 21265 } 21266 } 21267 } 21268 21269 return p; 21270 } 21271 21272 /* 21273 * Expands out the 'magic' {}'s in a variable/function name. 21274 * Note that this can call itself recursively, to deal with 21275 * constructs like foo{bar}{baz}{bam} 21276 * The four pointer arguments point to "foo{expre}ss{ion}bar" 21277 * "in_start" ^ 21278 * "expr_start" ^ 21279 * "expr_end" ^ 21280 * "in_end" ^ 21281 * 21282 * Returns a new allocated string, which the caller must free. 21283 * Returns NULL for failure. 21284 */ 21285 static char_u * 21286 make_expanded_name( 21287 char_u *in_start, 21288 char_u *expr_start, 21289 char_u *expr_end, 21290 char_u *in_end) 21291 { 21292 char_u c1; 21293 char_u *retval = NULL; 21294 char_u *temp_result; 21295 char_u *nextcmd = NULL; 21296 21297 if (expr_end == NULL || in_end == NULL) 21298 return NULL; 21299 *expr_start = NUL; 21300 *expr_end = NUL; 21301 c1 = *in_end; 21302 *in_end = NUL; 21303 21304 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 21305 if (temp_result != NULL && nextcmd == NULL) 21306 { 21307 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 21308 + (in_end - expr_end) + 1)); 21309 if (retval != NULL) 21310 { 21311 STRCPY(retval, in_start); 21312 STRCAT(retval, temp_result); 21313 STRCAT(retval, expr_end + 1); 21314 } 21315 } 21316 vim_free(temp_result); 21317 21318 *in_end = c1; /* put char back for error messages */ 21319 *expr_start = '{'; 21320 *expr_end = '}'; 21321 21322 if (retval != NULL) 21323 { 21324 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 21325 if (expr_start != NULL) 21326 { 21327 /* Further expansion! */ 21328 temp_result = make_expanded_name(retval, expr_start, 21329 expr_end, temp_result); 21330 vim_free(retval); 21331 retval = temp_result; 21332 } 21333 } 21334 21335 return retval; 21336 } 21337 21338 /* 21339 * Return TRUE if character "c" can be used in a variable or function name. 21340 * Does not include '{' or '}' for magic braces. 21341 */ 21342 static int 21343 eval_isnamec(int c) 21344 { 21345 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 21346 } 21347 21348 /* 21349 * Return TRUE if character "c" can be used as the first character in a 21350 * variable or function name (excluding '{' and '}'). 21351 */ 21352 static int 21353 eval_isnamec1(int c) 21354 { 21355 return (ASCII_ISALPHA(c) || c == '_'); 21356 } 21357 21358 /* 21359 * Set number v: variable to "val". 21360 */ 21361 void 21362 set_vim_var_nr(int idx, long val) 21363 { 21364 vimvars[idx].vv_nr = val; 21365 } 21366 21367 /* 21368 * Get number v: variable value. 21369 */ 21370 long 21371 get_vim_var_nr(int idx) 21372 { 21373 return vimvars[idx].vv_nr; 21374 } 21375 21376 /* 21377 * Get string v: variable value. Uses a static buffer, can only be used once. 21378 */ 21379 char_u * 21380 get_vim_var_str(int idx) 21381 { 21382 return get_tv_string(&vimvars[idx].vv_tv); 21383 } 21384 21385 /* 21386 * Get List v: variable value. Caller must take care of reference count when 21387 * needed. 21388 */ 21389 list_T * 21390 get_vim_var_list(int idx) 21391 { 21392 return vimvars[idx].vv_list; 21393 } 21394 21395 /* 21396 * Set v:char to character "c". 21397 */ 21398 void 21399 set_vim_var_char(int c) 21400 { 21401 char_u buf[MB_MAXBYTES + 1]; 21402 21403 #ifdef FEAT_MBYTE 21404 if (has_mbyte) 21405 buf[(*mb_char2bytes)(c, buf)] = NUL; 21406 else 21407 #endif 21408 { 21409 buf[0] = c; 21410 buf[1] = NUL; 21411 } 21412 set_vim_var_string(VV_CHAR, buf, -1); 21413 } 21414 21415 /* 21416 * Set v:count to "count" and v:count1 to "count1". 21417 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 21418 */ 21419 void 21420 set_vcount( 21421 long count, 21422 long count1, 21423 int set_prevcount) 21424 { 21425 if (set_prevcount) 21426 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 21427 vimvars[VV_COUNT].vv_nr = count; 21428 vimvars[VV_COUNT1].vv_nr = count1; 21429 } 21430 21431 /* 21432 * Set string v: variable to a copy of "val". 21433 */ 21434 void 21435 set_vim_var_string( 21436 int idx, 21437 char_u *val, 21438 int len) /* length of "val" to use or -1 (whole string) */ 21439 { 21440 clear_tv(&vimvars[idx].vv_di.di_tv); 21441 vimvars[idx].vv_type = VAR_STRING; 21442 if (val == NULL) 21443 vimvars[idx].vv_str = NULL; 21444 else if (len == -1) 21445 vimvars[idx].vv_str = vim_strsave(val); 21446 else 21447 vimvars[idx].vv_str = vim_strnsave(val, len); 21448 } 21449 21450 /* 21451 * Set List v: variable to "val". 21452 */ 21453 void 21454 set_vim_var_list(int idx, list_T *val) 21455 { 21456 clear_tv(&vimvars[idx].vv_di.di_tv); 21457 vimvars[idx].vv_type = VAR_LIST; 21458 vimvars[idx].vv_list = val; 21459 if (val != NULL) 21460 ++val->lv_refcount; 21461 } 21462 21463 /* 21464 * Set Dictionary v: variable to "val". 21465 */ 21466 void 21467 set_vim_var_dict(int idx, dict_T *val) 21468 { 21469 int todo; 21470 hashitem_T *hi; 21471 21472 clear_tv(&vimvars[idx].vv_di.di_tv); 21473 vimvars[idx].vv_type = VAR_DICT; 21474 vimvars[idx].vv_dict = val; 21475 if (val != NULL) 21476 { 21477 ++val->dv_refcount; 21478 21479 /* Set readonly */ 21480 todo = (int)val->dv_hashtab.ht_used; 21481 for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) 21482 { 21483 if (HASHITEM_EMPTY(hi)) 21484 continue; 21485 --todo; 21486 HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21487 } 21488 } 21489 } 21490 21491 /* 21492 * Set v:register if needed. 21493 */ 21494 void 21495 set_reg_var(int c) 21496 { 21497 char_u regname; 21498 21499 if (c == 0 || c == ' ') 21500 regname = '"'; 21501 else 21502 regname = c; 21503 /* Avoid free/alloc when the value is already right. */ 21504 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 21505 set_vim_var_string(VV_REG, ®name, 1); 21506 } 21507 21508 /* 21509 * Get or set v:exception. If "oldval" == NULL, return the current value. 21510 * Otherwise, restore the value to "oldval" and return NULL. 21511 * Must always be called in pairs to save and restore v:exception! Does not 21512 * take care of memory allocations. 21513 */ 21514 char_u * 21515 v_exception(char_u *oldval) 21516 { 21517 if (oldval == NULL) 21518 return vimvars[VV_EXCEPTION].vv_str; 21519 21520 vimvars[VV_EXCEPTION].vv_str = oldval; 21521 return NULL; 21522 } 21523 21524 /* 21525 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 21526 * Otherwise, restore the value to "oldval" and return NULL. 21527 * Must always be called in pairs to save and restore v:throwpoint! Does not 21528 * take care of memory allocations. 21529 */ 21530 char_u * 21531 v_throwpoint(char_u *oldval) 21532 { 21533 if (oldval == NULL) 21534 return vimvars[VV_THROWPOINT].vv_str; 21535 21536 vimvars[VV_THROWPOINT].vv_str = oldval; 21537 return NULL; 21538 } 21539 21540 #if defined(FEAT_AUTOCMD) || defined(PROTO) 21541 /* 21542 * Set v:cmdarg. 21543 * If "eap" != NULL, use "eap" to generate the value and return the old value. 21544 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 21545 * Must always be called in pairs! 21546 */ 21547 char_u * 21548 set_cmdarg(exarg_T *eap, char_u *oldarg) 21549 { 21550 char_u *oldval; 21551 char_u *newval; 21552 unsigned len; 21553 21554 oldval = vimvars[VV_CMDARG].vv_str; 21555 if (eap == NULL) 21556 { 21557 vim_free(oldval); 21558 vimvars[VV_CMDARG].vv_str = oldarg; 21559 return NULL; 21560 } 21561 21562 if (eap->force_bin == FORCE_BIN) 21563 len = 6; 21564 else if (eap->force_bin == FORCE_NOBIN) 21565 len = 8; 21566 else 21567 len = 0; 21568 21569 if (eap->read_edit) 21570 len += 7; 21571 21572 if (eap->force_ff != 0) 21573 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 21574 # ifdef FEAT_MBYTE 21575 if (eap->force_enc != 0) 21576 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 21577 if (eap->bad_char != 0) 21578 len += 7 + 4; /* " ++bad=" + "keep" or "drop" */ 21579 # endif 21580 21581 newval = alloc(len + 1); 21582 if (newval == NULL) 21583 return NULL; 21584 21585 if (eap->force_bin == FORCE_BIN) 21586 sprintf((char *)newval, " ++bin"); 21587 else if (eap->force_bin == FORCE_NOBIN) 21588 sprintf((char *)newval, " ++nobin"); 21589 else 21590 *newval = NUL; 21591 21592 if (eap->read_edit) 21593 STRCAT(newval, " ++edit"); 21594 21595 if (eap->force_ff != 0) 21596 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 21597 eap->cmd + eap->force_ff); 21598 # ifdef FEAT_MBYTE 21599 if (eap->force_enc != 0) 21600 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 21601 eap->cmd + eap->force_enc); 21602 if (eap->bad_char == BAD_KEEP) 21603 STRCPY(newval + STRLEN(newval), " ++bad=keep"); 21604 else if (eap->bad_char == BAD_DROP) 21605 STRCPY(newval + STRLEN(newval), " ++bad=drop"); 21606 else if (eap->bad_char != 0) 21607 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); 21608 # endif 21609 vimvars[VV_CMDARG].vv_str = newval; 21610 return oldval; 21611 } 21612 #endif 21613 21614 /* 21615 * Get the value of internal variable "name". 21616 * Return OK or FAIL. 21617 */ 21618 static int 21619 get_var_tv( 21620 char_u *name, 21621 int len, /* length of "name" */ 21622 typval_T *rettv, /* NULL when only checking existence */ 21623 dictitem_T **dip, /* non-NULL when typval's dict item is needed */ 21624 int verbose, /* may give error message */ 21625 int no_autoload) /* do not use script autoloading */ 21626 { 21627 int ret = OK; 21628 typval_T *tv = NULL; 21629 typval_T atv; 21630 dictitem_T *v; 21631 int cc; 21632 21633 /* truncate the name, so that we can use strcmp() */ 21634 cc = name[len]; 21635 name[len] = NUL; 21636 21637 /* 21638 * Check for "b:changedtick". 21639 */ 21640 if (STRCMP(name, "b:changedtick") == 0) 21641 { 21642 atv.v_type = VAR_NUMBER; 21643 atv.vval.v_number = curbuf->b_changedtick; 21644 tv = &atv; 21645 } 21646 21647 /* 21648 * Check for user-defined variables. 21649 */ 21650 else 21651 { 21652 v = find_var(name, NULL, no_autoload); 21653 if (v != NULL) 21654 { 21655 tv = &v->di_tv; 21656 if (dip != NULL) 21657 *dip = v; 21658 } 21659 } 21660 21661 if (tv == NULL) 21662 { 21663 if (rettv != NULL && verbose) 21664 EMSG2(_(e_undefvar), name); 21665 ret = FAIL; 21666 } 21667 else if (rettv != NULL) 21668 copy_tv(tv, rettv); 21669 21670 name[len] = cc; 21671 21672 return ret; 21673 } 21674 21675 /* 21676 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 21677 * Also handle function call with Funcref variable: func(expr) 21678 * Can all be combined: dict.func(expr)[idx]['func'](expr) 21679 */ 21680 static int 21681 handle_subscript( 21682 char_u **arg, 21683 typval_T *rettv, 21684 int evaluate, /* do more than finding the end */ 21685 int verbose) /* give error messages */ 21686 { 21687 int ret = OK; 21688 dict_T *selfdict = NULL; 21689 char_u *s; 21690 int len; 21691 typval_T functv; 21692 21693 while (ret == OK 21694 && (**arg == '[' 21695 || (**arg == '.' && rettv->v_type == VAR_DICT) 21696 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC 21697 || rettv->v_type == VAR_PARTIAL))) 21698 && !vim_iswhite(*(*arg - 1))) 21699 { 21700 if (**arg == '(') 21701 { 21702 partial_T *pt = NULL; 21703 21704 /* need to copy the funcref so that we can clear rettv */ 21705 if (evaluate) 21706 { 21707 functv = *rettv; 21708 rettv->v_type = VAR_UNKNOWN; 21709 21710 /* Invoke the function. Recursive! */ 21711 if (functv.v_type == VAR_PARTIAL) 21712 { 21713 pt = functv.vval.v_partial; 21714 s = pt->pt_name; 21715 } 21716 else 21717 s = functv.vval.v_string; 21718 } 21719 else 21720 s = (char_u *)""; 21721 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 21722 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 21723 &len, evaluate, pt, selfdict); 21724 21725 /* Clear the funcref afterwards, so that deleting it while 21726 * evaluating the arguments is possible (see test55). */ 21727 if (evaluate) 21728 clear_tv(&functv); 21729 21730 /* Stop the expression evaluation when immediately aborting on 21731 * error, or when an interrupt occurred or an exception was thrown 21732 * but not caught. */ 21733 if (aborting()) 21734 { 21735 if (ret == OK) 21736 clear_tv(rettv); 21737 ret = FAIL; 21738 } 21739 dict_unref(selfdict); 21740 selfdict = NULL; 21741 } 21742 else /* **arg == '[' || **arg == '.' */ 21743 { 21744 dict_unref(selfdict); 21745 if (rettv->v_type == VAR_DICT) 21746 { 21747 selfdict = rettv->vval.v_dict; 21748 if (selfdict != NULL) 21749 ++selfdict->dv_refcount; 21750 } 21751 else 21752 selfdict = NULL; 21753 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 21754 { 21755 clear_tv(rettv); 21756 ret = FAIL; 21757 } 21758 } 21759 } 21760 21761 if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL) 21762 && selfdict != NULL) 21763 { 21764 char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string 21765 : rettv->vval.v_partial->pt_name; 21766 char_u *tofree = NULL; 21767 ufunc_T *fp; 21768 char_u fname_buf[FLEN_FIXED + 1]; 21769 int error; 21770 21771 /* Translate "s:func" to the stored function name. */ 21772 fname = fname_trans_sid(fname, fname_buf, &tofree, &error); 21773 fp = find_func(fname); 21774 vim_free(tofree); 21775 21776 /* Turn "dict.Func" into a partial for "Func" with "dict". */ 21777 if (fp != NULL && (fp->uf_flags & FC_DICT)) 21778 { 21779 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); 21780 21781 if (pt != NULL) 21782 { 21783 pt->pt_refcount = 1; 21784 pt->pt_dict = selfdict; 21785 selfdict = NULL; 21786 if (rettv->v_type == VAR_FUNC) 21787 { 21788 /* just a function: use selfdict */ 21789 pt->pt_name = rettv->vval.v_string; 21790 } 21791 else 21792 { 21793 partial_T *ret_pt = rettv->vval.v_partial; 21794 int i; 21795 21796 /* partial: use selfdict and copy args */ 21797 pt->pt_name = vim_strsave(ret_pt->pt_name); 21798 if (ret_pt->pt_argc > 0) 21799 { 21800 pt->pt_argv = (typval_T *)alloc( 21801 sizeof(typval_T) * ret_pt->pt_argc); 21802 if (pt->pt_argv == NULL) 21803 /* out of memory: drop the arguments */ 21804 pt->pt_argc = 0; 21805 else 21806 { 21807 pt->pt_argc = ret_pt->pt_argc; 21808 for (i = 0; i < pt->pt_argc; i++) 21809 copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]); 21810 } 21811 } 21812 partial_unref(ret_pt); 21813 } 21814 func_ref(pt->pt_name); 21815 rettv->v_type = VAR_PARTIAL; 21816 rettv->vval.v_partial = pt; 21817 } 21818 } 21819 } 21820 21821 dict_unref(selfdict); 21822 return ret; 21823 } 21824 21825 /* 21826 * Allocate memory for a variable type-value, and make it empty (0 or NULL 21827 * value). 21828 */ 21829 typval_T * 21830 alloc_tv(void) 21831 { 21832 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 21833 } 21834 21835 /* 21836 * Allocate memory for a variable type-value, and assign a string to it. 21837 * The string "s" must have been allocated, it is consumed. 21838 * Return NULL for out of memory, the variable otherwise. 21839 */ 21840 static typval_T * 21841 alloc_string_tv(char_u *s) 21842 { 21843 typval_T *rettv; 21844 21845 rettv = alloc_tv(); 21846 if (rettv != NULL) 21847 { 21848 rettv->v_type = VAR_STRING; 21849 rettv->vval.v_string = s; 21850 } 21851 else 21852 vim_free(s); 21853 return rettv; 21854 } 21855 21856 /* 21857 * Free the memory for a variable type-value. 21858 */ 21859 void 21860 free_tv(typval_T *varp) 21861 { 21862 if (varp != NULL) 21863 { 21864 switch (varp->v_type) 21865 { 21866 case VAR_FUNC: 21867 func_unref(varp->vval.v_string); 21868 /*FALLTHROUGH*/ 21869 case VAR_STRING: 21870 vim_free(varp->vval.v_string); 21871 break; 21872 case VAR_PARTIAL: 21873 partial_unref(varp->vval.v_partial); 21874 break; 21875 case VAR_LIST: 21876 list_unref(varp->vval.v_list); 21877 break; 21878 case VAR_DICT: 21879 dict_unref(varp->vval.v_dict); 21880 break; 21881 case VAR_JOB: 21882 #ifdef FEAT_JOB_CHANNEL 21883 job_unref(varp->vval.v_job); 21884 break; 21885 #endif 21886 case VAR_CHANNEL: 21887 #ifdef FEAT_JOB_CHANNEL 21888 channel_unref(varp->vval.v_channel); 21889 break; 21890 #endif 21891 case VAR_NUMBER: 21892 case VAR_FLOAT: 21893 case VAR_UNKNOWN: 21894 case VAR_SPECIAL: 21895 break; 21896 } 21897 vim_free(varp); 21898 } 21899 } 21900 21901 /* 21902 * Free the memory for a variable value and set the value to NULL or 0. 21903 */ 21904 void 21905 clear_tv(typval_T *varp) 21906 { 21907 if (varp != NULL) 21908 { 21909 switch (varp->v_type) 21910 { 21911 case VAR_FUNC: 21912 func_unref(varp->vval.v_string); 21913 /*FALLTHROUGH*/ 21914 case VAR_STRING: 21915 vim_free(varp->vval.v_string); 21916 varp->vval.v_string = NULL; 21917 break; 21918 case VAR_PARTIAL: 21919 partial_unref(varp->vval.v_partial); 21920 varp->vval.v_partial = NULL; 21921 break; 21922 case VAR_LIST: 21923 list_unref(varp->vval.v_list); 21924 varp->vval.v_list = NULL; 21925 break; 21926 case VAR_DICT: 21927 dict_unref(varp->vval.v_dict); 21928 varp->vval.v_dict = NULL; 21929 break; 21930 case VAR_NUMBER: 21931 case VAR_SPECIAL: 21932 varp->vval.v_number = 0; 21933 break; 21934 case VAR_FLOAT: 21935 #ifdef FEAT_FLOAT 21936 varp->vval.v_float = 0.0; 21937 break; 21938 #endif 21939 case VAR_JOB: 21940 #ifdef FEAT_JOB_CHANNEL 21941 job_unref(varp->vval.v_job); 21942 varp->vval.v_job = NULL; 21943 #endif 21944 break; 21945 case VAR_CHANNEL: 21946 #ifdef FEAT_JOB_CHANNEL 21947 channel_unref(varp->vval.v_channel); 21948 varp->vval.v_channel = NULL; 21949 #endif 21950 case VAR_UNKNOWN: 21951 break; 21952 } 21953 varp->v_lock = 0; 21954 } 21955 } 21956 21957 /* 21958 * Set the value of a variable to NULL without freeing items. 21959 */ 21960 static void 21961 init_tv(typval_T *varp) 21962 { 21963 if (varp != NULL) 21964 vim_memset(varp, 0, sizeof(typval_T)); 21965 } 21966 21967 /* 21968 * Get the number value of a variable. 21969 * If it is a String variable, uses vim_str2nr(). 21970 * For incompatible types, return 0. 21971 * get_tv_number_chk() is similar to get_tv_number(), but informs the 21972 * caller of incompatible types: it sets *denote to TRUE if "denote" 21973 * is not NULL or returns -1 otherwise. 21974 */ 21975 long 21976 get_tv_number(typval_T *varp) 21977 { 21978 int error = FALSE; 21979 21980 return get_tv_number_chk(varp, &error); /* return 0L on error */ 21981 } 21982 21983 long 21984 get_tv_number_chk(typval_T *varp, int *denote) 21985 { 21986 long n = 0L; 21987 21988 switch (varp->v_type) 21989 { 21990 case VAR_NUMBER: 21991 return (long)(varp->vval.v_number); 21992 case VAR_FLOAT: 21993 #ifdef FEAT_FLOAT 21994 EMSG(_("E805: Using a Float as a Number")); 21995 break; 21996 #endif 21997 case VAR_FUNC: 21998 case VAR_PARTIAL: 21999 EMSG(_("E703: Using a Funcref as a Number")); 22000 break; 22001 case VAR_STRING: 22002 if (varp->vval.v_string != NULL) 22003 vim_str2nr(varp->vval.v_string, NULL, NULL, 22004 STR2NR_ALL, &n, NULL, 0); 22005 return n; 22006 case VAR_LIST: 22007 EMSG(_("E745: Using a List as a Number")); 22008 break; 22009 case VAR_DICT: 22010 EMSG(_("E728: Using a Dictionary as a Number")); 22011 break; 22012 case VAR_SPECIAL: 22013 return varp->vval.v_number == VVAL_TRUE ? 1 : 0; 22014 break; 22015 case VAR_JOB: 22016 #ifdef FEAT_JOB_CHANNEL 22017 EMSG(_("E910: Using a Job as a Number")); 22018 break; 22019 #endif 22020 case VAR_CHANNEL: 22021 #ifdef FEAT_JOB_CHANNEL 22022 EMSG(_("E913: Using a Channel as a Number")); 22023 break; 22024 #endif 22025 case VAR_UNKNOWN: 22026 EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)"); 22027 break; 22028 } 22029 if (denote == NULL) /* useful for values that must be unsigned */ 22030 n = -1; 22031 else 22032 *denote = TRUE; 22033 return n; 22034 } 22035 22036 #ifdef FEAT_FLOAT 22037 static float_T 22038 get_tv_float(typval_T *varp) 22039 { 22040 switch (varp->v_type) 22041 { 22042 case VAR_NUMBER: 22043 return (float_T)(varp->vval.v_number); 22044 case VAR_FLOAT: 22045 return varp->vval.v_float; 22046 case VAR_FUNC: 22047 case VAR_PARTIAL: 22048 EMSG(_("E891: Using a Funcref as a Float")); 22049 break; 22050 case VAR_STRING: 22051 EMSG(_("E892: Using a String as a Float")); 22052 break; 22053 case VAR_LIST: 22054 EMSG(_("E893: Using a List as a Float")); 22055 break; 22056 case VAR_DICT: 22057 EMSG(_("E894: Using a Dictionary as a Float")); 22058 break; 22059 case VAR_SPECIAL: 22060 EMSG(_("E907: Using a special value as a Float")); 22061 break; 22062 case VAR_JOB: 22063 # ifdef FEAT_JOB_CHANNEL 22064 EMSG(_("E911: Using a Job as a Float")); 22065 break; 22066 # endif 22067 case VAR_CHANNEL: 22068 # ifdef FEAT_JOB_CHANNEL 22069 EMSG(_("E914: Using a Channel as a Float")); 22070 break; 22071 # endif 22072 case VAR_UNKNOWN: 22073 EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)"); 22074 break; 22075 } 22076 return 0; 22077 } 22078 #endif 22079 22080 /* 22081 * Get the lnum from the first argument. 22082 * Also accepts ".", "$", etc., but that only works for the current buffer. 22083 * Returns -1 on error. 22084 */ 22085 static linenr_T 22086 get_tv_lnum(typval_T *argvars) 22087 { 22088 typval_T rettv; 22089 linenr_T lnum; 22090 22091 lnum = get_tv_number_chk(&argvars[0], NULL); 22092 if (lnum == 0) /* no valid number, try using line() */ 22093 { 22094 rettv.v_type = VAR_NUMBER; 22095 f_line(argvars, &rettv); 22096 lnum = rettv.vval.v_number; 22097 clear_tv(&rettv); 22098 } 22099 return lnum; 22100 } 22101 22102 /* 22103 * Get the lnum from the first argument. 22104 * Also accepts "$", then "buf" is used. 22105 * Returns 0 on error. 22106 */ 22107 static linenr_T 22108 get_tv_lnum_buf(typval_T *argvars, buf_T *buf) 22109 { 22110 if (argvars[0].v_type == VAR_STRING 22111 && argvars[0].vval.v_string != NULL 22112 && argvars[0].vval.v_string[0] == '$' 22113 && buf != NULL) 22114 return buf->b_ml.ml_line_count; 22115 return get_tv_number_chk(&argvars[0], NULL); 22116 } 22117 22118 /* 22119 * Get the string value of a variable. 22120 * If it is a Number variable, the number is converted into a string. 22121 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 22122 * get_tv_string_buf() uses a given buffer. 22123 * If the String variable has never been set, return an empty string. 22124 * Never returns NULL; 22125 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 22126 * NULL on error. 22127 */ 22128 char_u * 22129 get_tv_string(typval_T *varp) 22130 { 22131 static char_u mybuf[NUMBUFLEN]; 22132 22133 return get_tv_string_buf(varp, mybuf); 22134 } 22135 22136 char_u * 22137 get_tv_string_buf(typval_T *varp, char_u *buf) 22138 { 22139 char_u *res = get_tv_string_buf_chk(varp, buf); 22140 22141 return res != NULL ? res : (char_u *)""; 22142 } 22143 22144 /* 22145 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 22146 */ 22147 char_u * 22148 get_tv_string_chk(typval_T *varp) 22149 { 22150 static char_u mybuf[NUMBUFLEN]; 22151 22152 return get_tv_string_buf_chk(varp, mybuf); 22153 } 22154 22155 char_u * 22156 get_tv_string_buf_chk(typval_T *varp, char_u *buf) 22157 { 22158 switch (varp->v_type) 22159 { 22160 case VAR_NUMBER: 22161 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 22162 return buf; 22163 case VAR_FUNC: 22164 case VAR_PARTIAL: 22165 EMSG(_("E729: using Funcref as a String")); 22166 break; 22167 case VAR_LIST: 22168 EMSG(_("E730: using List as a String")); 22169 break; 22170 case VAR_DICT: 22171 EMSG(_("E731: using Dictionary as a String")); 22172 break; 22173 case VAR_FLOAT: 22174 #ifdef FEAT_FLOAT 22175 EMSG(_(e_float_as_string)); 22176 break; 22177 #endif 22178 case VAR_STRING: 22179 if (varp->vval.v_string != NULL) 22180 return varp->vval.v_string; 22181 return (char_u *)""; 22182 case VAR_SPECIAL: 22183 STRCPY(buf, get_var_special_name(varp->vval.v_number)); 22184 return buf; 22185 case VAR_JOB: 22186 #ifdef FEAT_JOB_CHANNEL 22187 { 22188 job_T *job = varp->vval.v_job; 22189 char *status; 22190 22191 if (job == NULL) 22192 return (char_u *)"no process"; 22193 status = job->jv_status == JOB_FAILED ? "fail" 22194 : job->jv_status == JOB_ENDED ? "dead" 22195 : "run"; 22196 # ifdef UNIX 22197 vim_snprintf((char *)buf, NUMBUFLEN, 22198 "process %ld %s", (long)job->jv_pid, status); 22199 # elif defined(WIN32) 22200 vim_snprintf((char *)buf, NUMBUFLEN, 22201 "process %ld %s", 22202 (long)job->jv_proc_info.dwProcessId, 22203 status); 22204 # else 22205 /* fall-back */ 22206 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status); 22207 # endif 22208 return buf; 22209 } 22210 #endif 22211 break; 22212 case VAR_CHANNEL: 22213 #ifdef FEAT_JOB_CHANNEL 22214 { 22215 channel_T *channel = varp->vval.v_channel; 22216 char *status = channel_status(channel); 22217 22218 if (channel == NULL) 22219 vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status); 22220 else 22221 vim_snprintf((char *)buf, NUMBUFLEN, 22222 "channel %d %s", channel->ch_id, status); 22223 return buf; 22224 } 22225 #endif 22226 break; 22227 case VAR_UNKNOWN: 22228 EMSG(_("E908: using an invalid value as a String")); 22229 break; 22230 } 22231 return NULL; 22232 } 22233 22234 /* 22235 * Find variable "name" in the list of variables. 22236 * Return a pointer to it if found, NULL if not found. 22237 * Careful: "a:0" variables don't have a name. 22238 * When "htp" is not NULL we are writing to the variable, set "htp" to the 22239 * hashtab_T used. 22240 */ 22241 static dictitem_T * 22242 find_var(char_u *name, hashtab_T **htp, int no_autoload) 22243 { 22244 char_u *varname; 22245 hashtab_T *ht; 22246 22247 ht = find_var_ht(name, &varname); 22248 if (htp != NULL) 22249 *htp = ht; 22250 if (ht == NULL) 22251 return NULL; 22252 return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); 22253 } 22254 22255 /* 22256 * Find variable "varname" in hashtab "ht" with name "htname". 22257 * Returns NULL if not found. 22258 */ 22259 static dictitem_T * 22260 find_var_in_ht( 22261 hashtab_T *ht, 22262 int htname, 22263 char_u *varname, 22264 int no_autoload) 22265 { 22266 hashitem_T *hi; 22267 22268 if (*varname == NUL) 22269 { 22270 /* Must be something like "s:", otherwise "ht" would be NULL. */ 22271 switch (htname) 22272 { 22273 case 's': return &SCRIPT_SV(current_SID)->sv_var; 22274 case 'g': return &globvars_var; 22275 case 'v': return &vimvars_var; 22276 case 'b': return &curbuf->b_bufvar; 22277 case 'w': return &curwin->w_winvar; 22278 #ifdef FEAT_WINDOWS 22279 case 't': return &curtab->tp_winvar; 22280 #endif 22281 case 'l': return current_funccal == NULL 22282 ? NULL : ¤t_funccal->l_vars_var; 22283 case 'a': return current_funccal == NULL 22284 ? NULL : ¤t_funccal->l_avars_var; 22285 } 22286 return NULL; 22287 } 22288 22289 hi = hash_find(ht, varname); 22290 if (HASHITEM_EMPTY(hi)) 22291 { 22292 /* For global variables we may try auto-loading the script. If it 22293 * worked find the variable again. Don't auto-load a script if it was 22294 * loaded already, otherwise it would be loaded every time when 22295 * checking if a function name is a Funcref variable. */ 22296 if (ht == &globvarht && !no_autoload) 22297 { 22298 /* Note: script_autoload() may make "hi" invalid. It must either 22299 * be obtained again or not used. */ 22300 if (!script_autoload(varname, FALSE) || aborting()) 22301 return NULL; 22302 hi = hash_find(ht, varname); 22303 } 22304 if (HASHITEM_EMPTY(hi)) 22305 return NULL; 22306 } 22307 return HI2DI(hi); 22308 } 22309 22310 /* 22311 * Find the hashtab used for a variable name. 22312 * Return NULL if the name is not valid. 22313 * Set "varname" to the start of name without ':'. 22314 */ 22315 static hashtab_T * 22316 find_var_ht(char_u *name, char_u **varname) 22317 { 22318 hashitem_T *hi; 22319 22320 if (name[0] == NUL) 22321 return NULL; 22322 if (name[1] != ':') 22323 { 22324 /* The name must not start with a colon or #. */ 22325 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 22326 return NULL; 22327 *varname = name; 22328 22329 /* "version" is "v:version" in all scopes */ 22330 hi = hash_find(&compat_hashtab, name); 22331 if (!HASHITEM_EMPTY(hi)) 22332 return &compat_hashtab; 22333 22334 if (current_funccal == NULL) 22335 return &globvarht; /* global variable */ 22336 return &get_funccal()->l_vars.dv_hashtab; /* l: variable */ 22337 } 22338 *varname = name + 2; 22339 if (*name == 'g') /* global variable */ 22340 return &globvarht; 22341 /* There must be no ':' or '#' in the rest of the name, unless g: is used 22342 */ 22343 if (vim_strchr(name + 2, ':') != NULL 22344 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 22345 return NULL; 22346 if (*name == 'b') /* buffer variable */ 22347 return &curbuf->b_vars->dv_hashtab; 22348 if (*name == 'w') /* window variable */ 22349 return &curwin->w_vars->dv_hashtab; 22350 #ifdef FEAT_WINDOWS 22351 if (*name == 't') /* tab page variable */ 22352 return &curtab->tp_vars->dv_hashtab; 22353 #endif 22354 if (*name == 'v') /* v: variable */ 22355 return &vimvarht; 22356 if (*name == 'a' && current_funccal != NULL) /* function argument */ 22357 return &get_funccal()->l_avars.dv_hashtab; 22358 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 22359 return &get_funccal()->l_vars.dv_hashtab; 22360 if (*name == 's' /* script variable */ 22361 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 22362 return &SCRIPT_VARS(current_SID); 22363 return NULL; 22364 } 22365 22366 /* 22367 * Get function call environment based on bactrace debug level 22368 */ 22369 static funccall_T * 22370 get_funccal(void) 22371 { 22372 int i; 22373 funccall_T *funccal; 22374 funccall_T *temp_funccal; 22375 22376 funccal = current_funccal; 22377 if (debug_backtrace_level > 0) 22378 { 22379 for (i = 0; i < debug_backtrace_level; i++) 22380 { 22381 temp_funccal = funccal->caller; 22382 if (temp_funccal) 22383 funccal = temp_funccal; 22384 else 22385 /* backtrace level overflow. reset to max */ 22386 debug_backtrace_level = i; 22387 } 22388 } 22389 return funccal; 22390 } 22391 22392 /* 22393 * Get the string value of a (global/local) variable. 22394 * Note: see get_tv_string() for how long the pointer remains valid. 22395 * Returns NULL when it doesn't exist. 22396 */ 22397 char_u * 22398 get_var_value(char_u *name) 22399 { 22400 dictitem_T *v; 22401 22402 v = find_var(name, NULL, FALSE); 22403 if (v == NULL) 22404 return NULL; 22405 return get_tv_string(&v->di_tv); 22406 } 22407 22408 /* 22409 * Allocate a new hashtab for a sourced script. It will be used while 22410 * sourcing this script and when executing functions defined in the script. 22411 */ 22412 void 22413 new_script_vars(scid_T id) 22414 { 22415 int i; 22416 hashtab_T *ht; 22417 scriptvar_T *sv; 22418 22419 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 22420 { 22421 /* Re-allocating ga_data means that an ht_array pointing to 22422 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 22423 * at its init value. Also reset "v_dict", it's always the same. */ 22424 for (i = 1; i <= ga_scripts.ga_len; ++i) 22425 { 22426 ht = &SCRIPT_VARS(i); 22427 if (ht->ht_mask == HT_INIT_SIZE - 1) 22428 ht->ht_array = ht->ht_smallarray; 22429 sv = SCRIPT_SV(i); 22430 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 22431 } 22432 22433 while (ga_scripts.ga_len < id) 22434 { 22435 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = 22436 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); 22437 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); 22438 ++ga_scripts.ga_len; 22439 } 22440 } 22441 } 22442 22443 /* 22444 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 22445 * point to it. 22446 */ 22447 void 22448 init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope) 22449 { 22450 hash_init(&dict->dv_hashtab); 22451 dict->dv_lock = 0; 22452 dict->dv_scope = scope; 22453 dict->dv_refcount = DO_NOT_FREE_CNT; 22454 dict->dv_copyID = 0; 22455 dict_var->di_tv.vval.v_dict = dict; 22456 dict_var->di_tv.v_type = VAR_DICT; 22457 dict_var->di_tv.v_lock = VAR_FIXED; 22458 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 22459 dict_var->di_key[0] = NUL; 22460 } 22461 22462 /* 22463 * Unreference a dictionary initialized by init_var_dict(). 22464 */ 22465 void 22466 unref_var_dict(dict_T *dict) 22467 { 22468 /* Now the dict needs to be freed if no one else is using it, go back to 22469 * normal reference counting. */ 22470 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; 22471 dict_unref(dict); 22472 } 22473 22474 /* 22475 * Clean up a list of internal variables. 22476 * Frees all allocated variables and the value they contain. 22477 * Clears hashtab "ht", does not free it. 22478 */ 22479 void 22480 vars_clear(hashtab_T *ht) 22481 { 22482 vars_clear_ext(ht, TRUE); 22483 } 22484 22485 /* 22486 * Like vars_clear(), but only free the value if "free_val" is TRUE. 22487 */ 22488 static void 22489 vars_clear_ext(hashtab_T *ht, int free_val) 22490 { 22491 int todo; 22492 hashitem_T *hi; 22493 dictitem_T *v; 22494 22495 hash_lock(ht); 22496 todo = (int)ht->ht_used; 22497 for (hi = ht->ht_array; todo > 0; ++hi) 22498 { 22499 if (!HASHITEM_EMPTY(hi)) 22500 { 22501 --todo; 22502 22503 /* Free the variable. Don't remove it from the hashtab, 22504 * ht_array might change then. hash_clear() takes care of it 22505 * later. */ 22506 v = HI2DI(hi); 22507 if (free_val) 22508 clear_tv(&v->di_tv); 22509 if (v->di_flags & DI_FLAGS_ALLOC) 22510 vim_free(v); 22511 } 22512 } 22513 hash_clear(ht); 22514 ht->ht_used = 0; 22515 } 22516 22517 /* 22518 * Delete a variable from hashtab "ht" at item "hi". 22519 * Clear the variable value and free the dictitem. 22520 */ 22521 static void 22522 delete_var(hashtab_T *ht, hashitem_T *hi) 22523 { 22524 dictitem_T *di = HI2DI(hi); 22525 22526 hash_remove(ht, hi); 22527 clear_tv(&di->di_tv); 22528 vim_free(di); 22529 } 22530 22531 /* 22532 * List the value of one internal variable. 22533 */ 22534 static void 22535 list_one_var(dictitem_T *v, char_u *prefix, int *first) 22536 { 22537 char_u *tofree; 22538 char_u *s; 22539 char_u numbuf[NUMBUFLEN]; 22540 22541 s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID()); 22542 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 22543 s == NULL ? (char_u *)"" : s, first); 22544 vim_free(tofree); 22545 } 22546 22547 static void 22548 list_one_var_a( 22549 char_u *prefix, 22550 char_u *name, 22551 int type, 22552 char_u *string, 22553 int *first) /* when TRUE clear rest of screen and set to FALSE */ 22554 { 22555 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 22556 msg_start(); 22557 msg_puts(prefix); 22558 if (name != NULL) /* "a:" vars don't have a name stored */ 22559 msg_puts(name); 22560 msg_putchar(' '); 22561 msg_advance(22); 22562 if (type == VAR_NUMBER) 22563 msg_putchar('#'); 22564 else if (type == VAR_FUNC || type == VAR_PARTIAL) 22565 msg_putchar('*'); 22566 else if (type == VAR_LIST) 22567 { 22568 msg_putchar('['); 22569 if (*string == '[') 22570 ++string; 22571 } 22572 else if (type == VAR_DICT) 22573 { 22574 msg_putchar('{'); 22575 if (*string == '{') 22576 ++string; 22577 } 22578 else 22579 msg_putchar(' '); 22580 22581 msg_outtrans(string); 22582 22583 if (type == VAR_FUNC || type == VAR_PARTIAL) 22584 msg_puts((char_u *)"()"); 22585 if (*first) 22586 { 22587 msg_clr_eos(); 22588 *first = FALSE; 22589 } 22590 } 22591 22592 /* 22593 * Set variable "name" to value in "tv". 22594 * If the variable already exists, the value is updated. 22595 * Otherwise the variable is created. 22596 */ 22597 static void 22598 set_var( 22599 char_u *name, 22600 typval_T *tv, 22601 int copy) /* make copy of value in "tv" */ 22602 { 22603 dictitem_T *v; 22604 char_u *varname; 22605 hashtab_T *ht; 22606 22607 ht = find_var_ht(name, &varname); 22608 if (ht == NULL || *varname == NUL) 22609 { 22610 EMSG2(_(e_illvar), name); 22611 return; 22612 } 22613 v = find_var_in_ht(ht, 0, varname, TRUE); 22614 22615 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) 22616 && var_check_func_name(name, v == NULL)) 22617 return; 22618 22619 if (v != NULL) 22620 { 22621 /* existing variable, need to clear the value */ 22622 if (var_check_ro(v->di_flags, name, FALSE) 22623 || tv_check_lock(v->di_tv.v_lock, name, FALSE)) 22624 return; 22625 22626 /* 22627 * Handle setting internal v: variables separately where needed to 22628 * prevent changing the type. 22629 */ 22630 if (ht == &vimvarht) 22631 { 22632 if (v->di_tv.v_type == VAR_STRING) 22633 { 22634 vim_free(v->di_tv.vval.v_string); 22635 if (copy || tv->v_type != VAR_STRING) 22636 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 22637 else 22638 { 22639 /* Take over the string to avoid an extra alloc/free. */ 22640 v->di_tv.vval.v_string = tv->vval.v_string; 22641 tv->vval.v_string = NULL; 22642 } 22643 return; 22644 } 22645 else if (v->di_tv.v_type == VAR_NUMBER) 22646 { 22647 v->di_tv.vval.v_number = get_tv_number(tv); 22648 if (STRCMP(varname, "searchforward") == 0) 22649 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 22650 #ifdef FEAT_SEARCH_EXTRA 22651 else if (STRCMP(varname, "hlsearch") == 0) 22652 { 22653 no_hlsearch = !v->di_tv.vval.v_number; 22654 redraw_all_later(SOME_VALID); 22655 } 22656 #endif 22657 return; 22658 } 22659 else if (v->di_tv.v_type != tv->v_type) 22660 EMSG2(_(e_intern2), "set_var()"); 22661 } 22662 22663 clear_tv(&v->di_tv); 22664 } 22665 else /* add a new variable */ 22666 { 22667 /* Can't add "v:" variable. */ 22668 if (ht == &vimvarht) 22669 { 22670 EMSG2(_(e_illvar), name); 22671 return; 22672 } 22673 22674 /* Make sure the variable name is valid. */ 22675 if (!valid_varname(varname)) 22676 return; 22677 22678 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 22679 + STRLEN(varname))); 22680 if (v == NULL) 22681 return; 22682 STRCPY(v->di_key, varname); 22683 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 22684 { 22685 vim_free(v); 22686 return; 22687 } 22688 v->di_flags = DI_FLAGS_ALLOC; 22689 } 22690 22691 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 22692 copy_tv(tv, &v->di_tv); 22693 else 22694 { 22695 v->di_tv = *tv; 22696 v->di_tv.v_lock = 0; 22697 init_tv(tv); 22698 } 22699 } 22700 22701 /* 22702 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 22703 * Also give an error message. 22704 */ 22705 static int 22706 var_check_ro(int flags, char_u *name, int use_gettext) 22707 { 22708 if (flags & DI_FLAGS_RO) 22709 { 22710 EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); 22711 return TRUE; 22712 } 22713 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 22714 { 22715 EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name); 22716 return TRUE; 22717 } 22718 return FALSE; 22719 } 22720 22721 /* 22722 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 22723 * Also give an error message. 22724 */ 22725 static int 22726 var_check_fixed(int flags, char_u *name, int use_gettext) 22727 { 22728 if (flags & DI_FLAGS_FIX) 22729 { 22730 EMSG2(_("E795: Cannot delete variable %s"), 22731 use_gettext ? (char_u *)_(name) : name); 22732 return TRUE; 22733 } 22734 return FALSE; 22735 } 22736 22737 /* 22738 * Check if a funcref is assigned to a valid variable name. 22739 * Return TRUE and give an error if not. 22740 */ 22741 static int 22742 var_check_func_name( 22743 char_u *name, /* points to start of variable name */ 22744 int new_var) /* TRUE when creating the variable */ 22745 { 22746 /* Allow for w: b: s: and t:. */ 22747 if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':') 22748 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 22749 ? name[2] : name[0])) 22750 { 22751 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), 22752 name); 22753 return TRUE; 22754 } 22755 /* Don't allow hiding a function. When "v" is not NULL we might be 22756 * assigning another function to the same var, the type is checked 22757 * below. */ 22758 if (new_var && function_exists(name)) 22759 { 22760 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 22761 name); 22762 return TRUE; 22763 } 22764 return FALSE; 22765 } 22766 22767 /* 22768 * Check if a variable name is valid. 22769 * Return FALSE and give an error if not. 22770 */ 22771 static int 22772 valid_varname(char_u *varname) 22773 { 22774 char_u *p; 22775 22776 for (p = varname; *p != NUL; ++p) 22777 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 22778 && *p != AUTOLOAD_CHAR) 22779 { 22780 EMSG2(_(e_illvar), varname); 22781 return FALSE; 22782 } 22783 return TRUE; 22784 } 22785 22786 /* 22787 * Return TRUE if typeval "tv" is set to be locked (immutable). 22788 * Also give an error message, using "name" or _("name") when use_gettext is 22789 * TRUE. 22790 */ 22791 static int 22792 tv_check_lock(int lock, char_u *name, int use_gettext) 22793 { 22794 if (lock & VAR_LOCKED) 22795 { 22796 EMSG2(_("E741: Value is locked: %s"), 22797 name == NULL ? (char_u *)_("Unknown") 22798 : use_gettext ? (char_u *)_(name) 22799 : name); 22800 return TRUE; 22801 } 22802 if (lock & VAR_FIXED) 22803 { 22804 EMSG2(_("E742: Cannot change value of %s"), 22805 name == NULL ? (char_u *)_("Unknown") 22806 : use_gettext ? (char_u *)_(name) 22807 : name); 22808 return TRUE; 22809 } 22810 return FALSE; 22811 } 22812 22813 /* 22814 * Copy the values from typval_T "from" to typval_T "to". 22815 * When needed allocates string or increases reference count. 22816 * Does not make a copy of a list or dict but copies the reference! 22817 * It is OK for "from" and "to" to point to the same item. This is used to 22818 * make a copy later. 22819 */ 22820 void 22821 copy_tv(typval_T *from, typval_T *to) 22822 { 22823 to->v_type = from->v_type; 22824 to->v_lock = 0; 22825 switch (from->v_type) 22826 { 22827 case VAR_NUMBER: 22828 case VAR_SPECIAL: 22829 to->vval.v_number = from->vval.v_number; 22830 break; 22831 case VAR_FLOAT: 22832 #ifdef FEAT_FLOAT 22833 to->vval.v_float = from->vval.v_float; 22834 break; 22835 #endif 22836 case VAR_JOB: 22837 #ifdef FEAT_JOB_CHANNEL 22838 to->vval.v_job = from->vval.v_job; 22839 if (to->vval.v_job != NULL) 22840 ++to->vval.v_job->jv_refcount; 22841 break; 22842 #endif 22843 case VAR_CHANNEL: 22844 #ifdef FEAT_JOB_CHANNEL 22845 to->vval.v_channel = from->vval.v_channel; 22846 if (to->vval.v_channel != NULL) 22847 ++to->vval.v_channel->ch_refcount; 22848 break; 22849 #endif 22850 case VAR_STRING: 22851 case VAR_FUNC: 22852 if (from->vval.v_string == NULL) 22853 to->vval.v_string = NULL; 22854 else 22855 { 22856 to->vval.v_string = vim_strsave(from->vval.v_string); 22857 if (from->v_type == VAR_FUNC) 22858 func_ref(to->vval.v_string); 22859 } 22860 break; 22861 case VAR_PARTIAL: 22862 if (from->vval.v_partial == NULL) 22863 to->vval.v_partial = NULL; 22864 else 22865 { 22866 to->vval.v_partial = from->vval.v_partial; 22867 ++to->vval.v_partial->pt_refcount; 22868 } 22869 break; 22870 case VAR_LIST: 22871 if (from->vval.v_list == NULL) 22872 to->vval.v_list = NULL; 22873 else 22874 { 22875 to->vval.v_list = from->vval.v_list; 22876 ++to->vval.v_list->lv_refcount; 22877 } 22878 break; 22879 case VAR_DICT: 22880 if (from->vval.v_dict == NULL) 22881 to->vval.v_dict = NULL; 22882 else 22883 { 22884 to->vval.v_dict = from->vval.v_dict; 22885 ++to->vval.v_dict->dv_refcount; 22886 } 22887 break; 22888 case VAR_UNKNOWN: 22889 EMSG2(_(e_intern2), "copy_tv(UNKNOWN)"); 22890 break; 22891 } 22892 } 22893 22894 /* 22895 * Make a copy of an item. 22896 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 22897 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 22898 * reference to an already copied list/dict can be used. 22899 * Returns FAIL or OK. 22900 */ 22901 static int 22902 item_copy( 22903 typval_T *from, 22904 typval_T *to, 22905 int deep, 22906 int copyID) 22907 { 22908 static int recurse = 0; 22909 int ret = OK; 22910 22911 if (recurse >= DICT_MAXNEST) 22912 { 22913 EMSG(_("E698: variable nested too deep for making a copy")); 22914 return FAIL; 22915 } 22916 ++recurse; 22917 22918 switch (from->v_type) 22919 { 22920 case VAR_NUMBER: 22921 case VAR_FLOAT: 22922 case VAR_STRING: 22923 case VAR_FUNC: 22924 case VAR_PARTIAL: 22925 case VAR_SPECIAL: 22926 case VAR_JOB: 22927 case VAR_CHANNEL: 22928 copy_tv(from, to); 22929 break; 22930 case VAR_LIST: 22931 to->v_type = VAR_LIST; 22932 to->v_lock = 0; 22933 if (from->vval.v_list == NULL) 22934 to->vval.v_list = NULL; 22935 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 22936 { 22937 /* use the copy made earlier */ 22938 to->vval.v_list = from->vval.v_list->lv_copylist; 22939 ++to->vval.v_list->lv_refcount; 22940 } 22941 else 22942 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 22943 if (to->vval.v_list == NULL) 22944 ret = FAIL; 22945 break; 22946 case VAR_DICT: 22947 to->v_type = VAR_DICT; 22948 to->v_lock = 0; 22949 if (from->vval.v_dict == NULL) 22950 to->vval.v_dict = NULL; 22951 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 22952 { 22953 /* use the copy made earlier */ 22954 to->vval.v_dict = from->vval.v_dict->dv_copydict; 22955 ++to->vval.v_dict->dv_refcount; 22956 } 22957 else 22958 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 22959 if (to->vval.v_dict == NULL) 22960 ret = FAIL; 22961 break; 22962 case VAR_UNKNOWN: 22963 EMSG2(_(e_intern2), "item_copy(UNKNOWN)"); 22964 ret = FAIL; 22965 } 22966 --recurse; 22967 return ret; 22968 } 22969 22970 /* 22971 * ":echo expr1 ..." print each argument separated with a space, add a 22972 * newline at the end. 22973 * ":echon expr1 ..." print each argument plain. 22974 */ 22975 void 22976 ex_echo(exarg_T *eap) 22977 { 22978 char_u *arg = eap->arg; 22979 typval_T rettv; 22980 char_u *tofree; 22981 char_u *p; 22982 int needclr = TRUE; 22983 int atstart = TRUE; 22984 char_u numbuf[NUMBUFLEN]; 22985 22986 if (eap->skip) 22987 ++emsg_skip; 22988 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 22989 { 22990 /* If eval1() causes an error message the text from the command may 22991 * still need to be cleared. E.g., "echo 22,44". */ 22992 need_clr_eos = needclr; 22993 22994 p = arg; 22995 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 22996 { 22997 /* 22998 * Report the invalid expression unless the expression evaluation 22999 * has been cancelled due to an aborting error, an interrupt, or an 23000 * exception. 23001 */ 23002 if (!aborting()) 23003 EMSG2(_(e_invexpr2), p); 23004 need_clr_eos = FALSE; 23005 break; 23006 } 23007 need_clr_eos = FALSE; 23008 23009 if (!eap->skip) 23010 { 23011 if (atstart) 23012 { 23013 atstart = FALSE; 23014 /* Call msg_start() after eval1(), evaluating the expression 23015 * may cause a message to appear. */ 23016 if (eap->cmdidx == CMD_echo) 23017 { 23018 /* Mark the saved text as finishing the line, so that what 23019 * follows is displayed on a new line when scrolling back 23020 * at the more prompt. */ 23021 msg_sb_eol(); 23022 msg_start(); 23023 } 23024 } 23025 else if (eap->cmdidx == CMD_echo) 23026 msg_puts_attr((char_u *)" ", echo_attr); 23027 p = echo_string(&rettv, &tofree, numbuf, get_copyID()); 23028 if (p != NULL) 23029 for ( ; *p != NUL && !got_int; ++p) 23030 { 23031 if (*p == '\n' || *p == '\r' || *p == TAB) 23032 { 23033 if (*p != TAB && needclr) 23034 { 23035 /* remove any text still there from the command */ 23036 msg_clr_eos(); 23037 needclr = FALSE; 23038 } 23039 msg_putchar_attr(*p, echo_attr); 23040 } 23041 else 23042 { 23043 #ifdef FEAT_MBYTE 23044 if (has_mbyte) 23045 { 23046 int i = (*mb_ptr2len)(p); 23047 23048 (void)msg_outtrans_len_attr(p, i, echo_attr); 23049 p += i - 1; 23050 } 23051 else 23052 #endif 23053 (void)msg_outtrans_len_attr(p, 1, echo_attr); 23054 } 23055 } 23056 vim_free(tofree); 23057 } 23058 clear_tv(&rettv); 23059 arg = skipwhite(arg); 23060 } 23061 eap->nextcmd = check_nextcmd(arg); 23062 23063 if (eap->skip) 23064 --emsg_skip; 23065 else 23066 { 23067 /* remove text that may still be there from the command */ 23068 if (needclr) 23069 msg_clr_eos(); 23070 if (eap->cmdidx == CMD_echo) 23071 msg_end(); 23072 } 23073 } 23074 23075 /* 23076 * ":echohl {name}". 23077 */ 23078 void 23079 ex_echohl(exarg_T *eap) 23080 { 23081 int id; 23082 23083 id = syn_name2id(eap->arg); 23084 if (id == 0) 23085 echo_attr = 0; 23086 else 23087 echo_attr = syn_id2attr(id); 23088 } 23089 23090 /* 23091 * ":execute expr1 ..." execute the result of an expression. 23092 * ":echomsg expr1 ..." Print a message 23093 * ":echoerr expr1 ..." Print an error 23094 * Each gets spaces around each argument and a newline at the end for 23095 * echo commands 23096 */ 23097 void 23098 ex_execute(exarg_T *eap) 23099 { 23100 char_u *arg = eap->arg; 23101 typval_T rettv; 23102 int ret = OK; 23103 char_u *p; 23104 garray_T ga; 23105 int len; 23106 int save_did_emsg; 23107 23108 ga_init2(&ga, 1, 80); 23109 23110 if (eap->skip) 23111 ++emsg_skip; 23112 while (*arg != NUL && *arg != '|' && *arg != '\n') 23113 { 23114 p = arg; 23115 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 23116 { 23117 /* 23118 * Report the invalid expression unless the expression evaluation 23119 * has been cancelled due to an aborting error, an interrupt, or an 23120 * exception. 23121 */ 23122 if (!aborting()) 23123 EMSG2(_(e_invexpr2), p); 23124 ret = FAIL; 23125 break; 23126 } 23127 23128 if (!eap->skip) 23129 { 23130 p = get_tv_string(&rettv); 23131 len = (int)STRLEN(p); 23132 if (ga_grow(&ga, len + 2) == FAIL) 23133 { 23134 clear_tv(&rettv); 23135 ret = FAIL; 23136 break; 23137 } 23138 if (ga.ga_len) 23139 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 23140 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 23141 ga.ga_len += len; 23142 } 23143 23144 clear_tv(&rettv); 23145 arg = skipwhite(arg); 23146 } 23147 23148 if (ret != FAIL && ga.ga_data != NULL) 23149 { 23150 if (eap->cmdidx == CMD_echomsg) 23151 { 23152 MSG_ATTR(ga.ga_data, echo_attr); 23153 out_flush(); 23154 } 23155 else if (eap->cmdidx == CMD_echoerr) 23156 { 23157 /* We don't want to abort following commands, restore did_emsg. */ 23158 save_did_emsg = did_emsg; 23159 EMSG((char_u *)ga.ga_data); 23160 if (!force_abort) 23161 did_emsg = save_did_emsg; 23162 } 23163 else if (eap->cmdidx == CMD_execute) 23164 do_cmdline((char_u *)ga.ga_data, 23165 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 23166 } 23167 23168 ga_clear(&ga); 23169 23170 if (eap->skip) 23171 --emsg_skip; 23172 23173 eap->nextcmd = check_nextcmd(arg); 23174 } 23175 23176 /* 23177 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 23178 * "arg" points to the "&" or '+' when called, to "option" when returning. 23179 * Returns NULL when no option name found. Otherwise pointer to the char 23180 * after the option name. 23181 */ 23182 static char_u * 23183 find_option_end(char_u **arg, int *opt_flags) 23184 { 23185 char_u *p = *arg; 23186 23187 ++p; 23188 if (*p == 'g' && p[1] == ':') 23189 { 23190 *opt_flags = OPT_GLOBAL; 23191 p += 2; 23192 } 23193 else if (*p == 'l' && p[1] == ':') 23194 { 23195 *opt_flags = OPT_LOCAL; 23196 p += 2; 23197 } 23198 else 23199 *opt_flags = 0; 23200 23201 if (!ASCII_ISALPHA(*p)) 23202 return NULL; 23203 *arg = p; 23204 23205 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 23206 p += 4; /* termcap option */ 23207 else 23208 while (ASCII_ISALPHA(*p)) 23209 ++p; 23210 return p; 23211 } 23212 23213 /* 23214 * ":function" 23215 */ 23216 void 23217 ex_function(exarg_T *eap) 23218 { 23219 char_u *theline; 23220 int i; 23221 int j; 23222 int c; 23223 int saved_did_emsg; 23224 int saved_wait_return = need_wait_return; 23225 char_u *name = NULL; 23226 char_u *p; 23227 char_u *arg; 23228 char_u *line_arg = NULL; 23229 garray_T newargs; 23230 garray_T newlines; 23231 int varargs = FALSE; 23232 int mustend = FALSE; 23233 int flags = 0; 23234 ufunc_T *fp; 23235 int indent; 23236 int nesting; 23237 char_u *skip_until = NULL; 23238 dictitem_T *v; 23239 funcdict_T fudi; 23240 static int func_nr = 0; /* number for nameless function */ 23241 int paren; 23242 hashtab_T *ht; 23243 int todo; 23244 hashitem_T *hi; 23245 int sourcing_lnum_off; 23246 23247 /* 23248 * ":function" without argument: list functions. 23249 */ 23250 if (ends_excmd(*eap->arg)) 23251 { 23252 if (!eap->skip) 23253 { 23254 todo = (int)func_hashtab.ht_used; 23255 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 23256 { 23257 if (!HASHITEM_EMPTY(hi)) 23258 { 23259 --todo; 23260 fp = HI2UF(hi); 23261 if (!isdigit(*fp->uf_name)) 23262 list_func_head(fp, FALSE); 23263 } 23264 } 23265 } 23266 eap->nextcmd = check_nextcmd(eap->arg); 23267 return; 23268 } 23269 23270 /* 23271 * ":function /pat": list functions matching pattern. 23272 */ 23273 if (*eap->arg == '/') 23274 { 23275 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 23276 if (!eap->skip) 23277 { 23278 regmatch_T regmatch; 23279 23280 c = *p; 23281 *p = NUL; 23282 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 23283 *p = c; 23284 if (regmatch.regprog != NULL) 23285 { 23286 regmatch.rm_ic = p_ic; 23287 23288 todo = (int)func_hashtab.ht_used; 23289 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 23290 { 23291 if (!HASHITEM_EMPTY(hi)) 23292 { 23293 --todo; 23294 fp = HI2UF(hi); 23295 if (!isdigit(*fp->uf_name) 23296 && vim_regexec(®match, fp->uf_name, 0)) 23297 list_func_head(fp, FALSE); 23298 } 23299 } 23300 vim_regfree(regmatch.regprog); 23301 } 23302 } 23303 if (*p == '/') 23304 ++p; 23305 eap->nextcmd = check_nextcmd(p); 23306 return; 23307 } 23308 23309 /* 23310 * Get the function name. There are these situations: 23311 * func normal function name 23312 * "name" == func, "fudi.fd_dict" == NULL 23313 * dict.func new dictionary entry 23314 * "name" == NULL, "fudi.fd_dict" set, 23315 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 23316 * dict.func existing dict entry with a Funcref 23317 * "name" == func, "fudi.fd_dict" set, 23318 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 23319 * dict.func existing dict entry that's not a Funcref 23320 * "name" == NULL, "fudi.fd_dict" set, 23321 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 23322 * s:func script-local function name 23323 * g:func global function name, same as "func" 23324 */ 23325 p = eap->arg; 23326 name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); 23327 paren = (vim_strchr(p, '(') != NULL); 23328 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 23329 { 23330 /* 23331 * Return on an invalid expression in braces, unless the expression 23332 * evaluation has been cancelled due to an aborting error, an 23333 * interrupt, or an exception. 23334 */ 23335 if (!aborting()) 23336 { 23337 if (!eap->skip && fudi.fd_newkey != NULL) 23338 EMSG2(_(e_dictkey), fudi.fd_newkey); 23339 vim_free(fudi.fd_newkey); 23340 return; 23341 } 23342 else 23343 eap->skip = TRUE; 23344 } 23345 23346 /* An error in a function call during evaluation of an expression in magic 23347 * braces should not cause the function not to be defined. */ 23348 saved_did_emsg = did_emsg; 23349 did_emsg = FALSE; 23350 23351 /* 23352 * ":function func" with only function name: list function. 23353 */ 23354 if (!paren) 23355 { 23356 if (!ends_excmd(*skipwhite(p))) 23357 { 23358 EMSG(_(e_trailing)); 23359 goto ret_free; 23360 } 23361 eap->nextcmd = check_nextcmd(p); 23362 if (eap->nextcmd != NULL) 23363 *p = NUL; 23364 if (!eap->skip && !got_int) 23365 { 23366 fp = find_func(name); 23367 if (fp != NULL) 23368 { 23369 list_func_head(fp, TRUE); 23370 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 23371 { 23372 if (FUNCLINE(fp, j) == NULL) 23373 continue; 23374 msg_putchar('\n'); 23375 msg_outnum((long)(j + 1)); 23376 if (j < 9) 23377 msg_putchar(' '); 23378 if (j < 99) 23379 msg_putchar(' '); 23380 msg_prt_line(FUNCLINE(fp, j), FALSE); 23381 out_flush(); /* show a line at a time */ 23382 ui_breakcheck(); 23383 } 23384 if (!got_int) 23385 { 23386 msg_putchar('\n'); 23387 msg_puts((char_u *)" endfunction"); 23388 } 23389 } 23390 else 23391 emsg_funcname(N_("E123: Undefined function: %s"), name); 23392 } 23393 goto ret_free; 23394 } 23395 23396 /* 23397 * ":function name(arg1, arg2)" Define function. 23398 */ 23399 p = skipwhite(p); 23400 if (*p != '(') 23401 { 23402 if (!eap->skip) 23403 { 23404 EMSG2(_("E124: Missing '(': %s"), eap->arg); 23405 goto ret_free; 23406 } 23407 /* attempt to continue by skipping some text */ 23408 if (vim_strchr(p, '(') != NULL) 23409 p = vim_strchr(p, '('); 23410 } 23411 p = skipwhite(p + 1); 23412 23413 ga_init2(&newargs, (int)sizeof(char_u *), 3); 23414 ga_init2(&newlines, (int)sizeof(char_u *), 3); 23415 23416 if (!eap->skip) 23417 { 23418 /* Check the name of the function. Unless it's a dictionary function 23419 * (that we are overwriting). */ 23420 if (name != NULL) 23421 arg = name; 23422 else 23423 arg = fudi.fd_newkey; 23424 if (arg != NULL && (fudi.fd_di == NULL 23425 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 23426 { 23427 if (*arg == K_SPECIAL) 23428 j = 3; 23429 else 23430 j = 0; 23431 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 23432 : eval_isnamec(arg[j]))) 23433 ++j; 23434 if (arg[j] != NUL) 23435 emsg_funcname((char *)e_invarg2, arg); 23436 } 23437 /* Disallow using the g: dict. */ 23438 if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) 23439 EMSG(_("E862: Cannot use g: here")); 23440 } 23441 23442 /* 23443 * Isolate the arguments: "arg1, arg2, ...)" 23444 */ 23445 while (*p != ')') 23446 { 23447 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 23448 { 23449 varargs = TRUE; 23450 p += 3; 23451 mustend = TRUE; 23452 } 23453 else 23454 { 23455 arg = p; 23456 while (ASCII_ISALNUM(*p) || *p == '_') 23457 ++p; 23458 if (arg == p || isdigit(*arg) 23459 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 23460 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 23461 { 23462 if (!eap->skip) 23463 EMSG2(_("E125: Illegal argument: %s"), arg); 23464 break; 23465 } 23466 if (ga_grow(&newargs, 1) == FAIL) 23467 goto erret; 23468 c = *p; 23469 *p = NUL; 23470 arg = vim_strsave(arg); 23471 if (arg == NULL) 23472 goto erret; 23473 23474 /* Check for duplicate argument name. */ 23475 for (i = 0; i < newargs.ga_len; ++i) 23476 if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0) 23477 { 23478 EMSG2(_("E853: Duplicate argument name: %s"), arg); 23479 vim_free(arg); 23480 goto erret; 23481 } 23482 23483 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 23484 *p = c; 23485 newargs.ga_len++; 23486 if (*p == ',') 23487 ++p; 23488 else 23489 mustend = TRUE; 23490 } 23491 p = skipwhite(p); 23492 if (mustend && *p != ')') 23493 { 23494 if (!eap->skip) 23495 EMSG2(_(e_invarg2), eap->arg); 23496 break; 23497 } 23498 } 23499 if (*p != ')') 23500 goto erret; 23501 ++p; /* skip the ')' */ 23502 23503 /* find extra arguments "range", "dict" and "abort" */ 23504 for (;;) 23505 { 23506 p = skipwhite(p); 23507 if (STRNCMP(p, "range", 5) == 0) 23508 { 23509 flags |= FC_RANGE; 23510 p += 5; 23511 } 23512 else if (STRNCMP(p, "dict", 4) == 0) 23513 { 23514 flags |= FC_DICT; 23515 p += 4; 23516 } 23517 else if (STRNCMP(p, "abort", 5) == 0) 23518 { 23519 flags |= FC_ABORT; 23520 p += 5; 23521 } 23522 else 23523 break; 23524 } 23525 23526 /* When there is a line break use what follows for the function body. 23527 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 23528 if (*p == '\n') 23529 line_arg = p + 1; 23530 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 23531 EMSG(_(e_trailing)); 23532 23533 /* 23534 * Read the body of the function, until ":endfunction" is found. 23535 */ 23536 if (KeyTyped) 23537 { 23538 /* Check if the function already exists, don't let the user type the 23539 * whole function before telling him it doesn't work! For a script we 23540 * need to skip the body to be able to find what follows. */ 23541 if (!eap->skip && !eap->forceit) 23542 { 23543 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 23544 EMSG(_(e_funcdict)); 23545 else if (name != NULL && find_func(name) != NULL) 23546 emsg_funcname(e_funcexts, name); 23547 } 23548 23549 if (!eap->skip && did_emsg) 23550 goto erret; 23551 23552 msg_putchar('\n'); /* don't overwrite the function name */ 23553 cmdline_row = msg_row; 23554 } 23555 23556 indent = 2; 23557 nesting = 0; 23558 for (;;) 23559 { 23560 if (KeyTyped) 23561 { 23562 msg_scroll = TRUE; 23563 saved_wait_return = FALSE; 23564 } 23565 need_wait_return = FALSE; 23566 sourcing_lnum_off = sourcing_lnum; 23567 23568 if (line_arg != NULL) 23569 { 23570 /* Use eap->arg, split up in parts by line breaks. */ 23571 theline = line_arg; 23572 p = vim_strchr(theline, '\n'); 23573 if (p == NULL) 23574 line_arg += STRLEN(line_arg); 23575 else 23576 { 23577 *p = NUL; 23578 line_arg = p + 1; 23579 } 23580 } 23581 else if (eap->getline == NULL) 23582 theline = getcmdline(':', 0L, indent); 23583 else 23584 theline = eap->getline(':', eap->cookie, indent); 23585 if (KeyTyped) 23586 lines_left = Rows - 1; 23587 if (theline == NULL) 23588 { 23589 EMSG(_("E126: Missing :endfunction")); 23590 goto erret; 23591 } 23592 23593 /* Detect line continuation: sourcing_lnum increased more than one. */ 23594 if (sourcing_lnum > sourcing_lnum_off + 1) 23595 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 23596 else 23597 sourcing_lnum_off = 0; 23598 23599 if (skip_until != NULL) 23600 { 23601 /* between ":append" and "." and between ":python <<EOF" and "EOF" 23602 * don't check for ":endfunc". */ 23603 if (STRCMP(theline, skip_until) == 0) 23604 { 23605 vim_free(skip_until); 23606 skip_until = NULL; 23607 } 23608 } 23609 else 23610 { 23611 /* skip ':' and blanks*/ 23612 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 23613 ; 23614 23615 /* Check for "endfunction". */ 23616 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 23617 { 23618 if (line_arg == NULL) 23619 vim_free(theline); 23620 break; 23621 } 23622 23623 /* Increase indent inside "if", "while", "for" and "try", decrease 23624 * at "end". */ 23625 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 23626 indent -= 2; 23627 else if (STRNCMP(p, "if", 2) == 0 23628 || STRNCMP(p, "wh", 2) == 0 23629 || STRNCMP(p, "for", 3) == 0 23630 || STRNCMP(p, "try", 3) == 0) 23631 indent += 2; 23632 23633 /* Check for defining a function inside this function. */ 23634 if (checkforcmd(&p, "function", 2)) 23635 { 23636 if (*p == '!') 23637 p = skipwhite(p + 1); 23638 p += eval_fname_script(p); 23639 vim_free(trans_function_name(&p, TRUE, 0, NULL, NULL)); 23640 if (*skipwhite(p) == '(') 23641 { 23642 ++nesting; 23643 indent += 2; 23644 } 23645 } 23646 23647 /* Check for ":append" or ":insert". */ 23648 p = skip_range(p, NULL); 23649 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 23650 || (p[0] == 'i' 23651 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 23652 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 23653 skip_until = vim_strsave((char_u *)"."); 23654 23655 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 23656 arg = skipwhite(skiptowhite(p)); 23657 if (arg[0] == '<' && arg[1] =='<' 23658 && ((p[0] == 'p' && p[1] == 'y' 23659 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 23660 || (p[0] == 'p' && p[1] == 'e' 23661 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 23662 || (p[0] == 't' && p[1] == 'c' 23663 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 23664 || (p[0] == 'l' && p[1] == 'u' && p[2] == 'a' 23665 && !ASCII_ISALPHA(p[3])) 23666 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 23667 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 23668 || (p[0] == 'm' && p[1] == 'z' 23669 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 23670 )) 23671 { 23672 /* ":python <<" continues until a dot, like ":append" */ 23673 p = skipwhite(arg + 2); 23674 if (*p == NUL) 23675 skip_until = vim_strsave((char_u *)"."); 23676 else 23677 skip_until = vim_strsave(p); 23678 } 23679 } 23680 23681 /* Add the line to the function. */ 23682 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 23683 { 23684 if (line_arg == NULL) 23685 vim_free(theline); 23686 goto erret; 23687 } 23688 23689 /* Copy the line to newly allocated memory. get_one_sourceline() 23690 * allocates 250 bytes per line, this saves 80% on average. The cost 23691 * is an extra alloc/free. */ 23692 p = vim_strsave(theline); 23693 if (p != NULL) 23694 { 23695 if (line_arg == NULL) 23696 vim_free(theline); 23697 theline = p; 23698 } 23699 23700 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 23701 23702 /* Add NULL lines for continuation lines, so that the line count is 23703 * equal to the index in the growarray. */ 23704 while (sourcing_lnum_off-- > 0) 23705 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 23706 23707 /* Check for end of eap->arg. */ 23708 if (line_arg != NULL && *line_arg == NUL) 23709 line_arg = NULL; 23710 } 23711 23712 /* Don't define the function when skipping commands or when an error was 23713 * detected. */ 23714 if (eap->skip || did_emsg) 23715 goto erret; 23716 23717 /* 23718 * If there are no errors, add the function 23719 */ 23720 if (fudi.fd_dict == NULL) 23721 { 23722 v = find_var(name, &ht, FALSE); 23723 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 23724 { 23725 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 23726 name); 23727 goto erret; 23728 } 23729 23730 fp = find_func(name); 23731 if (fp != NULL) 23732 { 23733 if (!eap->forceit) 23734 { 23735 emsg_funcname(e_funcexts, name); 23736 goto erret; 23737 } 23738 if (fp->uf_calls > 0) 23739 { 23740 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 23741 name); 23742 goto erret; 23743 } 23744 /* redefine existing function */ 23745 ga_clear_strings(&(fp->uf_args)); 23746 ga_clear_strings(&(fp->uf_lines)); 23747 vim_free(name); 23748 name = NULL; 23749 } 23750 } 23751 else 23752 { 23753 char numbuf[20]; 23754 23755 fp = NULL; 23756 if (fudi.fd_newkey == NULL && !eap->forceit) 23757 { 23758 EMSG(_(e_funcdict)); 23759 goto erret; 23760 } 23761 if (fudi.fd_di == NULL) 23762 { 23763 /* Can't add a function to a locked dictionary */ 23764 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, FALSE)) 23765 goto erret; 23766 } 23767 /* Can't change an existing function if it is locked */ 23768 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, FALSE)) 23769 goto erret; 23770 23771 /* Give the function a sequential number. Can only be used with a 23772 * Funcref! */ 23773 vim_free(name); 23774 sprintf(numbuf, "%d", ++func_nr); 23775 name = vim_strsave((char_u *)numbuf); 23776 if (name == NULL) 23777 goto erret; 23778 } 23779 23780 if (fp == NULL) 23781 { 23782 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 23783 { 23784 int slen, plen; 23785 char_u *scriptname; 23786 23787 /* Check that the autoload name matches the script name. */ 23788 j = FAIL; 23789 if (sourcing_name != NULL) 23790 { 23791 scriptname = autoload_name(name); 23792 if (scriptname != NULL) 23793 { 23794 p = vim_strchr(scriptname, '/'); 23795 plen = (int)STRLEN(p); 23796 slen = (int)STRLEN(sourcing_name); 23797 if (slen > plen && fnamecmp(p, 23798 sourcing_name + slen - plen) == 0) 23799 j = OK; 23800 vim_free(scriptname); 23801 } 23802 } 23803 if (j == FAIL) 23804 { 23805 EMSG2(_("E746: Function name does not match script file name: %s"), name); 23806 goto erret; 23807 } 23808 } 23809 23810 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 23811 if (fp == NULL) 23812 goto erret; 23813 23814 if (fudi.fd_dict != NULL) 23815 { 23816 if (fudi.fd_di == NULL) 23817 { 23818 /* add new dict entry */ 23819 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 23820 if (fudi.fd_di == NULL) 23821 { 23822 vim_free(fp); 23823 goto erret; 23824 } 23825 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 23826 { 23827 vim_free(fudi.fd_di); 23828 vim_free(fp); 23829 goto erret; 23830 } 23831 } 23832 else 23833 /* overwrite existing dict entry */ 23834 clear_tv(&fudi.fd_di->di_tv); 23835 fudi.fd_di->di_tv.v_type = VAR_FUNC; 23836 fudi.fd_di->di_tv.v_lock = 0; 23837 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 23838 fp->uf_refcount = 1; 23839 23840 /* behave like "dict" was used */ 23841 flags |= FC_DICT; 23842 } 23843 23844 /* insert the new function in the function list */ 23845 STRCPY(fp->uf_name, name); 23846 if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) 23847 { 23848 vim_free(fp); 23849 goto erret; 23850 } 23851 } 23852 fp->uf_args = newargs; 23853 fp->uf_lines = newlines; 23854 #ifdef FEAT_PROFILE 23855 fp->uf_tml_count = NULL; 23856 fp->uf_tml_total = NULL; 23857 fp->uf_tml_self = NULL; 23858 fp->uf_profiling = FALSE; 23859 if (prof_def_func()) 23860 func_do_profile(fp); 23861 #endif 23862 fp->uf_varargs = varargs; 23863 fp->uf_flags = flags; 23864 fp->uf_calls = 0; 23865 fp->uf_script_ID = current_SID; 23866 goto ret_free; 23867 23868 erret: 23869 ga_clear_strings(&newargs); 23870 ga_clear_strings(&newlines); 23871 ret_free: 23872 vim_free(skip_until); 23873 vim_free(fudi.fd_newkey); 23874 vim_free(name); 23875 did_emsg |= saved_did_emsg; 23876 need_wait_return |= saved_wait_return; 23877 } 23878 23879 /* 23880 * Get a function name, translating "<SID>" and "<SNR>". 23881 * Also handles a Funcref in a List or Dictionary. 23882 * Returns the function name in allocated memory, or NULL for failure. 23883 * flags: 23884 * TFN_INT: internal function name OK 23885 * TFN_QUIET: be quiet 23886 * TFN_NO_AUTOLOAD: do not use script autoloading 23887 * Advances "pp" to just after the function name (if no error). 23888 */ 23889 static char_u * 23890 trans_function_name( 23891 char_u **pp, 23892 int skip, /* only find the end, don't evaluate */ 23893 int flags, 23894 funcdict_T *fdp, /* return: info about dictionary used */ 23895 partial_T **partial) /* return: partial of a FuncRef */ 23896 { 23897 char_u *name = NULL; 23898 char_u *start; 23899 char_u *end; 23900 int lead; 23901 char_u sid_buf[20]; 23902 int len; 23903 lval_T lv; 23904 23905 if (fdp != NULL) 23906 vim_memset(fdp, 0, sizeof(funcdict_T)); 23907 start = *pp; 23908 23909 /* Check for hard coded <SNR>: already translated function ID (from a user 23910 * command). */ 23911 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 23912 && (*pp)[2] == (int)KE_SNR) 23913 { 23914 *pp += 3; 23915 len = get_id_len(pp) + 3; 23916 return vim_strnsave(start, len); 23917 } 23918 23919 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 23920 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 23921 lead = eval_fname_script(start); 23922 if (lead > 2) 23923 start += lead; 23924 23925 /* Note that TFN_ flags use the same values as GLV_ flags. */ 23926 end = get_lval(start, NULL, &lv, FALSE, skip, flags, 23927 lead > 2 ? 0 : FNE_CHECK_START); 23928 if (end == start) 23929 { 23930 if (!skip) 23931 EMSG(_("E129: Function name required")); 23932 goto theend; 23933 } 23934 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 23935 { 23936 /* 23937 * Report an invalid expression in braces, unless the expression 23938 * evaluation has been cancelled due to an aborting error, an 23939 * interrupt, or an exception. 23940 */ 23941 if (!aborting()) 23942 { 23943 if (end != NULL) 23944 EMSG2(_(e_invarg2), start); 23945 } 23946 else 23947 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 23948 goto theend; 23949 } 23950 23951 if (lv.ll_tv != NULL) 23952 { 23953 if (fdp != NULL) 23954 { 23955 fdp->fd_dict = lv.ll_dict; 23956 fdp->fd_newkey = lv.ll_newkey; 23957 lv.ll_newkey = NULL; 23958 fdp->fd_di = lv.ll_di; 23959 } 23960 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 23961 { 23962 name = vim_strsave(lv.ll_tv->vval.v_string); 23963 *pp = end; 23964 } 23965 else if (lv.ll_tv->v_type == VAR_PARTIAL 23966 && lv.ll_tv->vval.v_partial != NULL) 23967 { 23968 name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name); 23969 *pp = end; 23970 if (partial != NULL) 23971 *partial = lv.ll_tv->vval.v_partial; 23972 } 23973 else 23974 { 23975 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 23976 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 23977 EMSG(_(e_funcref)); 23978 else 23979 *pp = end; 23980 name = NULL; 23981 } 23982 goto theend; 23983 } 23984 23985 if (lv.ll_name == NULL) 23986 { 23987 /* Error found, but continue after the function name. */ 23988 *pp = end; 23989 goto theend; 23990 } 23991 23992 /* Check if the name is a Funcref. If so, use the value. */ 23993 if (lv.ll_exp_name != NULL) 23994 { 23995 len = (int)STRLEN(lv.ll_exp_name); 23996 name = deref_func_name(lv.ll_exp_name, &len, partial, 23997 flags & TFN_NO_AUTOLOAD); 23998 if (name == lv.ll_exp_name) 23999 name = NULL; 24000 } 24001 else 24002 { 24003 len = (int)(end - *pp); 24004 name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD); 24005 if (name == *pp) 24006 name = NULL; 24007 } 24008 if (name != NULL) 24009 { 24010 name = vim_strsave(name); 24011 *pp = end; 24012 if (STRNCMP(name, "<SNR>", 5) == 0) 24013 { 24014 /* Change "<SNR>" to the byte sequence. */ 24015 name[0] = K_SPECIAL; 24016 name[1] = KS_EXTRA; 24017 name[2] = (int)KE_SNR; 24018 mch_memmove(name + 3, name + 5, STRLEN(name + 5) + 1); 24019 } 24020 goto theend; 24021 } 24022 24023 if (lv.ll_exp_name != NULL) 24024 { 24025 len = (int)STRLEN(lv.ll_exp_name); 24026 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 24027 && STRNCMP(lv.ll_name, "s:", 2) == 0) 24028 { 24029 /* When there was "s:" already or the name expanded to get a 24030 * leading "s:" then remove it. */ 24031 lv.ll_name += 2; 24032 len -= 2; 24033 lead = 2; 24034 } 24035 } 24036 else 24037 { 24038 /* skip over "s:" and "g:" */ 24039 if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':')) 24040 lv.ll_name += 2; 24041 len = (int)(end - lv.ll_name); 24042 } 24043 24044 /* 24045 * Copy the function name to allocated memory. 24046 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 24047 * Accept <SNR>123_name() outside a script. 24048 */ 24049 if (skip) 24050 lead = 0; /* do nothing */ 24051 else if (lead > 0) 24052 { 24053 lead = 3; 24054 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 24055 || eval_fname_sid(*pp)) 24056 { 24057 /* It's "s:" or "<SID>" */ 24058 if (current_SID <= 0) 24059 { 24060 EMSG(_(e_usingsid)); 24061 goto theend; 24062 } 24063 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 24064 lead += (int)STRLEN(sid_buf); 24065 } 24066 } 24067 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) 24068 { 24069 EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"), 24070 start); 24071 goto theend; 24072 } 24073 if (!skip && !(flags & TFN_QUIET)) 24074 { 24075 char_u *cp = vim_strchr(lv.ll_name, ':'); 24076 24077 if (cp != NULL && cp < end) 24078 { 24079 EMSG2(_("E884: Function name cannot contain a colon: %s"), start); 24080 goto theend; 24081 } 24082 } 24083 24084 name = alloc((unsigned)(len + lead + 1)); 24085 if (name != NULL) 24086 { 24087 if (lead > 0) 24088 { 24089 name[0] = K_SPECIAL; 24090 name[1] = KS_EXTRA; 24091 name[2] = (int)KE_SNR; 24092 if (lead > 3) /* If it's "<SID>" */ 24093 STRCPY(name + 3, sid_buf); 24094 } 24095 mch_memmove(name + lead, lv.ll_name, (size_t)len); 24096 name[lead + len] = NUL; 24097 } 24098 *pp = end; 24099 24100 theend: 24101 clear_lval(&lv); 24102 return name; 24103 } 24104 24105 /* 24106 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 24107 * Return 2 if "p" starts with "s:". 24108 * Return 0 otherwise. 24109 */ 24110 static int 24111 eval_fname_script(char_u *p) 24112 { 24113 /* Use MB_STRICMP() because in Turkish comparing the "I" may not work with 24114 * the standard library function. */ 24115 if (p[0] == '<' && (MB_STRNICMP(p + 1, "SID>", 4) == 0 24116 || MB_STRNICMP(p + 1, "SNR>", 4) == 0)) 24117 return 5; 24118 if (p[0] == 's' && p[1] == ':') 24119 return 2; 24120 return 0; 24121 } 24122 24123 /* 24124 * Return TRUE if "p" starts with "<SID>" or "s:". 24125 * Only works if eval_fname_script() returned non-zero for "p"! 24126 */ 24127 static int 24128 eval_fname_sid(char_u *p) 24129 { 24130 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 24131 } 24132 24133 /* 24134 * List the head of the function: "name(arg1, arg2)". 24135 */ 24136 static void 24137 list_func_head(ufunc_T *fp, int indent) 24138 { 24139 int j; 24140 24141 msg_start(); 24142 if (indent) 24143 MSG_PUTS(" "); 24144 MSG_PUTS("function "); 24145 if (fp->uf_name[0] == K_SPECIAL) 24146 { 24147 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 24148 msg_puts(fp->uf_name + 3); 24149 } 24150 else 24151 msg_puts(fp->uf_name); 24152 msg_putchar('('); 24153 for (j = 0; j < fp->uf_args.ga_len; ++j) 24154 { 24155 if (j) 24156 MSG_PUTS(", "); 24157 msg_puts(FUNCARG(fp, j)); 24158 } 24159 if (fp->uf_varargs) 24160 { 24161 if (j) 24162 MSG_PUTS(", "); 24163 MSG_PUTS("..."); 24164 } 24165 msg_putchar(')'); 24166 if (fp->uf_flags & FC_ABORT) 24167 MSG_PUTS(" abort"); 24168 if (fp->uf_flags & FC_RANGE) 24169 MSG_PUTS(" range"); 24170 if (fp->uf_flags & FC_DICT) 24171 MSG_PUTS(" dict"); 24172 msg_clr_eos(); 24173 if (p_verbose > 0) 24174 last_set_msg(fp->uf_script_ID); 24175 } 24176 24177 /* 24178 * Find a function by name, return pointer to it in ufuncs. 24179 * Return NULL for unknown function. 24180 */ 24181 static ufunc_T * 24182 find_func(char_u *name) 24183 { 24184 hashitem_T *hi; 24185 24186 hi = hash_find(&func_hashtab, name); 24187 if (!HASHITEM_EMPTY(hi)) 24188 return HI2UF(hi); 24189 return NULL; 24190 } 24191 24192 #if defined(EXITFREE) || defined(PROTO) 24193 void 24194 free_all_functions(void) 24195 { 24196 hashitem_T *hi; 24197 24198 /* Need to start all over every time, because func_free() may change the 24199 * hash table. */ 24200 while (func_hashtab.ht_used > 0) 24201 for (hi = func_hashtab.ht_array; ; ++hi) 24202 if (!HASHITEM_EMPTY(hi)) 24203 { 24204 func_free(HI2UF(hi)); 24205 break; 24206 } 24207 } 24208 #endif 24209 24210 int 24211 translated_function_exists(char_u *name) 24212 { 24213 if (builtin_function(name, -1)) 24214 return find_internal_func(name) >= 0; 24215 return find_func(name) != NULL; 24216 } 24217 24218 /* 24219 * Return TRUE if a function "name" exists. 24220 */ 24221 static int 24222 function_exists(char_u *name) 24223 { 24224 char_u *nm = name; 24225 char_u *p; 24226 int n = FALSE; 24227 24228 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, 24229 NULL, NULL); 24230 nm = skipwhite(nm); 24231 24232 /* Only accept "funcname", "funcname ", "funcname (..." and 24233 * "funcname(...", not "funcname!...". */ 24234 if (p != NULL && (*nm == NUL || *nm == '(')) 24235 n = translated_function_exists(p); 24236 vim_free(p); 24237 return n; 24238 } 24239 24240 char_u * 24241 get_expanded_name(char_u *name, int check) 24242 { 24243 char_u *nm = name; 24244 char_u *p; 24245 24246 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL, NULL); 24247 24248 if (p != NULL && *nm == NUL) 24249 if (!check || translated_function_exists(p)) 24250 return p; 24251 24252 vim_free(p); 24253 return NULL; 24254 } 24255 24256 /* 24257 * Return TRUE if "name" looks like a builtin function name: starts with a 24258 * lower case letter and doesn't contain AUTOLOAD_CHAR. 24259 * "len" is the length of "name", or -1 for NUL terminated. 24260 */ 24261 static int 24262 builtin_function(char_u *name, int len) 24263 { 24264 char_u *p; 24265 24266 if (!ASCII_ISLOWER(name[0])) 24267 return FALSE; 24268 p = vim_strchr(name, AUTOLOAD_CHAR); 24269 return p == NULL || (len > 0 && p > name + len); 24270 } 24271 24272 #if defined(FEAT_PROFILE) || defined(PROTO) 24273 /* 24274 * Start profiling function "fp". 24275 */ 24276 static void 24277 func_do_profile(ufunc_T *fp) 24278 { 24279 int len = fp->uf_lines.ga_len; 24280 24281 if (len == 0) 24282 len = 1; /* avoid getting error for allocating zero bytes */ 24283 fp->uf_tm_count = 0; 24284 profile_zero(&fp->uf_tm_self); 24285 profile_zero(&fp->uf_tm_total); 24286 if (fp->uf_tml_count == NULL) 24287 fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len)); 24288 if (fp->uf_tml_total == NULL) 24289 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 24290 (sizeof(proftime_T) * len)); 24291 if (fp->uf_tml_self == NULL) 24292 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 24293 (sizeof(proftime_T) * len)); 24294 fp->uf_tml_idx = -1; 24295 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 24296 || fp->uf_tml_self == NULL) 24297 return; /* out of memory */ 24298 24299 fp->uf_profiling = TRUE; 24300 } 24301 24302 /* 24303 * Dump the profiling results for all functions in file "fd". 24304 */ 24305 void 24306 func_dump_profile(FILE *fd) 24307 { 24308 hashitem_T *hi; 24309 int todo; 24310 ufunc_T *fp; 24311 int i; 24312 ufunc_T **sorttab; 24313 int st_len = 0; 24314 24315 todo = (int)func_hashtab.ht_used; 24316 if (todo == 0) 24317 return; /* nothing to dump */ 24318 24319 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T *) * todo)); 24320 24321 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 24322 { 24323 if (!HASHITEM_EMPTY(hi)) 24324 { 24325 --todo; 24326 fp = HI2UF(hi); 24327 if (fp->uf_profiling) 24328 { 24329 if (sorttab != NULL) 24330 sorttab[st_len++] = fp; 24331 24332 if (fp->uf_name[0] == K_SPECIAL) 24333 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 24334 else 24335 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 24336 if (fp->uf_tm_count == 1) 24337 fprintf(fd, "Called 1 time\n"); 24338 else 24339 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 24340 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 24341 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 24342 fprintf(fd, "\n"); 24343 fprintf(fd, "count total (s) self (s)\n"); 24344 24345 for (i = 0; i < fp->uf_lines.ga_len; ++i) 24346 { 24347 if (FUNCLINE(fp, i) == NULL) 24348 continue; 24349 prof_func_line(fd, fp->uf_tml_count[i], 24350 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 24351 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 24352 } 24353 fprintf(fd, "\n"); 24354 } 24355 } 24356 } 24357 24358 if (sorttab != NULL && st_len > 0) 24359 { 24360 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 24361 prof_total_cmp); 24362 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 24363 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 24364 prof_self_cmp); 24365 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 24366 } 24367 24368 vim_free(sorttab); 24369 } 24370 24371 static void 24372 prof_sort_list( 24373 FILE *fd, 24374 ufunc_T **sorttab, 24375 int st_len, 24376 char *title, 24377 int prefer_self) /* when equal print only self time */ 24378 { 24379 int i; 24380 ufunc_T *fp; 24381 24382 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 24383 fprintf(fd, "count total (s) self (s) function\n"); 24384 for (i = 0; i < 20 && i < st_len; ++i) 24385 { 24386 fp = sorttab[i]; 24387 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 24388 prefer_self); 24389 if (fp->uf_name[0] == K_SPECIAL) 24390 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 24391 else 24392 fprintf(fd, " %s()\n", fp->uf_name); 24393 } 24394 fprintf(fd, "\n"); 24395 } 24396 24397 /* 24398 * Print the count and times for one function or function line. 24399 */ 24400 static void 24401 prof_func_line( 24402 FILE *fd, 24403 int count, 24404 proftime_T *total, 24405 proftime_T *self, 24406 int prefer_self) /* when equal print only self time */ 24407 { 24408 if (count > 0) 24409 { 24410 fprintf(fd, "%5d ", count); 24411 if (prefer_self && profile_equal(total, self)) 24412 fprintf(fd, " "); 24413 else 24414 fprintf(fd, "%s ", profile_msg(total)); 24415 if (!prefer_self && profile_equal(total, self)) 24416 fprintf(fd, " "); 24417 else 24418 fprintf(fd, "%s ", profile_msg(self)); 24419 } 24420 else 24421 fprintf(fd, " "); 24422 } 24423 24424 /* 24425 * Compare function for total time sorting. 24426 */ 24427 static int 24428 #ifdef __BORLANDC__ 24429 _RTLENTRYF 24430 #endif 24431 prof_total_cmp(const void *s1, const void *s2) 24432 { 24433 ufunc_T *p1, *p2; 24434 24435 p1 = *(ufunc_T **)s1; 24436 p2 = *(ufunc_T **)s2; 24437 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 24438 } 24439 24440 /* 24441 * Compare function for self time sorting. 24442 */ 24443 static int 24444 #ifdef __BORLANDC__ 24445 _RTLENTRYF 24446 #endif 24447 prof_self_cmp(const void *s1, const void *s2) 24448 { 24449 ufunc_T *p1, *p2; 24450 24451 p1 = *(ufunc_T **)s1; 24452 p2 = *(ufunc_T **)s2; 24453 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 24454 } 24455 24456 #endif 24457 24458 /* 24459 * If "name" has a package name try autoloading the script for it. 24460 * Return TRUE if a package was loaded. 24461 */ 24462 static int 24463 script_autoload( 24464 char_u *name, 24465 int reload) /* load script again when already loaded */ 24466 { 24467 char_u *p; 24468 char_u *scriptname, *tofree; 24469 int ret = FALSE; 24470 int i; 24471 24472 /* If there is no '#' after name[0] there is no package name. */ 24473 p = vim_strchr(name, AUTOLOAD_CHAR); 24474 if (p == NULL || p == name) 24475 return FALSE; 24476 24477 tofree = scriptname = autoload_name(name); 24478 24479 /* Find the name in the list of previously loaded package names. Skip 24480 * "autoload/", it's always the same. */ 24481 for (i = 0; i < ga_loaded.ga_len; ++i) 24482 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 24483 break; 24484 if (!reload && i < ga_loaded.ga_len) 24485 ret = FALSE; /* was loaded already */ 24486 else 24487 { 24488 /* Remember the name if it wasn't loaded already. */ 24489 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 24490 { 24491 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 24492 tofree = NULL; 24493 } 24494 24495 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 24496 if (source_runtime(scriptname, 0) == OK) 24497 ret = TRUE; 24498 } 24499 24500 vim_free(tofree); 24501 return ret; 24502 } 24503 24504 /* 24505 * Return the autoload script name for a function or variable name. 24506 * Returns NULL when out of memory. 24507 */ 24508 static char_u * 24509 autoload_name(char_u *name) 24510 { 24511 char_u *p; 24512 char_u *scriptname; 24513 24514 /* Get the script file name: replace '#' with '/', append ".vim". */ 24515 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 24516 if (scriptname == NULL) 24517 return FALSE; 24518 STRCPY(scriptname, "autoload/"); 24519 STRCAT(scriptname, name); 24520 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 24521 STRCAT(scriptname, ".vim"); 24522 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 24523 *p = '/'; 24524 return scriptname; 24525 } 24526 24527 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 24528 24529 /* 24530 * Function given to ExpandGeneric() to obtain the list of user defined 24531 * function names. 24532 */ 24533 char_u * 24534 get_user_func_name(expand_T *xp, int idx) 24535 { 24536 static long_u done; 24537 static hashitem_T *hi; 24538 ufunc_T *fp; 24539 24540 if (idx == 0) 24541 { 24542 done = 0; 24543 hi = func_hashtab.ht_array; 24544 } 24545 if (done < func_hashtab.ht_used) 24546 { 24547 if (done++ > 0) 24548 ++hi; 24549 while (HASHITEM_EMPTY(hi)) 24550 ++hi; 24551 fp = HI2UF(hi); 24552 24553 if (fp->uf_flags & FC_DICT) 24554 return (char_u *)""; /* don't show dict functions */ 24555 24556 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 24557 return fp->uf_name; /* prevents overflow */ 24558 24559 cat_func_name(IObuff, fp); 24560 if (xp->xp_context != EXPAND_USER_FUNC) 24561 { 24562 STRCAT(IObuff, "("); 24563 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 24564 STRCAT(IObuff, ")"); 24565 } 24566 return IObuff; 24567 } 24568 return NULL; 24569 } 24570 24571 #endif /* FEAT_CMDL_COMPL */ 24572 24573 /* 24574 * Copy the function name of "fp" to buffer "buf". 24575 * "buf" must be able to hold the function name plus three bytes. 24576 * Takes care of script-local function names. 24577 */ 24578 static void 24579 cat_func_name(char_u *buf, ufunc_T *fp) 24580 { 24581 if (fp->uf_name[0] == K_SPECIAL) 24582 { 24583 STRCPY(buf, "<SNR>"); 24584 STRCAT(buf, fp->uf_name + 3); 24585 } 24586 else 24587 STRCPY(buf, fp->uf_name); 24588 } 24589 24590 /* 24591 * ":delfunction {name}" 24592 */ 24593 void 24594 ex_delfunction(exarg_T *eap) 24595 { 24596 ufunc_T *fp = NULL; 24597 char_u *p; 24598 char_u *name; 24599 funcdict_T fudi; 24600 24601 p = eap->arg; 24602 name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); 24603 vim_free(fudi.fd_newkey); 24604 if (name == NULL) 24605 { 24606 if (fudi.fd_dict != NULL && !eap->skip) 24607 EMSG(_(e_funcref)); 24608 return; 24609 } 24610 if (!ends_excmd(*skipwhite(p))) 24611 { 24612 vim_free(name); 24613 EMSG(_(e_trailing)); 24614 return; 24615 } 24616 eap->nextcmd = check_nextcmd(p); 24617 if (eap->nextcmd != NULL) 24618 *p = NUL; 24619 24620 if (!eap->skip) 24621 fp = find_func(name); 24622 vim_free(name); 24623 24624 if (!eap->skip) 24625 { 24626 if (fp == NULL) 24627 { 24628 EMSG2(_(e_nofunc), eap->arg); 24629 return; 24630 } 24631 if (fp->uf_calls > 0) 24632 { 24633 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 24634 return; 24635 } 24636 24637 if (fudi.fd_dict != NULL) 24638 { 24639 /* Delete the dict item that refers to the function, it will 24640 * invoke func_unref() and possibly delete the function. */ 24641 dictitem_remove(fudi.fd_dict, fudi.fd_di); 24642 } 24643 else 24644 func_free(fp); 24645 } 24646 } 24647 24648 /* 24649 * Free a function and remove it from the list of functions. 24650 */ 24651 static void 24652 func_free(ufunc_T *fp) 24653 { 24654 hashitem_T *hi; 24655 24656 /* clear this function */ 24657 ga_clear_strings(&(fp->uf_args)); 24658 ga_clear_strings(&(fp->uf_lines)); 24659 #ifdef FEAT_PROFILE 24660 vim_free(fp->uf_tml_count); 24661 vim_free(fp->uf_tml_total); 24662 vim_free(fp->uf_tml_self); 24663 #endif 24664 24665 /* remove the function from the function hashtable */ 24666 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 24667 if (HASHITEM_EMPTY(hi)) 24668 EMSG2(_(e_intern2), "func_free()"); 24669 else 24670 hash_remove(&func_hashtab, hi); 24671 24672 vim_free(fp); 24673 } 24674 24675 /* 24676 * Unreference a Function: decrement the reference count and free it when it 24677 * becomes zero. Only for numbered functions. 24678 */ 24679 void 24680 func_unref(char_u *name) 24681 { 24682 ufunc_T *fp; 24683 24684 if (name != NULL && isdigit(*name)) 24685 { 24686 fp = find_func(name); 24687 if (fp == NULL) 24688 EMSG2(_(e_intern2), "func_unref()"); 24689 else if (--fp->uf_refcount <= 0) 24690 { 24691 /* Only delete it when it's not being used. Otherwise it's done 24692 * when "uf_calls" becomes zero. */ 24693 if (fp->uf_calls == 0) 24694 func_free(fp); 24695 } 24696 } 24697 } 24698 24699 /* 24700 * Count a reference to a Function. 24701 */ 24702 void 24703 func_ref(char_u *name) 24704 { 24705 ufunc_T *fp; 24706 24707 if (name != NULL && isdigit(*name)) 24708 { 24709 fp = find_func(name); 24710 if (fp == NULL) 24711 EMSG2(_(e_intern2), "func_ref()"); 24712 else 24713 ++fp->uf_refcount; 24714 } 24715 } 24716 24717 /* 24718 * Call a user function. 24719 */ 24720 static void 24721 call_user_func( 24722 ufunc_T *fp, /* pointer to function */ 24723 int argcount, /* nr of args */ 24724 typval_T *argvars, /* arguments */ 24725 typval_T *rettv, /* return value */ 24726 linenr_T firstline, /* first line of range */ 24727 linenr_T lastline, /* last line of range */ 24728 dict_T *selfdict) /* Dictionary for "self" */ 24729 { 24730 char_u *save_sourcing_name; 24731 linenr_T save_sourcing_lnum; 24732 scid_T save_current_SID; 24733 funccall_T *fc; 24734 int save_did_emsg; 24735 static int depth = 0; 24736 dictitem_T *v; 24737 int fixvar_idx = 0; /* index in fixvar[] */ 24738 int i; 24739 int ai; 24740 char_u numbuf[NUMBUFLEN]; 24741 char_u *name; 24742 size_t len; 24743 #ifdef FEAT_PROFILE 24744 proftime_T wait_start; 24745 proftime_T call_start; 24746 #endif 24747 24748 /* If depth of calling is getting too high, don't execute the function */ 24749 if (depth >= p_mfd) 24750 { 24751 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 24752 rettv->v_type = VAR_NUMBER; 24753 rettv->vval.v_number = -1; 24754 return; 24755 } 24756 ++depth; 24757 24758 line_breakcheck(); /* check for CTRL-C hit */ 24759 24760 fc = (funccall_T *)alloc(sizeof(funccall_T)); 24761 fc->caller = current_funccal; 24762 current_funccal = fc; 24763 fc->func = fp; 24764 fc->rettv = rettv; 24765 rettv->vval.v_number = 0; 24766 fc->linenr = 0; 24767 fc->returned = FALSE; 24768 fc->level = ex_nesting_level; 24769 /* Check if this function has a breakpoint. */ 24770 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 24771 fc->dbg_tick = debug_tick; 24772 24773 /* 24774 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 24775 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 24776 * each argument variable and saves a lot of time. 24777 */ 24778 /* 24779 * Init l: variables. 24780 */ 24781 init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE); 24782 if (selfdict != NULL) 24783 { 24784 /* Set l:self to "selfdict". Use "name" to avoid a warning from 24785 * some compiler that checks the destination size. */ 24786 v = &fc->fixvar[fixvar_idx++].var; 24787 name = v->di_key; 24788 STRCPY(name, "self"); 24789 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 24790 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 24791 v->di_tv.v_type = VAR_DICT; 24792 v->di_tv.v_lock = 0; 24793 v->di_tv.vval.v_dict = selfdict; 24794 ++selfdict->dv_refcount; 24795 } 24796 24797 /* 24798 * Init a: variables. 24799 * Set a:0 to "argcount". 24800 * Set a:000 to a list with room for the "..." arguments. 24801 */ 24802 init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE); 24803 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 24804 (varnumber_T)(argcount - fp->uf_args.ga_len)); 24805 /* Use "name" to avoid a warning from some compiler that checks the 24806 * destination size. */ 24807 v = &fc->fixvar[fixvar_idx++].var; 24808 name = v->di_key; 24809 STRCPY(name, "000"); 24810 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24811 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 24812 v->di_tv.v_type = VAR_LIST; 24813 v->di_tv.v_lock = VAR_FIXED; 24814 v->di_tv.vval.v_list = &fc->l_varlist; 24815 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 24816 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 24817 fc->l_varlist.lv_lock = VAR_FIXED; 24818 24819 /* 24820 * Set a:firstline to "firstline" and a:lastline to "lastline". 24821 * Set a:name to named arguments. 24822 * Set a:N to the "..." arguments. 24823 */ 24824 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 24825 (varnumber_T)firstline); 24826 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 24827 (varnumber_T)lastline); 24828 for (i = 0; i < argcount; ++i) 24829 { 24830 ai = i - fp->uf_args.ga_len; 24831 if (ai < 0) 24832 /* named argument a:name */ 24833 name = FUNCARG(fp, i); 24834 else 24835 { 24836 /* "..." argument a:1, a:2, etc. */ 24837 sprintf((char *)numbuf, "%d", ai + 1); 24838 name = numbuf; 24839 } 24840 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 24841 { 24842 v = &fc->fixvar[fixvar_idx++].var; 24843 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24844 } 24845 else 24846 { 24847 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 24848 + STRLEN(name))); 24849 if (v == NULL) 24850 break; 24851 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC; 24852 } 24853 STRCPY(v->di_key, name); 24854 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 24855 24856 /* Note: the values are copied directly to avoid alloc/free. 24857 * "argvars" must have VAR_FIXED for v_lock. */ 24858 v->di_tv = argvars[i]; 24859 v->di_tv.v_lock = VAR_FIXED; 24860 24861 if (ai >= 0 && ai < MAX_FUNC_ARGS) 24862 { 24863 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 24864 fc->l_listitems[ai].li_tv = argvars[i]; 24865 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 24866 } 24867 } 24868 24869 /* Don't redraw while executing the function. */ 24870 ++RedrawingDisabled; 24871 save_sourcing_name = sourcing_name; 24872 save_sourcing_lnum = sourcing_lnum; 24873 sourcing_lnum = 1; 24874 /* need space for function name + ("function " + 3) or "[number]" */ 24875 len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name)) 24876 + STRLEN(fp->uf_name) + 20; 24877 sourcing_name = alloc((unsigned)len); 24878 if (sourcing_name != NULL) 24879 { 24880 if (save_sourcing_name != NULL 24881 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 24882 sprintf((char *)sourcing_name, "%s[%d]..", 24883 save_sourcing_name, (int)save_sourcing_lnum); 24884 else 24885 STRCPY(sourcing_name, "function "); 24886 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 24887 24888 if (p_verbose >= 12) 24889 { 24890 ++no_wait_return; 24891 verbose_enter_scroll(); 24892 24893 smsg((char_u *)_("calling %s"), sourcing_name); 24894 if (p_verbose >= 14) 24895 { 24896 char_u buf[MSG_BUF_LEN]; 24897 char_u numbuf2[NUMBUFLEN]; 24898 char_u *tofree; 24899 char_u *s; 24900 24901 msg_puts((char_u *)"("); 24902 for (i = 0; i < argcount; ++i) 24903 { 24904 if (i > 0) 24905 msg_puts((char_u *)", "); 24906 if (argvars[i].v_type == VAR_NUMBER) 24907 msg_outnum((long)argvars[i].vval.v_number); 24908 else 24909 { 24910 /* Do not want errors such as E724 here. */ 24911 ++emsg_off; 24912 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 24913 --emsg_off; 24914 if (s != NULL) 24915 { 24916 if (vim_strsize(s) > MSG_BUF_CLEN) 24917 { 24918 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); 24919 s = buf; 24920 } 24921 msg_puts(s); 24922 vim_free(tofree); 24923 } 24924 } 24925 } 24926 msg_puts((char_u *)")"); 24927 } 24928 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 24929 24930 verbose_leave_scroll(); 24931 --no_wait_return; 24932 } 24933 } 24934 #ifdef FEAT_PROFILE 24935 if (do_profiling == PROF_YES) 24936 { 24937 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 24938 func_do_profile(fp); 24939 if (fp->uf_profiling 24940 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 24941 { 24942 ++fp->uf_tm_count; 24943 profile_start(&call_start); 24944 profile_zero(&fp->uf_tm_children); 24945 } 24946 script_prof_save(&wait_start); 24947 } 24948 #endif 24949 24950 save_current_SID = current_SID; 24951 current_SID = fp->uf_script_ID; 24952 save_did_emsg = did_emsg; 24953 did_emsg = FALSE; 24954 24955 /* call do_cmdline() to execute the lines */ 24956 do_cmdline(NULL, get_func_line, (void *)fc, 24957 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 24958 24959 --RedrawingDisabled; 24960 24961 /* when the function was aborted because of an error, return -1 */ 24962 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 24963 { 24964 clear_tv(rettv); 24965 rettv->v_type = VAR_NUMBER; 24966 rettv->vval.v_number = -1; 24967 } 24968 24969 #ifdef FEAT_PROFILE 24970 if (do_profiling == PROF_YES && (fp->uf_profiling 24971 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 24972 { 24973 profile_end(&call_start); 24974 profile_sub_wait(&wait_start, &call_start); 24975 profile_add(&fp->uf_tm_total, &call_start); 24976 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 24977 if (fc->caller != NULL && fc->caller->func->uf_profiling) 24978 { 24979 profile_add(&fc->caller->func->uf_tm_children, &call_start); 24980 profile_add(&fc->caller->func->uf_tml_children, &call_start); 24981 } 24982 } 24983 #endif 24984 24985 /* when being verbose, mention the return value */ 24986 if (p_verbose >= 12) 24987 { 24988 ++no_wait_return; 24989 verbose_enter_scroll(); 24990 24991 if (aborting()) 24992 smsg((char_u *)_("%s aborted"), sourcing_name); 24993 else if (fc->rettv->v_type == VAR_NUMBER) 24994 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 24995 (long)fc->rettv->vval.v_number); 24996 else 24997 { 24998 char_u buf[MSG_BUF_LEN]; 24999 char_u numbuf2[NUMBUFLEN]; 25000 char_u *tofree; 25001 char_u *s; 25002 25003 /* The value may be very long. Skip the middle part, so that we 25004 * have some idea how it starts and ends. smsg() would always 25005 * truncate it at the end. Don't want errors such as E724 here. */ 25006 ++emsg_off; 25007 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 25008 --emsg_off; 25009 if (s != NULL) 25010 { 25011 if (vim_strsize(s) > MSG_BUF_CLEN) 25012 { 25013 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); 25014 s = buf; 25015 } 25016 smsg((char_u *)_("%s returning %s"), sourcing_name, s); 25017 vim_free(tofree); 25018 } 25019 } 25020 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 25021 25022 verbose_leave_scroll(); 25023 --no_wait_return; 25024 } 25025 25026 vim_free(sourcing_name); 25027 sourcing_name = save_sourcing_name; 25028 sourcing_lnum = save_sourcing_lnum; 25029 current_SID = save_current_SID; 25030 #ifdef FEAT_PROFILE 25031 if (do_profiling == PROF_YES) 25032 script_prof_restore(&wait_start); 25033 #endif 25034 25035 if (p_verbose >= 12 && sourcing_name != NULL) 25036 { 25037 ++no_wait_return; 25038 verbose_enter_scroll(); 25039 25040 smsg((char_u *)_("continuing in %s"), sourcing_name); 25041 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 25042 25043 verbose_leave_scroll(); 25044 --no_wait_return; 25045 } 25046 25047 did_emsg |= save_did_emsg; 25048 current_funccal = fc->caller; 25049 --depth; 25050 25051 /* If the a:000 list and the l: and a: dicts are not referenced we can 25052 * free the funccall_T and what's in it. */ 25053 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 25054 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 25055 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 25056 { 25057 free_funccal(fc, FALSE); 25058 } 25059 else 25060 { 25061 hashitem_T *hi; 25062 listitem_T *li; 25063 int todo; 25064 25065 /* "fc" is still in use. This can happen when returning "a:000" or 25066 * assigning "l:" to a global variable. 25067 * Link "fc" in the list for garbage collection later. */ 25068 fc->caller = previous_funccal; 25069 previous_funccal = fc; 25070 25071 /* Make a copy of the a: variables, since we didn't do that above. */ 25072 todo = (int)fc->l_avars.dv_hashtab.ht_used; 25073 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 25074 { 25075 if (!HASHITEM_EMPTY(hi)) 25076 { 25077 --todo; 25078 v = HI2DI(hi); 25079 copy_tv(&v->di_tv, &v->di_tv); 25080 } 25081 } 25082 25083 /* Make a copy of the a:000 items, since we didn't do that above. */ 25084 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 25085 copy_tv(&li->li_tv, &li->li_tv); 25086 } 25087 } 25088 25089 /* 25090 * Return TRUE if items in "fc" do not have "copyID". That means they are not 25091 * referenced from anywhere that is in use. 25092 */ 25093 static int 25094 can_free_funccal(funccall_T *fc, int copyID) 25095 { 25096 return (fc->l_varlist.lv_copyID != copyID 25097 && fc->l_vars.dv_copyID != copyID 25098 && fc->l_avars.dv_copyID != copyID); 25099 } 25100 25101 /* 25102 * Free "fc" and what it contains. 25103 */ 25104 static void 25105 free_funccal( 25106 funccall_T *fc, 25107 int free_val) /* a: vars were allocated */ 25108 { 25109 listitem_T *li; 25110 25111 /* The a: variables typevals may not have been allocated, only free the 25112 * allocated variables. */ 25113 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 25114 25115 /* free all l: variables */ 25116 vars_clear(&fc->l_vars.dv_hashtab); 25117 25118 /* Free the a:000 variables if they were allocated. */ 25119 if (free_val) 25120 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 25121 clear_tv(&li->li_tv); 25122 25123 vim_free(fc); 25124 } 25125 25126 /* 25127 * Add a number variable "name" to dict "dp" with value "nr". 25128 */ 25129 static void 25130 add_nr_var( 25131 dict_T *dp, 25132 dictitem_T *v, 25133 char *name, 25134 varnumber_T nr) 25135 { 25136 STRCPY(v->di_key, name); 25137 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 25138 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 25139 v->di_tv.v_type = VAR_NUMBER; 25140 v->di_tv.v_lock = VAR_FIXED; 25141 v->di_tv.vval.v_number = nr; 25142 } 25143 25144 /* 25145 * ":return [expr]" 25146 */ 25147 void 25148 ex_return(exarg_T *eap) 25149 { 25150 char_u *arg = eap->arg; 25151 typval_T rettv; 25152 int returning = FALSE; 25153 25154 if (current_funccal == NULL) 25155 { 25156 EMSG(_("E133: :return not inside a function")); 25157 return; 25158 } 25159 25160 if (eap->skip) 25161 ++emsg_skip; 25162 25163 eap->nextcmd = NULL; 25164 if ((*arg != NUL && *arg != '|' && *arg != '\n') 25165 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 25166 { 25167 if (!eap->skip) 25168 returning = do_return(eap, FALSE, TRUE, &rettv); 25169 else 25170 clear_tv(&rettv); 25171 } 25172 /* It's safer to return also on error. */ 25173 else if (!eap->skip) 25174 { 25175 /* 25176 * Return unless the expression evaluation has been cancelled due to an 25177 * aborting error, an interrupt, or an exception. 25178 */ 25179 if (!aborting()) 25180 returning = do_return(eap, FALSE, TRUE, NULL); 25181 } 25182 25183 /* When skipping or the return gets pending, advance to the next command 25184 * in this line (!returning). Otherwise, ignore the rest of the line. 25185 * Following lines will be ignored by get_func_line(). */ 25186 if (returning) 25187 eap->nextcmd = NULL; 25188 else if (eap->nextcmd == NULL) /* no argument */ 25189 eap->nextcmd = check_nextcmd(arg); 25190 25191 if (eap->skip) 25192 --emsg_skip; 25193 } 25194 25195 /* 25196 * Return from a function. Possibly makes the return pending. Also called 25197 * for a pending return at the ":endtry" or after returning from an extra 25198 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 25199 * when called due to a ":return" command. "rettv" may point to a typval_T 25200 * with the return rettv. Returns TRUE when the return can be carried out, 25201 * FALSE when the return gets pending. 25202 */ 25203 int 25204 do_return( 25205 exarg_T *eap, 25206 int reanimate, 25207 int is_cmd, 25208 void *rettv) 25209 { 25210 int idx; 25211 struct condstack *cstack = eap->cstack; 25212 25213 if (reanimate) 25214 /* Undo the return. */ 25215 current_funccal->returned = FALSE; 25216 25217 /* 25218 * Cleanup (and inactivate) conditionals, but stop when a try conditional 25219 * not in its finally clause (which then is to be executed next) is found. 25220 * In this case, make the ":return" pending for execution at the ":endtry". 25221 * Otherwise, return normally. 25222 */ 25223 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 25224 if (idx >= 0) 25225 { 25226 cstack->cs_pending[idx] = CSTP_RETURN; 25227 25228 if (!is_cmd && !reanimate) 25229 /* A pending return again gets pending. "rettv" points to an 25230 * allocated variable with the rettv of the original ":return"'s 25231 * argument if present or is NULL else. */ 25232 cstack->cs_rettv[idx] = rettv; 25233 else 25234 { 25235 /* When undoing a return in order to make it pending, get the stored 25236 * return rettv. */ 25237 if (reanimate) 25238 rettv = current_funccal->rettv; 25239 25240 if (rettv != NULL) 25241 { 25242 /* Store the value of the pending return. */ 25243 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 25244 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 25245 else 25246 EMSG(_(e_outofmem)); 25247 } 25248 else 25249 cstack->cs_rettv[idx] = NULL; 25250 25251 if (reanimate) 25252 { 25253 /* The pending return value could be overwritten by a ":return" 25254 * without argument in a finally clause; reset the default 25255 * return value. */ 25256 current_funccal->rettv->v_type = VAR_NUMBER; 25257 current_funccal->rettv->vval.v_number = 0; 25258 } 25259 } 25260 report_make_pending(CSTP_RETURN, rettv); 25261 } 25262 else 25263 { 25264 current_funccal->returned = TRUE; 25265 25266 /* If the return is carried out now, store the return value. For 25267 * a return immediately after reanimation, the value is already 25268 * there. */ 25269 if (!reanimate && rettv != NULL) 25270 { 25271 clear_tv(current_funccal->rettv); 25272 *current_funccal->rettv = *(typval_T *)rettv; 25273 if (!is_cmd) 25274 vim_free(rettv); 25275 } 25276 } 25277 25278 return idx < 0; 25279 } 25280 25281 /* 25282 * Free the variable with a pending return value. 25283 */ 25284 void 25285 discard_pending_return(void *rettv) 25286 { 25287 free_tv((typval_T *)rettv); 25288 } 25289 25290 /* 25291 * Generate a return command for producing the value of "rettv". The result 25292 * is an allocated string. Used by report_pending() for verbose messages. 25293 */ 25294 char_u * 25295 get_return_cmd(void *rettv) 25296 { 25297 char_u *s = NULL; 25298 char_u *tofree = NULL; 25299 char_u numbuf[NUMBUFLEN]; 25300 25301 if (rettv != NULL) 25302 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 25303 if (s == NULL) 25304 s = (char_u *)""; 25305 25306 STRCPY(IObuff, ":return "); 25307 STRNCPY(IObuff + 8, s, IOSIZE - 8); 25308 if (STRLEN(s) + 8 >= IOSIZE) 25309 STRCPY(IObuff + IOSIZE - 4, "..."); 25310 vim_free(tofree); 25311 return vim_strsave(IObuff); 25312 } 25313 25314 /* 25315 * Get next function line. 25316 * Called by do_cmdline() to get the next line. 25317 * Returns allocated string, or NULL for end of function. 25318 */ 25319 char_u * 25320 get_func_line( 25321 int c UNUSED, 25322 void *cookie, 25323 int indent UNUSED) 25324 { 25325 funccall_T *fcp = (funccall_T *)cookie; 25326 ufunc_T *fp = fcp->func; 25327 char_u *retval; 25328 garray_T *gap; /* growarray with function lines */ 25329 25330 /* If breakpoints have been added/deleted need to check for it. */ 25331 if (fcp->dbg_tick != debug_tick) 25332 { 25333 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 25334 sourcing_lnum); 25335 fcp->dbg_tick = debug_tick; 25336 } 25337 #ifdef FEAT_PROFILE 25338 if (do_profiling == PROF_YES) 25339 func_line_end(cookie); 25340 #endif 25341 25342 gap = &fp->uf_lines; 25343 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 25344 || fcp->returned) 25345 retval = NULL; 25346 else 25347 { 25348 /* Skip NULL lines (continuation lines). */ 25349 while (fcp->linenr < gap->ga_len 25350 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 25351 ++fcp->linenr; 25352 if (fcp->linenr >= gap->ga_len) 25353 retval = NULL; 25354 else 25355 { 25356 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 25357 sourcing_lnum = fcp->linenr; 25358 #ifdef FEAT_PROFILE 25359 if (do_profiling == PROF_YES) 25360 func_line_start(cookie); 25361 #endif 25362 } 25363 } 25364 25365 /* Did we encounter a breakpoint? */ 25366 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 25367 { 25368 dbg_breakpoint(fp->uf_name, sourcing_lnum); 25369 /* Find next breakpoint. */ 25370 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 25371 sourcing_lnum); 25372 fcp->dbg_tick = debug_tick; 25373 } 25374 25375 return retval; 25376 } 25377 25378 #if defined(FEAT_PROFILE) || defined(PROTO) 25379 /* 25380 * Called when starting to read a function line. 25381 * "sourcing_lnum" must be correct! 25382 * When skipping lines it may not actually be executed, but we won't find out 25383 * until later and we need to store the time now. 25384 */ 25385 void 25386 func_line_start(void *cookie) 25387 { 25388 funccall_T *fcp = (funccall_T *)cookie; 25389 ufunc_T *fp = fcp->func; 25390 25391 if (fp->uf_profiling && sourcing_lnum >= 1 25392 && sourcing_lnum <= fp->uf_lines.ga_len) 25393 { 25394 fp->uf_tml_idx = sourcing_lnum - 1; 25395 /* Skip continuation lines. */ 25396 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 25397 --fp->uf_tml_idx; 25398 fp->uf_tml_execed = FALSE; 25399 profile_start(&fp->uf_tml_start); 25400 profile_zero(&fp->uf_tml_children); 25401 profile_get_wait(&fp->uf_tml_wait); 25402 } 25403 } 25404 25405 /* 25406 * Called when actually executing a function line. 25407 */ 25408 void 25409 func_line_exec(void *cookie) 25410 { 25411 funccall_T *fcp = (funccall_T *)cookie; 25412 ufunc_T *fp = fcp->func; 25413 25414 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 25415 fp->uf_tml_execed = TRUE; 25416 } 25417 25418 /* 25419 * Called when done with a function line. 25420 */ 25421 void 25422 func_line_end(void *cookie) 25423 { 25424 funccall_T *fcp = (funccall_T *)cookie; 25425 ufunc_T *fp = fcp->func; 25426 25427 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 25428 { 25429 if (fp->uf_tml_execed) 25430 { 25431 ++fp->uf_tml_count[fp->uf_tml_idx]; 25432 profile_end(&fp->uf_tml_start); 25433 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 25434 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 25435 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 25436 &fp->uf_tml_children); 25437 } 25438 fp->uf_tml_idx = -1; 25439 } 25440 } 25441 #endif 25442 25443 /* 25444 * Return TRUE if the currently active function should be ended, because a 25445 * return was encountered or an error occurred. Used inside a ":while". 25446 */ 25447 int 25448 func_has_ended(void *cookie) 25449 { 25450 funccall_T *fcp = (funccall_T *)cookie; 25451 25452 /* Ignore the "abort" flag if the abortion behavior has been changed due to 25453 * an error inside a try conditional. */ 25454 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 25455 || fcp->returned); 25456 } 25457 25458 /* 25459 * return TRUE if cookie indicates a function which "abort"s on errors. 25460 */ 25461 int 25462 func_has_abort( 25463 void *cookie) 25464 { 25465 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 25466 } 25467 25468 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 25469 typedef enum 25470 { 25471 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 25472 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 25473 VAR_FLAVOUR_VIMINFO /* all uppercase */ 25474 } var_flavour_T; 25475 25476 static var_flavour_T var_flavour(char_u *varname); 25477 25478 static var_flavour_T 25479 var_flavour(char_u *varname) 25480 { 25481 char_u *p = varname; 25482 25483 if (ASCII_ISUPPER(*p)) 25484 { 25485 while (*(++p)) 25486 if (ASCII_ISLOWER(*p)) 25487 return VAR_FLAVOUR_SESSION; 25488 return VAR_FLAVOUR_VIMINFO; 25489 } 25490 else 25491 return VAR_FLAVOUR_DEFAULT; 25492 } 25493 #endif 25494 25495 #if defined(FEAT_VIMINFO) || defined(PROTO) 25496 /* 25497 * Restore global vars that start with a capital from the viminfo file 25498 */ 25499 int 25500 read_viminfo_varlist(vir_T *virp, int writing) 25501 { 25502 char_u *tab; 25503 int type = VAR_NUMBER; 25504 typval_T tv; 25505 funccall_T *save_funccal; 25506 25507 if (!writing && (find_viminfo_parameter('!') != NULL)) 25508 { 25509 tab = vim_strchr(virp->vir_line + 1, '\t'); 25510 if (tab != NULL) 25511 { 25512 *tab++ = '\0'; /* isolate the variable name */ 25513 switch (*tab) 25514 { 25515 case 'S': type = VAR_STRING; break; 25516 #ifdef FEAT_FLOAT 25517 case 'F': type = VAR_FLOAT; break; 25518 #endif 25519 case 'D': type = VAR_DICT; break; 25520 case 'L': type = VAR_LIST; break; 25521 case 'X': type = VAR_SPECIAL; break; 25522 } 25523 25524 tab = vim_strchr(tab, '\t'); 25525 if (tab != NULL) 25526 { 25527 tv.v_type = type; 25528 if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST) 25529 tv.vval.v_string = viminfo_readstring(virp, 25530 (int)(tab - virp->vir_line + 1), TRUE); 25531 #ifdef FEAT_FLOAT 25532 else if (type == VAR_FLOAT) 25533 (void)string2float(tab + 1, &tv.vval.v_float); 25534 #endif 25535 else 25536 tv.vval.v_number = atol((char *)tab + 1); 25537 if (type == VAR_DICT || type == VAR_LIST) 25538 { 25539 typval_T *etv = eval_expr(tv.vval.v_string, NULL); 25540 25541 if (etv == NULL) 25542 /* Failed to parse back the dict or list, use it as a 25543 * string. */ 25544 tv.v_type = VAR_STRING; 25545 else 25546 { 25547 vim_free(tv.vval.v_string); 25548 tv = *etv; 25549 vim_free(etv); 25550 } 25551 } 25552 25553 /* when in a function use global variables */ 25554 save_funccal = current_funccal; 25555 current_funccal = NULL; 25556 set_var(virp->vir_line + 1, &tv, FALSE); 25557 current_funccal = save_funccal; 25558 25559 if (tv.v_type == VAR_STRING) 25560 vim_free(tv.vval.v_string); 25561 else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST) 25562 clear_tv(&tv); 25563 } 25564 } 25565 } 25566 25567 return viminfo_readline(virp); 25568 } 25569 25570 /* 25571 * Write global vars that start with a capital to the viminfo file 25572 */ 25573 void 25574 write_viminfo_varlist(FILE *fp) 25575 { 25576 hashitem_T *hi; 25577 dictitem_T *this_var; 25578 int todo; 25579 char *s = ""; 25580 char_u *p; 25581 char_u *tofree; 25582 char_u numbuf[NUMBUFLEN]; 25583 25584 if (find_viminfo_parameter('!') == NULL) 25585 return; 25586 25587 fputs(_("\n# global variables:\n"), fp); 25588 25589 todo = (int)globvarht.ht_used; 25590 for (hi = globvarht.ht_array; todo > 0; ++hi) 25591 { 25592 if (!HASHITEM_EMPTY(hi)) 25593 { 25594 --todo; 25595 this_var = HI2DI(hi); 25596 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 25597 { 25598 switch (this_var->di_tv.v_type) 25599 { 25600 case VAR_STRING: s = "STR"; break; 25601 case VAR_NUMBER: s = "NUM"; break; 25602 case VAR_FLOAT: s = "FLO"; break; 25603 case VAR_DICT: s = "DIC"; break; 25604 case VAR_LIST: s = "LIS"; break; 25605 case VAR_SPECIAL: s = "XPL"; break; 25606 25607 case VAR_UNKNOWN: 25608 case VAR_FUNC: 25609 case VAR_PARTIAL: 25610 case VAR_JOB: 25611 case VAR_CHANNEL: 25612 continue; 25613 } 25614 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 25615 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 25616 if (p != NULL) 25617 viminfo_writestring(fp, p); 25618 vim_free(tofree); 25619 } 25620 } 25621 } 25622 } 25623 #endif 25624 25625 #if defined(FEAT_SESSION) || defined(PROTO) 25626 int 25627 store_session_globals(FILE *fd) 25628 { 25629 hashitem_T *hi; 25630 dictitem_T *this_var; 25631 int todo; 25632 char_u *p, *t; 25633 25634 todo = (int)globvarht.ht_used; 25635 for (hi = globvarht.ht_array; todo > 0; ++hi) 25636 { 25637 if (!HASHITEM_EMPTY(hi)) 25638 { 25639 --todo; 25640 this_var = HI2DI(hi); 25641 if ((this_var->di_tv.v_type == VAR_NUMBER 25642 || this_var->di_tv.v_type == VAR_STRING) 25643 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 25644 { 25645 /* Escape special characters with a backslash. Turn a LF and 25646 * CR into \n and \r. */ 25647 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 25648 (char_u *)"\\\"\n\r"); 25649 if (p == NULL) /* out of memory */ 25650 break; 25651 for (t = p; *t != NUL; ++t) 25652 if (*t == '\n') 25653 *t = 'n'; 25654 else if (*t == '\r') 25655 *t = 'r'; 25656 if ((fprintf(fd, "let %s = %c%s%c", 25657 this_var->di_key, 25658 (this_var->di_tv.v_type == VAR_STRING) ? '"' 25659 : ' ', 25660 p, 25661 (this_var->di_tv.v_type == VAR_STRING) ? '"' 25662 : ' ') < 0) 25663 || put_eol(fd) == FAIL) 25664 { 25665 vim_free(p); 25666 return FAIL; 25667 } 25668 vim_free(p); 25669 } 25670 #ifdef FEAT_FLOAT 25671 else if (this_var->di_tv.v_type == VAR_FLOAT 25672 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 25673 { 25674 float_T f = this_var->di_tv.vval.v_float; 25675 int sign = ' '; 25676 25677 if (f < 0) 25678 { 25679 f = -f; 25680 sign = '-'; 25681 } 25682 if ((fprintf(fd, "let %s = %c%f", 25683 this_var->di_key, sign, f) < 0) 25684 || put_eol(fd) == FAIL) 25685 return FAIL; 25686 } 25687 #endif 25688 } 25689 } 25690 return OK; 25691 } 25692 #endif 25693 25694 /* 25695 * Display script name where an item was last set. 25696 * Should only be invoked when 'verbose' is non-zero. 25697 */ 25698 void 25699 last_set_msg(scid_T scriptID) 25700 { 25701 char_u *p; 25702 25703 if (scriptID != 0) 25704 { 25705 p = home_replace_save(NULL, get_scriptname(scriptID)); 25706 if (p != NULL) 25707 { 25708 verbose_enter(); 25709 MSG_PUTS(_("\n\tLast set from ")); 25710 MSG_PUTS(p); 25711 vim_free(p); 25712 verbose_leave(); 25713 } 25714 } 25715 } 25716 25717 /* 25718 * List v:oldfiles in a nice way. 25719 */ 25720 void 25721 ex_oldfiles(exarg_T *eap UNUSED) 25722 { 25723 list_T *l = vimvars[VV_OLDFILES].vv_list; 25724 listitem_T *li; 25725 int nr = 0; 25726 25727 if (l == NULL) 25728 msg((char_u *)_("No old files")); 25729 else 25730 { 25731 msg_start(); 25732 msg_scroll = TRUE; 25733 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 25734 { 25735 msg_outnum((long)++nr); 25736 MSG_PUTS(": "); 25737 msg_outtrans(get_tv_string(&li->li_tv)); 25738 msg_putchar('\n'); 25739 out_flush(); /* output one line at a time */ 25740 ui_breakcheck(); 25741 } 25742 /* Assume "got_int" was set to truncate the listing. */ 25743 got_int = FALSE; 25744 25745 #ifdef FEAT_BROWSE_CMD 25746 if (cmdmod.browse) 25747 { 25748 quit_more = FALSE; 25749 nr = prompt_for_number(FALSE); 25750 msg_starthere(); 25751 if (nr > 0) 25752 { 25753 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 25754 (long)nr); 25755 25756 if (p != NULL) 25757 { 25758 p = expand_env_save(p); 25759 eap->arg = p; 25760 eap->cmdidx = CMD_edit; 25761 cmdmod.browse = FALSE; 25762 do_exedit(eap, NULL); 25763 vim_free(p); 25764 } 25765 } 25766 } 25767 #endif 25768 } 25769 } 25770 25771 /* reset v:option_new, v:option_old and v:option_type */ 25772 void 25773 reset_v_option_vars(void) 25774 { 25775 set_vim_var_string(VV_OPTION_NEW, NULL, -1); 25776 set_vim_var_string(VV_OPTION_OLD, NULL, -1); 25777 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); 25778 } 25779 25780 25781 #endif /* FEAT_EVAL */ 25782 25783 25784 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 25785 25786 #ifdef WIN3264 25787 /* 25788 * Functions for ":8" filename modifier: get 8.3 version of a filename. 25789 */ 25790 static int get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen); 25791 static int shortpath_for_invalid_fname(char_u **fname, char_u **bufp, int *fnamelen); 25792 static int shortpath_for_partial(char_u **fnamep, char_u **bufp, int *fnamelen); 25793 25794 /* 25795 * Get the short path (8.3) for the filename in "fnamep". 25796 * Only works for a valid file name. 25797 * When the path gets longer "fnamep" is changed and the allocated buffer 25798 * is put in "bufp". 25799 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 25800 * Returns OK on success, FAIL on failure. 25801 */ 25802 static int 25803 get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen) 25804 { 25805 int l, len; 25806 char_u *newbuf; 25807 25808 len = *fnamelen; 25809 l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len); 25810 if (l > len - 1) 25811 { 25812 /* If that doesn't work (not enough space), then save the string 25813 * and try again with a new buffer big enough. */ 25814 newbuf = vim_strnsave(*fnamep, l); 25815 if (newbuf == NULL) 25816 return FAIL; 25817 25818 vim_free(*bufp); 25819 *fnamep = *bufp = newbuf; 25820 25821 /* Really should always succeed, as the buffer is big enough. */ 25822 l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1); 25823 } 25824 25825 *fnamelen = l; 25826 return OK; 25827 } 25828 25829 /* 25830 * Get the short path (8.3) for the filename in "fname". The converted 25831 * path is returned in "bufp". 25832 * 25833 * Some of the directories specified in "fname" may not exist. This function 25834 * will shorten the existing directories at the beginning of the path and then 25835 * append the remaining non-existing path. 25836 * 25837 * fname - Pointer to the filename to shorten. On return, contains the 25838 * pointer to the shortened pathname 25839 * bufp - Pointer to an allocated buffer for the filename. 25840 * fnamelen - Length of the filename pointed to by fname 25841 * 25842 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 25843 */ 25844 static int 25845 shortpath_for_invalid_fname( 25846 char_u **fname, 25847 char_u **bufp, 25848 int *fnamelen) 25849 { 25850 char_u *short_fname, *save_fname, *pbuf_unused; 25851 char_u *endp, *save_endp; 25852 char_u ch; 25853 int old_len, len; 25854 int new_len, sfx_len; 25855 int retval = OK; 25856 25857 /* Make a copy */ 25858 old_len = *fnamelen; 25859 save_fname = vim_strnsave(*fname, old_len); 25860 pbuf_unused = NULL; 25861 short_fname = NULL; 25862 25863 endp = save_fname + old_len - 1; /* Find the end of the copy */ 25864 save_endp = endp; 25865 25866 /* 25867 * Try shortening the supplied path till it succeeds by removing one 25868 * directory at a time from the tail of the path. 25869 */ 25870 len = 0; 25871 for (;;) 25872 { 25873 /* go back one path-separator */ 25874 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 25875 --endp; 25876 if (endp <= save_fname) 25877 break; /* processed the complete path */ 25878 25879 /* 25880 * Replace the path separator with a NUL and try to shorten the 25881 * resulting path. 25882 */ 25883 ch = *endp; 25884 *endp = 0; 25885 short_fname = save_fname; 25886 len = (int)STRLEN(short_fname) + 1; 25887 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 25888 { 25889 retval = FAIL; 25890 goto theend; 25891 } 25892 *endp = ch; /* preserve the string */ 25893 25894 if (len > 0) 25895 break; /* successfully shortened the path */ 25896 25897 /* failed to shorten the path. Skip the path separator */ 25898 --endp; 25899 } 25900 25901 if (len > 0) 25902 { 25903 /* 25904 * Succeeded in shortening the path. Now concatenate the shortened 25905 * path with the remaining path at the tail. 25906 */ 25907 25908 /* Compute the length of the new path. */ 25909 sfx_len = (int)(save_endp - endp) + 1; 25910 new_len = len + sfx_len; 25911 25912 *fnamelen = new_len; 25913 vim_free(*bufp); 25914 if (new_len > old_len) 25915 { 25916 /* There is not enough space in the currently allocated string, 25917 * copy it to a buffer big enough. */ 25918 *fname = *bufp = vim_strnsave(short_fname, new_len); 25919 if (*fname == NULL) 25920 { 25921 retval = FAIL; 25922 goto theend; 25923 } 25924 } 25925 else 25926 { 25927 /* Transfer short_fname to the main buffer (it's big enough), 25928 * unless get_short_pathname() did its work in-place. */ 25929 *fname = *bufp = save_fname; 25930 if (short_fname != save_fname) 25931 vim_strncpy(save_fname, short_fname, len); 25932 save_fname = NULL; 25933 } 25934 25935 /* concat the not-shortened part of the path */ 25936 vim_strncpy(*fname + len, endp, sfx_len); 25937 (*fname)[new_len] = NUL; 25938 } 25939 25940 theend: 25941 vim_free(pbuf_unused); 25942 vim_free(save_fname); 25943 25944 return retval; 25945 } 25946 25947 /* 25948 * Get a pathname for a partial path. 25949 * Returns OK for success, FAIL for failure. 25950 */ 25951 static int 25952 shortpath_for_partial( 25953 char_u **fnamep, 25954 char_u **bufp, 25955 int *fnamelen) 25956 { 25957 int sepcount, len, tflen; 25958 char_u *p; 25959 char_u *pbuf, *tfname; 25960 int hasTilde; 25961 25962 /* Count up the path separators from the RHS.. so we know which part 25963 * of the path to return. */ 25964 sepcount = 0; 25965 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 25966 if (vim_ispathsep(*p)) 25967 ++sepcount; 25968 25969 /* Need full path first (use expand_env() to remove a "~/") */ 25970 hasTilde = (**fnamep == '~'); 25971 if (hasTilde) 25972 pbuf = tfname = expand_env_save(*fnamep); 25973 else 25974 pbuf = tfname = FullName_save(*fnamep, FALSE); 25975 25976 len = tflen = (int)STRLEN(tfname); 25977 25978 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 25979 return FAIL; 25980 25981 if (len == 0) 25982 { 25983 /* Don't have a valid filename, so shorten the rest of the 25984 * path if we can. This CAN give us invalid 8.3 filenames, but 25985 * there's not a lot of point in guessing what it might be. 25986 */ 25987 len = tflen; 25988 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 25989 return FAIL; 25990 } 25991 25992 /* Count the paths backward to find the beginning of the desired string. */ 25993 for (p = tfname + len - 1; p >= tfname; --p) 25994 { 25995 #ifdef FEAT_MBYTE 25996 if (has_mbyte) 25997 p -= mb_head_off(tfname, p); 25998 #endif 25999 if (vim_ispathsep(*p)) 26000 { 26001 if (sepcount == 0 || (hasTilde && sepcount == 1)) 26002 break; 26003 else 26004 sepcount --; 26005 } 26006 } 26007 if (hasTilde) 26008 { 26009 --p; 26010 if (p >= tfname) 26011 *p = '~'; 26012 else 26013 return FAIL; 26014 } 26015 else 26016 ++p; 26017 26018 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 26019 vim_free(*bufp); 26020 *fnamelen = (int)STRLEN(p); 26021 *bufp = pbuf; 26022 *fnamep = p; 26023 26024 return OK; 26025 } 26026 #endif /* WIN3264 */ 26027 26028 /* 26029 * Adjust a filename, according to a string of modifiers. 26030 * *fnamep must be NUL terminated when called. When returning, the length is 26031 * determined by *fnamelen. 26032 * Returns VALID_ flags or -1 for failure. 26033 * When there is an error, *fnamep is set to NULL. 26034 */ 26035 int 26036 modify_fname( 26037 char_u *src, /* string with modifiers */ 26038 int *usedlen, /* characters after src that are used */ 26039 char_u **fnamep, /* file name so far */ 26040 char_u **bufp, /* buffer for allocated file name or NULL */ 26041 int *fnamelen) /* length of fnamep */ 26042 { 26043 int valid = 0; 26044 char_u *tail; 26045 char_u *s, *p, *pbuf; 26046 char_u dirname[MAXPATHL]; 26047 int c; 26048 int has_fullname = 0; 26049 #ifdef WIN3264 26050 char_u *fname_start = *fnamep; 26051 int has_shortname = 0; 26052 #endif 26053 26054 repeat: 26055 /* ":p" - full path/file_name */ 26056 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 26057 { 26058 has_fullname = 1; 26059 26060 valid |= VALID_PATH; 26061 *usedlen += 2; 26062 26063 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 26064 if ((*fnamep)[0] == '~' 26065 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 26066 && ((*fnamep)[1] == '/' 26067 # ifdef BACKSLASH_IN_FILENAME 26068 || (*fnamep)[1] == '\\' 26069 # endif 26070 || (*fnamep)[1] == NUL) 26071 26072 #endif 26073 ) 26074 { 26075 *fnamep = expand_env_save(*fnamep); 26076 vim_free(*bufp); /* free any allocated file name */ 26077 *bufp = *fnamep; 26078 if (*fnamep == NULL) 26079 return -1; 26080 } 26081 26082 /* When "/." or "/.." is used: force expansion to get rid of it. */ 26083 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 26084 { 26085 if (vim_ispathsep(*p) 26086 && p[1] == '.' 26087 && (p[2] == NUL 26088 || vim_ispathsep(p[2]) 26089 || (p[2] == '.' 26090 && (p[3] == NUL || vim_ispathsep(p[3]))))) 26091 break; 26092 } 26093 26094 /* FullName_save() is slow, don't use it when not needed. */ 26095 if (*p != NUL || !vim_isAbsName(*fnamep)) 26096 { 26097 *fnamep = FullName_save(*fnamep, *p != NUL); 26098 vim_free(*bufp); /* free any allocated file name */ 26099 *bufp = *fnamep; 26100 if (*fnamep == NULL) 26101 return -1; 26102 } 26103 26104 #ifdef WIN3264 26105 # if _WIN32_WINNT >= 0x0500 26106 if (vim_strchr(*fnamep, '~') != NULL) 26107 { 26108 /* Expand 8.3 filename to full path. Needed to make sure the same 26109 * file does not have two different names. 26110 * Note: problem does not occur if _WIN32_WINNT < 0x0500. */ 26111 p = alloc(_MAX_PATH + 1); 26112 if (p != NULL) 26113 { 26114 if (GetLongPathName((LPSTR)*fnamep, (LPSTR)p, _MAX_PATH)) 26115 { 26116 vim_free(*bufp); 26117 *bufp = *fnamep = p; 26118 } 26119 else 26120 vim_free(p); 26121 } 26122 } 26123 # endif 26124 #endif 26125 /* Append a path separator to a directory. */ 26126 if (mch_isdir(*fnamep)) 26127 { 26128 /* Make room for one or two extra characters. */ 26129 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 26130 vim_free(*bufp); /* free any allocated file name */ 26131 *bufp = *fnamep; 26132 if (*fnamep == NULL) 26133 return -1; 26134 add_pathsep(*fnamep); 26135 } 26136 } 26137 26138 /* ":." - path relative to the current directory */ 26139 /* ":~" - path relative to the home directory */ 26140 /* ":8" - shortname path - postponed till after */ 26141 while (src[*usedlen] == ':' 26142 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 26143 { 26144 *usedlen += 2; 26145 if (c == '8') 26146 { 26147 #ifdef WIN3264 26148 has_shortname = 1; /* Postpone this. */ 26149 #endif 26150 continue; 26151 } 26152 pbuf = NULL; 26153 /* Need full path first (use expand_env() to remove a "~/") */ 26154 if (!has_fullname) 26155 { 26156 if (c == '.' && **fnamep == '~') 26157 p = pbuf = expand_env_save(*fnamep); 26158 else 26159 p = pbuf = FullName_save(*fnamep, FALSE); 26160 } 26161 else 26162 p = *fnamep; 26163 26164 has_fullname = 0; 26165 26166 if (p != NULL) 26167 { 26168 if (c == '.') 26169 { 26170 mch_dirname(dirname, MAXPATHL); 26171 s = shorten_fname(p, dirname); 26172 if (s != NULL) 26173 { 26174 *fnamep = s; 26175 if (pbuf != NULL) 26176 { 26177 vim_free(*bufp); /* free any allocated file name */ 26178 *bufp = pbuf; 26179 pbuf = NULL; 26180 } 26181 } 26182 } 26183 else 26184 { 26185 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 26186 /* Only replace it when it starts with '~' */ 26187 if (*dirname == '~') 26188 { 26189 s = vim_strsave(dirname); 26190 if (s != NULL) 26191 { 26192 *fnamep = s; 26193 vim_free(*bufp); 26194 *bufp = s; 26195 } 26196 } 26197 } 26198 vim_free(pbuf); 26199 } 26200 } 26201 26202 tail = gettail(*fnamep); 26203 *fnamelen = (int)STRLEN(*fnamep); 26204 26205 /* ":h" - head, remove "/file_name", can be repeated */ 26206 /* Don't remove the first "/" or "c:\" */ 26207 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 26208 { 26209 valid |= VALID_HEAD; 26210 *usedlen += 2; 26211 s = get_past_head(*fnamep); 26212 while (tail > s && after_pathsep(s, tail)) 26213 mb_ptr_back(*fnamep, tail); 26214 *fnamelen = (int)(tail - *fnamep); 26215 #ifdef VMS 26216 if (*fnamelen > 0) 26217 *fnamelen += 1; /* the path separator is part of the path */ 26218 #endif 26219 if (*fnamelen == 0) 26220 { 26221 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 26222 p = vim_strsave((char_u *)"."); 26223 if (p == NULL) 26224 return -1; 26225 vim_free(*bufp); 26226 *bufp = *fnamep = tail = p; 26227 *fnamelen = 1; 26228 } 26229 else 26230 { 26231 while (tail > s && !after_pathsep(s, tail)) 26232 mb_ptr_back(*fnamep, tail); 26233 } 26234 } 26235 26236 /* ":8" - shortname */ 26237 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 26238 { 26239 *usedlen += 2; 26240 #ifdef WIN3264 26241 has_shortname = 1; 26242 #endif 26243 } 26244 26245 #ifdef WIN3264 26246 /* 26247 * Handle ":8" after we have done 'heads' and before we do 'tails'. 26248 */ 26249 if (has_shortname) 26250 { 26251 /* Copy the string if it is shortened by :h and when it wasn't copied 26252 * yet, because we are going to change it in place. Avoids changing 26253 * the buffer name for "%:8". */ 26254 if (*fnamelen < (int)STRLEN(*fnamep) || *fnamep == fname_start) 26255 { 26256 p = vim_strnsave(*fnamep, *fnamelen); 26257 if (p == NULL) 26258 return -1; 26259 vim_free(*bufp); 26260 *bufp = *fnamep = p; 26261 } 26262 26263 /* Split into two implementations - makes it easier. First is where 26264 * there isn't a full name already, second is where there is. */ 26265 if (!has_fullname && !vim_isAbsName(*fnamep)) 26266 { 26267 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 26268 return -1; 26269 } 26270 else 26271 { 26272 int l = *fnamelen; 26273 26274 /* Simple case, already have the full-name. 26275 * Nearly always shorter, so try first time. */ 26276 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 26277 return -1; 26278 26279 if (l == 0) 26280 { 26281 /* Couldn't find the filename, search the paths. */ 26282 l = *fnamelen; 26283 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 26284 return -1; 26285 } 26286 *fnamelen = l; 26287 } 26288 } 26289 #endif /* WIN3264 */ 26290 26291 /* ":t" - tail, just the basename */ 26292 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 26293 { 26294 *usedlen += 2; 26295 *fnamelen -= (int)(tail - *fnamep); 26296 *fnamep = tail; 26297 } 26298 26299 /* ":e" - extension, can be repeated */ 26300 /* ":r" - root, without extension, can be repeated */ 26301 while (src[*usedlen] == ':' 26302 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 26303 { 26304 /* find a '.' in the tail: 26305 * - for second :e: before the current fname 26306 * - otherwise: The last '.' 26307 */ 26308 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 26309 s = *fnamep - 2; 26310 else 26311 s = *fnamep + *fnamelen - 1; 26312 for ( ; s > tail; --s) 26313 if (s[0] == '.') 26314 break; 26315 if (src[*usedlen + 1] == 'e') /* :e */ 26316 { 26317 if (s > tail) 26318 { 26319 *fnamelen += (int)(*fnamep - (s + 1)); 26320 *fnamep = s + 1; 26321 #ifdef VMS 26322 /* cut version from the extension */ 26323 s = *fnamep + *fnamelen - 1; 26324 for ( ; s > *fnamep; --s) 26325 if (s[0] == ';') 26326 break; 26327 if (s > *fnamep) 26328 *fnamelen = s - *fnamep; 26329 #endif 26330 } 26331 else if (*fnamep <= tail) 26332 *fnamelen = 0; 26333 } 26334 else /* :r */ 26335 { 26336 if (s > tail) /* remove one extension */ 26337 *fnamelen = (int)(s - *fnamep); 26338 } 26339 *usedlen += 2; 26340 } 26341 26342 /* ":s?pat?foo?" - substitute */ 26343 /* ":gs?pat?foo?" - global substitute */ 26344 if (src[*usedlen] == ':' 26345 && (src[*usedlen + 1] == 's' 26346 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 26347 { 26348 char_u *str; 26349 char_u *pat; 26350 char_u *sub; 26351 int sep; 26352 char_u *flags; 26353 int didit = FALSE; 26354 26355 flags = (char_u *)""; 26356 s = src + *usedlen + 2; 26357 if (src[*usedlen + 1] == 'g') 26358 { 26359 flags = (char_u *)"g"; 26360 ++s; 26361 } 26362 26363 sep = *s++; 26364 if (sep) 26365 { 26366 /* find end of pattern */ 26367 p = vim_strchr(s, sep); 26368 if (p != NULL) 26369 { 26370 pat = vim_strnsave(s, (int)(p - s)); 26371 if (pat != NULL) 26372 { 26373 s = p + 1; 26374 /* find end of substitution */ 26375 p = vim_strchr(s, sep); 26376 if (p != NULL) 26377 { 26378 sub = vim_strnsave(s, (int)(p - s)); 26379 str = vim_strnsave(*fnamep, *fnamelen); 26380 if (sub != NULL && str != NULL) 26381 { 26382 *usedlen = (int)(p + 1 - src); 26383 s = do_string_sub(str, pat, sub, flags); 26384 if (s != NULL) 26385 { 26386 *fnamep = s; 26387 *fnamelen = (int)STRLEN(s); 26388 vim_free(*bufp); 26389 *bufp = s; 26390 didit = TRUE; 26391 } 26392 } 26393 vim_free(sub); 26394 vim_free(str); 26395 } 26396 vim_free(pat); 26397 } 26398 } 26399 /* after using ":s", repeat all the modifiers */ 26400 if (didit) 26401 goto repeat; 26402 } 26403 } 26404 26405 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S') 26406 { 26407 p = vim_strsave_shellescape(*fnamep, FALSE, FALSE); 26408 if (p == NULL) 26409 return -1; 26410 vim_free(*bufp); 26411 *bufp = *fnamep = p; 26412 *fnamelen = (int)STRLEN(p); 26413 *usedlen += 2; 26414 } 26415 26416 return valid; 26417 } 26418 26419 /* 26420 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 26421 * "flags" can be "g" to do a global substitute. 26422 * Returns an allocated string, NULL for error. 26423 */ 26424 char_u * 26425 do_string_sub( 26426 char_u *str, 26427 char_u *pat, 26428 char_u *sub, 26429 char_u *flags) 26430 { 26431 int sublen; 26432 regmatch_T regmatch; 26433 int i; 26434 int do_all; 26435 char_u *tail; 26436 char_u *end; 26437 garray_T ga; 26438 char_u *ret; 26439 char_u *save_cpo; 26440 char_u *zero_width = NULL; 26441 26442 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 26443 save_cpo = p_cpo; 26444 p_cpo = empty_option; 26445 26446 ga_init2(&ga, 1, 200); 26447 26448 do_all = (flags[0] == 'g'); 26449 26450 regmatch.rm_ic = p_ic; 26451 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 26452 if (regmatch.regprog != NULL) 26453 { 26454 tail = str; 26455 end = str + STRLEN(str); 26456 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 26457 { 26458 /* Skip empty match except for first match. */ 26459 if (regmatch.startp[0] == regmatch.endp[0]) 26460 { 26461 if (zero_width == regmatch.startp[0]) 26462 { 26463 /* avoid getting stuck on a match with an empty string */ 26464 i = MB_PTR2LEN(tail); 26465 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, 26466 (size_t)i); 26467 ga.ga_len += i; 26468 tail += i; 26469 continue; 26470 } 26471 zero_width = regmatch.startp[0]; 26472 } 26473 26474 /* 26475 * Get some space for a temporary buffer to do the substitution 26476 * into. It will contain: 26477 * - The text up to where the match is. 26478 * - The substituted text. 26479 * - The text after the match. 26480 */ 26481 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 26482 if (ga_grow(&ga, (int)((end - tail) + sublen - 26483 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 26484 { 26485 ga_clear(&ga); 26486 break; 26487 } 26488 26489 /* copy the text up to where the match is */ 26490 i = (int)(regmatch.startp[0] - tail); 26491 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 26492 /* add the substituted text */ 26493 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 26494 + ga.ga_len + i, TRUE, TRUE, FALSE); 26495 ga.ga_len += i + sublen - 1; 26496 tail = regmatch.endp[0]; 26497 if (*tail == NUL) 26498 break; 26499 if (!do_all) 26500 break; 26501 } 26502 26503 if (ga.ga_data != NULL) 26504 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 26505 26506 vim_regfree(regmatch.regprog); 26507 } 26508 26509 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 26510 ga_clear(&ga); 26511 if (p_cpo == empty_option) 26512 p_cpo = save_cpo; 26513 else 26514 /* Darn, evaluating {sub} expression changed the value. */ 26515 free_string_option(save_cpo); 26516 26517 return ret; 26518 } 26519 26520 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 26521