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 14 #include "vim.h" 15 16 #if defined(FEAT_EVAL) || defined(PROTO) 17 18 #ifdef AMIGA 19 # include <time.h> /* for strftime() */ 20 #endif 21 22 #ifdef VMS 23 # include <float.h> 24 #endif 25 26 #ifdef MACOS 27 # include <time.h> /* for time_t */ 28 #endif 29 30 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 31 # include <math.h> 32 #endif 33 34 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 35 36 #define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not 37 be freed. */ 38 39 /* 40 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 41 * This avoids adding a pointer to the hashtab item. 42 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 43 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 44 * HI2DI() converts a hashitem pointer to a dictitem pointer. 45 */ 46 static dictitem_T dumdi; 47 #define DI2HIKEY(di) ((di)->di_key) 48 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 49 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 50 51 /* 52 * Structure returned by get_lval() and used by set_var_lval(). 53 * For a plain name: 54 * "name" points to the variable name. 55 * "exp_name" is NULL. 56 * "tv" is NULL 57 * For a magic braces name: 58 * "name" points to the expanded variable name. 59 * "exp_name" is non-NULL, to be freed later. 60 * "tv" is NULL 61 * For an index in a list: 62 * "name" points to the (expanded) variable name. 63 * "exp_name" NULL or non-NULL, to be freed later. 64 * "tv" points to the (first) list item value 65 * "li" points to the (first) list item 66 * "range", "n1", "n2" and "empty2" indicate what items are used. 67 * For an existing Dict item: 68 * "name" points to the (expanded) variable name. 69 * "exp_name" NULL or non-NULL, to be freed later. 70 * "tv" points to the dict item value 71 * "newkey" is NULL 72 * For a non-existing Dict item: 73 * "name" points to the (expanded) variable name. 74 * "exp_name" NULL or non-NULL, to be freed later. 75 * "tv" points to the Dictionary typval_T 76 * "newkey" is the key for the new item. 77 */ 78 typedef struct lval_S 79 { 80 char_u *ll_name; /* start of variable name (can be NULL) */ 81 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 82 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 83 isn't NULL it's the Dict to which to add 84 the item. */ 85 listitem_T *ll_li; /* The list item or NULL. */ 86 list_T *ll_list; /* The list or NULL. */ 87 int ll_range; /* TRUE when a [i:j] range was used */ 88 long ll_n1; /* First index for list */ 89 long ll_n2; /* Second index for list range */ 90 int ll_empty2; /* Second index is empty: [i:] */ 91 dict_T *ll_dict; /* The Dictionary or NULL */ 92 dictitem_T *ll_di; /* The dictitem or NULL */ 93 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 94 } lval_T; 95 96 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 97 static char *e_listidx = N_("E684: list index out of range: %ld"); 98 static char *e_undefvar = N_("E121: Undefined variable: %s"); 99 static char *e_missbrac = N_("E111: Missing ']'"); 100 static char *e_listarg = N_("E686: Argument of %s must be a List"); 101 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 102 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 103 static char *e_listreq = N_("E714: List required"); 104 static char *e_dictreq = N_("E715: Dictionary required"); 105 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 106 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 107 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 108 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 109 static char *e_funcref = N_("E718: Funcref required"); 110 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 111 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 112 static char *e_nofunc = N_("E130: Unknown function: %s"); 113 static char *e_illvar = N_("E461: Illegal variable name: %s"); 114 #ifdef FEAT_FLOAT 115 static char *e_float_as_string = N_("E806: using Float as a String"); 116 #endif 117 118 static dictitem_T globvars_var; /* variable used for g: */ 119 #define globvarht globvardict.dv_hashtab 120 121 /* 122 * Old Vim variables such as "v:version" are also available without the "v:". 123 * Also in functions. We need a special hashtable for them. 124 */ 125 static hashtab_T compat_hashtab; 126 127 /* 128 * When recursively copying lists and dicts we need to remember which ones we 129 * have done to avoid endless recursiveness. This unique ID is used for that. 130 * The last bit is used for previous_funccal, ignored when comparing. 131 */ 132 static int current_copyID = 0; 133 #define COPYID_INC 2 134 #define COPYID_MASK (~0x1) 135 136 /* Abort conversion to string after a recursion error. */ 137 static int did_echo_string_emsg = FALSE; 138 139 /* 140 * Array to hold the hashtab with variables local to each sourced script. 141 * Each item holds a variable (nameless) that points to the dict_T. 142 */ 143 typedef struct 144 { 145 dictitem_T sv_var; 146 dict_T sv_dict; 147 } scriptvar_T; 148 149 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; 150 #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) 151 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) 152 153 static int echo_attr = 0; /* attributes used for ":echo" */ 154 155 /* Values for trans_function_name() argument: */ 156 #define TFN_INT 1 /* internal function name OK */ 157 #define TFN_QUIET 2 /* no error messages */ 158 #define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */ 159 160 /* Values for get_lval() flags argument: */ 161 #define GLV_QUIET TFN_QUIET /* no error messages */ 162 #define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */ 163 164 /* 165 * Structure to hold info for a user function. 166 */ 167 typedef struct ufunc ufunc_T; 168 169 struct ufunc 170 { 171 int uf_varargs; /* variable nr of arguments */ 172 int uf_flags; 173 int uf_calls; /* nr of active calls */ 174 garray_T uf_args; /* arguments */ 175 garray_T uf_lines; /* function lines */ 176 #ifdef FEAT_PROFILE 177 int uf_profiling; /* TRUE when func is being profiled */ 178 /* profiling the function as a whole */ 179 int uf_tm_count; /* nr of calls */ 180 proftime_T uf_tm_total; /* time spent in function + children */ 181 proftime_T uf_tm_self; /* time spent in function itself */ 182 proftime_T uf_tm_children; /* time spent in children this call */ 183 /* profiling the function per line */ 184 int *uf_tml_count; /* nr of times line was executed */ 185 proftime_T *uf_tml_total; /* time spent in a line + children */ 186 proftime_T *uf_tml_self; /* time spent in a line itself */ 187 proftime_T uf_tml_start; /* start time for current line */ 188 proftime_T uf_tml_children; /* time spent in children for this line */ 189 proftime_T uf_tml_wait; /* start wait time for current line */ 190 int uf_tml_idx; /* index of line being timed; -1 if none */ 191 int uf_tml_execed; /* line being timed was executed */ 192 #endif 193 scid_T uf_script_ID; /* ID of script where function was defined, 194 used for s: variables */ 195 int uf_refcount; /* for numbered function: reference count */ 196 char_u uf_name[1]; /* name of function (actually longer); can 197 start with <SNR>123_ (<SNR> is K_SPECIAL 198 KS_EXTRA KE_SNR) */ 199 }; 200 201 /* function flags */ 202 #define FC_ABORT 1 /* abort function on error */ 203 #define FC_RANGE 2 /* function accepts range */ 204 #define FC_DICT 4 /* Dict function, uses "self" */ 205 206 /* 207 * All user-defined functions are found in this hashtable. 208 */ 209 static hashtab_T func_hashtab; 210 211 /* The names of packages that once were loaded are remembered. */ 212 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 213 214 /* list heads for garbage collection */ 215 static dict_T *first_dict = NULL; /* list of all dicts */ 216 static list_T *first_list = NULL; /* list of all lists */ 217 218 /* From user function to hashitem and back. */ 219 static ufunc_T dumuf; 220 #define UF2HIKEY(fp) ((fp)->uf_name) 221 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 222 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 223 224 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 225 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 226 227 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 228 #define VAR_SHORT_LEN 20 /* short variable name length */ 229 #define FIXVAR_CNT 12 /* number of fixed variables */ 230 231 /* structure to hold info for a function that is currently being executed. */ 232 typedef struct funccall_S funccall_T; 233 234 struct funccall_S 235 { 236 ufunc_T *func; /* function being called */ 237 int linenr; /* next line to be executed */ 238 int returned; /* ":return" used */ 239 struct /* fixed variables for arguments */ 240 { 241 dictitem_T var; /* variable (without room for name) */ 242 char_u room[VAR_SHORT_LEN]; /* room for the name */ 243 } fixvar[FIXVAR_CNT]; 244 dict_T l_vars; /* l: local function variables */ 245 dictitem_T l_vars_var; /* variable for l: scope */ 246 dict_T l_avars; /* a: argument variables */ 247 dictitem_T l_avars_var; /* variable for a: scope */ 248 list_T l_varlist; /* list for a:000 */ 249 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 250 typval_T *rettv; /* return value */ 251 linenr_T breakpoint; /* next line with breakpoint or zero */ 252 int dbg_tick; /* debug_tick when breakpoint was set */ 253 int level; /* top nesting level of executed function */ 254 #ifdef FEAT_PROFILE 255 proftime_T prof_child; /* time spent in a child */ 256 #endif 257 funccall_T *caller; /* calling function or NULL */ 258 }; 259 260 /* 261 * Info used by a ":for" loop. 262 */ 263 typedef struct 264 { 265 int fi_semicolon; /* TRUE if ending in '; var]' */ 266 int fi_varcount; /* nr of variables in the list */ 267 listwatch_T fi_lw; /* keep an eye on the item used. */ 268 list_T *fi_list; /* list being used */ 269 } forinfo_T; 270 271 /* 272 * Struct used by trans_function_name() 273 */ 274 typedef struct 275 { 276 dict_T *fd_dict; /* Dictionary used */ 277 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 278 dictitem_T *fd_di; /* Dictionary item used */ 279 } funcdict_T; 280 281 282 /* 283 * Array to hold the value of v: variables. 284 * The value is in a dictitem, so that it can also be used in the v: scope. 285 * The reason to use this table anyway is for very quick access to the 286 * variables with the VV_ defines. 287 */ 288 #include "version.h" 289 290 /* values for vv_flags: */ 291 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 292 #define VV_RO 2 /* read-only */ 293 #define VV_RO_SBX 4 /* read-only in the sandbox */ 294 295 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}, {0} 296 297 static struct vimvar 298 { 299 char *vv_name; /* name of variable, without v: */ 300 dictitem_T vv_di; /* value and name for key */ 301 char vv_filler[16]; /* space for LONGEST name below!!! */ 302 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 303 } vimvars[VV_LEN] = 304 { 305 /* 306 * The order here must match the VV_ defines in vim.h! 307 * Initializing a union does not work, leave tv.vval empty to get zero's. 308 */ 309 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 310 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 311 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 312 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 313 {VV_NAME("warningmsg", VAR_STRING), 0}, 314 {VV_NAME("statusmsg", VAR_STRING), 0}, 315 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 316 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 317 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 318 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 319 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 320 {VV_NAME("fname", VAR_STRING), VV_RO}, 321 {VV_NAME("lang", VAR_STRING), VV_RO}, 322 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 323 {VV_NAME("ctype", VAR_STRING), VV_RO}, 324 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 325 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 326 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 327 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 328 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 329 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 330 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 331 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 332 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 333 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 334 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 335 {VV_NAME("progname", VAR_STRING), VV_RO}, 336 {VV_NAME("servername", VAR_STRING), VV_RO}, 337 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 338 {VV_NAME("exception", VAR_STRING), VV_RO}, 339 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 340 {VV_NAME("register", VAR_STRING), VV_RO}, 341 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 342 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 343 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 344 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 345 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 346 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 347 {VV_NAME("fcs_choice", VAR_STRING), 0}, 348 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 349 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 350 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 351 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 352 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 353 {VV_NAME("scrollstart", VAR_STRING), 0}, 354 {VV_NAME("swapname", VAR_STRING), VV_RO}, 355 {VV_NAME("swapchoice", VAR_STRING), 0}, 356 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 357 {VV_NAME("char", VAR_STRING), 0}, 358 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 359 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 360 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 361 {VV_NAME("operator", VAR_STRING), VV_RO}, 362 {VV_NAME("searchforward", VAR_NUMBER), 0}, 363 {VV_NAME("hlsearch", VAR_NUMBER), 0}, 364 {VV_NAME("oldfiles", VAR_LIST), 0}, 365 {VV_NAME("windowid", VAR_NUMBER), VV_RO}, 366 {VV_NAME("progpath", VAR_STRING), VV_RO}, 367 {VV_NAME("completed_item", VAR_DICT), VV_RO}, 368 {VV_NAME("option_new", VAR_STRING), VV_RO}, 369 {VV_NAME("option_old", VAR_STRING), VV_RO}, 370 {VV_NAME("option_type", VAR_STRING), VV_RO}, 371 {VV_NAME("errors", VAR_LIST), 0}, 372 }; 373 374 /* shorthand */ 375 #define vv_type vv_di.di_tv.v_type 376 #define vv_nr vv_di.di_tv.vval.v_number 377 #define vv_float vv_di.di_tv.vval.v_float 378 #define vv_str vv_di.di_tv.vval.v_string 379 #define vv_list vv_di.di_tv.vval.v_list 380 #define vv_dict vv_di.di_tv.vval.v_dict 381 #define vv_tv vv_di.di_tv 382 383 static dictitem_T vimvars_var; /* variable used for v: */ 384 #define vimvarht vimvardict.dv_hashtab 385 386 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 387 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 388 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 389 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 390 static char_u *skip_var_one __ARGS((char_u *arg)); 391 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first)); 392 static void list_glob_vars __ARGS((int *first)); 393 static void list_buf_vars __ARGS((int *first)); 394 static void list_win_vars __ARGS((int *first)); 395 #ifdef FEAT_WINDOWS 396 static void list_tab_vars __ARGS((int *first)); 397 #endif 398 static void list_vim_vars __ARGS((int *first)); 399 static void list_script_vars __ARGS((int *first)); 400 static void list_func_vars __ARGS((int *first)); 401 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first)); 402 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 403 static int check_changedtick __ARGS((char_u *arg)); 404 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags)); 405 static void clear_lval __ARGS((lval_T *lp)); 406 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 407 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 408 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 409 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 410 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 411 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 412 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 413 static int tv_islocked __ARGS((typval_T *tv)); 414 415 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 416 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 417 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 418 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 419 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 420 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 421 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 422 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 423 424 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 425 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 426 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 427 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 428 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 429 static int rettv_list_alloc __ARGS((typval_T *rettv)); 430 static long list_len __ARGS((list_T *l)); 431 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive)); 432 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive)); 433 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic, int recursive)); 434 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 435 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 436 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 437 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 438 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 439 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 440 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 441 static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap)); 442 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 443 static int free_unref_items __ARGS((int copyID)); 444 static int rettv_dict_alloc __ARGS((typval_T *rettv)); 445 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 446 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 447 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 448 static long dict_len __ARGS((dict_T *d)); 449 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 450 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 451 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 452 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 453 static char_u *string_quote __ARGS((char_u *str, int function)); 454 #ifdef FEAT_FLOAT 455 static int string2float __ARGS((char_u *text, float_T *value)); 456 #endif 457 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 458 static int find_internal_func __ARGS((char_u *name)); 459 static char_u *deref_func_name __ARGS((char_u *name, int *lenp, int no_autoload)); 460 static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 461 static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 462 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); 463 static int non_zero_arg __ARGS((typval_T *argvars)); 464 465 #ifdef FEAT_FLOAT 466 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_acos __ARGS((typval_T *argvars, typval_T *rettv)); 468 #endif 469 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_and __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_arglistid __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_assert_equal __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_assert_false __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_assert_true __ARGS((typval_T *argvars, typval_T *rettv)); 479 #ifdef FEAT_FLOAT 480 static void f_asin __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_atan __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_atan2 __ARGS((typval_T *argvars, typval_T *rettv)); 483 #endif 484 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void byteidx __ARGS((typval_T *argvars, typval_T *rettv, int comp)); 494 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_byteidxcomp __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 497 #ifdef FEAT_FLOAT 498 static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); 499 #endif 500 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 505 #if defined(FEAT_INS_EXPAND) 506 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 509 #endif 510 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 512 #ifdef FEAT_FLOAT 513 static void f_cos __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_cosh __ARGS((typval_T *argvars, typval_T *rettv)); 515 #endif 516 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 519 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_exepath __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 531 #ifdef FEAT_FLOAT 532 static void f_exp __ARGS((typval_T *argvars, typval_T *rettv)); 533 #endif 534 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 542 #ifdef FEAT_FLOAT 543 static void f_float2nr __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_floor __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_fmod __ARGS((typval_T *argvars, typval_T *rettv)); 546 #endif 547 static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_getcharsearch __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_getcmdwintype __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_getcurpos __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_glob2regpat __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_invert __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 624 #ifdef FEAT_FLOAT 625 static void f_log __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv)); 627 #endif 628 #ifdef FEAT_LUA 629 static void f_luaeval __ARGS((typval_T *argvars, typval_T *rettv)); 630 #endif 631 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_matchaddpos __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 644 #ifdef vim_mkdir 645 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 646 #endif 647 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 648 #ifdef FEAT_MZSCHEME 649 static void f_mzeval __ARGS((typval_T *argvars, typval_T *rettv)); 650 #endif 651 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 653 static void f_or __ARGS((typval_T *argvars, typval_T *rettv)); 654 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 655 #ifdef FEAT_FLOAT 656 static void f_pow __ARGS((typval_T *argvars, typval_T *rettv)); 657 #endif 658 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 661 #ifdef FEAT_PYTHON3 662 static void f_py3eval __ARGS((typval_T *argvars, typval_T *rettv)); 663 #endif 664 #ifdef FEAT_PYTHON 665 static void f_pyeval __ARGS((typval_T *argvars, typval_T *rettv)); 666 #endif 667 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 668 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 669 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 670 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 671 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 672 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 673 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 674 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 675 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 676 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 677 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 678 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 679 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 680 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 681 #ifdef FEAT_FLOAT 682 static void f_round __ARGS((typval_T *argvars, typval_T *rettv)); 683 #endif 684 static void f_screenattr __ARGS((typval_T *argvars, typval_T *rettv)); 685 static void f_screenchar __ARGS((typval_T *argvars, typval_T *rettv)); 686 static void f_screencol __ARGS((typval_T *argvars, typval_T *rettv)); 687 static void f_screenrow __ARGS((typval_T *argvars, typval_T *rettv)); 688 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 689 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 690 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 691 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 692 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 693 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 694 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 695 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 696 static void f_setcharsearch __ARGS((typval_T *argvars, typval_T *rettv)); 697 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 698 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 699 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 700 static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv)); 701 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 702 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 703 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 704 static void f_settabvar __ARGS((typval_T *argvars, typval_T *rettv)); 705 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 706 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 707 #ifdef FEAT_CRYPT 708 static void f_sha256 __ARGS((typval_T *argvars, typval_T *rettv)); 709 #endif /* FEAT_CRYPT */ 710 static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); 711 static void f_shiftwidth __ARGS((typval_T *argvars, typval_T *rettv)); 712 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 713 #ifdef FEAT_FLOAT 714 static void f_sin __ARGS((typval_T *argvars, typval_T *rettv)); 715 static void f_sinh __ARGS((typval_T *argvars, typval_T *rettv)); 716 #endif 717 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 718 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 719 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 720 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 721 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 722 #ifdef FEAT_FLOAT 723 static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv)); 724 static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv)); 725 #endif 726 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 727 static void f_strchars __ARGS((typval_T *argvars, typval_T *rettv)); 728 #ifdef HAVE_STRFTIME 729 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 730 #endif 731 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 732 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 733 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 734 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 735 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 736 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 737 static void f_strdisplaywidth __ARGS((typval_T *argvars, typval_T *rettv)); 738 static void f_strwidth __ARGS((typval_T *argvars, typval_T *rettv)); 739 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 740 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 741 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 742 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 743 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 744 static void f_synstack __ARGS((typval_T *argvars, typval_T *rettv)); 745 static void f_synconcealed __ARGS((typval_T *argvars, typval_T *rettv)); 746 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 747 static void f_systemlist __ARGS((typval_T *argvars, typval_T *rettv)); 748 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 749 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 750 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 751 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 752 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 753 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 754 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 755 #ifdef FEAT_FLOAT 756 static void f_tan __ARGS((typval_T *argvars, typval_T *rettv)); 757 static void f_tanh __ARGS((typval_T *argvars, typval_T *rettv)); 758 #endif 759 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 760 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 761 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 762 #ifdef FEAT_FLOAT 763 static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv)); 764 #endif 765 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 766 static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv)); 767 static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv)); 768 static void f_uniq __ARGS((typval_T *argvars, typval_T *rettv)); 769 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 770 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 771 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 772 static void f_wildmenumode __ARGS((typval_T *argvars, typval_T *rettv)); 773 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 774 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 775 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 776 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 777 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 778 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 779 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 780 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 781 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 782 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 783 static void f_xor __ARGS((typval_T *argvars, typval_T *rettv)); 784 785 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp)); 786 static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum)); 787 static int get_env_len __ARGS((char_u **arg)); 788 static int get_id_len __ARGS((char_u **arg)); 789 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 790 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 791 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 792 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 793 valid character */ 794 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 795 static int eval_isnamec __ARGS((int c)); 796 static int eval_isnamec1 __ARGS((int c)); 797 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload)); 798 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 799 static typval_T *alloc_tv __ARGS((void)); 800 static typval_T *alloc_string_tv __ARGS((char_u *string)); 801 static void init_tv __ARGS((typval_T *varp)); 802 static long get_tv_number __ARGS((typval_T *varp)); 803 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 804 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 805 static char_u *get_tv_string __ARGS((typval_T *varp)); 806 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 807 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 808 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int no_autoload)); 809 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int no_autoload)); 810 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 811 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 812 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 813 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first)); 814 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first)); 815 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 816 static int var_check_ro __ARGS((int flags, char_u *name, int use_gettext)); 817 static int var_check_fixed __ARGS((int flags, char_u *name, int use_gettext)); 818 static int var_check_func_name __ARGS((char_u *name, int new_var)); 819 static int valid_varname __ARGS((char_u *varname)); 820 static int tv_check_lock __ARGS((int lock, char_u *name, int use_gettext)); 821 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 822 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 823 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 824 static int eval_fname_script __ARGS((char_u *p)); 825 static int eval_fname_sid __ARGS((char_u *p)); 826 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 827 static ufunc_T *find_func __ARGS((char_u *name)); 828 static int function_exists __ARGS((char_u *name)); 829 static int builtin_function __ARGS((char_u *name, int len)); 830 #ifdef FEAT_PROFILE 831 static void func_do_profile __ARGS((ufunc_T *fp)); 832 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 833 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 834 static int 835 # ifdef __BORLANDC__ 836 _RTLENTRYF 837 # endif 838 prof_total_cmp __ARGS((const void *s1, const void *s2)); 839 static int 840 # ifdef __BORLANDC__ 841 _RTLENTRYF 842 # endif 843 prof_self_cmp __ARGS((const void *s1, const void *s2)); 844 #endif 845 static int script_autoload __ARGS((char_u *name, int reload)); 846 static char_u *autoload_name __ARGS((char_u *name)); 847 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 848 static void func_free __ARGS((ufunc_T *fp)); 849 static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict)); 850 static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; 851 static void free_funccal __ARGS((funccall_T *fc, int free_val)); 852 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 853 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 854 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 855 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 856 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 857 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 858 static int write_list __ARGS((FILE *fd, list_T *list, int binary)); 859 static void get_cmd_output_as_rettv __ARGS((typval_T *argvars, typval_T *rettv, int retlist)); 860 861 862 #ifdef EBCDIC 863 static int compare_func_name __ARGS((const void *s1, const void *s2)); 864 static void sortFunctions __ARGS(()); 865 #endif 866 867 /* 868 * Initialize the global and v: variables. 869 */ 870 void 871 eval_init() 872 { 873 int i; 874 struct vimvar *p; 875 876 init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); 877 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); 878 vimvardict.dv_lock = VAR_FIXED; 879 hash_init(&compat_hashtab); 880 hash_init(&func_hashtab); 881 882 for (i = 0; i < VV_LEN; ++i) 883 { 884 p = &vimvars[i]; 885 STRCPY(p->vv_di.di_key, p->vv_name); 886 if (p->vv_flags & VV_RO) 887 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 888 else if (p->vv_flags & VV_RO_SBX) 889 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 890 else 891 p->vv_di.di_flags = DI_FLAGS_FIX; 892 893 /* add to v: scope dict, unless the value is not always available */ 894 if (p->vv_type != VAR_UNKNOWN) 895 hash_add(&vimvarht, p->vv_di.di_key); 896 if (p->vv_flags & VV_COMPAT) 897 /* add to compat scope dict */ 898 hash_add(&compat_hashtab, p->vv_di.di_key); 899 } 900 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 901 set_vim_var_nr(VV_HLSEARCH, 1L); 902 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); 903 set_vim_var_list(VV_ERRORS, list_alloc()); 904 set_reg_var(0); /* default for v:register is not 0 but '"' */ 905 906 #ifdef EBCDIC 907 /* 908 * Sort the function table, to enable binary search. 909 */ 910 sortFunctions(); 911 #endif 912 } 913 914 #if defined(EXITFREE) || defined(PROTO) 915 void 916 eval_clear() 917 { 918 int i; 919 struct vimvar *p; 920 921 for (i = 0; i < VV_LEN; ++i) 922 { 923 p = &vimvars[i]; 924 if (p->vv_di.di_tv.v_type == VAR_STRING) 925 { 926 vim_free(p->vv_str); 927 p->vv_str = NULL; 928 } 929 else if (p->vv_di.di_tv.v_type == VAR_LIST) 930 { 931 list_unref(p->vv_list); 932 p->vv_list = NULL; 933 } 934 } 935 hash_clear(&vimvarht); 936 hash_init(&vimvarht); /* garbage_collect() will access it */ 937 hash_clear(&compat_hashtab); 938 939 free_scriptnames(); 940 # if defined(FEAT_CMDL_COMPL) 941 free_locales(); 942 # endif 943 944 /* global variables */ 945 vars_clear(&globvarht); 946 947 /* autoloaded script names */ 948 ga_clear_strings(&ga_loaded); 949 950 /* Script-local variables. First clear all the variables and in a second 951 * loop free the scriptvar_T, because a variable in one script might hold 952 * a reference to the whole scope of another script. */ 953 for (i = 1; i <= ga_scripts.ga_len; ++i) 954 vars_clear(&SCRIPT_VARS(i)); 955 for (i = 1; i <= ga_scripts.ga_len; ++i) 956 vim_free(SCRIPT_SV(i)); 957 ga_clear(&ga_scripts); 958 959 /* unreferenced lists and dicts */ 960 (void)garbage_collect(); 961 962 /* functions */ 963 free_all_functions(); 964 hash_clear(&func_hashtab); 965 } 966 #endif 967 968 /* 969 * Return the name of the executed function. 970 */ 971 char_u * 972 func_name(cookie) 973 void *cookie; 974 { 975 return ((funccall_T *)cookie)->func->uf_name; 976 } 977 978 /* 979 * Return the address holding the next breakpoint line for a funccall cookie. 980 */ 981 linenr_T * 982 func_breakpoint(cookie) 983 void *cookie; 984 { 985 return &((funccall_T *)cookie)->breakpoint; 986 } 987 988 /* 989 * Return the address holding the debug tick for a funccall cookie. 990 */ 991 int * 992 func_dbg_tick(cookie) 993 void *cookie; 994 { 995 return &((funccall_T *)cookie)->dbg_tick; 996 } 997 998 /* 999 * Return the nesting level for a funccall cookie. 1000 */ 1001 int 1002 func_level(cookie) 1003 void *cookie; 1004 { 1005 return ((funccall_T *)cookie)->level; 1006 } 1007 1008 /* pointer to funccal for currently active function */ 1009 funccall_T *current_funccal = NULL; 1010 1011 /* pointer to list of previously used funccal, still around because some 1012 * item in it is still being used. */ 1013 funccall_T *previous_funccal = NULL; 1014 1015 /* 1016 * Return TRUE when a function was ended by a ":return" command. 1017 */ 1018 int 1019 current_func_returned() 1020 { 1021 return current_funccal->returned; 1022 } 1023 1024 1025 /* 1026 * Set an internal variable to a string value. Creates the variable if it does 1027 * not already exist. 1028 */ 1029 void 1030 set_internal_string_var(name, value) 1031 char_u *name; 1032 char_u *value; 1033 { 1034 char_u *val; 1035 typval_T *tvp; 1036 1037 val = vim_strsave(value); 1038 if (val != NULL) 1039 { 1040 tvp = alloc_string_tv(val); 1041 if (tvp != NULL) 1042 { 1043 set_var(name, tvp, FALSE); 1044 free_tv(tvp); 1045 } 1046 } 1047 } 1048 1049 static lval_T *redir_lval = NULL; 1050 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 1051 static char_u *redir_endp = NULL; 1052 static char_u *redir_varname = NULL; 1053 1054 /* 1055 * Start recording command output to a variable 1056 * Returns OK if successfully completed the setup. FAIL otherwise. 1057 */ 1058 int 1059 var_redir_start(name, append) 1060 char_u *name; 1061 int append; /* append to an existing variable */ 1062 { 1063 int save_emsg; 1064 int err; 1065 typval_T tv; 1066 1067 /* Catch a bad name early. */ 1068 if (!eval_isnamec1(*name)) 1069 { 1070 EMSG(_(e_invarg)); 1071 return FAIL; 1072 } 1073 1074 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 1075 redir_varname = vim_strsave(name); 1076 if (redir_varname == NULL) 1077 return FAIL; 1078 1079 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1080 if (redir_lval == NULL) 1081 { 1082 var_redir_stop(); 1083 return FAIL; 1084 } 1085 1086 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1087 ga_init2(&redir_ga, (int)sizeof(char), 500); 1088 1089 /* Parse the variable name (can be a dict or list entry). */ 1090 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0, 1091 FNE_CHECK_START); 1092 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1093 { 1094 clear_lval(redir_lval); 1095 if (redir_endp != NULL && *redir_endp != NUL) 1096 /* Trailing characters are present after the variable name */ 1097 EMSG(_(e_trailing)); 1098 else 1099 EMSG(_(e_invarg)); 1100 redir_endp = NULL; /* don't store a value, only cleanup */ 1101 var_redir_stop(); 1102 return FAIL; 1103 } 1104 1105 /* check if we can write to the variable: set it to or append an empty 1106 * string */ 1107 save_emsg = did_emsg; 1108 did_emsg = FALSE; 1109 tv.v_type = VAR_STRING; 1110 tv.vval.v_string = (char_u *)""; 1111 if (append) 1112 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1113 else 1114 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1115 clear_lval(redir_lval); 1116 err = did_emsg; 1117 did_emsg |= save_emsg; 1118 if (err) 1119 { 1120 redir_endp = NULL; /* don't store a value, only cleanup */ 1121 var_redir_stop(); 1122 return FAIL; 1123 } 1124 1125 return OK; 1126 } 1127 1128 /* 1129 * Append "value[value_len]" to the variable set by var_redir_start(). 1130 * The actual appending is postponed until redirection ends, because the value 1131 * appended may in fact be the string we write to, changing it may cause freed 1132 * memory to be used: 1133 * :redir => foo 1134 * :let foo 1135 * :redir END 1136 */ 1137 void 1138 var_redir_str(value, value_len) 1139 char_u *value; 1140 int value_len; 1141 { 1142 int len; 1143 1144 if (redir_lval == NULL) 1145 return; 1146 1147 if (value_len == -1) 1148 len = (int)STRLEN(value); /* Append the entire string */ 1149 else 1150 len = value_len; /* Append only "value_len" characters */ 1151 1152 if (ga_grow(&redir_ga, len) == OK) 1153 { 1154 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1155 redir_ga.ga_len += len; 1156 } 1157 else 1158 var_redir_stop(); 1159 } 1160 1161 /* 1162 * Stop redirecting command output to a variable. 1163 * Frees the allocated memory. 1164 */ 1165 void 1166 var_redir_stop() 1167 { 1168 typval_T tv; 1169 1170 if (redir_lval != NULL) 1171 { 1172 /* If there was no error: assign the text to the variable. */ 1173 if (redir_endp != NULL) 1174 { 1175 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1176 tv.v_type = VAR_STRING; 1177 tv.vval.v_string = redir_ga.ga_data; 1178 /* Call get_lval() again, if it's inside a Dict or List it may 1179 * have changed. */ 1180 redir_endp = get_lval(redir_varname, NULL, redir_lval, 1181 FALSE, FALSE, 0, FNE_CHECK_START); 1182 if (redir_endp != NULL && redir_lval->ll_name != NULL) 1183 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1184 clear_lval(redir_lval); 1185 } 1186 1187 /* free the collected output */ 1188 vim_free(redir_ga.ga_data); 1189 redir_ga.ga_data = NULL; 1190 1191 vim_free(redir_lval); 1192 redir_lval = NULL; 1193 } 1194 vim_free(redir_varname); 1195 redir_varname = NULL; 1196 } 1197 1198 # if defined(FEAT_MBYTE) || defined(PROTO) 1199 int 1200 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1201 char_u *enc_from; 1202 char_u *enc_to; 1203 char_u *fname_from; 1204 char_u *fname_to; 1205 { 1206 int err = FALSE; 1207 1208 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1209 set_vim_var_string(VV_CC_TO, enc_to, -1); 1210 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1211 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1212 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1213 err = TRUE; 1214 set_vim_var_string(VV_CC_FROM, NULL, -1); 1215 set_vim_var_string(VV_CC_TO, NULL, -1); 1216 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1217 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1218 1219 if (err) 1220 return FAIL; 1221 return OK; 1222 } 1223 # endif 1224 1225 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1226 int 1227 eval_printexpr(fname, args) 1228 char_u *fname; 1229 char_u *args; 1230 { 1231 int err = FALSE; 1232 1233 set_vim_var_string(VV_FNAME_IN, fname, -1); 1234 set_vim_var_string(VV_CMDARG, args, -1); 1235 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1236 err = TRUE; 1237 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1238 set_vim_var_string(VV_CMDARG, NULL, -1); 1239 1240 if (err) 1241 { 1242 mch_remove(fname); 1243 return FAIL; 1244 } 1245 return OK; 1246 } 1247 # endif 1248 1249 # if defined(FEAT_DIFF) || defined(PROTO) 1250 void 1251 eval_diff(origfile, newfile, outfile) 1252 char_u *origfile; 1253 char_u *newfile; 1254 char_u *outfile; 1255 { 1256 int err = FALSE; 1257 1258 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1259 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1260 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1261 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1262 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1263 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1264 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1265 } 1266 1267 void 1268 eval_patch(origfile, difffile, outfile) 1269 char_u *origfile; 1270 char_u *difffile; 1271 char_u *outfile; 1272 { 1273 int err; 1274 1275 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1276 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1277 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1278 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1279 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1280 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1281 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1282 } 1283 # endif 1284 1285 /* 1286 * Top level evaluation function, returning a boolean. 1287 * Sets "error" to TRUE if there was an error. 1288 * Return TRUE or FALSE. 1289 */ 1290 int 1291 eval_to_bool(arg, error, nextcmd, skip) 1292 char_u *arg; 1293 int *error; 1294 char_u **nextcmd; 1295 int skip; /* only parse, don't execute */ 1296 { 1297 typval_T tv; 1298 int retval = FALSE; 1299 1300 if (skip) 1301 ++emsg_skip; 1302 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1303 *error = TRUE; 1304 else 1305 { 1306 *error = FALSE; 1307 if (!skip) 1308 { 1309 retval = (get_tv_number_chk(&tv, error) != 0); 1310 clear_tv(&tv); 1311 } 1312 } 1313 if (skip) 1314 --emsg_skip; 1315 1316 return retval; 1317 } 1318 1319 /* 1320 * Top level evaluation function, returning a string. If "skip" is TRUE, 1321 * only parsing to "nextcmd" is done, without reporting errors. Return 1322 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1323 */ 1324 char_u * 1325 eval_to_string_skip(arg, nextcmd, skip) 1326 char_u *arg; 1327 char_u **nextcmd; 1328 int skip; /* only parse, don't execute */ 1329 { 1330 typval_T tv; 1331 char_u *retval; 1332 1333 if (skip) 1334 ++emsg_skip; 1335 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1336 retval = NULL; 1337 else 1338 { 1339 retval = vim_strsave(get_tv_string(&tv)); 1340 clear_tv(&tv); 1341 } 1342 if (skip) 1343 --emsg_skip; 1344 1345 return retval; 1346 } 1347 1348 /* 1349 * Skip over an expression at "*pp". 1350 * Return FAIL for an error, OK otherwise. 1351 */ 1352 int 1353 skip_expr(pp) 1354 char_u **pp; 1355 { 1356 typval_T rettv; 1357 1358 *pp = skipwhite(*pp); 1359 return eval1(pp, &rettv, FALSE); 1360 } 1361 1362 /* 1363 * Top level evaluation function, returning a string. 1364 * When "convert" is TRUE convert a List into a sequence of lines and convert 1365 * a Float to a String. 1366 * Return pointer to allocated memory, or NULL for failure. 1367 */ 1368 char_u * 1369 eval_to_string(arg, nextcmd, convert) 1370 char_u *arg; 1371 char_u **nextcmd; 1372 int convert; 1373 { 1374 typval_T tv; 1375 char_u *retval; 1376 garray_T ga; 1377 #ifdef FEAT_FLOAT 1378 char_u numbuf[NUMBUFLEN]; 1379 #endif 1380 1381 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1382 retval = NULL; 1383 else 1384 { 1385 if (convert && tv.v_type == VAR_LIST) 1386 { 1387 ga_init2(&ga, (int)sizeof(char), 80); 1388 if (tv.vval.v_list != NULL) 1389 { 1390 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1391 if (tv.vval.v_list->lv_len > 0) 1392 ga_append(&ga, NL); 1393 } 1394 ga_append(&ga, NUL); 1395 retval = (char_u *)ga.ga_data; 1396 } 1397 #ifdef FEAT_FLOAT 1398 else if (convert && tv.v_type == VAR_FLOAT) 1399 { 1400 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1401 retval = vim_strsave(numbuf); 1402 } 1403 #endif 1404 else 1405 retval = vim_strsave(get_tv_string(&tv)); 1406 clear_tv(&tv); 1407 } 1408 1409 return retval; 1410 } 1411 1412 /* 1413 * Call eval_to_string() without using current local variables and using 1414 * textlock. When "use_sandbox" is TRUE use the sandbox. 1415 */ 1416 char_u * 1417 eval_to_string_safe(arg, nextcmd, use_sandbox) 1418 char_u *arg; 1419 char_u **nextcmd; 1420 int use_sandbox; 1421 { 1422 char_u *retval; 1423 void *save_funccalp; 1424 1425 save_funccalp = save_funccal(); 1426 if (use_sandbox) 1427 ++sandbox; 1428 ++textlock; 1429 retval = eval_to_string(arg, nextcmd, FALSE); 1430 if (use_sandbox) 1431 --sandbox; 1432 --textlock; 1433 restore_funccal(save_funccalp); 1434 return retval; 1435 } 1436 1437 /* 1438 * Top level evaluation function, returning a number. 1439 * Evaluates "expr" silently. 1440 * Returns -1 for an error. 1441 */ 1442 int 1443 eval_to_number(expr) 1444 char_u *expr; 1445 { 1446 typval_T rettv; 1447 int retval; 1448 char_u *p = skipwhite(expr); 1449 1450 ++emsg_off; 1451 1452 if (eval1(&p, &rettv, TRUE) == FAIL) 1453 retval = -1; 1454 else 1455 { 1456 retval = get_tv_number_chk(&rettv, NULL); 1457 clear_tv(&rettv); 1458 } 1459 --emsg_off; 1460 1461 return retval; 1462 } 1463 1464 /* 1465 * Prepare v: variable "idx" to be used. 1466 * Save the current typeval in "save_tv". 1467 * When not used yet add the variable to the v: hashtable. 1468 */ 1469 static void 1470 prepare_vimvar(idx, save_tv) 1471 int idx; 1472 typval_T *save_tv; 1473 { 1474 *save_tv = vimvars[idx].vv_tv; 1475 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1476 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1477 } 1478 1479 /* 1480 * Restore v: variable "idx" to typeval "save_tv". 1481 * When no longer defined, remove the variable from the v: hashtable. 1482 */ 1483 static void 1484 restore_vimvar(idx, save_tv) 1485 int idx; 1486 typval_T *save_tv; 1487 { 1488 hashitem_T *hi; 1489 1490 vimvars[idx].vv_tv = *save_tv; 1491 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1492 { 1493 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1494 if (HASHITEM_EMPTY(hi)) 1495 EMSG2(_(e_intern2), "restore_vimvar()"); 1496 else 1497 hash_remove(&vimvarht, hi); 1498 } 1499 } 1500 1501 #if defined(FEAT_SPELL) || defined(PROTO) 1502 /* 1503 * Evaluate an expression to a list with suggestions. 1504 * For the "expr:" part of 'spellsuggest'. 1505 * Returns NULL when there is an error. 1506 */ 1507 list_T * 1508 eval_spell_expr(badword, expr) 1509 char_u *badword; 1510 char_u *expr; 1511 { 1512 typval_T save_val; 1513 typval_T rettv; 1514 list_T *list = NULL; 1515 char_u *p = skipwhite(expr); 1516 1517 /* Set "v:val" to the bad word. */ 1518 prepare_vimvar(VV_VAL, &save_val); 1519 vimvars[VV_VAL].vv_type = VAR_STRING; 1520 vimvars[VV_VAL].vv_str = badword; 1521 if (p_verbose == 0) 1522 ++emsg_off; 1523 1524 if (eval1(&p, &rettv, TRUE) == OK) 1525 { 1526 if (rettv.v_type != VAR_LIST) 1527 clear_tv(&rettv); 1528 else 1529 list = rettv.vval.v_list; 1530 } 1531 1532 if (p_verbose == 0) 1533 --emsg_off; 1534 restore_vimvar(VV_VAL, &save_val); 1535 1536 return list; 1537 } 1538 1539 /* 1540 * "list" is supposed to contain two items: a word and a number. Return the 1541 * word in "pp" and the number as the return value. 1542 * Return -1 if anything isn't right. 1543 * Used to get the good word and score from the eval_spell_expr() result. 1544 */ 1545 int 1546 get_spellword(list, pp) 1547 list_T *list; 1548 char_u **pp; 1549 { 1550 listitem_T *li; 1551 1552 li = list->lv_first; 1553 if (li == NULL) 1554 return -1; 1555 *pp = get_tv_string(&li->li_tv); 1556 1557 li = li->li_next; 1558 if (li == NULL) 1559 return -1; 1560 return get_tv_number(&li->li_tv); 1561 } 1562 #endif 1563 1564 /* 1565 * Top level evaluation function. 1566 * Returns an allocated typval_T with the result. 1567 * Returns NULL when there is an error. 1568 */ 1569 typval_T * 1570 eval_expr(arg, nextcmd) 1571 char_u *arg; 1572 char_u **nextcmd; 1573 { 1574 typval_T *tv; 1575 1576 tv = (typval_T *)alloc(sizeof(typval_T)); 1577 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1578 { 1579 vim_free(tv); 1580 tv = NULL; 1581 } 1582 1583 return tv; 1584 } 1585 1586 1587 /* 1588 * Call some vimL function and return the result in "*rettv". 1589 * Uses argv[argc] for the function arguments. Only Number and String 1590 * arguments are currently supported. 1591 * Returns OK or FAIL. 1592 */ 1593 int 1594 call_vim_function(func, argc, argv, safe, str_arg_only, rettv) 1595 char_u *func; 1596 int argc; 1597 char_u **argv; 1598 int safe; /* use the sandbox */ 1599 int str_arg_only; /* all arguments are strings */ 1600 typval_T *rettv; 1601 { 1602 typval_T *argvars; 1603 long n; 1604 int len; 1605 int i; 1606 int doesrange; 1607 void *save_funccalp = NULL; 1608 int ret; 1609 1610 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1611 if (argvars == NULL) 1612 return FAIL; 1613 1614 for (i = 0; i < argc; i++) 1615 { 1616 /* Pass a NULL or empty argument as an empty string */ 1617 if (argv[i] == NULL || *argv[i] == NUL) 1618 { 1619 argvars[i].v_type = VAR_STRING; 1620 argvars[i].vval.v_string = (char_u *)""; 1621 continue; 1622 } 1623 1624 if (str_arg_only) 1625 len = 0; 1626 else 1627 /* Recognize a number argument, the others must be strings. */ 1628 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL, 0); 1629 if (len != 0 && len == (int)STRLEN(argv[i])) 1630 { 1631 argvars[i].v_type = VAR_NUMBER; 1632 argvars[i].vval.v_number = n; 1633 } 1634 else 1635 { 1636 argvars[i].v_type = VAR_STRING; 1637 argvars[i].vval.v_string = argv[i]; 1638 } 1639 } 1640 1641 if (safe) 1642 { 1643 save_funccalp = save_funccal(); 1644 ++sandbox; 1645 } 1646 1647 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1648 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1649 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1650 &doesrange, TRUE, NULL); 1651 if (safe) 1652 { 1653 --sandbox; 1654 restore_funccal(save_funccalp); 1655 } 1656 vim_free(argvars); 1657 1658 if (ret == FAIL) 1659 clear_tv(rettv); 1660 1661 return ret; 1662 } 1663 1664 /* 1665 * Call vimL function "func" and return the result as a number. 1666 * Returns -1 when calling the function fails. 1667 * Uses argv[argc] for the function arguments. 1668 */ 1669 long 1670 call_func_retnr(func, argc, argv, safe) 1671 char_u *func; 1672 int argc; 1673 char_u **argv; 1674 int safe; /* use the sandbox */ 1675 { 1676 typval_T rettv; 1677 long retval; 1678 1679 /* All arguments are passed as strings, no conversion to number. */ 1680 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1681 return -1; 1682 1683 retval = get_tv_number_chk(&rettv, NULL); 1684 clear_tv(&rettv); 1685 return retval; 1686 } 1687 1688 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1689 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1690 1691 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1692 /* 1693 * Call vimL function "func" and return the result as a string. 1694 * Returns NULL when calling the function fails. 1695 * Uses argv[argc] for the function arguments. 1696 */ 1697 void * 1698 call_func_retstr(func, argc, argv, safe) 1699 char_u *func; 1700 int argc; 1701 char_u **argv; 1702 int safe; /* use the sandbox */ 1703 { 1704 typval_T rettv; 1705 char_u *retval; 1706 1707 /* All arguments are passed as strings, no conversion to number. */ 1708 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1709 return NULL; 1710 1711 retval = vim_strsave(get_tv_string(&rettv)); 1712 clear_tv(&rettv); 1713 return retval; 1714 } 1715 # endif 1716 1717 /* 1718 * Call vimL function "func" and return the result as a List. 1719 * Uses argv[argc] for the function arguments. 1720 * Returns NULL when there is something wrong. 1721 */ 1722 void * 1723 call_func_retlist(func, argc, argv, safe) 1724 char_u *func; 1725 int argc; 1726 char_u **argv; 1727 int safe; /* use the sandbox */ 1728 { 1729 typval_T rettv; 1730 1731 /* All arguments are passed as strings, no conversion to number. */ 1732 if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) 1733 return NULL; 1734 1735 if (rettv.v_type != VAR_LIST) 1736 { 1737 clear_tv(&rettv); 1738 return NULL; 1739 } 1740 1741 return rettv.vval.v_list; 1742 } 1743 #endif 1744 1745 /* 1746 * Save the current function call pointer, and set it to NULL. 1747 * Used when executing autocommands and for ":source". 1748 */ 1749 void * 1750 save_funccal() 1751 { 1752 funccall_T *fc = current_funccal; 1753 1754 current_funccal = NULL; 1755 return (void *)fc; 1756 } 1757 1758 void 1759 restore_funccal(vfc) 1760 void *vfc; 1761 { 1762 funccall_T *fc = (funccall_T *)vfc; 1763 1764 current_funccal = fc; 1765 } 1766 1767 #if defined(FEAT_PROFILE) || defined(PROTO) 1768 /* 1769 * Prepare profiling for entering a child or something else that is not 1770 * counted for the script/function itself. 1771 * Should always be called in pair with prof_child_exit(). 1772 */ 1773 void 1774 prof_child_enter(tm) 1775 proftime_T *tm; /* place to store waittime */ 1776 { 1777 funccall_T *fc = current_funccal; 1778 1779 if (fc != NULL && fc->func->uf_profiling) 1780 profile_start(&fc->prof_child); 1781 script_prof_save(tm); 1782 } 1783 1784 /* 1785 * Take care of time spent in a child. 1786 * Should always be called after prof_child_enter(). 1787 */ 1788 void 1789 prof_child_exit(tm) 1790 proftime_T *tm; /* where waittime was stored */ 1791 { 1792 funccall_T *fc = current_funccal; 1793 1794 if (fc != NULL && fc->func->uf_profiling) 1795 { 1796 profile_end(&fc->prof_child); 1797 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1798 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1799 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1800 } 1801 script_prof_restore(tm); 1802 } 1803 #endif 1804 1805 1806 #ifdef FEAT_FOLDING 1807 /* 1808 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1809 * it in "*cp". Doesn't give error messages. 1810 */ 1811 int 1812 eval_foldexpr(arg, cp) 1813 char_u *arg; 1814 int *cp; 1815 { 1816 typval_T tv; 1817 int retval; 1818 char_u *s; 1819 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1820 OPT_LOCAL); 1821 1822 ++emsg_off; 1823 if (use_sandbox) 1824 ++sandbox; 1825 ++textlock; 1826 *cp = NUL; 1827 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1828 retval = 0; 1829 else 1830 { 1831 /* If the result is a number, just return the number. */ 1832 if (tv.v_type == VAR_NUMBER) 1833 retval = tv.vval.v_number; 1834 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1835 retval = 0; 1836 else 1837 { 1838 /* If the result is a string, check if there is a non-digit before 1839 * the number. */ 1840 s = tv.vval.v_string; 1841 if (!VIM_ISDIGIT(*s) && *s != '-') 1842 *cp = *s++; 1843 retval = atol((char *)s); 1844 } 1845 clear_tv(&tv); 1846 } 1847 --emsg_off; 1848 if (use_sandbox) 1849 --sandbox; 1850 --textlock; 1851 1852 return retval; 1853 } 1854 #endif 1855 1856 /* 1857 * ":let" list all variable values 1858 * ":let var1 var2" list variable values 1859 * ":let var = expr" assignment command. 1860 * ":let var += expr" assignment command. 1861 * ":let var -= expr" assignment command. 1862 * ":let var .= expr" assignment command. 1863 * ":let [var1, var2] = expr" unpack list. 1864 */ 1865 void 1866 ex_let(eap) 1867 exarg_T *eap; 1868 { 1869 char_u *arg = eap->arg; 1870 char_u *expr = NULL; 1871 typval_T rettv; 1872 int i; 1873 int var_count = 0; 1874 int semicolon = 0; 1875 char_u op[2]; 1876 char_u *argend; 1877 int first = TRUE; 1878 1879 argend = skip_var_list(arg, &var_count, &semicolon); 1880 if (argend == NULL) 1881 return; 1882 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1883 --argend; 1884 expr = skipwhite(argend); 1885 if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL 1886 && expr[1] == '=')) 1887 { 1888 /* 1889 * ":let" without "=": list variables 1890 */ 1891 if (*arg == '[') 1892 EMSG(_(e_invarg)); 1893 else if (!ends_excmd(*arg)) 1894 /* ":let var1 var2" */ 1895 arg = list_arg_vars(eap, arg, &first); 1896 else if (!eap->skip) 1897 { 1898 /* ":let" */ 1899 list_glob_vars(&first); 1900 list_buf_vars(&first); 1901 list_win_vars(&first); 1902 #ifdef FEAT_WINDOWS 1903 list_tab_vars(&first); 1904 #endif 1905 list_script_vars(&first); 1906 list_func_vars(&first); 1907 list_vim_vars(&first); 1908 } 1909 eap->nextcmd = check_nextcmd(arg); 1910 } 1911 else 1912 { 1913 op[0] = '='; 1914 op[1] = NUL; 1915 if (*expr != '=') 1916 { 1917 if (vim_strchr((char_u *)"+-.", *expr) != NULL) 1918 op[0] = *expr; /* +=, -= or .= */ 1919 expr = skipwhite(expr + 2); 1920 } 1921 else 1922 expr = skipwhite(expr + 1); 1923 1924 if (eap->skip) 1925 ++emsg_skip; 1926 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1927 if (eap->skip) 1928 { 1929 if (i != FAIL) 1930 clear_tv(&rettv); 1931 --emsg_skip; 1932 } 1933 else if (i != FAIL) 1934 { 1935 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1936 op); 1937 clear_tv(&rettv); 1938 } 1939 } 1940 } 1941 1942 /* 1943 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1944 * Handles both "var" with any type and "[var, var; var]" with a list type. 1945 * When "nextchars" is not NULL it points to a string with characters that 1946 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1947 * or concatenate. 1948 * Returns OK or FAIL; 1949 */ 1950 static int 1951 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1952 char_u *arg_start; 1953 typval_T *tv; 1954 int copy; /* copy values from "tv", don't move */ 1955 int semicolon; /* from skip_var_list() */ 1956 int var_count; /* from skip_var_list() */ 1957 char_u *nextchars; 1958 { 1959 char_u *arg = arg_start; 1960 list_T *l; 1961 int i; 1962 listitem_T *item; 1963 typval_T ltv; 1964 1965 if (*arg != '[') 1966 { 1967 /* 1968 * ":let var = expr" or ":for var in list" 1969 */ 1970 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1971 return FAIL; 1972 return OK; 1973 } 1974 1975 /* 1976 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1977 */ 1978 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1979 { 1980 EMSG(_(e_listreq)); 1981 return FAIL; 1982 } 1983 1984 i = list_len(l); 1985 if (semicolon == 0 && var_count < i) 1986 { 1987 EMSG(_("E687: Less targets than List items")); 1988 return FAIL; 1989 } 1990 if (var_count - semicolon > i) 1991 { 1992 EMSG(_("E688: More targets than List items")); 1993 return FAIL; 1994 } 1995 1996 item = l->lv_first; 1997 while (*arg != ']') 1998 { 1999 arg = skipwhite(arg + 1); 2000 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 2001 item = item->li_next; 2002 if (arg == NULL) 2003 return FAIL; 2004 2005 arg = skipwhite(arg); 2006 if (*arg == ';') 2007 { 2008 /* Put the rest of the list (may be empty) in the var after ';'. 2009 * Create a new list for this. */ 2010 l = list_alloc(); 2011 if (l == NULL) 2012 return FAIL; 2013 while (item != NULL) 2014 { 2015 list_append_tv(l, &item->li_tv); 2016 item = item->li_next; 2017 } 2018 2019 ltv.v_type = VAR_LIST; 2020 ltv.v_lock = 0; 2021 ltv.vval.v_list = l; 2022 l->lv_refcount = 1; 2023 2024 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 2025 (char_u *)"]", nextchars); 2026 clear_tv(<v); 2027 if (arg == NULL) 2028 return FAIL; 2029 break; 2030 } 2031 else if (*arg != ',' && *arg != ']') 2032 { 2033 EMSG2(_(e_intern2), "ex_let_vars()"); 2034 return FAIL; 2035 } 2036 } 2037 2038 return OK; 2039 } 2040 2041 /* 2042 * Skip over assignable variable "var" or list of variables "[var, var]". 2043 * Used for ":let varvar = expr" and ":for varvar in expr". 2044 * For "[var, var]" increment "*var_count" for each variable. 2045 * for "[var, var; var]" set "semicolon". 2046 * Return NULL for an error. 2047 */ 2048 static char_u * 2049 skip_var_list(arg, var_count, semicolon) 2050 char_u *arg; 2051 int *var_count; 2052 int *semicolon; 2053 { 2054 char_u *p, *s; 2055 2056 if (*arg == '[') 2057 { 2058 /* "[var, var]": find the matching ']'. */ 2059 p = arg; 2060 for (;;) 2061 { 2062 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 2063 s = skip_var_one(p); 2064 if (s == p) 2065 { 2066 EMSG2(_(e_invarg2), p); 2067 return NULL; 2068 } 2069 ++*var_count; 2070 2071 p = skipwhite(s); 2072 if (*p == ']') 2073 break; 2074 else if (*p == ';') 2075 { 2076 if (*semicolon == 1) 2077 { 2078 EMSG(_("Double ; in list of variables")); 2079 return NULL; 2080 } 2081 *semicolon = 1; 2082 } 2083 else if (*p != ',') 2084 { 2085 EMSG2(_(e_invarg2), p); 2086 return NULL; 2087 } 2088 } 2089 return p + 1; 2090 } 2091 else 2092 return skip_var_one(arg); 2093 } 2094 2095 /* 2096 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2097 * l[idx]. 2098 */ 2099 static char_u * 2100 skip_var_one(arg) 2101 char_u *arg; 2102 { 2103 if (*arg == '@' && arg[1] != NUL) 2104 return arg + 2; 2105 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2106 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2107 } 2108 2109 /* 2110 * List variables for hashtab "ht" with prefix "prefix". 2111 * If "empty" is TRUE also list NULL strings as empty strings. 2112 */ 2113 static void 2114 list_hashtable_vars(ht, prefix, empty, first) 2115 hashtab_T *ht; 2116 char_u *prefix; 2117 int empty; 2118 int *first; 2119 { 2120 hashitem_T *hi; 2121 dictitem_T *di; 2122 int todo; 2123 2124 todo = (int)ht->ht_used; 2125 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2126 { 2127 if (!HASHITEM_EMPTY(hi)) 2128 { 2129 --todo; 2130 di = HI2DI(hi); 2131 if (empty || di->di_tv.v_type != VAR_STRING 2132 || di->di_tv.vval.v_string != NULL) 2133 list_one_var(di, prefix, first); 2134 } 2135 } 2136 } 2137 2138 /* 2139 * List global variables. 2140 */ 2141 static void 2142 list_glob_vars(first) 2143 int *first; 2144 { 2145 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2146 } 2147 2148 /* 2149 * List buffer variables. 2150 */ 2151 static void 2152 list_buf_vars(first) 2153 int *first; 2154 { 2155 char_u numbuf[NUMBUFLEN]; 2156 2157 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:", 2158 TRUE, first); 2159 2160 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2161 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2162 numbuf, first); 2163 } 2164 2165 /* 2166 * List window variables. 2167 */ 2168 static void 2169 list_win_vars(first) 2170 int *first; 2171 { 2172 list_hashtable_vars(&curwin->w_vars->dv_hashtab, 2173 (char_u *)"w:", TRUE, first); 2174 } 2175 2176 #ifdef FEAT_WINDOWS 2177 /* 2178 * List tab page variables. 2179 */ 2180 static void 2181 list_tab_vars(first) 2182 int *first; 2183 { 2184 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, 2185 (char_u *)"t:", TRUE, first); 2186 } 2187 #endif 2188 2189 /* 2190 * List Vim variables. 2191 */ 2192 static void 2193 list_vim_vars(first) 2194 int *first; 2195 { 2196 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2197 } 2198 2199 /* 2200 * List script-local variables, if there is a script. 2201 */ 2202 static void 2203 list_script_vars(first) 2204 int *first; 2205 { 2206 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2207 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2208 (char_u *)"s:", FALSE, first); 2209 } 2210 2211 /* 2212 * List function variables, if there is a function. 2213 */ 2214 static void 2215 list_func_vars(first) 2216 int *first; 2217 { 2218 if (current_funccal != NULL) 2219 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2220 (char_u *)"l:", FALSE, first); 2221 } 2222 2223 /* 2224 * List variables in "arg". 2225 */ 2226 static char_u * 2227 list_arg_vars(eap, arg, first) 2228 exarg_T *eap; 2229 char_u *arg; 2230 int *first; 2231 { 2232 int error = FALSE; 2233 int len; 2234 char_u *name; 2235 char_u *name_start; 2236 char_u *arg_subsc; 2237 char_u *tofree; 2238 typval_T tv; 2239 2240 while (!ends_excmd(*arg) && !got_int) 2241 { 2242 if (error || eap->skip) 2243 { 2244 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2245 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2246 { 2247 emsg_severe = TRUE; 2248 EMSG(_(e_trailing)); 2249 break; 2250 } 2251 } 2252 else 2253 { 2254 /* get_name_len() takes care of expanding curly braces */ 2255 name_start = name = arg; 2256 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2257 if (len <= 0) 2258 { 2259 /* This is mainly to keep test 49 working: when expanding 2260 * curly braces fails overrule the exception error message. */ 2261 if (len < 0 && !aborting()) 2262 { 2263 emsg_severe = TRUE; 2264 EMSG2(_(e_invarg2), arg); 2265 break; 2266 } 2267 error = TRUE; 2268 } 2269 else 2270 { 2271 if (tofree != NULL) 2272 name = tofree; 2273 if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL) 2274 error = TRUE; 2275 else 2276 { 2277 /* handle d.key, l[idx], f(expr) */ 2278 arg_subsc = arg; 2279 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2280 error = TRUE; 2281 else 2282 { 2283 if (arg == arg_subsc && len == 2 && name[1] == ':') 2284 { 2285 switch (*name) 2286 { 2287 case 'g': list_glob_vars(first); break; 2288 case 'b': list_buf_vars(first); break; 2289 case 'w': list_win_vars(first); break; 2290 #ifdef FEAT_WINDOWS 2291 case 't': list_tab_vars(first); break; 2292 #endif 2293 case 'v': list_vim_vars(first); break; 2294 case 's': list_script_vars(first); break; 2295 case 'l': list_func_vars(first); break; 2296 default: 2297 EMSG2(_("E738: Can't list variables for %s"), name); 2298 } 2299 } 2300 else 2301 { 2302 char_u numbuf[NUMBUFLEN]; 2303 char_u *tf; 2304 int c; 2305 char_u *s; 2306 2307 s = echo_string(&tv, &tf, numbuf, 0); 2308 c = *arg; 2309 *arg = NUL; 2310 list_one_var_a((char_u *)"", 2311 arg == arg_subsc ? name : name_start, 2312 tv.v_type, 2313 s == NULL ? (char_u *)"" : s, 2314 first); 2315 *arg = c; 2316 vim_free(tf); 2317 } 2318 clear_tv(&tv); 2319 } 2320 } 2321 } 2322 2323 vim_free(tofree); 2324 } 2325 2326 arg = skipwhite(arg); 2327 } 2328 2329 return arg; 2330 } 2331 2332 /* 2333 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2334 * Returns a pointer to the char just after the var name. 2335 * Returns NULL if there is an error. 2336 */ 2337 static char_u * 2338 ex_let_one(arg, tv, copy, endchars, op) 2339 char_u *arg; /* points to variable name */ 2340 typval_T *tv; /* value to assign to variable */ 2341 int copy; /* copy value from "tv" */ 2342 char_u *endchars; /* valid chars after variable name or NULL */ 2343 char_u *op; /* "+", "-", "." or NULL*/ 2344 { 2345 int c1; 2346 char_u *name; 2347 char_u *p; 2348 char_u *arg_end = NULL; 2349 int len; 2350 int opt_flags; 2351 char_u *tofree = NULL; 2352 2353 /* 2354 * ":let $VAR = expr": Set environment variable. 2355 */ 2356 if (*arg == '$') 2357 { 2358 /* Find the end of the name. */ 2359 ++arg; 2360 name = arg; 2361 len = get_env_len(&arg); 2362 if (len == 0) 2363 EMSG2(_(e_invarg2), name - 1); 2364 else 2365 { 2366 if (op != NULL && (*op == '+' || *op == '-')) 2367 EMSG2(_(e_letwrong), op); 2368 else if (endchars != NULL 2369 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2370 EMSG(_(e_letunexp)); 2371 else if (!check_secure()) 2372 { 2373 c1 = name[len]; 2374 name[len] = NUL; 2375 p = get_tv_string_chk(tv); 2376 if (p != NULL && op != NULL && *op == '.') 2377 { 2378 int mustfree = FALSE; 2379 char_u *s = vim_getenv(name, &mustfree); 2380 2381 if (s != NULL) 2382 { 2383 p = tofree = concat_str(s, p); 2384 if (mustfree) 2385 vim_free(s); 2386 } 2387 } 2388 if (p != NULL) 2389 { 2390 vim_setenv(name, p); 2391 if (STRICMP(name, "HOME") == 0) 2392 init_homedir(); 2393 else if (didset_vim && STRICMP(name, "VIM") == 0) 2394 didset_vim = FALSE; 2395 else if (didset_vimruntime 2396 && STRICMP(name, "VIMRUNTIME") == 0) 2397 didset_vimruntime = FALSE; 2398 arg_end = arg; 2399 } 2400 name[len] = c1; 2401 vim_free(tofree); 2402 } 2403 } 2404 } 2405 2406 /* 2407 * ":let &option = expr": Set option value. 2408 * ":let &l:option = expr": Set local option value. 2409 * ":let &g:option = expr": Set global option value. 2410 */ 2411 else if (*arg == '&') 2412 { 2413 /* Find the end of the name. */ 2414 p = find_option_end(&arg, &opt_flags); 2415 if (p == NULL || (endchars != NULL 2416 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2417 EMSG(_(e_letunexp)); 2418 else 2419 { 2420 long n; 2421 int opt_type; 2422 long numval; 2423 char_u *stringval = NULL; 2424 char_u *s; 2425 2426 c1 = *p; 2427 *p = NUL; 2428 2429 n = get_tv_number(tv); 2430 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2431 if (s != NULL && op != NULL && *op != '=') 2432 { 2433 opt_type = get_option_value(arg, &numval, 2434 &stringval, opt_flags); 2435 if ((opt_type == 1 && *op == '.') 2436 || (opt_type == 0 && *op != '.')) 2437 EMSG2(_(e_letwrong), op); 2438 else 2439 { 2440 if (opt_type == 1) /* number */ 2441 { 2442 if (*op == '+') 2443 n = numval + n; 2444 else 2445 n = numval - n; 2446 } 2447 else if (opt_type == 0 && stringval != NULL) /* string */ 2448 { 2449 s = concat_str(stringval, s); 2450 vim_free(stringval); 2451 stringval = s; 2452 } 2453 } 2454 } 2455 if (s != NULL) 2456 { 2457 set_option_value(arg, n, s, opt_flags); 2458 arg_end = p; 2459 } 2460 *p = c1; 2461 vim_free(stringval); 2462 } 2463 } 2464 2465 /* 2466 * ":let @r = expr": Set register contents. 2467 */ 2468 else if (*arg == '@') 2469 { 2470 ++arg; 2471 if (op != NULL && (*op == '+' || *op == '-')) 2472 EMSG2(_(e_letwrong), op); 2473 else if (endchars != NULL 2474 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2475 EMSG(_(e_letunexp)); 2476 else 2477 { 2478 char_u *ptofree = NULL; 2479 char_u *s; 2480 2481 p = get_tv_string_chk(tv); 2482 if (p != NULL && op != NULL && *op == '.') 2483 { 2484 s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); 2485 if (s != NULL) 2486 { 2487 p = ptofree = concat_str(s, p); 2488 vim_free(s); 2489 } 2490 } 2491 if (p != NULL) 2492 { 2493 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2494 arg_end = arg + 1; 2495 } 2496 vim_free(ptofree); 2497 } 2498 } 2499 2500 /* 2501 * ":let var = expr": Set internal variable. 2502 * ":let {expr} = expr": Idem, name made with curly braces 2503 */ 2504 else if (eval_isnamec1(*arg) || *arg == '{') 2505 { 2506 lval_T lv; 2507 2508 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); 2509 if (p != NULL && lv.ll_name != NULL) 2510 { 2511 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2512 EMSG(_(e_letunexp)); 2513 else 2514 { 2515 set_var_lval(&lv, p, tv, copy, op); 2516 arg_end = p; 2517 } 2518 } 2519 clear_lval(&lv); 2520 } 2521 2522 else 2523 EMSG2(_(e_invarg2), arg); 2524 2525 return arg_end; 2526 } 2527 2528 /* 2529 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2530 */ 2531 static int 2532 check_changedtick(arg) 2533 char_u *arg; 2534 { 2535 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2536 { 2537 EMSG2(_(e_readonlyvar), arg); 2538 return TRUE; 2539 } 2540 return FALSE; 2541 } 2542 2543 /* 2544 * Get an lval: variable, Dict item or List item that can be assigned a value 2545 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2546 * "name.key", "name.key[expr]" etc. 2547 * Indexing only works if "name" is an existing List or Dictionary. 2548 * "name" points to the start of the name. 2549 * If "rettv" is not NULL it points to the value to be assigned. 2550 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2551 * wrong; must end in space or cmd separator. 2552 * 2553 * flags: 2554 * GLV_QUIET: do not give error messages 2555 * GLV_NO_AUTOLOAD: do not use script autoloading 2556 * 2557 * Returns a pointer to just after the name, including indexes. 2558 * When an evaluation error occurs "lp->ll_name" is NULL; 2559 * Returns NULL for a parsing error. Still need to free items in "lp"! 2560 */ 2561 static char_u * 2562 get_lval(name, rettv, lp, unlet, skip, flags, fne_flags) 2563 char_u *name; 2564 typval_T *rettv; 2565 lval_T *lp; 2566 int unlet; 2567 int skip; 2568 int flags; /* GLV_ values */ 2569 int fne_flags; /* flags for find_name_end() */ 2570 { 2571 char_u *p; 2572 char_u *expr_start, *expr_end; 2573 int cc; 2574 dictitem_T *v; 2575 typval_T var1; 2576 typval_T var2; 2577 int empty1 = FALSE; 2578 listitem_T *ni; 2579 char_u *key = NULL; 2580 int len; 2581 hashtab_T *ht; 2582 int quiet = flags & GLV_QUIET; 2583 2584 /* Clear everything in "lp". */ 2585 vim_memset(lp, 0, sizeof(lval_T)); 2586 2587 if (skip) 2588 { 2589 /* When skipping just find the end of the name. */ 2590 lp->ll_name = name; 2591 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2592 } 2593 2594 /* Find the end of the name. */ 2595 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2596 if (expr_start != NULL) 2597 { 2598 /* Don't expand the name when we already know there is an error. */ 2599 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2600 && *p != '[' && *p != '.') 2601 { 2602 EMSG(_(e_trailing)); 2603 return NULL; 2604 } 2605 2606 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2607 if (lp->ll_exp_name == NULL) 2608 { 2609 /* Report an invalid expression in braces, unless the 2610 * expression evaluation has been cancelled due to an 2611 * aborting error, an interrupt, or an exception. */ 2612 if (!aborting() && !quiet) 2613 { 2614 emsg_severe = TRUE; 2615 EMSG2(_(e_invarg2), name); 2616 return NULL; 2617 } 2618 } 2619 lp->ll_name = lp->ll_exp_name; 2620 } 2621 else 2622 lp->ll_name = name; 2623 2624 /* Without [idx] or .key we are done. */ 2625 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2626 return p; 2627 2628 cc = *p; 2629 *p = NUL; 2630 v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD); 2631 if (v == NULL && !quiet) 2632 EMSG2(_(e_undefvar), lp->ll_name); 2633 *p = cc; 2634 if (v == NULL) 2635 return NULL; 2636 2637 /* 2638 * Loop until no more [idx] or .key is following. 2639 */ 2640 lp->ll_tv = &v->di_tv; 2641 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2642 { 2643 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2644 && !(lp->ll_tv->v_type == VAR_DICT 2645 && lp->ll_tv->vval.v_dict != NULL)) 2646 { 2647 if (!quiet) 2648 EMSG(_("E689: Can only index a List or Dictionary")); 2649 return NULL; 2650 } 2651 if (lp->ll_range) 2652 { 2653 if (!quiet) 2654 EMSG(_("E708: [:] must come last")); 2655 return NULL; 2656 } 2657 2658 len = -1; 2659 if (*p == '.') 2660 { 2661 key = p + 1; 2662 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2663 ; 2664 if (len == 0) 2665 { 2666 if (!quiet) 2667 EMSG(_(e_emptykey)); 2668 return NULL; 2669 } 2670 p = key + len; 2671 } 2672 else 2673 { 2674 /* Get the index [expr] or the first index [expr: ]. */ 2675 p = skipwhite(p + 1); 2676 if (*p == ':') 2677 empty1 = TRUE; 2678 else 2679 { 2680 empty1 = FALSE; 2681 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2682 return NULL; 2683 if (get_tv_string_chk(&var1) == NULL) 2684 { 2685 /* not a number or string */ 2686 clear_tv(&var1); 2687 return NULL; 2688 } 2689 } 2690 2691 /* Optionally get the second index [ :expr]. */ 2692 if (*p == ':') 2693 { 2694 if (lp->ll_tv->v_type == VAR_DICT) 2695 { 2696 if (!quiet) 2697 EMSG(_(e_dictrange)); 2698 if (!empty1) 2699 clear_tv(&var1); 2700 return NULL; 2701 } 2702 if (rettv != NULL && (rettv->v_type != VAR_LIST 2703 || rettv->vval.v_list == NULL)) 2704 { 2705 if (!quiet) 2706 EMSG(_("E709: [:] requires a List value")); 2707 if (!empty1) 2708 clear_tv(&var1); 2709 return NULL; 2710 } 2711 p = skipwhite(p + 1); 2712 if (*p == ']') 2713 lp->ll_empty2 = TRUE; 2714 else 2715 { 2716 lp->ll_empty2 = FALSE; 2717 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2718 { 2719 if (!empty1) 2720 clear_tv(&var1); 2721 return NULL; 2722 } 2723 if (get_tv_string_chk(&var2) == NULL) 2724 { 2725 /* not a number or string */ 2726 if (!empty1) 2727 clear_tv(&var1); 2728 clear_tv(&var2); 2729 return NULL; 2730 } 2731 } 2732 lp->ll_range = TRUE; 2733 } 2734 else 2735 lp->ll_range = FALSE; 2736 2737 if (*p != ']') 2738 { 2739 if (!quiet) 2740 EMSG(_(e_missbrac)); 2741 if (!empty1) 2742 clear_tv(&var1); 2743 if (lp->ll_range && !lp->ll_empty2) 2744 clear_tv(&var2); 2745 return NULL; 2746 } 2747 2748 /* Skip to past ']'. */ 2749 ++p; 2750 } 2751 2752 if (lp->ll_tv->v_type == VAR_DICT) 2753 { 2754 if (len == -1) 2755 { 2756 /* "[key]": get key from "var1" */ 2757 key = get_tv_string(&var1); /* is number or string */ 2758 if (*key == NUL) 2759 { 2760 if (!quiet) 2761 EMSG(_(e_emptykey)); 2762 clear_tv(&var1); 2763 return NULL; 2764 } 2765 } 2766 lp->ll_list = NULL; 2767 lp->ll_dict = lp->ll_tv->vval.v_dict; 2768 lp->ll_di = dict_find(lp->ll_dict, key, len); 2769 2770 /* When assigning to a scope dictionary check that a function and 2771 * variable name is valid (only variable name unless it is l: or 2772 * g: dictionary). Disallow overwriting a builtin function. */ 2773 if (rettv != NULL && lp->ll_dict->dv_scope != 0) 2774 { 2775 int prevval; 2776 int wrong; 2777 2778 if (len != -1) 2779 { 2780 prevval = key[len]; 2781 key[len] = NUL; 2782 } 2783 else 2784 prevval = 0; /* avoid compiler warning */ 2785 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE 2786 && rettv->v_type == VAR_FUNC 2787 && var_check_func_name(key, lp->ll_di == NULL)) 2788 || !valid_varname(key); 2789 if (len != -1) 2790 key[len] = prevval; 2791 if (wrong) 2792 return NULL; 2793 } 2794 2795 if (lp->ll_di == NULL) 2796 { 2797 /* Can't add "v:" variable. */ 2798 if (lp->ll_dict == &vimvardict) 2799 { 2800 EMSG2(_(e_illvar), name); 2801 return NULL; 2802 } 2803 2804 /* Key does not exist in dict: may need to add it. */ 2805 if (*p == '[' || *p == '.' || unlet) 2806 { 2807 if (!quiet) 2808 EMSG2(_(e_dictkey), key); 2809 if (len == -1) 2810 clear_tv(&var1); 2811 return NULL; 2812 } 2813 if (len == -1) 2814 lp->ll_newkey = vim_strsave(key); 2815 else 2816 lp->ll_newkey = vim_strnsave(key, len); 2817 if (len == -1) 2818 clear_tv(&var1); 2819 if (lp->ll_newkey == NULL) 2820 p = NULL; 2821 break; 2822 } 2823 /* existing variable, need to check if it can be changed */ 2824 else if (var_check_ro(lp->ll_di->di_flags, name, FALSE)) 2825 return NULL; 2826 2827 if (len == -1) 2828 clear_tv(&var1); 2829 lp->ll_tv = &lp->ll_di->di_tv; 2830 } 2831 else 2832 { 2833 /* 2834 * Get the number and item for the only or first index of the List. 2835 */ 2836 if (empty1) 2837 lp->ll_n1 = 0; 2838 else 2839 { 2840 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2841 clear_tv(&var1); 2842 } 2843 lp->ll_dict = NULL; 2844 lp->ll_list = lp->ll_tv->vval.v_list; 2845 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2846 if (lp->ll_li == NULL) 2847 { 2848 if (lp->ll_n1 < 0) 2849 { 2850 lp->ll_n1 = 0; 2851 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2852 } 2853 } 2854 if (lp->ll_li == NULL) 2855 { 2856 if (lp->ll_range && !lp->ll_empty2) 2857 clear_tv(&var2); 2858 if (!quiet) 2859 EMSGN(_(e_listidx), lp->ll_n1); 2860 return NULL; 2861 } 2862 2863 /* 2864 * May need to find the item or absolute index for the second 2865 * index of a range. 2866 * When no index given: "lp->ll_empty2" is TRUE. 2867 * Otherwise "lp->ll_n2" is set to the second index. 2868 */ 2869 if (lp->ll_range && !lp->ll_empty2) 2870 { 2871 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2872 clear_tv(&var2); 2873 if (lp->ll_n2 < 0) 2874 { 2875 ni = list_find(lp->ll_list, lp->ll_n2); 2876 if (ni == NULL) 2877 { 2878 if (!quiet) 2879 EMSGN(_(e_listidx), lp->ll_n2); 2880 return NULL; 2881 } 2882 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2883 } 2884 2885 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2886 if (lp->ll_n1 < 0) 2887 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2888 if (lp->ll_n2 < lp->ll_n1) 2889 { 2890 if (!quiet) 2891 EMSGN(_(e_listidx), lp->ll_n2); 2892 return NULL; 2893 } 2894 } 2895 2896 lp->ll_tv = &lp->ll_li->li_tv; 2897 } 2898 } 2899 2900 return p; 2901 } 2902 2903 /* 2904 * Clear lval "lp" that was filled by get_lval(). 2905 */ 2906 static void 2907 clear_lval(lp) 2908 lval_T *lp; 2909 { 2910 vim_free(lp->ll_exp_name); 2911 vim_free(lp->ll_newkey); 2912 } 2913 2914 /* 2915 * Set a variable that was parsed by get_lval() to "rettv". 2916 * "endp" points to just after the parsed name. 2917 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2918 */ 2919 static void 2920 set_var_lval(lp, endp, rettv, copy, op) 2921 lval_T *lp; 2922 char_u *endp; 2923 typval_T *rettv; 2924 int copy; 2925 char_u *op; 2926 { 2927 int cc; 2928 listitem_T *ri; 2929 dictitem_T *di; 2930 2931 if (lp->ll_tv == NULL) 2932 { 2933 if (!check_changedtick(lp->ll_name)) 2934 { 2935 cc = *endp; 2936 *endp = NUL; 2937 if (op != NULL && *op != '=') 2938 { 2939 typval_T tv; 2940 2941 /* handle +=, -= and .= */ 2942 di = NULL; 2943 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2944 &tv, &di, TRUE, FALSE) == OK) 2945 { 2946 if ((di == NULL 2947 || (!var_check_ro(di->di_flags, lp->ll_name, FALSE) 2948 && !tv_check_lock(di->di_tv.v_lock, lp->ll_name, 2949 FALSE))) 2950 && tv_op(&tv, rettv, op) == OK) 2951 set_var(lp->ll_name, &tv, FALSE); 2952 clear_tv(&tv); 2953 } 2954 } 2955 else 2956 set_var(lp->ll_name, rettv, copy); 2957 *endp = cc; 2958 } 2959 } 2960 else if (tv_check_lock(lp->ll_newkey == NULL 2961 ? lp->ll_tv->v_lock 2962 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) 2963 ; 2964 else if (lp->ll_range) 2965 { 2966 listitem_T *ll_li = lp->ll_li; 2967 int ll_n1 = lp->ll_n1; 2968 2969 /* 2970 * Check whether any of the list items is locked 2971 */ 2972 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) 2973 { 2974 if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) 2975 return; 2976 ri = ri->li_next; 2977 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1)) 2978 break; 2979 ll_li = ll_li->li_next; 2980 ++ll_n1; 2981 } 2982 2983 /* 2984 * Assign the List values to the list items. 2985 */ 2986 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2987 { 2988 if (op != NULL && *op != '=') 2989 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2990 else 2991 { 2992 clear_tv(&lp->ll_li->li_tv); 2993 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2994 } 2995 ri = ri->li_next; 2996 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2997 break; 2998 if (lp->ll_li->li_next == NULL) 2999 { 3000 /* Need to add an empty item. */ 3001 if (list_append_number(lp->ll_list, 0) == FAIL) 3002 { 3003 ri = NULL; 3004 break; 3005 } 3006 } 3007 lp->ll_li = lp->ll_li->li_next; 3008 ++lp->ll_n1; 3009 } 3010 if (ri != NULL) 3011 EMSG(_("E710: List value has more items than target")); 3012 else if (lp->ll_empty2 3013 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 3014 : lp->ll_n1 != lp->ll_n2) 3015 EMSG(_("E711: List value has not enough items")); 3016 } 3017 else 3018 { 3019 /* 3020 * Assign to a List or Dictionary item. 3021 */ 3022 if (lp->ll_newkey != NULL) 3023 { 3024 if (op != NULL && *op != '=') 3025 { 3026 EMSG2(_(e_letwrong), op); 3027 return; 3028 } 3029 3030 /* Need to add an item to the Dictionary. */ 3031 di = dictitem_alloc(lp->ll_newkey); 3032 if (di == NULL) 3033 return; 3034 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 3035 { 3036 vim_free(di); 3037 return; 3038 } 3039 lp->ll_tv = &di->di_tv; 3040 } 3041 else if (op != NULL && *op != '=') 3042 { 3043 tv_op(lp->ll_tv, rettv, op); 3044 return; 3045 } 3046 else 3047 clear_tv(lp->ll_tv); 3048 3049 /* 3050 * Assign the value to the variable or list item. 3051 */ 3052 if (copy) 3053 copy_tv(rettv, lp->ll_tv); 3054 else 3055 { 3056 *lp->ll_tv = *rettv; 3057 lp->ll_tv->v_lock = 0; 3058 init_tv(rettv); 3059 } 3060 } 3061 } 3062 3063 /* 3064 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 3065 * Returns OK or FAIL. 3066 */ 3067 static int 3068 tv_op(tv1, tv2, op) 3069 typval_T *tv1; 3070 typval_T *tv2; 3071 char_u *op; 3072 { 3073 long n; 3074 char_u numbuf[NUMBUFLEN]; 3075 char_u *s; 3076 3077 /* Can't do anything with a Funcref or a Dict on the right. */ 3078 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 3079 { 3080 switch (tv1->v_type) 3081 { 3082 case VAR_DICT: 3083 case VAR_FUNC: 3084 break; 3085 3086 case VAR_LIST: 3087 if (*op != '+' || tv2->v_type != VAR_LIST) 3088 break; 3089 /* List += List */ 3090 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 3091 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 3092 return OK; 3093 3094 case VAR_NUMBER: 3095 case VAR_STRING: 3096 if (tv2->v_type == VAR_LIST) 3097 break; 3098 if (*op == '+' || *op == '-') 3099 { 3100 /* nr += nr or nr -= nr*/ 3101 n = get_tv_number(tv1); 3102 #ifdef FEAT_FLOAT 3103 if (tv2->v_type == VAR_FLOAT) 3104 { 3105 float_T f = n; 3106 3107 if (*op == '+') 3108 f += tv2->vval.v_float; 3109 else 3110 f -= tv2->vval.v_float; 3111 clear_tv(tv1); 3112 tv1->v_type = VAR_FLOAT; 3113 tv1->vval.v_float = f; 3114 } 3115 else 3116 #endif 3117 { 3118 if (*op == '+') 3119 n += get_tv_number(tv2); 3120 else 3121 n -= get_tv_number(tv2); 3122 clear_tv(tv1); 3123 tv1->v_type = VAR_NUMBER; 3124 tv1->vval.v_number = n; 3125 } 3126 } 3127 else 3128 { 3129 if (tv2->v_type == VAR_FLOAT) 3130 break; 3131 3132 /* str .= str */ 3133 s = get_tv_string(tv1); 3134 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 3135 clear_tv(tv1); 3136 tv1->v_type = VAR_STRING; 3137 tv1->vval.v_string = s; 3138 } 3139 return OK; 3140 3141 #ifdef FEAT_FLOAT 3142 case VAR_FLOAT: 3143 { 3144 float_T f; 3145 3146 if (*op == '.' || (tv2->v_type != VAR_FLOAT 3147 && tv2->v_type != VAR_NUMBER 3148 && tv2->v_type != VAR_STRING)) 3149 break; 3150 if (tv2->v_type == VAR_FLOAT) 3151 f = tv2->vval.v_float; 3152 else 3153 f = get_tv_number(tv2); 3154 if (*op == '+') 3155 tv1->vval.v_float += f; 3156 else 3157 tv1->vval.v_float -= f; 3158 } 3159 return OK; 3160 #endif 3161 } 3162 } 3163 3164 EMSG2(_(e_letwrong), op); 3165 return FAIL; 3166 } 3167 3168 /* 3169 * Add a watcher to a list. 3170 */ 3171 void 3172 list_add_watch(l, lw) 3173 list_T *l; 3174 listwatch_T *lw; 3175 { 3176 lw->lw_next = l->lv_watch; 3177 l->lv_watch = lw; 3178 } 3179 3180 /* 3181 * Remove a watcher from a list. 3182 * No warning when it isn't found... 3183 */ 3184 void 3185 list_rem_watch(l, lwrem) 3186 list_T *l; 3187 listwatch_T *lwrem; 3188 { 3189 listwatch_T *lw, **lwp; 3190 3191 lwp = &l->lv_watch; 3192 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3193 { 3194 if (lw == lwrem) 3195 { 3196 *lwp = lw->lw_next; 3197 break; 3198 } 3199 lwp = &lw->lw_next; 3200 } 3201 } 3202 3203 /* 3204 * Just before removing an item from a list: advance watchers to the next 3205 * item. 3206 */ 3207 static void 3208 list_fix_watch(l, item) 3209 list_T *l; 3210 listitem_T *item; 3211 { 3212 listwatch_T *lw; 3213 3214 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3215 if (lw->lw_item == item) 3216 lw->lw_item = item->li_next; 3217 } 3218 3219 /* 3220 * Evaluate the expression used in a ":for var in expr" command. 3221 * "arg" points to "var". 3222 * Set "*errp" to TRUE for an error, FALSE otherwise; 3223 * Return a pointer that holds the info. Null when there is an error. 3224 */ 3225 void * 3226 eval_for_line(arg, errp, nextcmdp, skip) 3227 char_u *arg; 3228 int *errp; 3229 char_u **nextcmdp; 3230 int skip; 3231 { 3232 forinfo_T *fi; 3233 char_u *expr; 3234 typval_T tv; 3235 list_T *l; 3236 3237 *errp = TRUE; /* default: there is an error */ 3238 3239 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3240 if (fi == NULL) 3241 return NULL; 3242 3243 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3244 if (expr == NULL) 3245 return fi; 3246 3247 expr = skipwhite(expr); 3248 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3249 { 3250 EMSG(_("E690: Missing \"in\" after :for")); 3251 return fi; 3252 } 3253 3254 if (skip) 3255 ++emsg_skip; 3256 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3257 { 3258 *errp = FALSE; 3259 if (!skip) 3260 { 3261 l = tv.vval.v_list; 3262 if (tv.v_type != VAR_LIST || l == NULL) 3263 { 3264 EMSG(_(e_listreq)); 3265 clear_tv(&tv); 3266 } 3267 else 3268 { 3269 /* No need to increment the refcount, it's already set for the 3270 * list being used in "tv". */ 3271 fi->fi_list = l; 3272 list_add_watch(l, &fi->fi_lw); 3273 fi->fi_lw.lw_item = l->lv_first; 3274 } 3275 } 3276 } 3277 if (skip) 3278 --emsg_skip; 3279 3280 return fi; 3281 } 3282 3283 /* 3284 * Use the first item in a ":for" list. Advance to the next. 3285 * Assign the values to the variable (list). "arg" points to the first one. 3286 * Return TRUE when a valid item was found, FALSE when at end of list or 3287 * something wrong. 3288 */ 3289 int 3290 next_for_item(fi_void, arg) 3291 void *fi_void; 3292 char_u *arg; 3293 { 3294 forinfo_T *fi = (forinfo_T *)fi_void; 3295 int result; 3296 listitem_T *item; 3297 3298 item = fi->fi_lw.lw_item; 3299 if (item == NULL) 3300 result = FALSE; 3301 else 3302 { 3303 fi->fi_lw.lw_item = item->li_next; 3304 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3305 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3306 } 3307 return result; 3308 } 3309 3310 /* 3311 * Free the structure used to store info used by ":for". 3312 */ 3313 void 3314 free_for_info(fi_void) 3315 void *fi_void; 3316 { 3317 forinfo_T *fi = (forinfo_T *)fi_void; 3318 3319 if (fi != NULL && fi->fi_list != NULL) 3320 { 3321 list_rem_watch(fi->fi_list, &fi->fi_lw); 3322 list_unref(fi->fi_list); 3323 } 3324 vim_free(fi); 3325 } 3326 3327 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3328 3329 void 3330 set_context_for_expression(xp, arg, cmdidx) 3331 expand_T *xp; 3332 char_u *arg; 3333 cmdidx_T cmdidx; 3334 { 3335 int got_eq = FALSE; 3336 int c; 3337 char_u *p; 3338 3339 if (cmdidx == CMD_let) 3340 { 3341 xp->xp_context = EXPAND_USER_VARS; 3342 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3343 { 3344 /* ":let var1 var2 ...": find last space. */ 3345 for (p = arg + STRLEN(arg); p >= arg; ) 3346 { 3347 xp->xp_pattern = p; 3348 mb_ptr_back(arg, p); 3349 if (vim_iswhite(*p)) 3350 break; 3351 } 3352 return; 3353 } 3354 } 3355 else 3356 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3357 : EXPAND_EXPRESSION; 3358 while ((xp->xp_pattern = vim_strpbrk(arg, 3359 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3360 { 3361 c = *xp->xp_pattern; 3362 if (c == '&') 3363 { 3364 c = xp->xp_pattern[1]; 3365 if (c == '&') 3366 { 3367 ++xp->xp_pattern; 3368 xp->xp_context = cmdidx != CMD_let || got_eq 3369 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3370 } 3371 else if (c != ' ') 3372 { 3373 xp->xp_context = EXPAND_SETTINGS; 3374 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3375 xp->xp_pattern += 2; 3376 3377 } 3378 } 3379 else if (c == '$') 3380 { 3381 /* environment variable */ 3382 xp->xp_context = EXPAND_ENV_VARS; 3383 } 3384 else if (c == '=') 3385 { 3386 got_eq = TRUE; 3387 xp->xp_context = EXPAND_EXPRESSION; 3388 } 3389 else if ((c == '<' || c == '#') 3390 && xp->xp_context == EXPAND_FUNCTIONS 3391 && vim_strchr(xp->xp_pattern, '(') == NULL) 3392 { 3393 /* Function name can start with "<SNR>" and contain '#'. */ 3394 break; 3395 } 3396 else if (cmdidx != CMD_let || got_eq) 3397 { 3398 if (c == '"') /* string */ 3399 { 3400 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3401 if (c == '\\' && xp->xp_pattern[1] != NUL) 3402 ++xp->xp_pattern; 3403 xp->xp_context = EXPAND_NOTHING; 3404 } 3405 else if (c == '\'') /* literal string */ 3406 { 3407 /* Trick: '' is like stopping and starting a literal string. */ 3408 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3409 /* skip */ ; 3410 xp->xp_context = EXPAND_NOTHING; 3411 } 3412 else if (c == '|') 3413 { 3414 if (xp->xp_pattern[1] == '|') 3415 { 3416 ++xp->xp_pattern; 3417 xp->xp_context = EXPAND_EXPRESSION; 3418 } 3419 else 3420 xp->xp_context = EXPAND_COMMANDS; 3421 } 3422 else 3423 xp->xp_context = EXPAND_EXPRESSION; 3424 } 3425 else 3426 /* Doesn't look like something valid, expand as an expression 3427 * anyway. */ 3428 xp->xp_context = EXPAND_EXPRESSION; 3429 arg = xp->xp_pattern; 3430 if (*arg != NUL) 3431 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3432 /* skip */ ; 3433 } 3434 xp->xp_pattern = arg; 3435 } 3436 3437 #endif /* FEAT_CMDL_COMPL */ 3438 3439 /* 3440 * ":1,25call func(arg1, arg2)" function call. 3441 */ 3442 void 3443 ex_call(eap) 3444 exarg_T *eap; 3445 { 3446 char_u *arg = eap->arg; 3447 char_u *startarg; 3448 char_u *name; 3449 char_u *tofree; 3450 int len; 3451 typval_T rettv; 3452 linenr_T lnum; 3453 int doesrange; 3454 int failed = FALSE; 3455 funcdict_T fudi; 3456 3457 if (eap->skip) 3458 { 3459 /* trans_function_name() doesn't work well when skipping, use eval0() 3460 * instead to skip to any following command, e.g. for: 3461 * :if 0 | call dict.foo().bar() | endif */ 3462 ++emsg_skip; 3463 if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL) 3464 clear_tv(&rettv); 3465 --emsg_skip; 3466 return; 3467 } 3468 3469 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3470 if (fudi.fd_newkey != NULL) 3471 { 3472 /* Still need to give an error message for missing key. */ 3473 EMSG2(_(e_dictkey), fudi.fd_newkey); 3474 vim_free(fudi.fd_newkey); 3475 } 3476 if (tofree == NULL) 3477 return; 3478 3479 /* Increase refcount on dictionary, it could get deleted when evaluating 3480 * the arguments. */ 3481 if (fudi.fd_dict != NULL) 3482 ++fudi.fd_dict->dv_refcount; 3483 3484 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3485 len = (int)STRLEN(tofree); 3486 name = deref_func_name(tofree, &len, FALSE); 3487 3488 /* Skip white space to allow ":call func ()". Not good, but required for 3489 * backward compatibility. */ 3490 startarg = skipwhite(arg); 3491 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3492 3493 if (*startarg != '(') 3494 { 3495 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3496 goto end; 3497 } 3498 3499 /* 3500 * When skipping, evaluate the function once, to find the end of the 3501 * arguments. 3502 * When the function takes a range, this is discovered after the first 3503 * call, and the loop is broken. 3504 */ 3505 if (eap->skip) 3506 { 3507 ++emsg_skip; 3508 lnum = eap->line2; /* do it once, also with an invalid range */ 3509 } 3510 else 3511 lnum = eap->line1; 3512 for ( ; lnum <= eap->line2; ++lnum) 3513 { 3514 if (!eap->skip && eap->addr_count > 0) 3515 { 3516 curwin->w_cursor.lnum = lnum; 3517 curwin->w_cursor.col = 0; 3518 #ifdef FEAT_VIRTUALEDIT 3519 curwin->w_cursor.coladd = 0; 3520 #endif 3521 } 3522 arg = startarg; 3523 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3524 eap->line1, eap->line2, &doesrange, 3525 !eap->skip, fudi.fd_dict) == FAIL) 3526 { 3527 failed = TRUE; 3528 break; 3529 } 3530 3531 /* Handle a function returning a Funcref, Dictionary or List. */ 3532 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3533 { 3534 failed = TRUE; 3535 break; 3536 } 3537 3538 clear_tv(&rettv); 3539 if (doesrange || eap->skip) 3540 break; 3541 3542 /* Stop when immediately aborting on error, or when an interrupt 3543 * occurred or an exception was thrown but not caught. 3544 * get_func_tv() returned OK, so that the check for trailing 3545 * characters below is executed. */ 3546 if (aborting()) 3547 break; 3548 } 3549 if (eap->skip) 3550 --emsg_skip; 3551 3552 if (!failed) 3553 { 3554 /* Check for trailing illegal characters and a following command. */ 3555 if (!ends_excmd(*arg)) 3556 { 3557 emsg_severe = TRUE; 3558 EMSG(_(e_trailing)); 3559 } 3560 else 3561 eap->nextcmd = check_nextcmd(arg); 3562 } 3563 3564 end: 3565 dict_unref(fudi.fd_dict); 3566 vim_free(tofree); 3567 } 3568 3569 /* 3570 * ":unlet[!] var1 ... " command. 3571 */ 3572 void 3573 ex_unlet(eap) 3574 exarg_T *eap; 3575 { 3576 ex_unletlock(eap, eap->arg, 0); 3577 } 3578 3579 /* 3580 * ":lockvar" and ":unlockvar" commands 3581 */ 3582 void 3583 ex_lockvar(eap) 3584 exarg_T *eap; 3585 { 3586 char_u *arg = eap->arg; 3587 int deep = 2; 3588 3589 if (eap->forceit) 3590 deep = -1; 3591 else if (vim_isdigit(*arg)) 3592 { 3593 deep = getdigits(&arg); 3594 arg = skipwhite(arg); 3595 } 3596 3597 ex_unletlock(eap, arg, deep); 3598 } 3599 3600 /* 3601 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3602 */ 3603 static void 3604 ex_unletlock(eap, argstart, deep) 3605 exarg_T *eap; 3606 char_u *argstart; 3607 int deep; 3608 { 3609 char_u *arg = argstart; 3610 char_u *name_end; 3611 int error = FALSE; 3612 lval_T lv; 3613 3614 do 3615 { 3616 /* Parse the name and find the end. */ 3617 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, 3618 FNE_CHECK_START); 3619 if (lv.ll_name == NULL) 3620 error = TRUE; /* error but continue parsing */ 3621 if (name_end == NULL || (!vim_iswhite(*name_end) 3622 && !ends_excmd(*name_end))) 3623 { 3624 if (name_end != NULL) 3625 { 3626 emsg_severe = TRUE; 3627 EMSG(_(e_trailing)); 3628 } 3629 if (!(eap->skip || error)) 3630 clear_lval(&lv); 3631 break; 3632 } 3633 3634 if (!error && !eap->skip) 3635 { 3636 if (eap->cmdidx == CMD_unlet) 3637 { 3638 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3639 error = TRUE; 3640 } 3641 else 3642 { 3643 if (do_lock_var(&lv, name_end, deep, 3644 eap->cmdidx == CMD_lockvar) == FAIL) 3645 error = TRUE; 3646 } 3647 } 3648 3649 if (!eap->skip) 3650 clear_lval(&lv); 3651 3652 arg = skipwhite(name_end); 3653 } while (!ends_excmd(*arg)); 3654 3655 eap->nextcmd = check_nextcmd(arg); 3656 } 3657 3658 static int 3659 do_unlet_var(lp, name_end, forceit) 3660 lval_T *lp; 3661 char_u *name_end; 3662 int forceit; 3663 { 3664 int ret = OK; 3665 int cc; 3666 3667 if (lp->ll_tv == NULL) 3668 { 3669 cc = *name_end; 3670 *name_end = NUL; 3671 3672 /* Normal name or expanded name. */ 3673 if (check_changedtick(lp->ll_name)) 3674 ret = FAIL; 3675 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3676 ret = FAIL; 3677 *name_end = cc; 3678 } 3679 else if ((lp->ll_list != NULL 3680 && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) 3681 || (lp->ll_dict != NULL 3682 && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) 3683 return FAIL; 3684 else if (lp->ll_range) 3685 { 3686 listitem_T *li; 3687 listitem_T *ll_li = lp->ll_li; 3688 int ll_n1 = lp->ll_n1; 3689 3690 while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) 3691 { 3692 li = ll_li->li_next; 3693 if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) 3694 return FAIL; 3695 ll_li = li; 3696 ++ll_n1; 3697 } 3698 3699 /* Delete a range of List items. */ 3700 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3701 { 3702 li = lp->ll_li->li_next; 3703 listitem_remove(lp->ll_list, lp->ll_li); 3704 lp->ll_li = li; 3705 ++lp->ll_n1; 3706 } 3707 } 3708 else 3709 { 3710 if (lp->ll_list != NULL) 3711 /* unlet a List item. */ 3712 listitem_remove(lp->ll_list, lp->ll_li); 3713 else 3714 /* unlet a Dictionary item. */ 3715 dictitem_remove(lp->ll_dict, lp->ll_di); 3716 } 3717 3718 return ret; 3719 } 3720 3721 /* 3722 * "unlet" a variable. Return OK if it existed, FAIL if not. 3723 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3724 */ 3725 int 3726 do_unlet(name, forceit) 3727 char_u *name; 3728 int forceit; 3729 { 3730 hashtab_T *ht; 3731 hashitem_T *hi; 3732 char_u *varname; 3733 dict_T *d; 3734 dictitem_T *di; 3735 3736 ht = find_var_ht(name, &varname); 3737 if (ht != NULL && *varname != NUL) 3738 { 3739 if (ht == &globvarht) 3740 d = &globvardict; 3741 else if (current_funccal != NULL 3742 && ht == ¤t_funccal->l_vars.dv_hashtab) 3743 d = ¤t_funccal->l_vars; 3744 else 3745 { 3746 di = find_var_in_ht(ht, *name, (char_u *)"", FALSE); 3747 d = di->di_tv.vval.v_dict; 3748 } 3749 hi = hash_find(ht, varname); 3750 if (!HASHITEM_EMPTY(hi)) 3751 { 3752 di = HI2DI(hi); 3753 if (var_check_fixed(di->di_flags, name, FALSE) 3754 || var_check_ro(di->di_flags, name, FALSE) 3755 || tv_check_lock(d->dv_lock, name, FALSE)) 3756 return FAIL; 3757 delete_var(ht, hi); 3758 return OK; 3759 } 3760 } 3761 if (forceit) 3762 return OK; 3763 EMSG2(_("E108: No such variable: \"%s\""), name); 3764 return FAIL; 3765 } 3766 3767 /* 3768 * Lock or unlock variable indicated by "lp". 3769 * "deep" is the levels to go (-1 for unlimited); 3770 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3771 */ 3772 static int 3773 do_lock_var(lp, name_end, deep, lock) 3774 lval_T *lp; 3775 char_u *name_end; 3776 int deep; 3777 int lock; 3778 { 3779 int ret = OK; 3780 int cc; 3781 dictitem_T *di; 3782 3783 if (deep == 0) /* nothing to do */ 3784 return OK; 3785 3786 if (lp->ll_tv == NULL) 3787 { 3788 cc = *name_end; 3789 *name_end = NUL; 3790 3791 /* Normal name or expanded name. */ 3792 if (check_changedtick(lp->ll_name)) 3793 ret = FAIL; 3794 else 3795 { 3796 di = find_var(lp->ll_name, NULL, TRUE); 3797 if (di == NULL) 3798 ret = FAIL; 3799 else 3800 { 3801 if (lock) 3802 di->di_flags |= DI_FLAGS_LOCK; 3803 else 3804 di->di_flags &= ~DI_FLAGS_LOCK; 3805 item_lock(&di->di_tv, deep, lock); 3806 } 3807 } 3808 *name_end = cc; 3809 } 3810 else if (lp->ll_range) 3811 { 3812 listitem_T *li = lp->ll_li; 3813 3814 /* (un)lock a range of List items. */ 3815 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3816 { 3817 item_lock(&li->li_tv, deep, lock); 3818 li = li->li_next; 3819 ++lp->ll_n1; 3820 } 3821 } 3822 else if (lp->ll_list != NULL) 3823 /* (un)lock a List item. */ 3824 item_lock(&lp->ll_li->li_tv, deep, lock); 3825 else 3826 /* (un)lock a Dictionary item. */ 3827 item_lock(&lp->ll_di->di_tv, deep, lock); 3828 3829 return ret; 3830 } 3831 3832 /* 3833 * Lock or unlock an item. "deep" is nr of levels to go. 3834 */ 3835 static void 3836 item_lock(tv, deep, lock) 3837 typval_T *tv; 3838 int deep; 3839 int lock; 3840 { 3841 static int recurse = 0; 3842 list_T *l; 3843 listitem_T *li; 3844 dict_T *d; 3845 hashitem_T *hi; 3846 int todo; 3847 3848 if (recurse >= DICT_MAXNEST) 3849 { 3850 EMSG(_("E743: variable nested too deep for (un)lock")); 3851 return; 3852 } 3853 if (deep == 0) 3854 return; 3855 ++recurse; 3856 3857 /* lock/unlock the item itself */ 3858 if (lock) 3859 tv->v_lock |= VAR_LOCKED; 3860 else 3861 tv->v_lock &= ~VAR_LOCKED; 3862 3863 switch (tv->v_type) 3864 { 3865 case VAR_LIST: 3866 if ((l = tv->vval.v_list) != NULL) 3867 { 3868 if (lock) 3869 l->lv_lock |= VAR_LOCKED; 3870 else 3871 l->lv_lock &= ~VAR_LOCKED; 3872 if (deep < 0 || deep > 1) 3873 /* recursive: lock/unlock the items the List contains */ 3874 for (li = l->lv_first; li != NULL; li = li->li_next) 3875 item_lock(&li->li_tv, deep - 1, lock); 3876 } 3877 break; 3878 case VAR_DICT: 3879 if ((d = tv->vval.v_dict) != NULL) 3880 { 3881 if (lock) 3882 d->dv_lock |= VAR_LOCKED; 3883 else 3884 d->dv_lock &= ~VAR_LOCKED; 3885 if (deep < 0 || deep > 1) 3886 { 3887 /* recursive: lock/unlock the items the List contains */ 3888 todo = (int)d->dv_hashtab.ht_used; 3889 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3890 { 3891 if (!HASHITEM_EMPTY(hi)) 3892 { 3893 --todo; 3894 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3895 } 3896 } 3897 } 3898 } 3899 } 3900 --recurse; 3901 } 3902 3903 /* 3904 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3905 * or it refers to a List or Dictionary that is locked. 3906 */ 3907 static int 3908 tv_islocked(tv) 3909 typval_T *tv; 3910 { 3911 return (tv->v_lock & VAR_LOCKED) 3912 || (tv->v_type == VAR_LIST 3913 && tv->vval.v_list != NULL 3914 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3915 || (tv->v_type == VAR_DICT 3916 && tv->vval.v_dict != NULL 3917 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3918 } 3919 3920 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3921 /* 3922 * Delete all "menutrans_" variables. 3923 */ 3924 void 3925 del_menutrans_vars() 3926 { 3927 hashitem_T *hi; 3928 int todo; 3929 3930 hash_lock(&globvarht); 3931 todo = (int)globvarht.ht_used; 3932 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3933 { 3934 if (!HASHITEM_EMPTY(hi)) 3935 { 3936 --todo; 3937 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3938 delete_var(&globvarht, hi); 3939 } 3940 } 3941 hash_unlock(&globvarht); 3942 } 3943 #endif 3944 3945 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3946 3947 /* 3948 * Local string buffer for the next two functions to store a variable name 3949 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3950 * get_user_var_name(). 3951 */ 3952 3953 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3954 3955 static char_u *varnamebuf = NULL; 3956 static int varnamebuflen = 0; 3957 3958 /* 3959 * Function to concatenate a prefix and a variable name. 3960 */ 3961 static char_u * 3962 cat_prefix_varname(prefix, name) 3963 int prefix; 3964 char_u *name; 3965 { 3966 int len; 3967 3968 len = (int)STRLEN(name) + 3; 3969 if (len > varnamebuflen) 3970 { 3971 vim_free(varnamebuf); 3972 len += 10; /* some additional space */ 3973 varnamebuf = alloc(len); 3974 if (varnamebuf == NULL) 3975 { 3976 varnamebuflen = 0; 3977 return NULL; 3978 } 3979 varnamebuflen = len; 3980 } 3981 *varnamebuf = prefix; 3982 varnamebuf[1] = ':'; 3983 STRCPY(varnamebuf + 2, name); 3984 return varnamebuf; 3985 } 3986 3987 /* 3988 * Function given to ExpandGeneric() to obtain the list of user defined 3989 * (global/buffer/window/built-in) variable names. 3990 */ 3991 char_u * 3992 get_user_var_name(xp, idx) 3993 expand_T *xp; 3994 int idx; 3995 { 3996 static long_u gdone; 3997 static long_u bdone; 3998 static long_u wdone; 3999 #ifdef FEAT_WINDOWS 4000 static long_u tdone; 4001 #endif 4002 static int vidx; 4003 static hashitem_T *hi; 4004 hashtab_T *ht; 4005 4006 if (idx == 0) 4007 { 4008 gdone = bdone = wdone = vidx = 0; 4009 #ifdef FEAT_WINDOWS 4010 tdone = 0; 4011 #endif 4012 } 4013 4014 /* Global variables */ 4015 if (gdone < globvarht.ht_used) 4016 { 4017 if (gdone++ == 0) 4018 hi = globvarht.ht_array; 4019 else 4020 ++hi; 4021 while (HASHITEM_EMPTY(hi)) 4022 ++hi; 4023 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 4024 return cat_prefix_varname('g', hi->hi_key); 4025 return hi->hi_key; 4026 } 4027 4028 /* b: variables */ 4029 ht = &curbuf->b_vars->dv_hashtab; 4030 if (bdone < ht->ht_used) 4031 { 4032 if (bdone++ == 0) 4033 hi = ht->ht_array; 4034 else 4035 ++hi; 4036 while (HASHITEM_EMPTY(hi)) 4037 ++hi; 4038 return cat_prefix_varname('b', hi->hi_key); 4039 } 4040 if (bdone == ht->ht_used) 4041 { 4042 ++bdone; 4043 return (char_u *)"b:changedtick"; 4044 } 4045 4046 /* w: variables */ 4047 ht = &curwin->w_vars->dv_hashtab; 4048 if (wdone < ht->ht_used) 4049 { 4050 if (wdone++ == 0) 4051 hi = ht->ht_array; 4052 else 4053 ++hi; 4054 while (HASHITEM_EMPTY(hi)) 4055 ++hi; 4056 return cat_prefix_varname('w', hi->hi_key); 4057 } 4058 4059 #ifdef FEAT_WINDOWS 4060 /* t: variables */ 4061 ht = &curtab->tp_vars->dv_hashtab; 4062 if (tdone < ht->ht_used) 4063 { 4064 if (tdone++ == 0) 4065 hi = ht->ht_array; 4066 else 4067 ++hi; 4068 while (HASHITEM_EMPTY(hi)) 4069 ++hi; 4070 return cat_prefix_varname('t', hi->hi_key); 4071 } 4072 #endif 4073 4074 /* v: variables */ 4075 if (vidx < VV_LEN) 4076 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 4077 4078 vim_free(varnamebuf); 4079 varnamebuf = NULL; 4080 varnamebuflen = 0; 4081 return NULL; 4082 } 4083 4084 #endif /* FEAT_CMDL_COMPL */ 4085 4086 /* 4087 * types for expressions. 4088 */ 4089 typedef enum 4090 { 4091 TYPE_UNKNOWN = 0 4092 , TYPE_EQUAL /* == */ 4093 , TYPE_NEQUAL /* != */ 4094 , TYPE_GREATER /* > */ 4095 , TYPE_GEQUAL /* >= */ 4096 , TYPE_SMALLER /* < */ 4097 , TYPE_SEQUAL /* <= */ 4098 , TYPE_MATCH /* =~ */ 4099 , TYPE_NOMATCH /* !~ */ 4100 } exptype_T; 4101 4102 /* 4103 * The "evaluate" argument: When FALSE, the argument is only parsed but not 4104 * executed. The function may return OK, but the rettv will be of type 4105 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 4106 */ 4107 4108 /* 4109 * Handle zero level expression. 4110 * This calls eval1() and handles error message and nextcmd. 4111 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 4112 * Note: "rettv.v_lock" is not set. 4113 * Return OK or FAIL. 4114 */ 4115 static int 4116 eval0(arg, rettv, nextcmd, evaluate) 4117 char_u *arg; 4118 typval_T *rettv; 4119 char_u **nextcmd; 4120 int evaluate; 4121 { 4122 int ret; 4123 char_u *p; 4124 4125 p = skipwhite(arg); 4126 ret = eval1(&p, rettv, evaluate); 4127 if (ret == FAIL || !ends_excmd(*p)) 4128 { 4129 if (ret != FAIL) 4130 clear_tv(rettv); 4131 /* 4132 * Report the invalid expression unless the expression evaluation has 4133 * been cancelled due to an aborting error, an interrupt, or an 4134 * exception. 4135 */ 4136 if (!aborting()) 4137 EMSG2(_(e_invexpr2), arg); 4138 ret = FAIL; 4139 } 4140 if (nextcmd != NULL) 4141 *nextcmd = check_nextcmd(p); 4142 4143 return ret; 4144 } 4145 4146 /* 4147 * Handle top level expression: 4148 * expr2 ? expr1 : expr1 4149 * 4150 * "arg" must point to the first non-white of the expression. 4151 * "arg" is advanced to the next non-white after the recognized expression. 4152 * 4153 * Note: "rettv.v_lock" is not set. 4154 * 4155 * Return OK or FAIL. 4156 */ 4157 static int 4158 eval1(arg, rettv, evaluate) 4159 char_u **arg; 4160 typval_T *rettv; 4161 int evaluate; 4162 { 4163 int result; 4164 typval_T var2; 4165 4166 /* 4167 * Get the first variable. 4168 */ 4169 if (eval2(arg, rettv, evaluate) == FAIL) 4170 return FAIL; 4171 4172 if ((*arg)[0] == '?') 4173 { 4174 result = FALSE; 4175 if (evaluate) 4176 { 4177 int error = FALSE; 4178 4179 if (get_tv_number_chk(rettv, &error) != 0) 4180 result = TRUE; 4181 clear_tv(rettv); 4182 if (error) 4183 return FAIL; 4184 } 4185 4186 /* 4187 * Get the second variable. 4188 */ 4189 *arg = skipwhite(*arg + 1); 4190 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 4191 return FAIL; 4192 4193 /* 4194 * Check for the ":". 4195 */ 4196 if ((*arg)[0] != ':') 4197 { 4198 EMSG(_("E109: Missing ':' after '?'")); 4199 if (evaluate && result) 4200 clear_tv(rettv); 4201 return FAIL; 4202 } 4203 4204 /* 4205 * Get the third variable. 4206 */ 4207 *arg = skipwhite(*arg + 1); 4208 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4209 { 4210 if (evaluate && result) 4211 clear_tv(rettv); 4212 return FAIL; 4213 } 4214 if (evaluate && !result) 4215 *rettv = var2; 4216 } 4217 4218 return OK; 4219 } 4220 4221 /* 4222 * Handle first level expression: 4223 * expr2 || expr2 || expr2 logical OR 4224 * 4225 * "arg" must point to the first non-white of the expression. 4226 * "arg" is advanced to the next non-white after the recognized expression. 4227 * 4228 * Return OK or FAIL. 4229 */ 4230 static int 4231 eval2(arg, rettv, evaluate) 4232 char_u **arg; 4233 typval_T *rettv; 4234 int evaluate; 4235 { 4236 typval_T var2; 4237 long result; 4238 int first; 4239 int error = FALSE; 4240 4241 /* 4242 * Get the first variable. 4243 */ 4244 if (eval3(arg, rettv, evaluate) == FAIL) 4245 return FAIL; 4246 4247 /* 4248 * Repeat until there is no following "||". 4249 */ 4250 first = TRUE; 4251 result = FALSE; 4252 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4253 { 4254 if (evaluate && first) 4255 { 4256 if (get_tv_number_chk(rettv, &error) != 0) 4257 result = TRUE; 4258 clear_tv(rettv); 4259 if (error) 4260 return FAIL; 4261 first = FALSE; 4262 } 4263 4264 /* 4265 * Get the second variable. 4266 */ 4267 *arg = skipwhite(*arg + 2); 4268 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4269 return FAIL; 4270 4271 /* 4272 * Compute the result. 4273 */ 4274 if (evaluate && !result) 4275 { 4276 if (get_tv_number_chk(&var2, &error) != 0) 4277 result = TRUE; 4278 clear_tv(&var2); 4279 if (error) 4280 return FAIL; 4281 } 4282 if (evaluate) 4283 { 4284 rettv->v_type = VAR_NUMBER; 4285 rettv->vval.v_number = result; 4286 } 4287 } 4288 4289 return OK; 4290 } 4291 4292 /* 4293 * Handle second level expression: 4294 * expr3 && expr3 && expr3 logical AND 4295 * 4296 * "arg" must point to the first non-white of the expression. 4297 * "arg" is advanced to the next non-white after the recognized expression. 4298 * 4299 * Return OK or FAIL. 4300 */ 4301 static int 4302 eval3(arg, rettv, evaluate) 4303 char_u **arg; 4304 typval_T *rettv; 4305 int evaluate; 4306 { 4307 typval_T var2; 4308 long result; 4309 int first; 4310 int error = FALSE; 4311 4312 /* 4313 * Get the first variable. 4314 */ 4315 if (eval4(arg, rettv, evaluate) == FAIL) 4316 return FAIL; 4317 4318 /* 4319 * Repeat until there is no following "&&". 4320 */ 4321 first = TRUE; 4322 result = TRUE; 4323 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4324 { 4325 if (evaluate && first) 4326 { 4327 if (get_tv_number_chk(rettv, &error) == 0) 4328 result = FALSE; 4329 clear_tv(rettv); 4330 if (error) 4331 return FAIL; 4332 first = FALSE; 4333 } 4334 4335 /* 4336 * Get the second variable. 4337 */ 4338 *arg = skipwhite(*arg + 2); 4339 if (eval4(arg, &var2, evaluate && result) == FAIL) 4340 return FAIL; 4341 4342 /* 4343 * Compute the result. 4344 */ 4345 if (evaluate && result) 4346 { 4347 if (get_tv_number_chk(&var2, &error) == 0) 4348 result = FALSE; 4349 clear_tv(&var2); 4350 if (error) 4351 return FAIL; 4352 } 4353 if (evaluate) 4354 { 4355 rettv->v_type = VAR_NUMBER; 4356 rettv->vval.v_number = result; 4357 } 4358 } 4359 4360 return OK; 4361 } 4362 4363 /* 4364 * Handle third level expression: 4365 * var1 == var2 4366 * var1 =~ var2 4367 * var1 != var2 4368 * var1 !~ var2 4369 * var1 > var2 4370 * var1 >= var2 4371 * var1 < var2 4372 * var1 <= var2 4373 * var1 is var2 4374 * var1 isnot var2 4375 * 4376 * "arg" must point to the first non-white of the expression. 4377 * "arg" is advanced to the next non-white after the recognized expression. 4378 * 4379 * Return OK or FAIL. 4380 */ 4381 static int 4382 eval4(arg, rettv, evaluate) 4383 char_u **arg; 4384 typval_T *rettv; 4385 int evaluate; 4386 { 4387 typval_T var2; 4388 char_u *p; 4389 int i; 4390 exptype_T type = TYPE_UNKNOWN; 4391 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4392 int len = 2; 4393 long n1, n2; 4394 char_u *s1, *s2; 4395 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4396 regmatch_T regmatch; 4397 int ic; 4398 char_u *save_cpo; 4399 4400 /* 4401 * Get the first variable. 4402 */ 4403 if (eval5(arg, rettv, evaluate) == FAIL) 4404 return FAIL; 4405 4406 p = *arg; 4407 switch (p[0]) 4408 { 4409 case '=': if (p[1] == '=') 4410 type = TYPE_EQUAL; 4411 else if (p[1] == '~') 4412 type = TYPE_MATCH; 4413 break; 4414 case '!': if (p[1] == '=') 4415 type = TYPE_NEQUAL; 4416 else if (p[1] == '~') 4417 type = TYPE_NOMATCH; 4418 break; 4419 case '>': if (p[1] != '=') 4420 { 4421 type = TYPE_GREATER; 4422 len = 1; 4423 } 4424 else 4425 type = TYPE_GEQUAL; 4426 break; 4427 case '<': if (p[1] != '=') 4428 { 4429 type = TYPE_SMALLER; 4430 len = 1; 4431 } 4432 else 4433 type = TYPE_SEQUAL; 4434 break; 4435 case 'i': if (p[1] == 's') 4436 { 4437 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4438 len = 5; 4439 i = p[len]; 4440 if (!isalnum(i) && i != '_') 4441 { 4442 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4443 type_is = TRUE; 4444 } 4445 } 4446 break; 4447 } 4448 4449 /* 4450 * If there is a comparative operator, use it. 4451 */ 4452 if (type != TYPE_UNKNOWN) 4453 { 4454 /* extra question mark appended: ignore case */ 4455 if (p[len] == '?') 4456 { 4457 ic = TRUE; 4458 ++len; 4459 } 4460 /* extra '#' appended: match case */ 4461 else if (p[len] == '#') 4462 { 4463 ic = FALSE; 4464 ++len; 4465 } 4466 /* nothing appended: use 'ignorecase' */ 4467 else 4468 ic = p_ic; 4469 4470 /* 4471 * Get the second variable. 4472 */ 4473 *arg = skipwhite(p + len); 4474 if (eval5(arg, &var2, evaluate) == FAIL) 4475 { 4476 clear_tv(rettv); 4477 return FAIL; 4478 } 4479 4480 if (evaluate) 4481 { 4482 if (type_is && rettv->v_type != var2.v_type) 4483 { 4484 /* For "is" a different type always means FALSE, for "notis" 4485 * it means TRUE. */ 4486 n1 = (type == TYPE_NEQUAL); 4487 } 4488 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4489 { 4490 if (type_is) 4491 { 4492 n1 = (rettv->v_type == var2.v_type 4493 && rettv->vval.v_list == var2.vval.v_list); 4494 if (type == TYPE_NEQUAL) 4495 n1 = !n1; 4496 } 4497 else if (rettv->v_type != var2.v_type 4498 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4499 { 4500 if (rettv->v_type != var2.v_type) 4501 EMSG(_("E691: Can only compare List with List")); 4502 else 4503 EMSG(_("E692: Invalid operation for List")); 4504 clear_tv(rettv); 4505 clear_tv(&var2); 4506 return FAIL; 4507 } 4508 else 4509 { 4510 /* Compare two Lists for being equal or unequal. */ 4511 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, 4512 ic, FALSE); 4513 if (type == TYPE_NEQUAL) 4514 n1 = !n1; 4515 } 4516 } 4517 4518 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4519 { 4520 if (type_is) 4521 { 4522 n1 = (rettv->v_type == var2.v_type 4523 && rettv->vval.v_dict == var2.vval.v_dict); 4524 if (type == TYPE_NEQUAL) 4525 n1 = !n1; 4526 } 4527 else if (rettv->v_type != var2.v_type 4528 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4529 { 4530 if (rettv->v_type != var2.v_type) 4531 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4532 else 4533 EMSG(_("E736: Invalid operation for Dictionary")); 4534 clear_tv(rettv); 4535 clear_tv(&var2); 4536 return FAIL; 4537 } 4538 else 4539 { 4540 /* Compare two Dictionaries for being equal or unequal. */ 4541 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, 4542 ic, FALSE); 4543 if (type == TYPE_NEQUAL) 4544 n1 = !n1; 4545 } 4546 } 4547 4548 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4549 { 4550 if (rettv->v_type != var2.v_type 4551 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4552 { 4553 if (rettv->v_type != var2.v_type) 4554 EMSG(_("E693: Can only compare Funcref with Funcref")); 4555 else 4556 EMSG(_("E694: Invalid operation for Funcrefs")); 4557 clear_tv(rettv); 4558 clear_tv(&var2); 4559 return FAIL; 4560 } 4561 else 4562 { 4563 /* Compare two Funcrefs for being equal or unequal. */ 4564 if (rettv->vval.v_string == NULL 4565 || var2.vval.v_string == NULL) 4566 n1 = FALSE; 4567 else 4568 n1 = STRCMP(rettv->vval.v_string, 4569 var2.vval.v_string) == 0; 4570 if (type == TYPE_NEQUAL) 4571 n1 = !n1; 4572 } 4573 } 4574 4575 #ifdef FEAT_FLOAT 4576 /* 4577 * If one of the two variables is a float, compare as a float. 4578 * When using "=~" or "!~", always compare as string. 4579 */ 4580 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4581 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4582 { 4583 float_T f1, f2; 4584 4585 if (rettv->v_type == VAR_FLOAT) 4586 f1 = rettv->vval.v_float; 4587 else 4588 f1 = get_tv_number(rettv); 4589 if (var2.v_type == VAR_FLOAT) 4590 f2 = var2.vval.v_float; 4591 else 4592 f2 = get_tv_number(&var2); 4593 n1 = FALSE; 4594 switch (type) 4595 { 4596 case TYPE_EQUAL: n1 = (f1 == f2); break; 4597 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4598 case TYPE_GREATER: n1 = (f1 > f2); break; 4599 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4600 case TYPE_SMALLER: n1 = (f1 < f2); break; 4601 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4602 case TYPE_UNKNOWN: 4603 case TYPE_MATCH: 4604 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4605 } 4606 } 4607 #endif 4608 4609 /* 4610 * If one of the two variables is a number, compare as a number. 4611 * When using "=~" or "!~", always compare as string. 4612 */ 4613 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4614 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4615 { 4616 n1 = get_tv_number(rettv); 4617 n2 = get_tv_number(&var2); 4618 switch (type) 4619 { 4620 case TYPE_EQUAL: n1 = (n1 == n2); break; 4621 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4622 case TYPE_GREATER: n1 = (n1 > n2); break; 4623 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4624 case TYPE_SMALLER: n1 = (n1 < n2); break; 4625 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4626 case TYPE_UNKNOWN: 4627 case TYPE_MATCH: 4628 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4629 } 4630 } 4631 else 4632 { 4633 s1 = get_tv_string_buf(rettv, buf1); 4634 s2 = get_tv_string_buf(&var2, buf2); 4635 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4636 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4637 else 4638 i = 0; 4639 n1 = FALSE; 4640 switch (type) 4641 { 4642 case TYPE_EQUAL: n1 = (i == 0); break; 4643 case TYPE_NEQUAL: n1 = (i != 0); break; 4644 case TYPE_GREATER: n1 = (i > 0); break; 4645 case TYPE_GEQUAL: n1 = (i >= 0); break; 4646 case TYPE_SMALLER: n1 = (i < 0); break; 4647 case TYPE_SEQUAL: n1 = (i <= 0); break; 4648 4649 case TYPE_MATCH: 4650 case TYPE_NOMATCH: 4651 /* avoid 'l' flag in 'cpoptions' */ 4652 save_cpo = p_cpo; 4653 p_cpo = (char_u *)""; 4654 regmatch.regprog = vim_regcomp(s2, 4655 RE_MAGIC + RE_STRING); 4656 regmatch.rm_ic = ic; 4657 if (regmatch.regprog != NULL) 4658 { 4659 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4660 vim_regfree(regmatch.regprog); 4661 if (type == TYPE_NOMATCH) 4662 n1 = !n1; 4663 } 4664 p_cpo = save_cpo; 4665 break; 4666 4667 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4668 } 4669 } 4670 clear_tv(rettv); 4671 clear_tv(&var2); 4672 rettv->v_type = VAR_NUMBER; 4673 rettv->vval.v_number = n1; 4674 } 4675 } 4676 4677 return OK; 4678 } 4679 4680 /* 4681 * Handle fourth level expression: 4682 * + number addition 4683 * - number subtraction 4684 * . string concatenation 4685 * 4686 * "arg" must point to the first non-white of the expression. 4687 * "arg" is advanced to the next non-white after the recognized expression. 4688 * 4689 * Return OK or FAIL. 4690 */ 4691 static int 4692 eval5(arg, rettv, evaluate) 4693 char_u **arg; 4694 typval_T *rettv; 4695 int evaluate; 4696 { 4697 typval_T var2; 4698 typval_T var3; 4699 int op; 4700 long n1, n2; 4701 #ifdef FEAT_FLOAT 4702 float_T f1 = 0, f2 = 0; 4703 #endif 4704 char_u *s1, *s2; 4705 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4706 char_u *p; 4707 4708 /* 4709 * Get the first variable. 4710 */ 4711 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4712 return FAIL; 4713 4714 /* 4715 * Repeat computing, until no '+', '-' or '.' is following. 4716 */ 4717 for (;;) 4718 { 4719 op = **arg; 4720 if (op != '+' && op != '-' && op != '.') 4721 break; 4722 4723 if ((op != '+' || rettv->v_type != VAR_LIST) 4724 #ifdef FEAT_FLOAT 4725 && (op == '.' || rettv->v_type != VAR_FLOAT) 4726 #endif 4727 ) 4728 { 4729 /* For "list + ...", an illegal use of the first operand as 4730 * a number cannot be determined before evaluating the 2nd 4731 * operand: if this is also a list, all is ok. 4732 * For "something . ...", "something - ..." or "non-list + ...", 4733 * we know that the first operand needs to be a string or number 4734 * without evaluating the 2nd operand. So check before to avoid 4735 * side effects after an error. */ 4736 if (evaluate && get_tv_string_chk(rettv) == NULL) 4737 { 4738 clear_tv(rettv); 4739 return FAIL; 4740 } 4741 } 4742 4743 /* 4744 * Get the second variable. 4745 */ 4746 *arg = skipwhite(*arg + 1); 4747 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4748 { 4749 clear_tv(rettv); 4750 return FAIL; 4751 } 4752 4753 if (evaluate) 4754 { 4755 /* 4756 * Compute the result. 4757 */ 4758 if (op == '.') 4759 { 4760 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4761 s2 = get_tv_string_buf_chk(&var2, buf2); 4762 if (s2 == NULL) /* type error ? */ 4763 { 4764 clear_tv(rettv); 4765 clear_tv(&var2); 4766 return FAIL; 4767 } 4768 p = concat_str(s1, s2); 4769 clear_tv(rettv); 4770 rettv->v_type = VAR_STRING; 4771 rettv->vval.v_string = p; 4772 } 4773 else if (op == '+' && rettv->v_type == VAR_LIST 4774 && var2.v_type == VAR_LIST) 4775 { 4776 /* concatenate Lists */ 4777 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4778 &var3) == FAIL) 4779 { 4780 clear_tv(rettv); 4781 clear_tv(&var2); 4782 return FAIL; 4783 } 4784 clear_tv(rettv); 4785 *rettv = var3; 4786 } 4787 else 4788 { 4789 int error = FALSE; 4790 4791 #ifdef FEAT_FLOAT 4792 if (rettv->v_type == VAR_FLOAT) 4793 { 4794 f1 = rettv->vval.v_float; 4795 n1 = 0; 4796 } 4797 else 4798 #endif 4799 { 4800 n1 = get_tv_number_chk(rettv, &error); 4801 if (error) 4802 { 4803 /* This can only happen for "list + non-list". For 4804 * "non-list + ..." or "something - ...", we returned 4805 * before evaluating the 2nd operand. */ 4806 clear_tv(rettv); 4807 return FAIL; 4808 } 4809 #ifdef FEAT_FLOAT 4810 if (var2.v_type == VAR_FLOAT) 4811 f1 = n1; 4812 #endif 4813 } 4814 #ifdef FEAT_FLOAT 4815 if (var2.v_type == VAR_FLOAT) 4816 { 4817 f2 = var2.vval.v_float; 4818 n2 = 0; 4819 } 4820 else 4821 #endif 4822 { 4823 n2 = get_tv_number_chk(&var2, &error); 4824 if (error) 4825 { 4826 clear_tv(rettv); 4827 clear_tv(&var2); 4828 return FAIL; 4829 } 4830 #ifdef FEAT_FLOAT 4831 if (rettv->v_type == VAR_FLOAT) 4832 f2 = n2; 4833 #endif 4834 } 4835 clear_tv(rettv); 4836 4837 #ifdef FEAT_FLOAT 4838 /* If there is a float on either side the result is a float. */ 4839 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4840 { 4841 if (op == '+') 4842 f1 = f1 + f2; 4843 else 4844 f1 = f1 - f2; 4845 rettv->v_type = VAR_FLOAT; 4846 rettv->vval.v_float = f1; 4847 } 4848 else 4849 #endif 4850 { 4851 if (op == '+') 4852 n1 = n1 + n2; 4853 else 4854 n1 = n1 - n2; 4855 rettv->v_type = VAR_NUMBER; 4856 rettv->vval.v_number = n1; 4857 } 4858 } 4859 clear_tv(&var2); 4860 } 4861 } 4862 return OK; 4863 } 4864 4865 /* 4866 * Handle fifth level expression: 4867 * * number multiplication 4868 * / number division 4869 * % number modulo 4870 * 4871 * "arg" must point to the first non-white of the expression. 4872 * "arg" is advanced to the next non-white after the recognized expression. 4873 * 4874 * Return OK or FAIL. 4875 */ 4876 static int 4877 eval6(arg, rettv, evaluate, want_string) 4878 char_u **arg; 4879 typval_T *rettv; 4880 int evaluate; 4881 int want_string; /* after "." operator */ 4882 { 4883 typval_T var2; 4884 int op; 4885 long n1, n2; 4886 #ifdef FEAT_FLOAT 4887 int use_float = FALSE; 4888 float_T f1 = 0, f2; 4889 #endif 4890 int error = FALSE; 4891 4892 /* 4893 * Get the first variable. 4894 */ 4895 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4896 return FAIL; 4897 4898 /* 4899 * Repeat computing, until no '*', '/' or '%' is following. 4900 */ 4901 for (;;) 4902 { 4903 op = **arg; 4904 if (op != '*' && op != '/' && op != '%') 4905 break; 4906 4907 if (evaluate) 4908 { 4909 #ifdef FEAT_FLOAT 4910 if (rettv->v_type == VAR_FLOAT) 4911 { 4912 f1 = rettv->vval.v_float; 4913 use_float = TRUE; 4914 n1 = 0; 4915 } 4916 else 4917 #endif 4918 n1 = get_tv_number_chk(rettv, &error); 4919 clear_tv(rettv); 4920 if (error) 4921 return FAIL; 4922 } 4923 else 4924 n1 = 0; 4925 4926 /* 4927 * Get the second variable. 4928 */ 4929 *arg = skipwhite(*arg + 1); 4930 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4931 return FAIL; 4932 4933 if (evaluate) 4934 { 4935 #ifdef FEAT_FLOAT 4936 if (var2.v_type == VAR_FLOAT) 4937 { 4938 if (!use_float) 4939 { 4940 f1 = n1; 4941 use_float = TRUE; 4942 } 4943 f2 = var2.vval.v_float; 4944 n2 = 0; 4945 } 4946 else 4947 #endif 4948 { 4949 n2 = get_tv_number_chk(&var2, &error); 4950 clear_tv(&var2); 4951 if (error) 4952 return FAIL; 4953 #ifdef FEAT_FLOAT 4954 if (use_float) 4955 f2 = n2; 4956 #endif 4957 } 4958 4959 /* 4960 * Compute the result. 4961 * When either side is a float the result is a float. 4962 */ 4963 #ifdef FEAT_FLOAT 4964 if (use_float) 4965 { 4966 if (op == '*') 4967 f1 = f1 * f2; 4968 else if (op == '/') 4969 { 4970 # ifdef VMS 4971 /* VMS crashes on divide by zero, work around it */ 4972 if (f2 == 0.0) 4973 { 4974 if (f1 == 0) 4975 f1 = -1 * __F_FLT_MAX - 1L; /* similar to NaN */ 4976 else if (f1 < 0) 4977 f1 = -1 * __F_FLT_MAX; 4978 else 4979 f1 = __F_FLT_MAX; 4980 } 4981 else 4982 f1 = f1 / f2; 4983 # else 4984 /* We rely on the floating point library to handle divide 4985 * by zero to result in "inf" and not a crash. */ 4986 f1 = f1 / f2; 4987 # endif 4988 } 4989 else 4990 { 4991 EMSG(_("E804: Cannot use '%' with Float")); 4992 return FAIL; 4993 } 4994 rettv->v_type = VAR_FLOAT; 4995 rettv->vval.v_float = f1; 4996 } 4997 else 4998 #endif 4999 { 5000 if (op == '*') 5001 n1 = n1 * n2; 5002 else if (op == '/') 5003 { 5004 if (n2 == 0) /* give an error message? */ 5005 { 5006 if (n1 == 0) 5007 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 5008 else if (n1 < 0) 5009 n1 = -0x7fffffffL; 5010 else 5011 n1 = 0x7fffffffL; 5012 } 5013 else 5014 n1 = n1 / n2; 5015 } 5016 else 5017 { 5018 if (n2 == 0) /* give an error message? */ 5019 n1 = 0; 5020 else 5021 n1 = n1 % n2; 5022 } 5023 rettv->v_type = VAR_NUMBER; 5024 rettv->vval.v_number = n1; 5025 } 5026 } 5027 } 5028 5029 return OK; 5030 } 5031 5032 /* 5033 * Handle sixth level expression: 5034 * number number constant 5035 * "string" string constant 5036 * 'string' literal string constant 5037 * &option-name option value 5038 * @r register contents 5039 * identifier variable value 5040 * function() function call 5041 * $VAR environment variable 5042 * (expression) nested expression 5043 * [expr, expr] List 5044 * {key: val, key: val} Dictionary 5045 * 5046 * Also handle: 5047 * ! in front logical NOT 5048 * - in front unary minus 5049 * + in front unary plus (ignored) 5050 * trailing [] subscript in String or List 5051 * trailing .name entry in Dictionary 5052 * 5053 * "arg" must point to the first non-white of the expression. 5054 * "arg" is advanced to the next non-white after the recognized expression. 5055 * 5056 * Return OK or FAIL. 5057 */ 5058 static int 5059 eval7(arg, rettv, evaluate, want_string) 5060 char_u **arg; 5061 typval_T *rettv; 5062 int evaluate; 5063 int want_string UNUSED; /* after "." operator */ 5064 { 5065 long n; 5066 int len; 5067 char_u *s; 5068 char_u *start_leader, *end_leader; 5069 int ret = OK; 5070 char_u *alias; 5071 5072 /* 5073 * Initialise variable so that clear_tv() can't mistake this for a 5074 * string and free a string that isn't there. 5075 */ 5076 rettv->v_type = VAR_UNKNOWN; 5077 5078 /* 5079 * Skip '!' and '-' characters. They are handled later. 5080 */ 5081 start_leader = *arg; 5082 while (**arg == '!' || **arg == '-' || **arg == '+') 5083 *arg = skipwhite(*arg + 1); 5084 end_leader = *arg; 5085 5086 switch (**arg) 5087 { 5088 /* 5089 * Number constant. 5090 */ 5091 case '0': 5092 case '1': 5093 case '2': 5094 case '3': 5095 case '4': 5096 case '5': 5097 case '6': 5098 case '7': 5099 case '8': 5100 case '9': 5101 { 5102 #ifdef FEAT_FLOAT 5103 char_u *p = skipdigits(*arg + 1); 5104 int get_float = FALSE; 5105 5106 /* We accept a float when the format matches 5107 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 5108 * strict to avoid backwards compatibility problems. 5109 * Don't look for a float after the "." operator, so that 5110 * ":let vers = 1.2.3" doesn't fail. */ 5111 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 5112 { 5113 get_float = TRUE; 5114 p = skipdigits(p + 2); 5115 if (*p == 'e' || *p == 'E') 5116 { 5117 ++p; 5118 if (*p == '-' || *p == '+') 5119 ++p; 5120 if (!vim_isdigit(*p)) 5121 get_float = FALSE; 5122 else 5123 p = skipdigits(p + 1); 5124 } 5125 if (ASCII_ISALPHA(*p) || *p == '.') 5126 get_float = FALSE; 5127 } 5128 if (get_float) 5129 { 5130 float_T f; 5131 5132 *arg += string2float(*arg, &f); 5133 if (evaluate) 5134 { 5135 rettv->v_type = VAR_FLOAT; 5136 rettv->vval.v_float = f; 5137 } 5138 } 5139 else 5140 #endif 5141 { 5142 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL, 0); 5143 *arg += len; 5144 if (evaluate) 5145 { 5146 rettv->v_type = VAR_NUMBER; 5147 rettv->vval.v_number = n; 5148 } 5149 } 5150 break; 5151 } 5152 5153 /* 5154 * String constant: "string". 5155 */ 5156 case '"': ret = get_string_tv(arg, rettv, evaluate); 5157 break; 5158 5159 /* 5160 * Literal string constant: 'str''ing'. 5161 */ 5162 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 5163 break; 5164 5165 /* 5166 * List: [expr, expr] 5167 */ 5168 case '[': ret = get_list_tv(arg, rettv, evaluate); 5169 break; 5170 5171 /* 5172 * Dictionary: {key: val, key: val} 5173 */ 5174 case '{': ret = get_dict_tv(arg, rettv, evaluate); 5175 break; 5176 5177 /* 5178 * Option value: &name 5179 */ 5180 case '&': ret = get_option_tv(arg, rettv, evaluate); 5181 break; 5182 5183 /* 5184 * Environment variable: $VAR. 5185 */ 5186 case '$': ret = get_env_tv(arg, rettv, evaluate); 5187 break; 5188 5189 /* 5190 * Register contents: @r. 5191 */ 5192 case '@': ++*arg; 5193 if (evaluate) 5194 { 5195 rettv->v_type = VAR_STRING; 5196 rettv->vval.v_string = get_reg_contents(**arg, 5197 GREG_EXPR_SRC); 5198 } 5199 if (**arg != NUL) 5200 ++*arg; 5201 break; 5202 5203 /* 5204 * nested expression: (expression). 5205 */ 5206 case '(': *arg = skipwhite(*arg + 1); 5207 ret = eval1(arg, rettv, evaluate); /* recursive! */ 5208 if (**arg == ')') 5209 ++*arg; 5210 else if (ret == OK) 5211 { 5212 EMSG(_("E110: Missing ')'")); 5213 clear_tv(rettv); 5214 ret = FAIL; 5215 } 5216 break; 5217 5218 default: ret = NOTDONE; 5219 break; 5220 } 5221 5222 if (ret == NOTDONE) 5223 { 5224 /* 5225 * Must be a variable or function name. 5226 * Can also be a curly-braces kind of name: {expr}. 5227 */ 5228 s = *arg; 5229 len = get_name_len(arg, &alias, evaluate, TRUE); 5230 if (alias != NULL) 5231 s = alias; 5232 5233 if (len <= 0) 5234 ret = FAIL; 5235 else 5236 { 5237 if (**arg == '(') /* recursive! */ 5238 { 5239 /* If "s" is the name of a variable of type VAR_FUNC 5240 * use its contents. */ 5241 s = deref_func_name(s, &len, !evaluate); 5242 5243 /* Invoke the function. */ 5244 ret = get_func_tv(s, len, rettv, arg, 5245 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5246 &len, evaluate, NULL); 5247 5248 /* If evaluate is FALSE rettv->v_type was not set in 5249 * get_func_tv, but it's needed in handle_subscript() to parse 5250 * what follows. So set it here. */ 5251 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') 5252 { 5253 rettv->vval.v_string = vim_strsave((char_u *)""); 5254 rettv->v_type = VAR_FUNC; 5255 } 5256 5257 /* Stop the expression evaluation when immediately 5258 * aborting on error, or when an interrupt occurred or 5259 * an exception was thrown but not caught. */ 5260 if (aborting()) 5261 { 5262 if (ret == OK) 5263 clear_tv(rettv); 5264 ret = FAIL; 5265 } 5266 } 5267 else if (evaluate) 5268 ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE); 5269 else 5270 ret = OK; 5271 } 5272 vim_free(alias); 5273 } 5274 5275 *arg = skipwhite(*arg); 5276 5277 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5278 * expr(expr). */ 5279 if (ret == OK) 5280 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5281 5282 /* 5283 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5284 */ 5285 if (ret == OK && evaluate && end_leader > start_leader) 5286 { 5287 int error = FALSE; 5288 int val = 0; 5289 #ifdef FEAT_FLOAT 5290 float_T f = 0.0; 5291 5292 if (rettv->v_type == VAR_FLOAT) 5293 f = rettv->vval.v_float; 5294 else 5295 #endif 5296 val = get_tv_number_chk(rettv, &error); 5297 if (error) 5298 { 5299 clear_tv(rettv); 5300 ret = FAIL; 5301 } 5302 else 5303 { 5304 while (end_leader > start_leader) 5305 { 5306 --end_leader; 5307 if (*end_leader == '!') 5308 { 5309 #ifdef FEAT_FLOAT 5310 if (rettv->v_type == VAR_FLOAT) 5311 f = !f; 5312 else 5313 #endif 5314 val = !val; 5315 } 5316 else if (*end_leader == '-') 5317 { 5318 #ifdef FEAT_FLOAT 5319 if (rettv->v_type == VAR_FLOAT) 5320 f = -f; 5321 else 5322 #endif 5323 val = -val; 5324 } 5325 } 5326 #ifdef FEAT_FLOAT 5327 if (rettv->v_type == VAR_FLOAT) 5328 { 5329 clear_tv(rettv); 5330 rettv->vval.v_float = f; 5331 } 5332 else 5333 #endif 5334 { 5335 clear_tv(rettv); 5336 rettv->v_type = VAR_NUMBER; 5337 rettv->vval.v_number = val; 5338 } 5339 } 5340 } 5341 5342 return ret; 5343 } 5344 5345 /* 5346 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5347 * "*arg" points to the '[' or '.'. 5348 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5349 */ 5350 static int 5351 eval_index(arg, rettv, evaluate, verbose) 5352 char_u **arg; 5353 typval_T *rettv; 5354 int evaluate; 5355 int verbose; /* give error messages */ 5356 { 5357 int empty1 = FALSE, empty2 = FALSE; 5358 typval_T var1, var2; 5359 long n1, n2 = 0; 5360 long len = -1; 5361 int range = FALSE; 5362 char_u *s; 5363 char_u *key = NULL; 5364 5365 if (rettv->v_type == VAR_FUNC) 5366 { 5367 if (verbose) 5368 EMSG(_("E695: Cannot index a Funcref")); 5369 return FAIL; 5370 } 5371 #ifdef FEAT_FLOAT 5372 else if (rettv->v_type == VAR_FLOAT) 5373 { 5374 if (verbose) 5375 EMSG(_(e_float_as_string)); 5376 return FAIL; 5377 } 5378 #endif 5379 5380 init_tv(&var1); 5381 init_tv(&var2); 5382 if (**arg == '.') 5383 { 5384 /* 5385 * dict.name 5386 */ 5387 key = *arg + 1; 5388 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5389 ; 5390 if (len == 0) 5391 return FAIL; 5392 *arg = skipwhite(key + len); 5393 } 5394 else 5395 { 5396 /* 5397 * something[idx] 5398 * 5399 * Get the (first) variable from inside the []. 5400 */ 5401 *arg = skipwhite(*arg + 1); 5402 if (**arg == ':') 5403 empty1 = TRUE; 5404 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5405 return FAIL; 5406 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5407 { 5408 /* not a number or string */ 5409 clear_tv(&var1); 5410 return FAIL; 5411 } 5412 5413 /* 5414 * Get the second variable from inside the [:]. 5415 */ 5416 if (**arg == ':') 5417 { 5418 range = TRUE; 5419 *arg = skipwhite(*arg + 1); 5420 if (**arg == ']') 5421 empty2 = TRUE; 5422 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5423 { 5424 if (!empty1) 5425 clear_tv(&var1); 5426 return FAIL; 5427 } 5428 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5429 { 5430 /* not a number or string */ 5431 if (!empty1) 5432 clear_tv(&var1); 5433 clear_tv(&var2); 5434 return FAIL; 5435 } 5436 } 5437 5438 /* Check for the ']'. */ 5439 if (**arg != ']') 5440 { 5441 if (verbose) 5442 EMSG(_(e_missbrac)); 5443 clear_tv(&var1); 5444 if (range) 5445 clear_tv(&var2); 5446 return FAIL; 5447 } 5448 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5449 } 5450 5451 if (evaluate) 5452 { 5453 n1 = 0; 5454 if (!empty1 && rettv->v_type != VAR_DICT) 5455 { 5456 n1 = get_tv_number(&var1); 5457 clear_tv(&var1); 5458 } 5459 if (range) 5460 { 5461 if (empty2) 5462 n2 = -1; 5463 else 5464 { 5465 n2 = get_tv_number(&var2); 5466 clear_tv(&var2); 5467 } 5468 } 5469 5470 switch (rettv->v_type) 5471 { 5472 case VAR_NUMBER: 5473 case VAR_STRING: 5474 s = get_tv_string(rettv); 5475 len = (long)STRLEN(s); 5476 if (range) 5477 { 5478 /* The resulting variable is a substring. If the indexes 5479 * are out of range the result is empty. */ 5480 if (n1 < 0) 5481 { 5482 n1 = len + n1; 5483 if (n1 < 0) 5484 n1 = 0; 5485 } 5486 if (n2 < 0) 5487 n2 = len + n2; 5488 else if (n2 >= len) 5489 n2 = len; 5490 if (n1 >= len || n2 < 0 || n1 > n2) 5491 s = NULL; 5492 else 5493 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5494 } 5495 else 5496 { 5497 /* The resulting variable is a string of a single 5498 * character. If the index is too big or negative the 5499 * result is empty. */ 5500 if (n1 >= len || n1 < 0) 5501 s = NULL; 5502 else 5503 s = vim_strnsave(s + n1, 1); 5504 } 5505 clear_tv(rettv); 5506 rettv->v_type = VAR_STRING; 5507 rettv->vval.v_string = s; 5508 break; 5509 5510 case VAR_LIST: 5511 len = list_len(rettv->vval.v_list); 5512 if (n1 < 0) 5513 n1 = len + n1; 5514 if (!empty1 && (n1 < 0 || n1 >= len)) 5515 { 5516 /* For a range we allow invalid values and return an empty 5517 * list. A list index out of range is an error. */ 5518 if (!range) 5519 { 5520 if (verbose) 5521 EMSGN(_(e_listidx), n1); 5522 return FAIL; 5523 } 5524 n1 = len; 5525 } 5526 if (range) 5527 { 5528 list_T *l; 5529 listitem_T *item; 5530 5531 if (n2 < 0) 5532 n2 = len + n2; 5533 else if (n2 >= len) 5534 n2 = len - 1; 5535 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5536 n2 = -1; 5537 l = list_alloc(); 5538 if (l == NULL) 5539 return FAIL; 5540 for (item = list_find(rettv->vval.v_list, n1); 5541 n1 <= n2; ++n1) 5542 { 5543 if (list_append_tv(l, &item->li_tv) == FAIL) 5544 { 5545 list_free(l, TRUE); 5546 return FAIL; 5547 } 5548 item = item->li_next; 5549 } 5550 clear_tv(rettv); 5551 rettv->v_type = VAR_LIST; 5552 rettv->vval.v_list = l; 5553 ++l->lv_refcount; 5554 } 5555 else 5556 { 5557 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5558 clear_tv(rettv); 5559 *rettv = var1; 5560 } 5561 break; 5562 5563 case VAR_DICT: 5564 if (range) 5565 { 5566 if (verbose) 5567 EMSG(_(e_dictrange)); 5568 if (len == -1) 5569 clear_tv(&var1); 5570 return FAIL; 5571 } 5572 { 5573 dictitem_T *item; 5574 5575 if (len == -1) 5576 { 5577 key = get_tv_string(&var1); 5578 if (*key == NUL) 5579 { 5580 if (verbose) 5581 EMSG(_(e_emptykey)); 5582 clear_tv(&var1); 5583 return FAIL; 5584 } 5585 } 5586 5587 item = dict_find(rettv->vval.v_dict, key, (int)len); 5588 5589 if (item == NULL && verbose) 5590 EMSG2(_(e_dictkey), key); 5591 if (len == -1) 5592 clear_tv(&var1); 5593 if (item == NULL) 5594 return FAIL; 5595 5596 copy_tv(&item->di_tv, &var1); 5597 clear_tv(rettv); 5598 *rettv = var1; 5599 } 5600 break; 5601 } 5602 } 5603 5604 return OK; 5605 } 5606 5607 /* 5608 * Get an option value. 5609 * "arg" points to the '&' or '+' before the option name. 5610 * "arg" is advanced to character after the option name. 5611 * Return OK or FAIL. 5612 */ 5613 static int 5614 get_option_tv(arg, rettv, evaluate) 5615 char_u **arg; 5616 typval_T *rettv; /* when NULL, only check if option exists */ 5617 int evaluate; 5618 { 5619 char_u *option_end; 5620 long numval; 5621 char_u *stringval; 5622 int opt_type; 5623 int c; 5624 int working = (**arg == '+'); /* has("+option") */ 5625 int ret = OK; 5626 int opt_flags; 5627 5628 /* 5629 * Isolate the option name and find its value. 5630 */ 5631 option_end = find_option_end(arg, &opt_flags); 5632 if (option_end == NULL) 5633 { 5634 if (rettv != NULL) 5635 EMSG2(_("E112: Option name missing: %s"), *arg); 5636 return FAIL; 5637 } 5638 5639 if (!evaluate) 5640 { 5641 *arg = option_end; 5642 return OK; 5643 } 5644 5645 c = *option_end; 5646 *option_end = NUL; 5647 opt_type = get_option_value(*arg, &numval, 5648 rettv == NULL ? NULL : &stringval, opt_flags); 5649 5650 if (opt_type == -3) /* invalid name */ 5651 { 5652 if (rettv != NULL) 5653 EMSG2(_("E113: Unknown option: %s"), *arg); 5654 ret = FAIL; 5655 } 5656 else if (rettv != NULL) 5657 { 5658 if (opt_type == -2) /* hidden string option */ 5659 { 5660 rettv->v_type = VAR_STRING; 5661 rettv->vval.v_string = NULL; 5662 } 5663 else if (opt_type == -1) /* hidden number option */ 5664 { 5665 rettv->v_type = VAR_NUMBER; 5666 rettv->vval.v_number = 0; 5667 } 5668 else if (opt_type == 1) /* number option */ 5669 { 5670 rettv->v_type = VAR_NUMBER; 5671 rettv->vval.v_number = numval; 5672 } 5673 else /* string option */ 5674 { 5675 rettv->v_type = VAR_STRING; 5676 rettv->vval.v_string = stringval; 5677 } 5678 } 5679 else if (working && (opt_type == -2 || opt_type == -1)) 5680 ret = FAIL; 5681 5682 *option_end = c; /* put back for error messages */ 5683 *arg = option_end; 5684 5685 return ret; 5686 } 5687 5688 /* 5689 * Allocate a variable for a string constant. 5690 * Return OK or FAIL. 5691 */ 5692 static int 5693 get_string_tv(arg, rettv, evaluate) 5694 char_u **arg; 5695 typval_T *rettv; 5696 int evaluate; 5697 { 5698 char_u *p; 5699 char_u *name; 5700 int extra = 0; 5701 5702 /* 5703 * Find the end of the string, skipping backslashed characters. 5704 */ 5705 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5706 { 5707 if (*p == '\\' && p[1] != NUL) 5708 { 5709 ++p; 5710 /* A "\<x>" form occupies at least 4 characters, and produces up 5711 * to 6 characters: reserve space for 2 extra */ 5712 if (*p == '<') 5713 extra += 2; 5714 } 5715 } 5716 5717 if (*p != '"') 5718 { 5719 EMSG2(_("E114: Missing quote: %s"), *arg); 5720 return FAIL; 5721 } 5722 5723 /* If only parsing, set *arg and return here */ 5724 if (!evaluate) 5725 { 5726 *arg = p + 1; 5727 return OK; 5728 } 5729 5730 /* 5731 * Copy the string into allocated memory, handling backslashed 5732 * characters. 5733 */ 5734 name = alloc((unsigned)(p - *arg + extra)); 5735 if (name == NULL) 5736 return FAIL; 5737 rettv->v_type = VAR_STRING; 5738 rettv->vval.v_string = name; 5739 5740 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5741 { 5742 if (*p == '\\') 5743 { 5744 switch (*++p) 5745 { 5746 case 'b': *name++ = BS; ++p; break; 5747 case 'e': *name++ = ESC; ++p; break; 5748 case 'f': *name++ = FF; ++p; break; 5749 case 'n': *name++ = NL; ++p; break; 5750 case 'r': *name++ = CAR; ++p; break; 5751 case 't': *name++ = TAB; ++p; break; 5752 5753 case 'X': /* hex: "\x1", "\x12" */ 5754 case 'x': 5755 case 'u': /* Unicode: "\u0023" */ 5756 case 'U': 5757 if (vim_isxdigit(p[1])) 5758 { 5759 int n, nr; 5760 int c = toupper(*p); 5761 5762 if (c == 'X') 5763 n = 2; 5764 else if (*p == 'u') 5765 n = 4; 5766 else 5767 n = 8; 5768 nr = 0; 5769 while (--n >= 0 && vim_isxdigit(p[1])) 5770 { 5771 ++p; 5772 nr = (nr << 4) + hex2nr(*p); 5773 } 5774 ++p; 5775 #ifdef FEAT_MBYTE 5776 /* For "\u" store the number according to 5777 * 'encoding'. */ 5778 if (c != 'X') 5779 name += (*mb_char2bytes)(nr, name); 5780 else 5781 #endif 5782 *name++ = nr; 5783 } 5784 break; 5785 5786 /* octal: "\1", "\12", "\123" */ 5787 case '0': 5788 case '1': 5789 case '2': 5790 case '3': 5791 case '4': 5792 case '5': 5793 case '6': 5794 case '7': *name = *p++ - '0'; 5795 if (*p >= '0' && *p <= '7') 5796 { 5797 *name = (*name << 3) + *p++ - '0'; 5798 if (*p >= '0' && *p <= '7') 5799 *name = (*name << 3) + *p++ - '0'; 5800 } 5801 ++name; 5802 break; 5803 5804 /* Special key, e.g.: "\<C-W>" */ 5805 case '<': extra = trans_special(&p, name, TRUE); 5806 if (extra != 0) 5807 { 5808 name += extra; 5809 break; 5810 } 5811 /* FALLTHROUGH */ 5812 5813 default: MB_COPY_CHAR(p, name); 5814 break; 5815 } 5816 } 5817 else 5818 MB_COPY_CHAR(p, name); 5819 5820 } 5821 *name = NUL; 5822 *arg = p + 1; 5823 5824 return OK; 5825 } 5826 5827 /* 5828 * Allocate a variable for a 'str''ing' constant. 5829 * Return OK or FAIL. 5830 */ 5831 static int 5832 get_lit_string_tv(arg, rettv, evaluate) 5833 char_u **arg; 5834 typval_T *rettv; 5835 int evaluate; 5836 { 5837 char_u *p; 5838 char_u *str; 5839 int reduce = 0; 5840 5841 /* 5842 * Find the end of the string, skipping ''. 5843 */ 5844 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5845 { 5846 if (*p == '\'') 5847 { 5848 if (p[1] != '\'') 5849 break; 5850 ++reduce; 5851 ++p; 5852 } 5853 } 5854 5855 if (*p != '\'') 5856 { 5857 EMSG2(_("E115: Missing quote: %s"), *arg); 5858 return FAIL; 5859 } 5860 5861 /* If only parsing return after setting "*arg" */ 5862 if (!evaluate) 5863 { 5864 *arg = p + 1; 5865 return OK; 5866 } 5867 5868 /* 5869 * Copy the string into allocated memory, handling '' to ' reduction. 5870 */ 5871 str = alloc((unsigned)((p - *arg) - reduce)); 5872 if (str == NULL) 5873 return FAIL; 5874 rettv->v_type = VAR_STRING; 5875 rettv->vval.v_string = str; 5876 5877 for (p = *arg + 1; *p != NUL; ) 5878 { 5879 if (*p == '\'') 5880 { 5881 if (p[1] != '\'') 5882 break; 5883 ++p; 5884 } 5885 MB_COPY_CHAR(p, str); 5886 } 5887 *str = NUL; 5888 *arg = p + 1; 5889 5890 return OK; 5891 } 5892 5893 /* 5894 * Allocate a variable for a List and fill it from "*arg". 5895 * Return OK or FAIL. 5896 */ 5897 static int 5898 get_list_tv(arg, rettv, evaluate) 5899 char_u **arg; 5900 typval_T *rettv; 5901 int evaluate; 5902 { 5903 list_T *l = NULL; 5904 typval_T tv; 5905 listitem_T *item; 5906 5907 if (evaluate) 5908 { 5909 l = list_alloc(); 5910 if (l == NULL) 5911 return FAIL; 5912 } 5913 5914 *arg = skipwhite(*arg + 1); 5915 while (**arg != ']' && **arg != NUL) 5916 { 5917 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5918 goto failret; 5919 if (evaluate) 5920 { 5921 item = listitem_alloc(); 5922 if (item != NULL) 5923 { 5924 item->li_tv = tv; 5925 item->li_tv.v_lock = 0; 5926 list_append(l, item); 5927 } 5928 else 5929 clear_tv(&tv); 5930 } 5931 5932 if (**arg == ']') 5933 break; 5934 if (**arg != ',') 5935 { 5936 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5937 goto failret; 5938 } 5939 *arg = skipwhite(*arg + 1); 5940 } 5941 5942 if (**arg != ']') 5943 { 5944 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5945 failret: 5946 if (evaluate) 5947 list_free(l, TRUE); 5948 return FAIL; 5949 } 5950 5951 *arg = skipwhite(*arg + 1); 5952 if (evaluate) 5953 { 5954 rettv->v_type = VAR_LIST; 5955 rettv->vval.v_list = l; 5956 ++l->lv_refcount; 5957 } 5958 5959 return OK; 5960 } 5961 5962 /* 5963 * Allocate an empty header for a list. 5964 * Caller should take care of the reference count. 5965 */ 5966 list_T * 5967 list_alloc() 5968 { 5969 list_T *l; 5970 5971 l = (list_T *)alloc_clear(sizeof(list_T)); 5972 if (l != NULL) 5973 { 5974 /* Prepend the list to the list of lists for garbage collection. */ 5975 if (first_list != NULL) 5976 first_list->lv_used_prev = l; 5977 l->lv_used_prev = NULL; 5978 l->lv_used_next = first_list; 5979 first_list = l; 5980 } 5981 return l; 5982 } 5983 5984 /* 5985 * Allocate an empty list for a return value. 5986 * Returns OK or FAIL. 5987 */ 5988 static int 5989 rettv_list_alloc(rettv) 5990 typval_T *rettv; 5991 { 5992 list_T *l = list_alloc(); 5993 5994 if (l == NULL) 5995 return FAIL; 5996 5997 rettv->vval.v_list = l; 5998 rettv->v_type = VAR_LIST; 5999 ++l->lv_refcount; 6000 return OK; 6001 } 6002 6003 /* 6004 * Unreference a list: decrement the reference count and free it when it 6005 * becomes zero. 6006 */ 6007 void 6008 list_unref(l) 6009 list_T *l; 6010 { 6011 if (l != NULL && --l->lv_refcount <= 0) 6012 list_free(l, TRUE); 6013 } 6014 6015 /* 6016 * Free a list, including all non-container items it points to. 6017 * Ignores the reference count. 6018 */ 6019 void 6020 list_free(l, recurse) 6021 list_T *l; 6022 int recurse; /* Free Lists and Dictionaries recursively. */ 6023 { 6024 listitem_T *item; 6025 6026 /* Remove the list from the list of lists for garbage collection. */ 6027 if (l->lv_used_prev == NULL) 6028 first_list = l->lv_used_next; 6029 else 6030 l->lv_used_prev->lv_used_next = l->lv_used_next; 6031 if (l->lv_used_next != NULL) 6032 l->lv_used_next->lv_used_prev = l->lv_used_prev; 6033 6034 for (item = l->lv_first; item != NULL; item = l->lv_first) 6035 { 6036 /* Remove the item before deleting it. */ 6037 l->lv_first = item->li_next; 6038 if (recurse || (item->li_tv.v_type != VAR_LIST 6039 && item->li_tv.v_type != VAR_DICT)) 6040 clear_tv(&item->li_tv); 6041 vim_free(item); 6042 } 6043 vim_free(l); 6044 } 6045 6046 /* 6047 * Allocate a list item. 6048 * It is not initialized, don't forget to set v_lock. 6049 */ 6050 listitem_T * 6051 listitem_alloc() 6052 { 6053 return (listitem_T *)alloc(sizeof(listitem_T)); 6054 } 6055 6056 /* 6057 * Free a list item. Also clears the value. Does not notify watchers. 6058 */ 6059 void 6060 listitem_free(item) 6061 listitem_T *item; 6062 { 6063 clear_tv(&item->li_tv); 6064 vim_free(item); 6065 } 6066 6067 /* 6068 * Remove a list item from a List and free it. Also clears the value. 6069 */ 6070 void 6071 listitem_remove(l, item) 6072 list_T *l; 6073 listitem_T *item; 6074 { 6075 vimlist_remove(l, item, item); 6076 listitem_free(item); 6077 } 6078 6079 /* 6080 * Get the number of items in a list. 6081 */ 6082 static long 6083 list_len(l) 6084 list_T *l; 6085 { 6086 if (l == NULL) 6087 return 0L; 6088 return l->lv_len; 6089 } 6090 6091 /* 6092 * Return TRUE when two lists have exactly the same values. 6093 */ 6094 static int 6095 list_equal(l1, l2, ic, recursive) 6096 list_T *l1; 6097 list_T *l2; 6098 int ic; /* ignore case for strings */ 6099 int recursive; /* TRUE when used recursively */ 6100 { 6101 listitem_T *item1, *item2; 6102 6103 if (l1 == NULL || l2 == NULL) 6104 return FALSE; 6105 if (l1 == l2) 6106 return TRUE; 6107 if (list_len(l1) != list_len(l2)) 6108 return FALSE; 6109 6110 for (item1 = l1->lv_first, item2 = l2->lv_first; 6111 item1 != NULL && item2 != NULL; 6112 item1 = item1->li_next, item2 = item2->li_next) 6113 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) 6114 return FALSE; 6115 return item1 == NULL && item2 == NULL; 6116 } 6117 6118 #if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ 6119 || defined(FEAT_MZSCHEME) || defined(FEAT_LUA) || defined(PROTO) 6120 /* 6121 * Return the dictitem that an entry in a hashtable points to. 6122 */ 6123 dictitem_T * 6124 dict_lookup(hi) 6125 hashitem_T *hi; 6126 { 6127 return HI2DI(hi); 6128 } 6129 #endif 6130 6131 /* 6132 * Return TRUE when two dictionaries have exactly the same key/values. 6133 */ 6134 static int 6135 dict_equal(d1, d2, ic, recursive) 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(tv1, tv2, ic, recursive) 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 if (tv1->v_type != tv2->v_type) 6188 return FALSE; 6189 6190 /* Catch lists and dicts that have an endless loop by limiting 6191 * recursiveness to a limit. We guess they are equal then. 6192 * A fixed limit has the problem of still taking an awful long time. 6193 * Reduce the limit every time running into it. That should work fine for 6194 * deeply linked structures that are not recursively linked and catch 6195 * recursiveness quickly. */ 6196 if (!recursive) 6197 tv_equal_recurse_limit = 1000; 6198 if (recursive_cnt >= tv_equal_recurse_limit) 6199 { 6200 --tv_equal_recurse_limit; 6201 return TRUE; 6202 } 6203 6204 switch (tv1->v_type) 6205 { 6206 case VAR_LIST: 6207 ++recursive_cnt; 6208 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); 6209 --recursive_cnt; 6210 return r; 6211 6212 case VAR_DICT: 6213 ++recursive_cnt; 6214 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE); 6215 --recursive_cnt; 6216 return r; 6217 6218 case VAR_FUNC: 6219 return (tv1->vval.v_string != NULL 6220 && tv2->vval.v_string != NULL 6221 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 6222 6223 case VAR_NUMBER: 6224 return tv1->vval.v_number == tv2->vval.v_number; 6225 6226 #ifdef FEAT_FLOAT 6227 case VAR_FLOAT: 6228 return tv1->vval.v_float == tv2->vval.v_float; 6229 #endif 6230 6231 case VAR_STRING: 6232 s1 = get_tv_string_buf(tv1, buf1); 6233 s2 = get_tv_string_buf(tv2, buf2); 6234 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 6235 } 6236 6237 EMSG2(_(e_intern2), "tv_equal()"); 6238 return TRUE; 6239 } 6240 6241 /* 6242 * Locate item with index "n" in list "l" and return it. 6243 * A negative index is counted from the end; -1 is the last item. 6244 * Returns NULL when "n" is out of range. 6245 */ 6246 listitem_T * 6247 list_find(l, n) 6248 list_T *l; 6249 long n; 6250 { 6251 listitem_T *item; 6252 long idx; 6253 6254 if (l == NULL) 6255 return NULL; 6256 6257 /* Negative index is relative to the end. */ 6258 if (n < 0) 6259 n = l->lv_len + n; 6260 6261 /* Check for index out of range. */ 6262 if (n < 0 || n >= l->lv_len) 6263 return NULL; 6264 6265 /* When there is a cached index may start search from there. */ 6266 if (l->lv_idx_item != NULL) 6267 { 6268 if (n < l->lv_idx / 2) 6269 { 6270 /* closest to the start of the list */ 6271 item = l->lv_first; 6272 idx = 0; 6273 } 6274 else if (n > (l->lv_idx + l->lv_len) / 2) 6275 { 6276 /* closest to the end of the list */ 6277 item = l->lv_last; 6278 idx = l->lv_len - 1; 6279 } 6280 else 6281 { 6282 /* closest to the cached index */ 6283 item = l->lv_idx_item; 6284 idx = l->lv_idx; 6285 } 6286 } 6287 else 6288 { 6289 if (n < l->lv_len / 2) 6290 { 6291 /* closest to the start of the list */ 6292 item = l->lv_first; 6293 idx = 0; 6294 } 6295 else 6296 { 6297 /* closest to the end of the list */ 6298 item = l->lv_last; 6299 idx = l->lv_len - 1; 6300 } 6301 } 6302 6303 while (n > idx) 6304 { 6305 /* search forward */ 6306 item = item->li_next; 6307 ++idx; 6308 } 6309 while (n < idx) 6310 { 6311 /* search backward */ 6312 item = item->li_prev; 6313 --idx; 6314 } 6315 6316 /* cache the used index */ 6317 l->lv_idx = idx; 6318 l->lv_idx_item = item; 6319 6320 return item; 6321 } 6322 6323 /* 6324 * Get list item "l[idx]" as a number. 6325 */ 6326 static long 6327 list_find_nr(l, idx, errorp) 6328 list_T *l; 6329 long idx; 6330 int *errorp; /* set to TRUE when something wrong */ 6331 { 6332 listitem_T *li; 6333 6334 li = list_find(l, idx); 6335 if (li == NULL) 6336 { 6337 if (errorp != NULL) 6338 *errorp = TRUE; 6339 return -1L; 6340 } 6341 return get_tv_number_chk(&li->li_tv, errorp); 6342 } 6343 6344 /* 6345 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6346 */ 6347 char_u * 6348 list_find_str(l, idx) 6349 list_T *l; 6350 long idx; 6351 { 6352 listitem_T *li; 6353 6354 li = list_find(l, idx - 1); 6355 if (li == NULL) 6356 { 6357 EMSGN(_(e_listidx), idx); 6358 return NULL; 6359 } 6360 return get_tv_string(&li->li_tv); 6361 } 6362 6363 /* 6364 * Locate "item" list "l" and return its index. 6365 * Returns -1 when "item" is not in the list. 6366 */ 6367 static long 6368 list_idx_of_item(l, item) 6369 list_T *l; 6370 listitem_T *item; 6371 { 6372 long idx = 0; 6373 listitem_T *li; 6374 6375 if (l == NULL) 6376 return -1; 6377 idx = 0; 6378 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6379 ++idx; 6380 if (li == NULL) 6381 return -1; 6382 return idx; 6383 } 6384 6385 /* 6386 * Append item "item" to the end of list "l". 6387 */ 6388 void 6389 list_append(l, item) 6390 list_T *l; 6391 listitem_T *item; 6392 { 6393 if (l->lv_last == NULL) 6394 { 6395 /* empty list */ 6396 l->lv_first = item; 6397 l->lv_last = item; 6398 item->li_prev = NULL; 6399 } 6400 else 6401 { 6402 l->lv_last->li_next = item; 6403 item->li_prev = l->lv_last; 6404 l->lv_last = item; 6405 } 6406 ++l->lv_len; 6407 item->li_next = NULL; 6408 } 6409 6410 /* 6411 * Append typval_T "tv" to the end of list "l". 6412 * Return FAIL when out of memory. 6413 */ 6414 int 6415 list_append_tv(l, tv) 6416 list_T *l; 6417 typval_T *tv; 6418 { 6419 listitem_T *li = listitem_alloc(); 6420 6421 if (li == NULL) 6422 return FAIL; 6423 copy_tv(tv, &li->li_tv); 6424 list_append(l, li); 6425 return OK; 6426 } 6427 6428 /* 6429 * Add a dictionary to a list. Used by getqflist(). 6430 * Return FAIL when out of memory. 6431 */ 6432 int 6433 list_append_dict(list, dict) 6434 list_T *list; 6435 dict_T *dict; 6436 { 6437 listitem_T *li = listitem_alloc(); 6438 6439 if (li == NULL) 6440 return FAIL; 6441 li->li_tv.v_type = VAR_DICT; 6442 li->li_tv.v_lock = 0; 6443 li->li_tv.vval.v_dict = dict; 6444 list_append(list, li); 6445 ++dict->dv_refcount; 6446 return OK; 6447 } 6448 6449 /* 6450 * Make a copy of "str" and append it as an item to list "l". 6451 * When "len" >= 0 use "str[len]". 6452 * Returns FAIL when out of memory. 6453 */ 6454 int 6455 list_append_string(l, str, len) 6456 list_T *l; 6457 char_u *str; 6458 int len; 6459 { 6460 listitem_T *li = listitem_alloc(); 6461 6462 if (li == NULL) 6463 return FAIL; 6464 list_append(l, li); 6465 li->li_tv.v_type = VAR_STRING; 6466 li->li_tv.v_lock = 0; 6467 if (str == NULL) 6468 li->li_tv.vval.v_string = NULL; 6469 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6470 : vim_strsave(str))) == NULL) 6471 return FAIL; 6472 return OK; 6473 } 6474 6475 /* 6476 * Append "n" to list "l". 6477 * Returns FAIL when out of memory. 6478 */ 6479 static int 6480 list_append_number(l, n) 6481 list_T *l; 6482 varnumber_T n; 6483 { 6484 listitem_T *li; 6485 6486 li = listitem_alloc(); 6487 if (li == NULL) 6488 return FAIL; 6489 li->li_tv.v_type = VAR_NUMBER; 6490 li->li_tv.v_lock = 0; 6491 li->li_tv.vval.v_number = n; 6492 list_append(l, li); 6493 return OK; 6494 } 6495 6496 /* 6497 * Insert typval_T "tv" in list "l" before "item". 6498 * If "item" is NULL append at the end. 6499 * Return FAIL when out of memory. 6500 */ 6501 int 6502 list_insert_tv(l, tv, item) 6503 list_T *l; 6504 typval_T *tv; 6505 listitem_T *item; 6506 { 6507 listitem_T *ni = listitem_alloc(); 6508 6509 if (ni == NULL) 6510 return FAIL; 6511 copy_tv(tv, &ni->li_tv); 6512 list_insert(l, ni, item); 6513 return OK; 6514 } 6515 6516 void 6517 list_insert(l, ni, item) 6518 list_T *l; 6519 listitem_T *ni; 6520 listitem_T *item; 6521 { 6522 if (item == NULL) 6523 /* Append new item at end of list. */ 6524 list_append(l, ni); 6525 else 6526 { 6527 /* Insert new item before existing item. */ 6528 ni->li_prev = item->li_prev; 6529 ni->li_next = item; 6530 if (item->li_prev == NULL) 6531 { 6532 l->lv_first = ni; 6533 ++l->lv_idx; 6534 } 6535 else 6536 { 6537 item->li_prev->li_next = ni; 6538 l->lv_idx_item = NULL; 6539 } 6540 item->li_prev = ni; 6541 ++l->lv_len; 6542 } 6543 } 6544 6545 /* 6546 * Extend "l1" with "l2". 6547 * If "bef" is NULL append at the end, otherwise insert before this item. 6548 * Returns FAIL when out of memory. 6549 */ 6550 static int 6551 list_extend(l1, l2, bef) 6552 list_T *l1; 6553 list_T *l2; 6554 listitem_T *bef; 6555 { 6556 listitem_T *item; 6557 int todo = l2->lv_len; 6558 6559 /* We also quit the loop when we have inserted the original item count of 6560 * the list, avoid a hang when we extend a list with itself. */ 6561 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6562 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6563 return FAIL; 6564 return OK; 6565 } 6566 6567 /* 6568 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6569 * Return FAIL when out of memory. 6570 */ 6571 static int 6572 list_concat(l1, l2, tv) 6573 list_T *l1; 6574 list_T *l2; 6575 typval_T *tv; 6576 { 6577 list_T *l; 6578 6579 if (l1 == NULL || l2 == NULL) 6580 return FAIL; 6581 6582 /* make a copy of the first list. */ 6583 l = list_copy(l1, FALSE, 0); 6584 if (l == NULL) 6585 return FAIL; 6586 tv->v_type = VAR_LIST; 6587 tv->vval.v_list = l; 6588 6589 /* append all items from the second list */ 6590 return list_extend(l, l2, NULL); 6591 } 6592 6593 /* 6594 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6595 * The refcount of the new list is set to 1. 6596 * See item_copy() for "copyID". 6597 * Returns NULL when out of memory. 6598 */ 6599 static list_T * 6600 list_copy(orig, deep, copyID) 6601 list_T *orig; 6602 int deep; 6603 int copyID; 6604 { 6605 list_T *copy; 6606 listitem_T *item; 6607 listitem_T *ni; 6608 6609 if (orig == NULL) 6610 return NULL; 6611 6612 copy = list_alloc(); 6613 if (copy != NULL) 6614 { 6615 if (copyID != 0) 6616 { 6617 /* Do this before adding the items, because one of the items may 6618 * refer back to this list. */ 6619 orig->lv_copyID = copyID; 6620 orig->lv_copylist = copy; 6621 } 6622 for (item = orig->lv_first; item != NULL && !got_int; 6623 item = item->li_next) 6624 { 6625 ni = listitem_alloc(); 6626 if (ni == NULL) 6627 break; 6628 if (deep) 6629 { 6630 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6631 { 6632 vim_free(ni); 6633 break; 6634 } 6635 } 6636 else 6637 copy_tv(&item->li_tv, &ni->li_tv); 6638 list_append(copy, ni); 6639 } 6640 ++copy->lv_refcount; 6641 if (item != NULL) 6642 { 6643 list_unref(copy); 6644 copy = NULL; 6645 } 6646 } 6647 6648 return copy; 6649 } 6650 6651 /* 6652 * Remove items "item" to "item2" from list "l". 6653 * Does not free the listitem or the value! 6654 * This used to be called list_remove, but that conflicts with a Sun header 6655 * file. 6656 */ 6657 void 6658 vimlist_remove(l, item, item2) 6659 list_T *l; 6660 listitem_T *item; 6661 listitem_T *item2; 6662 { 6663 listitem_T *ip; 6664 6665 /* notify watchers */ 6666 for (ip = item; ip != NULL; ip = ip->li_next) 6667 { 6668 --l->lv_len; 6669 list_fix_watch(l, ip); 6670 if (ip == item2) 6671 break; 6672 } 6673 6674 if (item2->li_next == NULL) 6675 l->lv_last = item->li_prev; 6676 else 6677 item2->li_next->li_prev = item->li_prev; 6678 if (item->li_prev == NULL) 6679 l->lv_first = item2->li_next; 6680 else 6681 item->li_prev->li_next = item2->li_next; 6682 l->lv_idx_item = NULL; 6683 } 6684 6685 /* 6686 * Return an allocated string with the string representation of a list. 6687 * May return NULL. 6688 */ 6689 static char_u * 6690 list2string(tv, copyID) 6691 typval_T *tv; 6692 int copyID; 6693 { 6694 garray_T ga; 6695 6696 if (tv->vval.v_list == NULL) 6697 return NULL; 6698 ga_init2(&ga, (int)sizeof(char), 80); 6699 ga_append(&ga, '['); 6700 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6701 { 6702 vim_free(ga.ga_data); 6703 return NULL; 6704 } 6705 ga_append(&ga, ']'); 6706 ga_append(&ga, NUL); 6707 return (char_u *)ga.ga_data; 6708 } 6709 6710 typedef struct join_S { 6711 char_u *s; 6712 char_u *tofree; 6713 } join_T; 6714 6715 static int 6716 list_join_inner(gap, l, sep, echo_style, copyID, join_gap) 6717 garray_T *gap; /* to store the result in */ 6718 list_T *l; 6719 char_u *sep; 6720 int echo_style; 6721 int copyID; 6722 garray_T *join_gap; /* to keep each list item string */ 6723 { 6724 int i; 6725 join_T *p; 6726 int len; 6727 int sumlen = 0; 6728 int first = TRUE; 6729 char_u *tofree; 6730 char_u numbuf[NUMBUFLEN]; 6731 listitem_T *item; 6732 char_u *s; 6733 6734 /* Stringify each item in the list. */ 6735 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6736 { 6737 if (echo_style) 6738 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6739 else 6740 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6741 if (s == NULL) 6742 return FAIL; 6743 6744 len = (int)STRLEN(s); 6745 sumlen += len; 6746 6747 (void)ga_grow(join_gap, 1); 6748 p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++); 6749 if (tofree != NULL || s != numbuf) 6750 { 6751 p->s = s; 6752 p->tofree = tofree; 6753 } 6754 else 6755 { 6756 p->s = vim_strnsave(s, len); 6757 p->tofree = p->s; 6758 } 6759 6760 line_breakcheck(); 6761 if (did_echo_string_emsg) /* recursion error, bail out */ 6762 break; 6763 } 6764 6765 /* Allocate result buffer with its total size, avoid re-allocation and 6766 * multiple copy operations. Add 2 for a tailing ']' and NUL. */ 6767 if (join_gap->ga_len >= 2) 6768 sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1); 6769 if (ga_grow(gap, sumlen + 2) == FAIL) 6770 return FAIL; 6771 6772 for (i = 0; i < join_gap->ga_len && !got_int; ++i) 6773 { 6774 if (first) 6775 first = FALSE; 6776 else 6777 ga_concat(gap, sep); 6778 p = ((join_T *)join_gap->ga_data) + i; 6779 6780 if (p->s != NULL) 6781 ga_concat(gap, p->s); 6782 line_breakcheck(); 6783 } 6784 6785 return OK; 6786 } 6787 6788 /* 6789 * Join list "l" into a string in "*gap", using separator "sep". 6790 * When "echo_style" is TRUE use String as echoed, otherwise as inside a List. 6791 * Return FAIL or OK. 6792 */ 6793 static int 6794 list_join(gap, l, sep, echo_style, copyID) 6795 garray_T *gap; 6796 list_T *l; 6797 char_u *sep; 6798 int echo_style; 6799 int copyID; 6800 { 6801 garray_T join_ga; 6802 int retval; 6803 join_T *p; 6804 int i; 6805 6806 if (l->lv_len < 1) 6807 return OK; /* nothing to do */ 6808 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); 6809 retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga); 6810 6811 /* Dispose each item in join_ga. */ 6812 if (join_ga.ga_data != NULL) 6813 { 6814 p = (join_T *)join_ga.ga_data; 6815 for (i = 0; i < join_ga.ga_len; ++i) 6816 { 6817 vim_free(p->tofree); 6818 ++p; 6819 } 6820 ga_clear(&join_ga); 6821 } 6822 6823 return retval; 6824 } 6825 6826 /* 6827 * Garbage collection for lists and dictionaries. 6828 * 6829 * We use reference counts to be able to free most items right away when they 6830 * are no longer used. But for composite items it's possible that it becomes 6831 * unused while the reference count is > 0: When there is a recursive 6832 * reference. Example: 6833 * :let l = [1, 2, 3] 6834 * :let d = {9: l} 6835 * :let l[1] = d 6836 * 6837 * Since this is quite unusual we handle this with garbage collection: every 6838 * once in a while find out which lists and dicts are not referenced from any 6839 * variable. 6840 * 6841 * Here is a good reference text about garbage collection (refers to Python 6842 * but it applies to all reference-counting mechanisms): 6843 * http://python.ca/nas/python/gc/ 6844 */ 6845 6846 /* 6847 * Do garbage collection for lists and dicts. 6848 * Return TRUE if some memory was freed. 6849 */ 6850 int 6851 garbage_collect() 6852 { 6853 int copyID; 6854 int abort = FALSE; 6855 buf_T *buf; 6856 win_T *wp; 6857 int i; 6858 funccall_T *fc, **pfc; 6859 int did_free = FALSE; 6860 int did_free_funccal = FALSE; 6861 #ifdef FEAT_WINDOWS 6862 tabpage_T *tp; 6863 #endif 6864 6865 /* Only do this once. */ 6866 want_garbage_collect = FALSE; 6867 may_garbage_collect = FALSE; 6868 garbage_collect_at_exit = FALSE; 6869 6870 /* We advance by two because we add one for items referenced through 6871 * previous_funccal. */ 6872 current_copyID += COPYID_INC; 6873 copyID = current_copyID; 6874 6875 /* 6876 * 1. Go through all accessible variables and mark all lists and dicts 6877 * with copyID. 6878 */ 6879 6880 /* Don't free variables in the previous_funccal list unless they are only 6881 * referenced through previous_funccal. This must be first, because if 6882 * the item is referenced elsewhere the funccal must not be freed. */ 6883 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6884 { 6885 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, 6886 NULL); 6887 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, 6888 NULL); 6889 } 6890 6891 /* script-local variables */ 6892 for (i = 1; i <= ga_scripts.ga_len; ++i) 6893 abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); 6894 6895 /* buffer-local variables */ 6896 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6897 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID, 6898 NULL, NULL); 6899 6900 /* window-local variables */ 6901 FOR_ALL_TAB_WINDOWS(tp, wp) 6902 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, 6903 NULL, NULL); 6904 #ifdef FEAT_AUTOCMD 6905 if (aucmd_win != NULL) 6906 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID, 6907 NULL, NULL); 6908 #endif 6909 6910 #ifdef FEAT_WINDOWS 6911 /* tabpage-local variables */ 6912 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6913 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID, 6914 NULL, NULL); 6915 #endif 6916 6917 /* global variables */ 6918 abort = abort || set_ref_in_ht(&globvarht, copyID, NULL); 6919 6920 /* function-local variables */ 6921 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6922 { 6923 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL); 6924 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL); 6925 } 6926 6927 /* v: vars */ 6928 abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL); 6929 6930 #ifdef FEAT_LUA 6931 abort = abort || set_ref_in_lua(copyID); 6932 #endif 6933 6934 #ifdef FEAT_PYTHON 6935 abort = abort || set_ref_in_python(copyID); 6936 #endif 6937 6938 #ifdef FEAT_PYTHON3 6939 abort = abort || set_ref_in_python3(copyID); 6940 #endif 6941 6942 if (!abort) 6943 { 6944 /* 6945 * 2. Free lists and dictionaries that are not referenced. 6946 */ 6947 did_free = free_unref_items(copyID); 6948 6949 /* 6950 * 3. Check if any funccal can be freed now. 6951 */ 6952 for (pfc = &previous_funccal; *pfc != NULL; ) 6953 { 6954 if (can_free_funccal(*pfc, copyID)) 6955 { 6956 fc = *pfc; 6957 *pfc = fc->caller; 6958 free_funccal(fc, TRUE); 6959 did_free = TRUE; 6960 did_free_funccal = TRUE; 6961 } 6962 else 6963 pfc = &(*pfc)->caller; 6964 } 6965 if (did_free_funccal) 6966 /* When a funccal was freed some more items might be garbage 6967 * collected, so run again. */ 6968 (void)garbage_collect(); 6969 } 6970 else if (p_verbose > 0) 6971 { 6972 verb_msg((char_u *)_("Not enough memory to set references, garbage collection aborted!")); 6973 } 6974 6975 return did_free; 6976 } 6977 6978 /* 6979 * Free lists and dictionaries that are no longer referenced. 6980 */ 6981 static int 6982 free_unref_items(copyID) 6983 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 return did_free; 7026 } 7027 7028 /* 7029 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 7030 * "list_stack" is used to add lists to be marked. Can be NULL. 7031 * 7032 * Returns TRUE if setting references failed somehow. 7033 */ 7034 int 7035 set_ref_in_ht(ht, copyID, list_stack) 7036 hashtab_T *ht; 7037 int copyID; 7038 list_stack_T **list_stack; 7039 { 7040 int todo; 7041 int abort = FALSE; 7042 hashitem_T *hi; 7043 hashtab_T *cur_ht; 7044 ht_stack_T *ht_stack = NULL; 7045 ht_stack_T *tempitem; 7046 7047 cur_ht = ht; 7048 for (;;) 7049 { 7050 if (!abort) 7051 { 7052 /* Mark each item in the hashtab. If the item contains a hashtab 7053 * it is added to ht_stack, if it contains a list it is added to 7054 * list_stack. */ 7055 todo = (int)cur_ht->ht_used; 7056 for (hi = cur_ht->ht_array; todo > 0; ++hi) 7057 if (!HASHITEM_EMPTY(hi)) 7058 { 7059 --todo; 7060 abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID, 7061 &ht_stack, list_stack); 7062 } 7063 } 7064 7065 if (ht_stack == NULL) 7066 break; 7067 7068 /* take an item from the stack */ 7069 cur_ht = ht_stack->ht; 7070 tempitem = ht_stack; 7071 ht_stack = ht_stack->prev; 7072 free(tempitem); 7073 } 7074 7075 return abort; 7076 } 7077 7078 /* 7079 * Mark all lists and dicts referenced through list "l" with "copyID". 7080 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 7081 * 7082 * Returns TRUE if setting references failed somehow. 7083 */ 7084 int 7085 set_ref_in_list(l, copyID, ht_stack) 7086 list_T *l; 7087 int copyID; 7088 ht_stack_T **ht_stack; 7089 { 7090 listitem_T *li; 7091 int abort = FALSE; 7092 list_T *cur_l; 7093 list_stack_T *list_stack = NULL; 7094 list_stack_T *tempitem; 7095 7096 cur_l = l; 7097 for (;;) 7098 { 7099 if (!abort) 7100 /* Mark each item in the list. If the item contains a hashtab 7101 * it is added to ht_stack, if it contains a list it is added to 7102 * list_stack. */ 7103 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next) 7104 abort = abort || set_ref_in_item(&li->li_tv, copyID, 7105 ht_stack, &list_stack); 7106 if (list_stack == NULL) 7107 break; 7108 7109 /* take an item from the stack */ 7110 cur_l = list_stack->list; 7111 tempitem = list_stack; 7112 list_stack = list_stack->prev; 7113 free(tempitem); 7114 } 7115 7116 return abort; 7117 } 7118 7119 /* 7120 * Mark all lists and dicts referenced through typval "tv" with "copyID". 7121 * "list_stack" is used to add lists to be marked. Can be NULL. 7122 * "ht_stack" is used to add hashtabs to be marked. Can be NULL. 7123 * 7124 * Returns TRUE if setting references failed somehow. 7125 */ 7126 int 7127 set_ref_in_item(tv, copyID, ht_stack, list_stack) 7128 typval_T *tv; 7129 int copyID; 7130 ht_stack_T **ht_stack; 7131 list_stack_T **list_stack; 7132 { 7133 dict_T *dd; 7134 list_T *ll; 7135 int abort = FALSE; 7136 7137 switch (tv->v_type) 7138 { 7139 case VAR_DICT: 7140 dd = tv->vval.v_dict; 7141 if (dd != NULL && dd->dv_copyID != copyID) 7142 { 7143 /* Didn't see this dict yet. */ 7144 dd->dv_copyID = copyID; 7145 if (ht_stack == NULL) 7146 { 7147 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); 7148 } 7149 else 7150 { 7151 ht_stack_T *newitem = (ht_stack_T*)malloc( 7152 sizeof(ht_stack_T)); 7153 if (newitem == NULL) 7154 abort = TRUE; 7155 else 7156 { 7157 newitem->ht = &dd->dv_hashtab; 7158 newitem->prev = *ht_stack; 7159 *ht_stack = newitem; 7160 } 7161 } 7162 } 7163 break; 7164 7165 case VAR_LIST: 7166 ll = tv->vval.v_list; 7167 if (ll != NULL && ll->lv_copyID != copyID) 7168 { 7169 /* Didn't see this list yet. */ 7170 ll->lv_copyID = copyID; 7171 if (list_stack == NULL) 7172 { 7173 abort = set_ref_in_list(ll, copyID, ht_stack); 7174 } 7175 else 7176 { 7177 list_stack_T *newitem = (list_stack_T*)malloc( 7178 sizeof(list_stack_T)); 7179 if (newitem == NULL) 7180 abort = TRUE; 7181 else 7182 { 7183 newitem->list = ll; 7184 newitem->prev = *list_stack; 7185 *list_stack = newitem; 7186 } 7187 } 7188 } 7189 break; 7190 } 7191 return abort; 7192 } 7193 7194 /* 7195 * Allocate an empty header for a dictionary. 7196 */ 7197 dict_T * 7198 dict_alloc() 7199 { 7200 dict_T *d; 7201 7202 d = (dict_T *)alloc(sizeof(dict_T)); 7203 if (d != NULL) 7204 { 7205 /* Add the dict to the list of dicts for garbage collection. */ 7206 if (first_dict != NULL) 7207 first_dict->dv_used_prev = d; 7208 d->dv_used_next = first_dict; 7209 d->dv_used_prev = NULL; 7210 first_dict = d; 7211 7212 hash_init(&d->dv_hashtab); 7213 d->dv_lock = 0; 7214 d->dv_scope = 0; 7215 d->dv_refcount = 0; 7216 d->dv_copyID = 0; 7217 } 7218 return d; 7219 } 7220 7221 /* 7222 * Allocate an empty dict for a return value. 7223 * Returns OK or FAIL. 7224 */ 7225 static int 7226 rettv_dict_alloc(rettv) 7227 typval_T *rettv; 7228 { 7229 dict_T *d = dict_alloc(); 7230 7231 if (d == NULL) 7232 return FAIL; 7233 7234 rettv->vval.v_dict = d; 7235 rettv->v_type = VAR_DICT; 7236 ++d->dv_refcount; 7237 return OK; 7238 } 7239 7240 7241 /* 7242 * Unreference a Dictionary: decrement the reference count and free it when it 7243 * becomes zero. 7244 */ 7245 void 7246 dict_unref(d) 7247 dict_T *d; 7248 { 7249 if (d != NULL && --d->dv_refcount <= 0) 7250 dict_free(d, TRUE); 7251 } 7252 7253 /* 7254 * Free a Dictionary, including all non-container items it contains. 7255 * Ignores the reference count. 7256 */ 7257 void 7258 dict_free(d, recurse) 7259 dict_T *d; 7260 int recurse; /* Free Lists and Dictionaries recursively. */ 7261 { 7262 int todo; 7263 hashitem_T *hi; 7264 dictitem_T *di; 7265 7266 /* Remove the dict from the list of dicts for garbage collection. */ 7267 if (d->dv_used_prev == NULL) 7268 first_dict = d->dv_used_next; 7269 else 7270 d->dv_used_prev->dv_used_next = d->dv_used_next; 7271 if (d->dv_used_next != NULL) 7272 d->dv_used_next->dv_used_prev = d->dv_used_prev; 7273 7274 /* Lock the hashtab, we don't want it to resize while freeing items. */ 7275 hash_lock(&d->dv_hashtab); 7276 todo = (int)d->dv_hashtab.ht_used; 7277 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 7278 { 7279 if (!HASHITEM_EMPTY(hi)) 7280 { 7281 /* Remove the item before deleting it, just in case there is 7282 * something recursive causing trouble. */ 7283 di = HI2DI(hi); 7284 hash_remove(&d->dv_hashtab, hi); 7285 if (recurse || (di->di_tv.v_type != VAR_LIST 7286 && di->di_tv.v_type != VAR_DICT)) 7287 clear_tv(&di->di_tv); 7288 vim_free(di); 7289 --todo; 7290 } 7291 } 7292 hash_clear(&d->dv_hashtab); 7293 vim_free(d); 7294 } 7295 7296 /* 7297 * Allocate a Dictionary item. 7298 * The "key" is copied to the new item. 7299 * Note that the value of the item "di_tv" still needs to be initialized! 7300 * Returns NULL when out of memory. 7301 */ 7302 dictitem_T * 7303 dictitem_alloc(key) 7304 char_u *key; 7305 { 7306 dictitem_T *di; 7307 7308 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 7309 if (di != NULL) 7310 { 7311 STRCPY(di->di_key, key); 7312 di->di_flags = DI_FLAGS_ALLOC; 7313 } 7314 return di; 7315 } 7316 7317 /* 7318 * Make a copy of a Dictionary item. 7319 */ 7320 static dictitem_T * 7321 dictitem_copy(org) 7322 dictitem_T *org; 7323 { 7324 dictitem_T *di; 7325 7326 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 7327 + STRLEN(org->di_key))); 7328 if (di != NULL) 7329 { 7330 STRCPY(di->di_key, org->di_key); 7331 di->di_flags = DI_FLAGS_ALLOC; 7332 copy_tv(&org->di_tv, &di->di_tv); 7333 } 7334 return di; 7335 } 7336 7337 /* 7338 * Remove item "item" from Dictionary "dict" and free it. 7339 */ 7340 static void 7341 dictitem_remove(dict, item) 7342 dict_T *dict; 7343 dictitem_T *item; 7344 { 7345 hashitem_T *hi; 7346 7347 hi = hash_find(&dict->dv_hashtab, item->di_key); 7348 if (HASHITEM_EMPTY(hi)) 7349 EMSG2(_(e_intern2), "dictitem_remove()"); 7350 else 7351 hash_remove(&dict->dv_hashtab, hi); 7352 dictitem_free(item); 7353 } 7354 7355 /* 7356 * Free a dict item. Also clears the value. 7357 */ 7358 void 7359 dictitem_free(item) 7360 dictitem_T *item; 7361 { 7362 clear_tv(&item->di_tv); 7363 if (item->di_flags & DI_FLAGS_ALLOC) 7364 vim_free(item); 7365 } 7366 7367 /* 7368 * Make a copy of dict "d". Shallow if "deep" is FALSE. 7369 * The refcount of the new dict is set to 1. 7370 * See item_copy() for "copyID". 7371 * Returns NULL when out of memory. 7372 */ 7373 static dict_T * 7374 dict_copy(orig, deep, copyID) 7375 dict_T *orig; 7376 int deep; 7377 int copyID; 7378 { 7379 dict_T *copy; 7380 dictitem_T *di; 7381 int todo; 7382 hashitem_T *hi; 7383 7384 if (orig == NULL) 7385 return NULL; 7386 7387 copy = dict_alloc(); 7388 if (copy != NULL) 7389 { 7390 if (copyID != 0) 7391 { 7392 orig->dv_copyID = copyID; 7393 orig->dv_copydict = copy; 7394 } 7395 todo = (int)orig->dv_hashtab.ht_used; 7396 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7397 { 7398 if (!HASHITEM_EMPTY(hi)) 7399 { 7400 --todo; 7401 7402 di = dictitem_alloc(hi->hi_key); 7403 if (di == NULL) 7404 break; 7405 if (deep) 7406 { 7407 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 7408 copyID) == FAIL) 7409 { 7410 vim_free(di); 7411 break; 7412 } 7413 } 7414 else 7415 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 7416 if (dict_add(copy, di) == FAIL) 7417 { 7418 dictitem_free(di); 7419 break; 7420 } 7421 } 7422 } 7423 7424 ++copy->dv_refcount; 7425 if (todo > 0) 7426 { 7427 dict_unref(copy); 7428 copy = NULL; 7429 } 7430 } 7431 7432 return copy; 7433 } 7434 7435 /* 7436 * Add item "item" to Dictionary "d". 7437 * Returns FAIL when out of memory and when key already exists. 7438 */ 7439 int 7440 dict_add(d, item) 7441 dict_T *d; 7442 dictitem_T *item; 7443 { 7444 return hash_add(&d->dv_hashtab, item->di_key); 7445 } 7446 7447 /* 7448 * Add a number or string entry to dictionary "d". 7449 * When "str" is NULL use number "nr", otherwise use "str". 7450 * Returns FAIL when out of memory and when key already exists. 7451 */ 7452 int 7453 dict_add_nr_str(d, key, nr, str) 7454 dict_T *d; 7455 char *key; 7456 long nr; 7457 char_u *str; 7458 { 7459 dictitem_T *item; 7460 7461 item = dictitem_alloc((char_u *)key); 7462 if (item == NULL) 7463 return FAIL; 7464 item->di_tv.v_lock = 0; 7465 if (str == NULL) 7466 { 7467 item->di_tv.v_type = VAR_NUMBER; 7468 item->di_tv.vval.v_number = nr; 7469 } 7470 else 7471 { 7472 item->di_tv.v_type = VAR_STRING; 7473 item->di_tv.vval.v_string = vim_strsave(str); 7474 } 7475 if (dict_add(d, item) == FAIL) 7476 { 7477 dictitem_free(item); 7478 return FAIL; 7479 } 7480 return OK; 7481 } 7482 7483 /* 7484 * Add a list entry to dictionary "d". 7485 * Returns FAIL when out of memory and when key already exists. 7486 */ 7487 int 7488 dict_add_list(d, key, list) 7489 dict_T *d; 7490 char *key; 7491 list_T *list; 7492 { 7493 dictitem_T *item; 7494 7495 item = dictitem_alloc((char_u *)key); 7496 if (item == NULL) 7497 return FAIL; 7498 item->di_tv.v_lock = 0; 7499 item->di_tv.v_type = VAR_LIST; 7500 item->di_tv.vval.v_list = list; 7501 if (dict_add(d, item) == FAIL) 7502 { 7503 dictitem_free(item); 7504 return FAIL; 7505 } 7506 ++list->lv_refcount; 7507 return OK; 7508 } 7509 7510 /* 7511 * Get the number of items in a Dictionary. 7512 */ 7513 static long 7514 dict_len(d) 7515 dict_T *d; 7516 { 7517 if (d == NULL) 7518 return 0L; 7519 return (long)d->dv_hashtab.ht_used; 7520 } 7521 7522 /* 7523 * Find item "key[len]" in Dictionary "d". 7524 * If "len" is negative use strlen(key). 7525 * Returns NULL when not found. 7526 */ 7527 dictitem_T * 7528 dict_find(d, key, len) 7529 dict_T *d; 7530 char_u *key; 7531 int len; 7532 { 7533 #define AKEYLEN 200 7534 char_u buf[AKEYLEN]; 7535 char_u *akey; 7536 char_u *tofree = NULL; 7537 hashitem_T *hi; 7538 7539 if (len < 0) 7540 akey = key; 7541 else if (len >= AKEYLEN) 7542 { 7543 tofree = akey = vim_strnsave(key, len); 7544 if (akey == NULL) 7545 return NULL; 7546 } 7547 else 7548 { 7549 /* Avoid a malloc/free by using buf[]. */ 7550 vim_strncpy(buf, key, len); 7551 akey = buf; 7552 } 7553 7554 hi = hash_find(&d->dv_hashtab, akey); 7555 vim_free(tofree); 7556 if (HASHITEM_EMPTY(hi)) 7557 return NULL; 7558 return HI2DI(hi); 7559 } 7560 7561 /* 7562 * Get a string item from a dictionary. 7563 * When "save" is TRUE allocate memory for it. 7564 * Returns NULL if the entry doesn't exist or out of memory. 7565 */ 7566 char_u * 7567 get_dict_string(d, key, save) 7568 dict_T *d; 7569 char_u *key; 7570 int save; 7571 { 7572 dictitem_T *di; 7573 char_u *s; 7574 7575 di = dict_find(d, key, -1); 7576 if (di == NULL) 7577 return NULL; 7578 s = get_tv_string(&di->di_tv); 7579 if (save && s != NULL) 7580 s = vim_strsave(s); 7581 return s; 7582 } 7583 7584 /* 7585 * Get a number item from a dictionary. 7586 * Returns 0 if the entry doesn't exist or out of memory. 7587 */ 7588 long 7589 get_dict_number(d, key) 7590 dict_T *d; 7591 char_u *key; 7592 { 7593 dictitem_T *di; 7594 7595 di = dict_find(d, key, -1); 7596 if (di == NULL) 7597 return 0; 7598 return get_tv_number(&di->di_tv); 7599 } 7600 7601 /* 7602 * Return an allocated string with the string representation of a Dictionary. 7603 * May return NULL. 7604 */ 7605 static char_u * 7606 dict2string(tv, copyID) 7607 typval_T *tv; 7608 int copyID; 7609 { 7610 garray_T ga; 7611 int first = TRUE; 7612 char_u *tofree; 7613 char_u numbuf[NUMBUFLEN]; 7614 hashitem_T *hi; 7615 char_u *s; 7616 dict_T *d; 7617 int todo; 7618 7619 if ((d = tv->vval.v_dict) == NULL) 7620 return NULL; 7621 ga_init2(&ga, (int)sizeof(char), 80); 7622 ga_append(&ga, '{'); 7623 7624 todo = (int)d->dv_hashtab.ht_used; 7625 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7626 { 7627 if (!HASHITEM_EMPTY(hi)) 7628 { 7629 --todo; 7630 7631 if (first) 7632 first = FALSE; 7633 else 7634 ga_concat(&ga, (char_u *)", "); 7635 7636 tofree = string_quote(hi->hi_key, FALSE); 7637 if (tofree != NULL) 7638 { 7639 ga_concat(&ga, tofree); 7640 vim_free(tofree); 7641 } 7642 ga_concat(&ga, (char_u *)": "); 7643 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7644 if (s != NULL) 7645 ga_concat(&ga, s); 7646 vim_free(tofree); 7647 if (s == NULL || did_echo_string_emsg) 7648 break; 7649 line_breakcheck(); 7650 7651 } 7652 } 7653 if (todo > 0) 7654 { 7655 vim_free(ga.ga_data); 7656 return NULL; 7657 } 7658 7659 ga_append(&ga, '}'); 7660 ga_append(&ga, NUL); 7661 return (char_u *)ga.ga_data; 7662 } 7663 7664 /* 7665 * Allocate a variable for a Dictionary and fill it from "*arg". 7666 * Return OK or FAIL. Returns NOTDONE for {expr}. 7667 */ 7668 static int 7669 get_dict_tv(arg, rettv, evaluate) 7670 char_u **arg; 7671 typval_T *rettv; 7672 int evaluate; 7673 { 7674 dict_T *d = NULL; 7675 typval_T tvkey; 7676 typval_T tv; 7677 char_u *key = NULL; 7678 dictitem_T *item; 7679 char_u *start = skipwhite(*arg + 1); 7680 char_u buf[NUMBUFLEN]; 7681 7682 /* 7683 * First check if it's not a curly-braces thing: {expr}. 7684 * Must do this without evaluating, otherwise a function may be called 7685 * twice. Unfortunately this means we need to call eval1() twice for the 7686 * first item. 7687 * But {} is an empty Dictionary. 7688 */ 7689 if (*start != '}') 7690 { 7691 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7692 return FAIL; 7693 if (*start == '}') 7694 return NOTDONE; 7695 } 7696 7697 if (evaluate) 7698 { 7699 d = dict_alloc(); 7700 if (d == NULL) 7701 return FAIL; 7702 } 7703 tvkey.v_type = VAR_UNKNOWN; 7704 tv.v_type = VAR_UNKNOWN; 7705 7706 *arg = skipwhite(*arg + 1); 7707 while (**arg != '}' && **arg != NUL) 7708 { 7709 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7710 goto failret; 7711 if (**arg != ':') 7712 { 7713 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7714 clear_tv(&tvkey); 7715 goto failret; 7716 } 7717 if (evaluate) 7718 { 7719 key = get_tv_string_buf_chk(&tvkey, buf); 7720 if (key == NULL || *key == NUL) 7721 { 7722 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7723 if (key != NULL) 7724 EMSG(_(e_emptykey)); 7725 clear_tv(&tvkey); 7726 goto failret; 7727 } 7728 } 7729 7730 *arg = skipwhite(*arg + 1); 7731 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7732 { 7733 if (evaluate) 7734 clear_tv(&tvkey); 7735 goto failret; 7736 } 7737 if (evaluate) 7738 { 7739 item = dict_find(d, key, -1); 7740 if (item != NULL) 7741 { 7742 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7743 clear_tv(&tvkey); 7744 clear_tv(&tv); 7745 goto failret; 7746 } 7747 item = dictitem_alloc(key); 7748 clear_tv(&tvkey); 7749 if (item != NULL) 7750 { 7751 item->di_tv = tv; 7752 item->di_tv.v_lock = 0; 7753 if (dict_add(d, item) == FAIL) 7754 dictitem_free(item); 7755 } 7756 } 7757 7758 if (**arg == '}') 7759 break; 7760 if (**arg != ',') 7761 { 7762 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7763 goto failret; 7764 } 7765 *arg = skipwhite(*arg + 1); 7766 } 7767 7768 if (**arg != '}') 7769 { 7770 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7771 failret: 7772 if (evaluate) 7773 dict_free(d, TRUE); 7774 return FAIL; 7775 } 7776 7777 *arg = skipwhite(*arg + 1); 7778 if (evaluate) 7779 { 7780 rettv->v_type = VAR_DICT; 7781 rettv->vval.v_dict = d; 7782 ++d->dv_refcount; 7783 } 7784 7785 return OK; 7786 } 7787 7788 /* 7789 * Return a string with the string representation of a variable. 7790 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7791 * "numbuf" is used for a number. 7792 * Does not put quotes around strings, as ":echo" displays values. 7793 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7794 * May return NULL. 7795 */ 7796 static char_u * 7797 echo_string(tv, tofree, numbuf, copyID) 7798 typval_T *tv; 7799 char_u **tofree; 7800 char_u *numbuf; 7801 int copyID; 7802 { 7803 static int recurse = 0; 7804 char_u *r = NULL; 7805 7806 if (recurse >= DICT_MAXNEST) 7807 { 7808 if (!did_echo_string_emsg) 7809 { 7810 /* Only give this message once for a recursive call to avoid 7811 * flooding the user with errors. And stop iterating over lists 7812 * and dicts. */ 7813 did_echo_string_emsg = TRUE; 7814 EMSG(_("E724: variable nested too deep for displaying")); 7815 } 7816 *tofree = NULL; 7817 return (char_u *)"{E724}"; 7818 } 7819 ++recurse; 7820 7821 switch (tv->v_type) 7822 { 7823 case VAR_FUNC: 7824 *tofree = NULL; 7825 r = tv->vval.v_string; 7826 break; 7827 7828 case VAR_LIST: 7829 if (tv->vval.v_list == NULL) 7830 { 7831 *tofree = NULL; 7832 r = NULL; 7833 } 7834 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7835 { 7836 *tofree = NULL; 7837 r = (char_u *)"[...]"; 7838 } 7839 else 7840 { 7841 tv->vval.v_list->lv_copyID = copyID; 7842 *tofree = list2string(tv, copyID); 7843 r = *tofree; 7844 } 7845 break; 7846 7847 case VAR_DICT: 7848 if (tv->vval.v_dict == NULL) 7849 { 7850 *tofree = NULL; 7851 r = NULL; 7852 } 7853 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7854 { 7855 *tofree = NULL; 7856 r = (char_u *)"{...}"; 7857 } 7858 else 7859 { 7860 tv->vval.v_dict->dv_copyID = copyID; 7861 *tofree = dict2string(tv, copyID); 7862 r = *tofree; 7863 } 7864 break; 7865 7866 case VAR_STRING: 7867 case VAR_NUMBER: 7868 *tofree = NULL; 7869 r = get_tv_string_buf(tv, numbuf); 7870 break; 7871 7872 #ifdef FEAT_FLOAT 7873 case VAR_FLOAT: 7874 *tofree = NULL; 7875 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7876 r = numbuf; 7877 break; 7878 #endif 7879 7880 default: 7881 EMSG2(_(e_intern2), "echo_string()"); 7882 *tofree = NULL; 7883 } 7884 7885 if (--recurse == 0) 7886 did_echo_string_emsg = FALSE; 7887 return r; 7888 } 7889 7890 /* 7891 * Return a string with the string representation of a variable. 7892 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7893 * "numbuf" is used for a number. 7894 * Puts quotes around strings, so that they can be parsed back by eval(). 7895 * May return NULL. 7896 */ 7897 static char_u * 7898 tv2string(tv, tofree, numbuf, copyID) 7899 typval_T *tv; 7900 char_u **tofree; 7901 char_u *numbuf; 7902 int copyID; 7903 { 7904 switch (tv->v_type) 7905 { 7906 case VAR_FUNC: 7907 *tofree = string_quote(tv->vval.v_string, TRUE); 7908 return *tofree; 7909 case VAR_STRING: 7910 *tofree = string_quote(tv->vval.v_string, FALSE); 7911 return *tofree; 7912 #ifdef FEAT_FLOAT 7913 case VAR_FLOAT: 7914 *tofree = NULL; 7915 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 7916 return numbuf; 7917 #endif 7918 case VAR_NUMBER: 7919 case VAR_LIST: 7920 case VAR_DICT: 7921 break; 7922 default: 7923 EMSG2(_(e_intern2), "tv2string()"); 7924 } 7925 return echo_string(tv, tofree, numbuf, copyID); 7926 } 7927 7928 /* 7929 * Return string "str" in ' quotes, doubling ' characters. 7930 * If "str" is NULL an empty string is assumed. 7931 * If "function" is TRUE make it function('string'). 7932 */ 7933 static char_u * 7934 string_quote(str, function) 7935 char_u *str; 7936 int function; 7937 { 7938 unsigned len; 7939 char_u *p, *r, *s; 7940 7941 len = (function ? 13 : 3); 7942 if (str != NULL) 7943 { 7944 len += (unsigned)STRLEN(str); 7945 for (p = str; *p != NUL; mb_ptr_adv(p)) 7946 if (*p == '\'') 7947 ++len; 7948 } 7949 s = r = alloc(len); 7950 if (r != NULL) 7951 { 7952 if (function) 7953 { 7954 STRCPY(r, "function('"); 7955 r += 10; 7956 } 7957 else 7958 *r++ = '\''; 7959 if (str != NULL) 7960 for (p = str; *p != NUL; ) 7961 { 7962 if (*p == '\'') 7963 *r++ = '\''; 7964 MB_COPY_CHAR(p, r); 7965 } 7966 *r++ = '\''; 7967 if (function) 7968 *r++ = ')'; 7969 *r++ = NUL; 7970 } 7971 return s; 7972 } 7973 7974 #ifdef FEAT_FLOAT 7975 /* 7976 * Convert the string "text" to a floating point number. 7977 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 7978 * this always uses a decimal point. 7979 * Returns the length of the text that was consumed. 7980 */ 7981 static int 7982 string2float(text, value) 7983 char_u *text; 7984 float_T *value; /* result stored here */ 7985 { 7986 char *s = (char *)text; 7987 float_T f; 7988 7989 f = strtod(s, &s); 7990 *value = f; 7991 return (int)((char_u *)s - text); 7992 } 7993 #endif 7994 7995 /* 7996 * Get the value of an environment variable. 7997 * "arg" is pointing to the '$'. It is advanced to after the name. 7998 * If the environment variable was not set, silently assume it is empty. 7999 * Return FAIL if the name is invalid. 8000 */ 8001 static int 8002 get_env_tv(arg, rettv, evaluate) 8003 char_u **arg; 8004 typval_T *rettv; 8005 int evaluate; 8006 { 8007 char_u *string = NULL; 8008 int len; 8009 int cc; 8010 char_u *name; 8011 int mustfree = FALSE; 8012 8013 ++*arg; 8014 name = *arg; 8015 len = get_env_len(arg); 8016 if (evaluate) 8017 { 8018 if (len == 0) 8019 return FAIL; /* invalid empty name */ 8020 8021 cc = name[len]; 8022 name[len] = NUL; 8023 /* first try vim_getenv(), fast for normal environment vars */ 8024 string = vim_getenv(name, &mustfree); 8025 if (string != NULL && *string != NUL) 8026 { 8027 if (!mustfree) 8028 string = vim_strsave(string); 8029 } 8030 else 8031 { 8032 if (mustfree) 8033 vim_free(string); 8034 8035 /* next try expanding things like $VIM and ${HOME} */ 8036 string = expand_env_save(name - 1); 8037 if (string != NULL && *string == '$') 8038 { 8039 vim_free(string); 8040 string = NULL; 8041 } 8042 } 8043 name[len] = cc; 8044 8045 rettv->v_type = VAR_STRING; 8046 rettv->vval.v_string = string; 8047 } 8048 8049 return OK; 8050 } 8051 8052 /* 8053 * Array with names and number of arguments of all internal functions 8054 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 8055 */ 8056 static struct fst 8057 { 8058 char *f_name; /* function name */ 8059 char f_min_argc; /* minimal number of arguments */ 8060 char f_max_argc; /* maximal number of arguments */ 8061 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 8062 /* implementation of function */ 8063 } functions[] = 8064 { 8065 #ifdef FEAT_FLOAT 8066 {"abs", 1, 1, f_abs}, 8067 {"acos", 1, 1, f_acos}, /* WJMc */ 8068 #endif 8069 {"add", 2, 2, f_add}, 8070 {"and", 2, 2, f_and}, 8071 {"append", 2, 2, f_append}, 8072 {"argc", 0, 0, f_argc}, 8073 {"argidx", 0, 0, f_argidx}, 8074 {"arglistid", 0, 2, f_arglistid}, 8075 {"argv", 0, 1, f_argv}, 8076 #ifdef FEAT_FLOAT 8077 {"asin", 1, 1, f_asin}, /* WJMc */ 8078 #endif 8079 {"assert_equal", 2, 3, f_assert_equal}, 8080 {"assert_false", 1, 2, f_assert_false}, 8081 {"assert_true", 1, 2, f_assert_true}, 8082 #ifdef FEAT_FLOAT 8083 {"atan", 1, 1, f_atan}, 8084 {"atan2", 2, 2, f_atan2}, 8085 #endif 8086 {"browse", 4, 4, f_browse}, 8087 {"browsedir", 2, 2, f_browsedir}, 8088 {"bufexists", 1, 1, f_bufexists}, 8089 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 8090 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 8091 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 8092 {"buflisted", 1, 1, f_buflisted}, 8093 {"bufloaded", 1, 1, f_bufloaded}, 8094 {"bufname", 1, 1, f_bufname}, 8095 {"bufnr", 1, 2, f_bufnr}, 8096 {"bufwinnr", 1, 1, f_bufwinnr}, 8097 {"byte2line", 1, 1, f_byte2line}, 8098 {"byteidx", 2, 2, f_byteidx}, 8099 {"byteidxcomp", 2, 2, f_byteidxcomp}, 8100 {"call", 2, 3, f_call}, 8101 #ifdef FEAT_FLOAT 8102 {"ceil", 1, 1, f_ceil}, 8103 #endif 8104 {"changenr", 0, 0, f_changenr}, 8105 {"char2nr", 1, 2, f_char2nr}, 8106 {"cindent", 1, 1, f_cindent}, 8107 {"clearmatches", 0, 0, f_clearmatches}, 8108 {"col", 1, 1, f_col}, 8109 #if defined(FEAT_INS_EXPAND) 8110 {"complete", 2, 2, f_complete}, 8111 {"complete_add", 1, 1, f_complete_add}, 8112 {"complete_check", 0, 0, f_complete_check}, 8113 #endif 8114 {"confirm", 1, 4, f_confirm}, 8115 {"copy", 1, 1, f_copy}, 8116 #ifdef FEAT_FLOAT 8117 {"cos", 1, 1, f_cos}, 8118 {"cosh", 1, 1, f_cosh}, 8119 #endif 8120 {"count", 2, 4, f_count}, 8121 {"cscope_connection",0,3, f_cscope_connection}, 8122 {"cursor", 1, 3, f_cursor}, 8123 {"deepcopy", 1, 2, f_deepcopy}, 8124 {"delete", 1, 1, f_delete}, 8125 {"did_filetype", 0, 0, f_did_filetype}, 8126 {"diff_filler", 1, 1, f_diff_filler}, 8127 {"diff_hlID", 2, 2, f_diff_hlID}, 8128 {"empty", 1, 1, f_empty}, 8129 {"escape", 2, 2, f_escape}, 8130 {"eval", 1, 1, f_eval}, 8131 {"eventhandler", 0, 0, f_eventhandler}, 8132 {"executable", 1, 1, f_executable}, 8133 {"exepath", 1, 1, f_exepath}, 8134 {"exists", 1, 1, f_exists}, 8135 #ifdef FEAT_FLOAT 8136 {"exp", 1, 1, f_exp}, 8137 #endif 8138 {"expand", 1, 3, f_expand}, 8139 {"extend", 2, 3, f_extend}, 8140 {"feedkeys", 1, 2, f_feedkeys}, 8141 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 8142 {"filereadable", 1, 1, f_filereadable}, 8143 {"filewritable", 1, 1, f_filewritable}, 8144 {"filter", 2, 2, f_filter}, 8145 {"finddir", 1, 3, f_finddir}, 8146 {"findfile", 1, 3, f_findfile}, 8147 #ifdef FEAT_FLOAT 8148 {"float2nr", 1, 1, f_float2nr}, 8149 {"floor", 1, 1, f_floor}, 8150 {"fmod", 2, 2, f_fmod}, 8151 #endif 8152 {"fnameescape", 1, 1, f_fnameescape}, 8153 {"fnamemodify", 2, 2, f_fnamemodify}, 8154 {"foldclosed", 1, 1, f_foldclosed}, 8155 {"foldclosedend", 1, 1, f_foldclosedend}, 8156 {"foldlevel", 1, 1, f_foldlevel}, 8157 {"foldtext", 0, 0, f_foldtext}, 8158 {"foldtextresult", 1, 1, f_foldtextresult}, 8159 {"foreground", 0, 0, f_foreground}, 8160 {"function", 1, 1, f_function}, 8161 {"garbagecollect", 0, 1, f_garbagecollect}, 8162 {"get", 2, 3, f_get}, 8163 {"getbufline", 2, 3, f_getbufline}, 8164 {"getbufvar", 2, 3, f_getbufvar}, 8165 {"getchar", 0, 1, f_getchar}, 8166 {"getcharmod", 0, 0, f_getcharmod}, 8167 {"getcharsearch", 0, 0, f_getcharsearch}, 8168 {"getcmdline", 0, 0, f_getcmdline}, 8169 {"getcmdpos", 0, 0, f_getcmdpos}, 8170 {"getcmdtype", 0, 0, f_getcmdtype}, 8171 {"getcmdwintype", 0, 0, f_getcmdwintype}, 8172 {"getcurpos", 0, 0, f_getcurpos}, 8173 {"getcwd", 0, 0, f_getcwd}, 8174 {"getfontname", 0, 1, f_getfontname}, 8175 {"getfperm", 1, 1, f_getfperm}, 8176 {"getfsize", 1, 1, f_getfsize}, 8177 {"getftime", 1, 1, f_getftime}, 8178 {"getftype", 1, 1, f_getftype}, 8179 {"getline", 1, 2, f_getline}, 8180 {"getloclist", 1, 1, f_getqflist}, 8181 {"getmatches", 0, 0, f_getmatches}, 8182 {"getpid", 0, 0, f_getpid}, 8183 {"getpos", 1, 1, f_getpos}, 8184 {"getqflist", 0, 0, f_getqflist}, 8185 {"getreg", 0, 3, f_getreg}, 8186 {"getregtype", 0, 1, f_getregtype}, 8187 {"gettabvar", 2, 3, f_gettabvar}, 8188 {"gettabwinvar", 3, 4, f_gettabwinvar}, 8189 {"getwinposx", 0, 0, f_getwinposx}, 8190 {"getwinposy", 0, 0, f_getwinposy}, 8191 {"getwinvar", 2, 3, f_getwinvar}, 8192 {"glob", 1, 4, f_glob}, 8193 {"glob2regpat", 1, 1, f_glob2regpat}, 8194 {"globpath", 2, 5, f_globpath}, 8195 {"has", 1, 1, f_has}, 8196 {"has_key", 2, 2, f_has_key}, 8197 {"haslocaldir", 0, 0, f_haslocaldir}, 8198 {"hasmapto", 1, 3, f_hasmapto}, 8199 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 8200 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 8201 {"histadd", 2, 2, f_histadd}, 8202 {"histdel", 1, 2, f_histdel}, 8203 {"histget", 1, 2, f_histget}, 8204 {"histnr", 1, 1, f_histnr}, 8205 {"hlID", 1, 1, f_hlID}, 8206 {"hlexists", 1, 1, f_hlexists}, 8207 {"hostname", 0, 0, f_hostname}, 8208 {"iconv", 3, 3, f_iconv}, 8209 {"indent", 1, 1, f_indent}, 8210 {"index", 2, 4, f_index}, 8211 {"input", 1, 3, f_input}, 8212 {"inputdialog", 1, 3, f_inputdialog}, 8213 {"inputlist", 1, 1, f_inputlist}, 8214 {"inputrestore", 0, 0, f_inputrestore}, 8215 {"inputsave", 0, 0, f_inputsave}, 8216 {"inputsecret", 1, 2, f_inputsecret}, 8217 {"insert", 2, 3, f_insert}, 8218 {"invert", 1, 1, f_invert}, 8219 {"isdirectory", 1, 1, f_isdirectory}, 8220 {"islocked", 1, 1, f_islocked}, 8221 {"items", 1, 1, f_items}, 8222 {"join", 1, 2, f_join}, 8223 {"keys", 1, 1, f_keys}, 8224 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 8225 {"len", 1, 1, f_len}, 8226 {"libcall", 3, 3, f_libcall}, 8227 {"libcallnr", 3, 3, f_libcallnr}, 8228 {"line", 1, 1, f_line}, 8229 {"line2byte", 1, 1, f_line2byte}, 8230 {"lispindent", 1, 1, f_lispindent}, 8231 {"localtime", 0, 0, f_localtime}, 8232 #ifdef FEAT_FLOAT 8233 {"log", 1, 1, f_log}, 8234 {"log10", 1, 1, f_log10}, 8235 #endif 8236 #ifdef FEAT_LUA 8237 {"luaeval", 1, 2, f_luaeval}, 8238 #endif 8239 {"map", 2, 2, f_map}, 8240 {"maparg", 1, 4, f_maparg}, 8241 {"mapcheck", 1, 3, f_mapcheck}, 8242 {"match", 2, 4, f_match}, 8243 {"matchadd", 2, 5, f_matchadd}, 8244 {"matchaddpos", 2, 5, f_matchaddpos}, 8245 {"matcharg", 1, 1, f_matcharg}, 8246 {"matchdelete", 1, 1, f_matchdelete}, 8247 {"matchend", 2, 4, f_matchend}, 8248 {"matchlist", 2, 4, f_matchlist}, 8249 {"matchstr", 2, 4, f_matchstr}, 8250 {"max", 1, 1, f_max}, 8251 {"min", 1, 1, f_min}, 8252 #ifdef vim_mkdir 8253 {"mkdir", 1, 3, f_mkdir}, 8254 #endif 8255 {"mode", 0, 1, f_mode}, 8256 #ifdef FEAT_MZSCHEME 8257 {"mzeval", 1, 1, f_mzeval}, 8258 #endif 8259 {"nextnonblank", 1, 1, f_nextnonblank}, 8260 {"nr2char", 1, 2, f_nr2char}, 8261 {"or", 2, 2, f_or}, 8262 {"pathshorten", 1, 1, f_pathshorten}, 8263 #ifdef FEAT_FLOAT 8264 {"pow", 2, 2, f_pow}, 8265 #endif 8266 {"prevnonblank", 1, 1, f_prevnonblank}, 8267 {"printf", 2, 19, f_printf}, 8268 {"pumvisible", 0, 0, f_pumvisible}, 8269 #ifdef FEAT_PYTHON3 8270 {"py3eval", 1, 1, f_py3eval}, 8271 #endif 8272 #ifdef FEAT_PYTHON 8273 {"pyeval", 1, 1, f_pyeval}, 8274 #endif 8275 {"range", 1, 3, f_range}, 8276 {"readfile", 1, 3, f_readfile}, 8277 {"reltime", 0, 2, f_reltime}, 8278 {"reltimestr", 1, 1, f_reltimestr}, 8279 {"remote_expr", 2, 3, f_remote_expr}, 8280 {"remote_foreground", 1, 1, f_remote_foreground}, 8281 {"remote_peek", 1, 2, f_remote_peek}, 8282 {"remote_read", 1, 1, f_remote_read}, 8283 {"remote_send", 2, 3, f_remote_send}, 8284 {"remove", 2, 3, f_remove}, 8285 {"rename", 2, 2, f_rename}, 8286 {"repeat", 2, 2, f_repeat}, 8287 {"resolve", 1, 1, f_resolve}, 8288 {"reverse", 1, 1, f_reverse}, 8289 #ifdef FEAT_FLOAT 8290 {"round", 1, 1, f_round}, 8291 #endif 8292 {"screenattr", 2, 2, f_screenattr}, 8293 {"screenchar", 2, 2, f_screenchar}, 8294 {"screencol", 0, 0, f_screencol}, 8295 {"screenrow", 0, 0, f_screenrow}, 8296 {"search", 1, 4, f_search}, 8297 {"searchdecl", 1, 3, f_searchdecl}, 8298 {"searchpair", 3, 7, f_searchpair}, 8299 {"searchpairpos", 3, 7, f_searchpairpos}, 8300 {"searchpos", 1, 4, f_searchpos}, 8301 {"server2client", 2, 2, f_server2client}, 8302 {"serverlist", 0, 0, f_serverlist}, 8303 {"setbufvar", 3, 3, f_setbufvar}, 8304 {"setcharsearch", 1, 1, f_setcharsearch}, 8305 {"setcmdpos", 1, 1, f_setcmdpos}, 8306 {"setline", 2, 2, f_setline}, 8307 {"setloclist", 2, 3, f_setloclist}, 8308 {"setmatches", 1, 1, f_setmatches}, 8309 {"setpos", 2, 2, f_setpos}, 8310 {"setqflist", 1, 2, f_setqflist}, 8311 {"setreg", 2, 3, f_setreg}, 8312 {"settabvar", 3, 3, f_settabvar}, 8313 {"settabwinvar", 4, 4, f_settabwinvar}, 8314 {"setwinvar", 3, 3, f_setwinvar}, 8315 #ifdef FEAT_CRYPT 8316 {"sha256", 1, 1, f_sha256}, 8317 #endif 8318 {"shellescape", 1, 2, f_shellescape}, 8319 {"shiftwidth", 0, 0, f_shiftwidth}, 8320 {"simplify", 1, 1, f_simplify}, 8321 #ifdef FEAT_FLOAT 8322 {"sin", 1, 1, f_sin}, 8323 {"sinh", 1, 1, f_sinh}, 8324 #endif 8325 {"sort", 1, 3, f_sort}, 8326 {"soundfold", 1, 1, f_soundfold}, 8327 {"spellbadword", 0, 1, f_spellbadword}, 8328 {"spellsuggest", 1, 3, f_spellsuggest}, 8329 {"split", 1, 3, f_split}, 8330 #ifdef FEAT_FLOAT 8331 {"sqrt", 1, 1, f_sqrt}, 8332 {"str2float", 1, 1, f_str2float}, 8333 #endif 8334 {"str2nr", 1, 2, f_str2nr}, 8335 {"strchars", 1, 2, f_strchars}, 8336 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 8337 #ifdef HAVE_STRFTIME 8338 {"strftime", 1, 2, f_strftime}, 8339 #endif 8340 {"stridx", 2, 3, f_stridx}, 8341 {"string", 1, 1, f_string}, 8342 {"strlen", 1, 1, f_strlen}, 8343 {"strpart", 2, 3, f_strpart}, 8344 {"strridx", 2, 3, f_strridx}, 8345 {"strtrans", 1, 1, f_strtrans}, 8346 {"strwidth", 1, 1, f_strwidth}, 8347 {"submatch", 1, 2, f_submatch}, 8348 {"substitute", 4, 4, f_substitute}, 8349 {"synID", 3, 3, f_synID}, 8350 {"synIDattr", 2, 3, f_synIDattr}, 8351 {"synIDtrans", 1, 1, f_synIDtrans}, 8352 {"synconcealed", 2, 2, f_synconcealed}, 8353 {"synstack", 2, 2, f_synstack}, 8354 {"system", 1, 2, f_system}, 8355 {"systemlist", 1, 2, f_systemlist}, 8356 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 8357 {"tabpagenr", 0, 1, f_tabpagenr}, 8358 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 8359 {"tagfiles", 0, 0, f_tagfiles}, 8360 {"taglist", 1, 1, f_taglist}, 8361 #ifdef FEAT_FLOAT 8362 {"tan", 1, 1, f_tan}, 8363 {"tanh", 1, 1, f_tanh}, 8364 #endif 8365 {"tempname", 0, 0, f_tempname}, 8366 {"test", 1, 1, f_test}, 8367 {"tolower", 1, 1, f_tolower}, 8368 {"toupper", 1, 1, f_toupper}, 8369 {"tr", 3, 3, f_tr}, 8370 #ifdef FEAT_FLOAT 8371 {"trunc", 1, 1, f_trunc}, 8372 #endif 8373 {"type", 1, 1, f_type}, 8374 {"undofile", 1, 1, f_undofile}, 8375 {"undotree", 0, 0, f_undotree}, 8376 {"uniq", 1, 3, f_uniq}, 8377 {"values", 1, 1, f_values}, 8378 {"virtcol", 1, 1, f_virtcol}, 8379 {"visualmode", 0, 1, f_visualmode}, 8380 {"wildmenumode", 0, 0, f_wildmenumode}, 8381 {"winbufnr", 1, 1, f_winbufnr}, 8382 {"wincol", 0, 0, f_wincol}, 8383 {"winheight", 1, 1, f_winheight}, 8384 {"winline", 0, 0, f_winline}, 8385 {"winnr", 0, 1, f_winnr}, 8386 {"winrestcmd", 0, 0, f_winrestcmd}, 8387 {"winrestview", 1, 1, f_winrestview}, 8388 {"winsaveview", 0, 0, f_winsaveview}, 8389 {"winwidth", 1, 1, f_winwidth}, 8390 {"writefile", 2, 3, f_writefile}, 8391 {"xor", 2, 2, f_xor}, 8392 }; 8393 8394 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 8395 8396 /* 8397 * Function given to ExpandGeneric() to obtain the list of internal 8398 * or user defined function names. 8399 */ 8400 char_u * 8401 get_function_name(xp, idx) 8402 expand_T *xp; 8403 int idx; 8404 { 8405 static int intidx = -1; 8406 char_u *name; 8407 8408 if (idx == 0) 8409 intidx = -1; 8410 if (intidx < 0) 8411 { 8412 name = get_user_func_name(xp, idx); 8413 if (name != NULL) 8414 return name; 8415 } 8416 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 8417 { 8418 STRCPY(IObuff, functions[intidx].f_name); 8419 STRCAT(IObuff, "("); 8420 if (functions[intidx].f_max_argc == 0) 8421 STRCAT(IObuff, ")"); 8422 return IObuff; 8423 } 8424 8425 return NULL; 8426 } 8427 8428 /* 8429 * Function given to ExpandGeneric() to obtain the list of internal or 8430 * user defined variable or function names. 8431 */ 8432 char_u * 8433 get_expr_name(xp, idx) 8434 expand_T *xp; 8435 int idx; 8436 { 8437 static int intidx = -1; 8438 char_u *name; 8439 8440 if (idx == 0) 8441 intidx = -1; 8442 if (intidx < 0) 8443 { 8444 name = get_function_name(xp, idx); 8445 if (name != NULL) 8446 return name; 8447 } 8448 return get_user_var_name(xp, ++intidx); 8449 } 8450 8451 #endif /* FEAT_CMDL_COMPL */ 8452 8453 #if defined(EBCDIC) || defined(PROTO) 8454 /* 8455 * Compare struct fst by function name. 8456 */ 8457 static int 8458 compare_func_name(s1, s2) 8459 const void *s1; 8460 const void *s2; 8461 { 8462 struct fst *p1 = (struct fst *)s1; 8463 struct fst *p2 = (struct fst *)s2; 8464 8465 return STRCMP(p1->f_name, p2->f_name); 8466 } 8467 8468 /* 8469 * Sort the function table by function name. 8470 * The sorting of the table above is ASCII dependant. 8471 * On machines using EBCDIC we have to sort it. 8472 */ 8473 static void 8474 sortFunctions() 8475 { 8476 int funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8477 8478 qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name); 8479 } 8480 #endif 8481 8482 8483 /* 8484 * Find internal function in table above. 8485 * Return index, or -1 if not found 8486 */ 8487 static int 8488 find_internal_func(name) 8489 char_u *name; /* name of the function */ 8490 { 8491 int first = 0; 8492 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8493 int cmp; 8494 int x; 8495 8496 /* 8497 * Find the function name in the table. Binary search. 8498 */ 8499 while (first <= last) 8500 { 8501 x = first + ((unsigned)(last - first) >> 1); 8502 cmp = STRCMP(name, functions[x].f_name); 8503 if (cmp < 0) 8504 last = x - 1; 8505 else if (cmp > 0) 8506 first = x + 1; 8507 else 8508 return x; 8509 } 8510 return -1; 8511 } 8512 8513 /* 8514 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 8515 * name it contains, otherwise return "name". 8516 */ 8517 static char_u * 8518 deref_func_name(name, lenp, no_autoload) 8519 char_u *name; 8520 int *lenp; 8521 int no_autoload; 8522 { 8523 dictitem_T *v; 8524 int cc; 8525 8526 cc = name[*lenp]; 8527 name[*lenp] = NUL; 8528 v = find_var(name, NULL, no_autoload); 8529 name[*lenp] = cc; 8530 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 8531 { 8532 if (v->di_tv.vval.v_string == NULL) 8533 { 8534 *lenp = 0; 8535 return (char_u *)""; /* just in case */ 8536 } 8537 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 8538 return v->di_tv.vval.v_string; 8539 } 8540 8541 return name; 8542 } 8543 8544 /* 8545 * Allocate a variable for the result of a function. 8546 * Return OK or FAIL. 8547 */ 8548 static int 8549 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 8550 evaluate, selfdict) 8551 char_u *name; /* name of the function */ 8552 int len; /* length of "name" */ 8553 typval_T *rettv; 8554 char_u **arg; /* argument, pointing to the '(' */ 8555 linenr_T firstline; /* first line of range */ 8556 linenr_T lastline; /* last line of range */ 8557 int *doesrange; /* return: function handled range */ 8558 int evaluate; 8559 dict_T *selfdict; /* Dictionary for "self" */ 8560 { 8561 char_u *argp; 8562 int ret = OK; 8563 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 8564 int argcount = 0; /* number of arguments found */ 8565 8566 /* 8567 * Get the arguments. 8568 */ 8569 argp = *arg; 8570 while (argcount < MAX_FUNC_ARGS) 8571 { 8572 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 8573 if (*argp == ')' || *argp == ',' || *argp == NUL) 8574 break; 8575 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 8576 { 8577 ret = FAIL; 8578 break; 8579 } 8580 ++argcount; 8581 if (*argp != ',') 8582 break; 8583 } 8584 if (*argp == ')') 8585 ++argp; 8586 else 8587 ret = FAIL; 8588 8589 if (ret == OK) 8590 ret = call_func(name, len, rettv, argcount, argvars, 8591 firstline, lastline, doesrange, evaluate, selfdict); 8592 else if (!aborting()) 8593 { 8594 if (argcount == MAX_FUNC_ARGS) 8595 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 8596 else 8597 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 8598 } 8599 8600 while (--argcount >= 0) 8601 clear_tv(&argvars[argcount]); 8602 8603 *arg = skipwhite(argp); 8604 return ret; 8605 } 8606 8607 8608 /* 8609 * Call a function with its resolved parameters 8610 * Return FAIL when the function can't be called, OK otherwise. 8611 * Also returns OK when an error was encountered while executing the function. 8612 */ 8613 static int 8614 call_func(funcname, len, rettv, argcount, argvars, firstline, lastline, 8615 doesrange, evaluate, selfdict) 8616 char_u *funcname; /* name of the function */ 8617 int len; /* length of "name" */ 8618 typval_T *rettv; /* return value goes here */ 8619 int argcount; /* number of "argvars" */ 8620 typval_T *argvars; /* vars for arguments, must have "argcount" 8621 PLUS ONE elements! */ 8622 linenr_T firstline; /* first line of range */ 8623 linenr_T lastline; /* last line of range */ 8624 int *doesrange; /* return: function handled range */ 8625 int evaluate; 8626 dict_T *selfdict; /* Dictionary for "self" */ 8627 { 8628 int ret = FAIL; 8629 #define ERROR_UNKNOWN 0 8630 #define ERROR_TOOMANY 1 8631 #define ERROR_TOOFEW 2 8632 #define ERROR_SCRIPT 3 8633 #define ERROR_DICT 4 8634 #define ERROR_NONE 5 8635 #define ERROR_OTHER 6 8636 int error = ERROR_NONE; 8637 int i; 8638 int llen; 8639 ufunc_T *fp; 8640 #define FLEN_FIXED 40 8641 char_u fname_buf[FLEN_FIXED + 1]; 8642 char_u *fname; 8643 char_u *name; 8644 8645 /* Make a copy of the name, if it comes from a funcref variable it could 8646 * be changed or deleted in the called function. */ 8647 name = vim_strnsave(funcname, len); 8648 if (name == NULL) 8649 return ret; 8650 8651 /* 8652 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8653 * Change <SNR>123_name() to K_SNR 123_name(). 8654 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 8655 */ 8656 llen = eval_fname_script(name); 8657 if (llen > 0) 8658 { 8659 fname_buf[0] = K_SPECIAL; 8660 fname_buf[1] = KS_EXTRA; 8661 fname_buf[2] = (int)KE_SNR; 8662 i = 3; 8663 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8664 { 8665 if (current_SID <= 0) 8666 error = ERROR_SCRIPT; 8667 else 8668 { 8669 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8670 i = (int)STRLEN(fname_buf); 8671 } 8672 } 8673 if (i + STRLEN(name + llen) < FLEN_FIXED) 8674 { 8675 STRCPY(fname_buf + i, name + llen); 8676 fname = fname_buf; 8677 } 8678 else 8679 { 8680 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8681 if (fname == NULL) 8682 error = ERROR_OTHER; 8683 else 8684 { 8685 mch_memmove(fname, fname_buf, (size_t)i); 8686 STRCPY(fname + i, name + llen); 8687 } 8688 } 8689 } 8690 else 8691 fname = name; 8692 8693 *doesrange = FALSE; 8694 8695 8696 /* execute the function if no errors detected and executing */ 8697 if (evaluate && error == ERROR_NONE) 8698 { 8699 char_u *rfname = fname; 8700 8701 /* Ignore "g:" before a function name. */ 8702 if (fname[0] == 'g' && fname[1] == ':') 8703 rfname = fname + 2; 8704 8705 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8706 rettv->vval.v_number = 0; 8707 error = ERROR_UNKNOWN; 8708 8709 if (!builtin_function(rfname, -1)) 8710 { 8711 /* 8712 * User defined function. 8713 */ 8714 fp = find_func(rfname); 8715 8716 #ifdef FEAT_AUTOCMD 8717 /* Trigger FuncUndefined event, may load the function. */ 8718 if (fp == NULL 8719 && apply_autocmds(EVENT_FUNCUNDEFINED, 8720 rfname, rfname, TRUE, NULL) 8721 && !aborting()) 8722 { 8723 /* executed an autocommand, search for the function again */ 8724 fp = find_func(rfname); 8725 } 8726 #endif 8727 /* Try loading a package. */ 8728 if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) 8729 { 8730 /* loaded a package, search for the function again */ 8731 fp = find_func(rfname); 8732 } 8733 8734 if (fp != NULL) 8735 { 8736 if (fp->uf_flags & FC_RANGE) 8737 *doesrange = TRUE; 8738 if (argcount < fp->uf_args.ga_len) 8739 error = ERROR_TOOFEW; 8740 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8741 error = ERROR_TOOMANY; 8742 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8743 error = ERROR_DICT; 8744 else 8745 { 8746 int did_save_redo = FALSE; 8747 8748 /* 8749 * Call the user function. 8750 * Save and restore search patterns, script variables and 8751 * redo buffer. 8752 */ 8753 save_search_patterns(); 8754 #ifdef FEAT_INS_EXPAND 8755 if (!ins_compl_active()) 8756 #endif 8757 { 8758 saveRedobuff(); 8759 did_save_redo = TRUE; 8760 } 8761 ++fp->uf_calls; 8762 call_user_func(fp, argcount, argvars, rettv, 8763 firstline, lastline, 8764 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8765 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8766 && fp->uf_refcount <= 0) 8767 /* Function was unreferenced while being used, free it 8768 * now. */ 8769 func_free(fp); 8770 if (did_save_redo) 8771 restoreRedobuff(); 8772 restore_search_patterns(); 8773 error = ERROR_NONE; 8774 } 8775 } 8776 } 8777 else 8778 { 8779 /* 8780 * Find the function name in the table, call its implementation. 8781 */ 8782 i = find_internal_func(fname); 8783 if (i >= 0) 8784 { 8785 if (argcount < functions[i].f_min_argc) 8786 error = ERROR_TOOFEW; 8787 else if (argcount > functions[i].f_max_argc) 8788 error = ERROR_TOOMANY; 8789 else 8790 { 8791 argvars[argcount].v_type = VAR_UNKNOWN; 8792 functions[i].f_func(argvars, rettv); 8793 error = ERROR_NONE; 8794 } 8795 } 8796 } 8797 /* 8798 * The function call (or "FuncUndefined" autocommand sequence) might 8799 * have been aborted by an error, an interrupt, or an explicitly thrown 8800 * exception that has not been caught so far. This situation can be 8801 * tested for by calling aborting(). For an error in an internal 8802 * function or for the "E132" error in call_user_func(), however, the 8803 * throw point at which the "force_abort" flag (temporarily reset by 8804 * emsg()) is normally updated has not been reached yet. We need to 8805 * update that flag first to make aborting() reliable. 8806 */ 8807 update_force_abort(); 8808 } 8809 if (error == ERROR_NONE) 8810 ret = OK; 8811 8812 /* 8813 * Report an error unless the argument evaluation or function call has been 8814 * cancelled due to an aborting error, an interrupt, or an exception. 8815 */ 8816 if (!aborting()) 8817 { 8818 switch (error) 8819 { 8820 case ERROR_UNKNOWN: 8821 emsg_funcname(N_("E117: Unknown function: %s"), name); 8822 break; 8823 case ERROR_TOOMANY: 8824 emsg_funcname(e_toomanyarg, name); 8825 break; 8826 case ERROR_TOOFEW: 8827 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 8828 name); 8829 break; 8830 case ERROR_SCRIPT: 8831 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 8832 name); 8833 break; 8834 case ERROR_DICT: 8835 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 8836 name); 8837 break; 8838 } 8839 } 8840 8841 if (fname != name && fname != fname_buf) 8842 vim_free(fname); 8843 vim_free(name); 8844 8845 return ret; 8846 } 8847 8848 /* 8849 * Give an error message with a function name. Handle <SNR> things. 8850 * "ermsg" is to be passed without translation, use N_() instead of _(). 8851 */ 8852 static void 8853 emsg_funcname(ermsg, name) 8854 char *ermsg; 8855 char_u *name; 8856 { 8857 char_u *p; 8858 8859 if (*name == K_SPECIAL) 8860 p = concat_str((char_u *)"<SNR>", name + 3); 8861 else 8862 p = name; 8863 EMSG2(_(ermsg), p); 8864 if (p != name) 8865 vim_free(p); 8866 } 8867 8868 /* 8869 * Return TRUE for a non-zero Number and a non-empty String. 8870 */ 8871 static int 8872 non_zero_arg(argvars) 8873 typval_T *argvars; 8874 { 8875 return ((argvars[0].v_type == VAR_NUMBER 8876 && argvars[0].vval.v_number != 0) 8877 || (argvars[0].v_type == VAR_STRING 8878 && argvars[0].vval.v_string != NULL 8879 && *argvars[0].vval.v_string != NUL)); 8880 } 8881 8882 /********************************************* 8883 * Implementation of the built-in functions 8884 */ 8885 8886 #ifdef FEAT_FLOAT 8887 static int get_float_arg __ARGS((typval_T *argvars, float_T *f)); 8888 8889 /* 8890 * Get the float value of "argvars[0]" into "f". 8891 * Returns FAIL when the argument is not a Number or Float. 8892 */ 8893 static int 8894 get_float_arg(argvars, f) 8895 typval_T *argvars; 8896 float_T *f; 8897 { 8898 if (argvars[0].v_type == VAR_FLOAT) 8899 { 8900 *f = argvars[0].vval.v_float; 8901 return OK; 8902 } 8903 if (argvars[0].v_type == VAR_NUMBER) 8904 { 8905 *f = (float_T)argvars[0].vval.v_number; 8906 return OK; 8907 } 8908 EMSG(_("E808: Number or Float required")); 8909 return FAIL; 8910 } 8911 8912 /* 8913 * "abs(expr)" function 8914 */ 8915 static void 8916 f_abs(argvars, rettv) 8917 typval_T *argvars; 8918 typval_T *rettv; 8919 { 8920 if (argvars[0].v_type == VAR_FLOAT) 8921 { 8922 rettv->v_type = VAR_FLOAT; 8923 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 8924 } 8925 else 8926 { 8927 varnumber_T n; 8928 int error = FALSE; 8929 8930 n = get_tv_number_chk(&argvars[0], &error); 8931 if (error) 8932 rettv->vval.v_number = -1; 8933 else if (n > 0) 8934 rettv->vval.v_number = n; 8935 else 8936 rettv->vval.v_number = -n; 8937 } 8938 } 8939 8940 /* 8941 * "acos()" function 8942 */ 8943 static void 8944 f_acos(argvars, rettv) 8945 typval_T *argvars; 8946 typval_T *rettv; 8947 { 8948 float_T f; 8949 8950 rettv->v_type = VAR_FLOAT; 8951 if (get_float_arg(argvars, &f) == OK) 8952 rettv->vval.v_float = acos(f); 8953 else 8954 rettv->vval.v_float = 0.0; 8955 } 8956 #endif 8957 8958 /* 8959 * "add(list, item)" function 8960 */ 8961 static void 8962 f_add(argvars, rettv) 8963 typval_T *argvars; 8964 typval_T *rettv; 8965 { 8966 list_T *l; 8967 8968 rettv->vval.v_number = 1; /* Default: Failed */ 8969 if (argvars[0].v_type == VAR_LIST) 8970 { 8971 if ((l = argvars[0].vval.v_list) != NULL 8972 && !tv_check_lock(l->lv_lock, 8973 (char_u *)N_("add() argument"), TRUE) 8974 && list_append_tv(l, &argvars[1]) == OK) 8975 copy_tv(&argvars[0], rettv); 8976 } 8977 else 8978 EMSG(_(e_listreq)); 8979 } 8980 8981 /* 8982 * "and(expr, expr)" function 8983 */ 8984 static void 8985 f_and(argvars, rettv) 8986 typval_T *argvars; 8987 typval_T *rettv; 8988 { 8989 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 8990 & get_tv_number_chk(&argvars[1], NULL); 8991 } 8992 8993 /* 8994 * "append(lnum, string/list)" function 8995 */ 8996 static void 8997 f_append(argvars, rettv) 8998 typval_T *argvars; 8999 typval_T *rettv; 9000 { 9001 long lnum; 9002 char_u *line; 9003 list_T *l = NULL; 9004 listitem_T *li = NULL; 9005 typval_T *tv; 9006 long added = 0; 9007 9008 /* When coming here from Insert mode, sync undo, so that this can be 9009 * undone separately from what was previously inserted. */ 9010 if (u_sync_once == 2) 9011 { 9012 u_sync_once = 1; /* notify that u_sync() was called */ 9013 u_sync(TRUE); 9014 } 9015 9016 lnum = get_tv_lnum(argvars); 9017 if (lnum >= 0 9018 && lnum <= curbuf->b_ml.ml_line_count 9019 && u_save(lnum, lnum + 1) == OK) 9020 { 9021 if (argvars[1].v_type == VAR_LIST) 9022 { 9023 l = argvars[1].vval.v_list; 9024 if (l == NULL) 9025 return; 9026 li = l->lv_first; 9027 } 9028 for (;;) 9029 { 9030 if (l == NULL) 9031 tv = &argvars[1]; /* append a string */ 9032 else if (li == NULL) 9033 break; /* end of list */ 9034 else 9035 tv = &li->li_tv; /* append item from list */ 9036 line = get_tv_string_chk(tv); 9037 if (line == NULL) /* type error */ 9038 { 9039 rettv->vval.v_number = 1; /* Failed */ 9040 break; 9041 } 9042 ml_append(lnum + added, line, (colnr_T)0, FALSE); 9043 ++added; 9044 if (l == NULL) 9045 break; 9046 li = li->li_next; 9047 } 9048 9049 appended_lines_mark(lnum, added); 9050 if (curwin->w_cursor.lnum > lnum) 9051 curwin->w_cursor.lnum += added; 9052 } 9053 else 9054 rettv->vval.v_number = 1; /* Failed */ 9055 } 9056 9057 /* 9058 * "argc()" function 9059 */ 9060 static void 9061 f_argc(argvars, rettv) 9062 typval_T *argvars UNUSED; 9063 typval_T *rettv; 9064 { 9065 rettv->vval.v_number = ARGCOUNT; 9066 } 9067 9068 /* 9069 * "argidx()" function 9070 */ 9071 static void 9072 f_argidx(argvars, rettv) 9073 typval_T *argvars UNUSED; 9074 typval_T *rettv; 9075 { 9076 rettv->vval.v_number = curwin->w_arg_idx; 9077 } 9078 9079 /* 9080 * "arglistid()" function 9081 */ 9082 static void 9083 f_arglistid(argvars, rettv) 9084 typval_T *argvars UNUSED; 9085 typval_T *rettv; 9086 { 9087 win_T *wp; 9088 tabpage_T *tp = NULL; 9089 long n; 9090 9091 rettv->vval.v_number = -1; 9092 if (argvars[0].v_type != VAR_UNKNOWN) 9093 { 9094 if (argvars[1].v_type != VAR_UNKNOWN) 9095 { 9096 n = get_tv_number(&argvars[1]); 9097 if (n >= 0) 9098 tp = find_tabpage(n); 9099 } 9100 else 9101 tp = curtab; 9102 9103 if (tp != NULL) 9104 { 9105 wp = find_win_by_nr(&argvars[0], tp); 9106 if (wp != NULL) 9107 rettv->vval.v_number = wp->w_alist->id; 9108 } 9109 } 9110 else 9111 rettv->vval.v_number = curwin->w_alist->id; 9112 } 9113 9114 /* 9115 * "argv(nr)" function 9116 */ 9117 static void 9118 f_argv(argvars, rettv) 9119 typval_T *argvars; 9120 typval_T *rettv; 9121 { 9122 int idx; 9123 9124 if (argvars[0].v_type != VAR_UNKNOWN) 9125 { 9126 idx = get_tv_number_chk(&argvars[0], NULL); 9127 if (idx >= 0 && idx < ARGCOUNT) 9128 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 9129 else 9130 rettv->vval.v_string = NULL; 9131 rettv->v_type = VAR_STRING; 9132 } 9133 else if (rettv_list_alloc(rettv) == OK) 9134 for (idx = 0; idx < ARGCOUNT; ++idx) 9135 list_append_string(rettv->vval.v_list, 9136 alist_name(&ARGLIST[idx]), -1); 9137 } 9138 9139 static void prepare_assert_error __ARGS((garray_T*gap)); 9140 static void fill_assert_error __ARGS((garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv)); 9141 static void assert_error __ARGS((garray_T *gap)); 9142 static void assert_bool __ARGS((typval_T *argvars, int isTrue)); 9143 9144 /* 9145 * Prepare "gap" for an assert error and add the sourcing position. 9146 */ 9147 static void 9148 prepare_assert_error(gap) 9149 garray_T *gap; 9150 { 9151 char buf[NUMBUFLEN]; 9152 9153 ga_init2(gap, 1, 100); 9154 ga_concat(gap, sourcing_name); 9155 sprintf(buf, " line %ld", (long)sourcing_lnum); 9156 ga_concat(gap, (char_u *)buf); 9157 ga_concat(gap, (char_u *)": "); 9158 } 9159 9160 /* 9161 * Fill "gap" with information about an assert error. 9162 */ 9163 static void 9164 fill_assert_error(gap, opt_msg_tv, exp_str, exp_tv, got_tv) 9165 garray_T *gap; 9166 typval_T *opt_msg_tv; 9167 char_u *exp_str; 9168 typval_T *exp_tv; 9169 typval_T *got_tv; 9170 { 9171 char_u numbuf[NUMBUFLEN]; 9172 char_u *tofree; 9173 9174 if (opt_msg_tv->v_type != VAR_UNKNOWN) 9175 { 9176 ga_concat(gap, tv2string(opt_msg_tv, &tofree, numbuf, 0)); 9177 vim_free(tofree); 9178 } 9179 else 9180 { 9181 ga_concat(gap, (char_u *)"Expected "); 9182 if (exp_str == NULL) 9183 { 9184 ga_concat(gap, tv2string(exp_tv, &tofree, numbuf, 0)); 9185 vim_free(tofree); 9186 } 9187 else 9188 ga_concat(gap, exp_str); 9189 ga_concat(gap, (char_u *)" but got "); 9190 ga_concat(gap, tv2string(got_tv, &tofree, numbuf, 0)); 9191 vim_free(tofree); 9192 } 9193 } 9194 9195 /* 9196 * Add an assert error to v:errors. 9197 */ 9198 static void 9199 assert_error(gap) 9200 garray_T *gap; 9201 { 9202 struct vimvar *vp = &vimvars[VV_ERRORS]; 9203 9204 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) 9205 /* Make sure v:errors is a list. */ 9206 set_vim_var_list(VV_ERRORS, list_alloc()); 9207 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); 9208 } 9209 9210 /* 9211 * "assert_equal(expected, actual[, msg])" function 9212 */ 9213 static void 9214 f_assert_equal(argvars, rettv) 9215 typval_T *argvars; 9216 typval_T *rettv UNUSED; 9217 { 9218 garray_T ga; 9219 9220 if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)) 9221 { 9222 prepare_assert_error(&ga); 9223 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1]); 9224 assert_error(&ga); 9225 ga_clear(&ga); 9226 } 9227 } 9228 9229 /* 9230 * Common for assert_true() and assert_false(). 9231 */ 9232 static void 9233 assert_bool(argvars, isTrue) 9234 typval_T *argvars; 9235 int isTrue; 9236 { 9237 int error = FALSE; 9238 garray_T ga; 9239 9240 if (argvars[0].v_type != VAR_NUMBER 9241 || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue 9242 || error) 9243 { 9244 prepare_assert_error(&ga); 9245 fill_assert_error(&ga, &argvars[1], 9246 (char_u *)(isTrue ? "True " : "False "), 9247 NULL, &argvars[0]); 9248 assert_error(&ga); 9249 ga_clear(&ga); 9250 } 9251 } 9252 9253 /* 9254 * "assert_false(actual[, msg])" function 9255 */ 9256 static void 9257 f_assert_false(argvars, rettv) 9258 typval_T *argvars; 9259 typval_T *rettv UNUSED; 9260 { 9261 assert_bool(argvars, FALSE); 9262 } 9263 9264 /* 9265 * "assert_true(actual[, msg])" function 9266 */ 9267 static void 9268 f_assert_true(argvars, rettv) 9269 typval_T *argvars; 9270 typval_T *rettv UNUSED; 9271 { 9272 assert_bool(argvars, TRUE); 9273 } 9274 9275 #ifdef FEAT_FLOAT 9276 /* 9277 * "asin()" function 9278 */ 9279 static void 9280 f_asin(argvars, rettv) 9281 typval_T *argvars; 9282 typval_T *rettv; 9283 { 9284 float_T f; 9285 9286 rettv->v_type = VAR_FLOAT; 9287 if (get_float_arg(argvars, &f) == OK) 9288 rettv->vval.v_float = asin(f); 9289 else 9290 rettv->vval.v_float = 0.0; 9291 } 9292 9293 /* 9294 * "atan()" function 9295 */ 9296 static void 9297 f_atan(argvars, rettv) 9298 typval_T *argvars; 9299 typval_T *rettv; 9300 { 9301 float_T f; 9302 9303 rettv->v_type = VAR_FLOAT; 9304 if (get_float_arg(argvars, &f) == OK) 9305 rettv->vval.v_float = atan(f); 9306 else 9307 rettv->vval.v_float = 0.0; 9308 } 9309 9310 /* 9311 * "atan2()" function 9312 */ 9313 static void 9314 f_atan2(argvars, rettv) 9315 typval_T *argvars; 9316 typval_T *rettv; 9317 { 9318 float_T fx, fy; 9319 9320 rettv->v_type = VAR_FLOAT; 9321 if (get_float_arg(argvars, &fx) == OK 9322 && get_float_arg(&argvars[1], &fy) == OK) 9323 rettv->vval.v_float = atan2(fx, fy); 9324 else 9325 rettv->vval.v_float = 0.0; 9326 } 9327 #endif 9328 9329 /* 9330 * "browse(save, title, initdir, default)" function 9331 */ 9332 static void 9333 f_browse(argvars, rettv) 9334 typval_T *argvars UNUSED; 9335 typval_T *rettv; 9336 { 9337 #ifdef FEAT_BROWSE 9338 int save; 9339 char_u *title; 9340 char_u *initdir; 9341 char_u *defname; 9342 char_u buf[NUMBUFLEN]; 9343 char_u buf2[NUMBUFLEN]; 9344 int error = FALSE; 9345 9346 save = get_tv_number_chk(&argvars[0], &error); 9347 title = get_tv_string_chk(&argvars[1]); 9348 initdir = get_tv_string_buf_chk(&argvars[2], buf); 9349 defname = get_tv_string_buf_chk(&argvars[3], buf2); 9350 9351 if (error || title == NULL || initdir == NULL || defname == NULL) 9352 rettv->vval.v_string = NULL; 9353 else 9354 rettv->vval.v_string = 9355 do_browse(save ? BROWSE_SAVE : 0, 9356 title, defname, NULL, initdir, NULL, curbuf); 9357 #else 9358 rettv->vval.v_string = NULL; 9359 #endif 9360 rettv->v_type = VAR_STRING; 9361 } 9362 9363 /* 9364 * "browsedir(title, initdir)" function 9365 */ 9366 static void 9367 f_browsedir(argvars, rettv) 9368 typval_T *argvars UNUSED; 9369 typval_T *rettv; 9370 { 9371 #ifdef FEAT_BROWSE 9372 char_u *title; 9373 char_u *initdir; 9374 char_u buf[NUMBUFLEN]; 9375 9376 title = get_tv_string_chk(&argvars[0]); 9377 initdir = get_tv_string_buf_chk(&argvars[1], buf); 9378 9379 if (title == NULL || initdir == NULL) 9380 rettv->vval.v_string = NULL; 9381 else 9382 rettv->vval.v_string = do_browse(BROWSE_DIR, 9383 title, NULL, NULL, initdir, NULL, curbuf); 9384 #else 9385 rettv->vval.v_string = NULL; 9386 #endif 9387 rettv->v_type = VAR_STRING; 9388 } 9389 9390 static buf_T *find_buffer __ARGS((typval_T *avar)); 9391 9392 /* 9393 * Find a buffer by number or exact name. 9394 */ 9395 static buf_T * 9396 find_buffer(avar) 9397 typval_T *avar; 9398 { 9399 buf_T *buf = NULL; 9400 9401 if (avar->v_type == VAR_NUMBER) 9402 buf = buflist_findnr((int)avar->vval.v_number); 9403 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 9404 { 9405 buf = buflist_findname_exp(avar->vval.v_string); 9406 if (buf == NULL) 9407 { 9408 /* No full path name match, try a match with a URL or a "nofile" 9409 * buffer, these don't use the full path. */ 9410 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 9411 if (buf->b_fname != NULL 9412 && (path_with_url(buf->b_fname) 9413 #ifdef FEAT_QUICKFIX 9414 || bt_nofile(buf) 9415 #endif 9416 ) 9417 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 9418 break; 9419 } 9420 } 9421 return buf; 9422 } 9423 9424 /* 9425 * "bufexists(expr)" function 9426 */ 9427 static void 9428 f_bufexists(argvars, rettv) 9429 typval_T *argvars; 9430 typval_T *rettv; 9431 { 9432 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 9433 } 9434 9435 /* 9436 * "buflisted(expr)" function 9437 */ 9438 static void 9439 f_buflisted(argvars, rettv) 9440 typval_T *argvars; 9441 typval_T *rettv; 9442 { 9443 buf_T *buf; 9444 9445 buf = find_buffer(&argvars[0]); 9446 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 9447 } 9448 9449 /* 9450 * "bufloaded(expr)" function 9451 */ 9452 static void 9453 f_bufloaded(argvars, rettv) 9454 typval_T *argvars; 9455 typval_T *rettv; 9456 { 9457 buf_T *buf; 9458 9459 buf = find_buffer(&argvars[0]); 9460 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 9461 } 9462 9463 static buf_T *get_buf_tv __ARGS((typval_T *tv, int curtab_only)); 9464 9465 /* 9466 * Get buffer by number or pattern. 9467 */ 9468 static buf_T * 9469 get_buf_tv(tv, curtab_only) 9470 typval_T *tv; 9471 int curtab_only; 9472 { 9473 char_u *name = tv->vval.v_string; 9474 int save_magic; 9475 char_u *save_cpo; 9476 buf_T *buf; 9477 9478 if (tv->v_type == VAR_NUMBER) 9479 return buflist_findnr((int)tv->vval.v_number); 9480 if (tv->v_type != VAR_STRING) 9481 return NULL; 9482 if (name == NULL || *name == NUL) 9483 return curbuf; 9484 if (name[0] == '$' && name[1] == NUL) 9485 return lastbuf; 9486 9487 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 9488 save_magic = p_magic; 9489 p_magic = TRUE; 9490 save_cpo = p_cpo; 9491 p_cpo = (char_u *)""; 9492 9493 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 9494 TRUE, FALSE, curtab_only)); 9495 9496 p_magic = save_magic; 9497 p_cpo = save_cpo; 9498 9499 /* If not found, try expanding the name, like done for bufexists(). */ 9500 if (buf == NULL) 9501 buf = find_buffer(tv); 9502 9503 return buf; 9504 } 9505 9506 /* 9507 * "bufname(expr)" function 9508 */ 9509 static void 9510 f_bufname(argvars, rettv) 9511 typval_T *argvars; 9512 typval_T *rettv; 9513 { 9514 buf_T *buf; 9515 9516 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9517 ++emsg_off; 9518 buf = get_buf_tv(&argvars[0], FALSE); 9519 rettv->v_type = VAR_STRING; 9520 if (buf != NULL && buf->b_fname != NULL) 9521 rettv->vval.v_string = vim_strsave(buf->b_fname); 9522 else 9523 rettv->vval.v_string = NULL; 9524 --emsg_off; 9525 } 9526 9527 /* 9528 * "bufnr(expr)" function 9529 */ 9530 static void 9531 f_bufnr(argvars, rettv) 9532 typval_T *argvars; 9533 typval_T *rettv; 9534 { 9535 buf_T *buf; 9536 int error = FALSE; 9537 char_u *name; 9538 9539 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9540 ++emsg_off; 9541 buf = get_buf_tv(&argvars[0], FALSE); 9542 --emsg_off; 9543 9544 /* If the buffer isn't found and the second argument is not zero create a 9545 * new buffer. */ 9546 if (buf == NULL 9547 && argvars[1].v_type != VAR_UNKNOWN 9548 && get_tv_number_chk(&argvars[1], &error) != 0 9549 && !error 9550 && (name = get_tv_string_chk(&argvars[0])) != NULL 9551 && !error) 9552 buf = buflist_new(name, NULL, (linenr_T)1, 0); 9553 9554 if (buf != NULL) 9555 rettv->vval.v_number = buf->b_fnum; 9556 else 9557 rettv->vval.v_number = -1; 9558 } 9559 9560 /* 9561 * "bufwinnr(nr)" function 9562 */ 9563 static void 9564 f_bufwinnr(argvars, rettv) 9565 typval_T *argvars; 9566 typval_T *rettv; 9567 { 9568 #ifdef FEAT_WINDOWS 9569 win_T *wp; 9570 int winnr = 0; 9571 #endif 9572 buf_T *buf; 9573 9574 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9575 ++emsg_off; 9576 buf = get_buf_tv(&argvars[0], TRUE); 9577 #ifdef FEAT_WINDOWS 9578 for (wp = firstwin; wp; wp = wp->w_next) 9579 { 9580 ++winnr; 9581 if (wp->w_buffer == buf) 9582 break; 9583 } 9584 rettv->vval.v_number = (wp != NULL ? winnr : -1); 9585 #else 9586 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 9587 #endif 9588 --emsg_off; 9589 } 9590 9591 /* 9592 * "byte2line(byte)" function 9593 */ 9594 static void 9595 f_byte2line(argvars, rettv) 9596 typval_T *argvars UNUSED; 9597 typval_T *rettv; 9598 { 9599 #ifndef FEAT_BYTEOFF 9600 rettv->vval.v_number = -1; 9601 #else 9602 long boff = 0; 9603 9604 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 9605 if (boff < 0) 9606 rettv->vval.v_number = -1; 9607 else 9608 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 9609 (linenr_T)0, &boff); 9610 #endif 9611 } 9612 9613 static void 9614 byteidx(argvars, rettv, comp) 9615 typval_T *argvars; 9616 typval_T *rettv; 9617 int comp UNUSED; 9618 { 9619 #ifdef FEAT_MBYTE 9620 char_u *t; 9621 #endif 9622 char_u *str; 9623 long idx; 9624 9625 str = get_tv_string_chk(&argvars[0]); 9626 idx = get_tv_number_chk(&argvars[1], NULL); 9627 rettv->vval.v_number = -1; 9628 if (str == NULL || idx < 0) 9629 return; 9630 9631 #ifdef FEAT_MBYTE 9632 t = str; 9633 for ( ; idx > 0; idx--) 9634 { 9635 if (*t == NUL) /* EOL reached */ 9636 return; 9637 if (enc_utf8 && comp) 9638 t += utf_ptr2len(t); 9639 else 9640 t += (*mb_ptr2len)(t); 9641 } 9642 rettv->vval.v_number = (varnumber_T)(t - str); 9643 #else 9644 if ((size_t)idx <= STRLEN(str)) 9645 rettv->vval.v_number = idx; 9646 #endif 9647 } 9648 9649 /* 9650 * "byteidx()" function 9651 */ 9652 static void 9653 f_byteidx(argvars, rettv) 9654 typval_T *argvars; 9655 typval_T *rettv; 9656 { 9657 byteidx(argvars, rettv, FALSE); 9658 } 9659 9660 /* 9661 * "byteidxcomp()" function 9662 */ 9663 static void 9664 f_byteidxcomp(argvars, rettv) 9665 typval_T *argvars; 9666 typval_T *rettv; 9667 { 9668 byteidx(argvars, rettv, TRUE); 9669 } 9670 9671 int 9672 func_call(name, args, selfdict, rettv) 9673 char_u *name; 9674 typval_T *args; 9675 dict_T *selfdict; 9676 typval_T *rettv; 9677 { 9678 listitem_T *item; 9679 typval_T argv[MAX_FUNC_ARGS + 1]; 9680 int argc = 0; 9681 int dummy; 9682 int r = 0; 9683 9684 for (item = args->vval.v_list->lv_first; item != NULL; 9685 item = item->li_next) 9686 { 9687 if (argc == MAX_FUNC_ARGS) 9688 { 9689 EMSG(_("E699: Too many arguments")); 9690 break; 9691 } 9692 /* Make a copy of each argument. This is needed to be able to set 9693 * v_lock to VAR_FIXED in the copy without changing the original list. 9694 */ 9695 copy_tv(&item->li_tv, &argv[argc++]); 9696 } 9697 9698 if (item == NULL) 9699 r = call_func(name, (int)STRLEN(name), rettv, argc, argv, 9700 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 9701 &dummy, TRUE, selfdict); 9702 9703 /* Free the arguments. */ 9704 while (argc > 0) 9705 clear_tv(&argv[--argc]); 9706 9707 return r; 9708 } 9709 9710 /* 9711 * "call(func, arglist)" function 9712 */ 9713 static void 9714 f_call(argvars, rettv) 9715 typval_T *argvars; 9716 typval_T *rettv; 9717 { 9718 char_u *func; 9719 dict_T *selfdict = NULL; 9720 9721 if (argvars[1].v_type != VAR_LIST) 9722 { 9723 EMSG(_(e_listreq)); 9724 return; 9725 } 9726 if (argvars[1].vval.v_list == NULL) 9727 return; 9728 9729 if (argvars[0].v_type == VAR_FUNC) 9730 func = argvars[0].vval.v_string; 9731 else 9732 func = get_tv_string(&argvars[0]); 9733 if (*func == NUL) 9734 return; /* type error or empty name */ 9735 9736 if (argvars[2].v_type != VAR_UNKNOWN) 9737 { 9738 if (argvars[2].v_type != VAR_DICT) 9739 { 9740 EMSG(_(e_dictreq)); 9741 return; 9742 } 9743 selfdict = argvars[2].vval.v_dict; 9744 } 9745 9746 (void)func_call(func, &argvars[1], selfdict, rettv); 9747 } 9748 9749 #ifdef FEAT_FLOAT 9750 /* 9751 * "ceil({float})" function 9752 */ 9753 static void 9754 f_ceil(argvars, rettv) 9755 typval_T *argvars; 9756 typval_T *rettv; 9757 { 9758 float_T f; 9759 9760 rettv->v_type = VAR_FLOAT; 9761 if (get_float_arg(argvars, &f) == OK) 9762 rettv->vval.v_float = ceil(f); 9763 else 9764 rettv->vval.v_float = 0.0; 9765 } 9766 #endif 9767 9768 /* 9769 * "changenr()" function 9770 */ 9771 static void 9772 f_changenr(argvars, rettv) 9773 typval_T *argvars UNUSED; 9774 typval_T *rettv; 9775 { 9776 rettv->vval.v_number = curbuf->b_u_seq_cur; 9777 } 9778 9779 /* 9780 * "char2nr(string)" function 9781 */ 9782 static void 9783 f_char2nr(argvars, rettv) 9784 typval_T *argvars; 9785 typval_T *rettv; 9786 { 9787 #ifdef FEAT_MBYTE 9788 if (has_mbyte) 9789 { 9790 int utf8 = 0; 9791 9792 if (argvars[1].v_type != VAR_UNKNOWN) 9793 utf8 = get_tv_number_chk(&argvars[1], NULL); 9794 9795 if (utf8) 9796 rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0])); 9797 else 9798 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 9799 } 9800 else 9801 #endif 9802 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 9803 } 9804 9805 /* 9806 * "cindent(lnum)" function 9807 */ 9808 static void 9809 f_cindent(argvars, rettv) 9810 typval_T *argvars UNUSED; 9811 typval_T *rettv; 9812 { 9813 #ifdef FEAT_CINDENT 9814 pos_T pos; 9815 linenr_T lnum; 9816 9817 pos = curwin->w_cursor; 9818 lnum = get_tv_lnum(argvars); 9819 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9820 { 9821 curwin->w_cursor.lnum = lnum; 9822 rettv->vval.v_number = get_c_indent(); 9823 curwin->w_cursor = pos; 9824 } 9825 else 9826 #endif 9827 rettv->vval.v_number = -1; 9828 } 9829 9830 /* 9831 * "clearmatches()" function 9832 */ 9833 static void 9834 f_clearmatches(argvars, rettv) 9835 typval_T *argvars UNUSED; 9836 typval_T *rettv UNUSED; 9837 { 9838 #ifdef FEAT_SEARCH_EXTRA 9839 clear_matches(curwin); 9840 #endif 9841 } 9842 9843 /* 9844 * "col(string)" function 9845 */ 9846 static void 9847 f_col(argvars, rettv) 9848 typval_T *argvars; 9849 typval_T *rettv; 9850 { 9851 colnr_T col = 0; 9852 pos_T *fp; 9853 int fnum = curbuf->b_fnum; 9854 9855 fp = var2fpos(&argvars[0], FALSE, &fnum); 9856 if (fp != NULL && fnum == curbuf->b_fnum) 9857 { 9858 if (fp->col == MAXCOL) 9859 { 9860 /* '> can be MAXCOL, get the length of the line then */ 9861 if (fp->lnum <= curbuf->b_ml.ml_line_count) 9862 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 9863 else 9864 col = MAXCOL; 9865 } 9866 else 9867 { 9868 col = fp->col + 1; 9869 #ifdef FEAT_VIRTUALEDIT 9870 /* col(".") when the cursor is on the NUL at the end of the line 9871 * because of "coladd" can be seen as an extra column. */ 9872 if (virtual_active() && fp == &curwin->w_cursor) 9873 { 9874 char_u *p = ml_get_cursor(); 9875 9876 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 9877 curwin->w_virtcol - curwin->w_cursor.coladd)) 9878 { 9879 # ifdef FEAT_MBYTE 9880 int l; 9881 9882 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 9883 col += l; 9884 # else 9885 if (*p != NUL && p[1] == NUL) 9886 ++col; 9887 # endif 9888 } 9889 } 9890 #endif 9891 } 9892 } 9893 rettv->vval.v_number = col; 9894 } 9895 9896 #if defined(FEAT_INS_EXPAND) 9897 /* 9898 * "complete()" function 9899 */ 9900 static void 9901 f_complete(argvars, rettv) 9902 typval_T *argvars; 9903 typval_T *rettv UNUSED; 9904 { 9905 int startcol; 9906 9907 if ((State & INSERT) == 0) 9908 { 9909 EMSG(_("E785: complete() can only be used in Insert mode")); 9910 return; 9911 } 9912 9913 /* Check for undo allowed here, because if something was already inserted 9914 * the line was already saved for undo and this check isn't done. */ 9915 if (!undo_allowed()) 9916 return; 9917 9918 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 9919 { 9920 EMSG(_(e_invarg)); 9921 return; 9922 } 9923 9924 startcol = get_tv_number_chk(&argvars[0], NULL); 9925 if (startcol <= 0) 9926 return; 9927 9928 set_completion(startcol - 1, argvars[1].vval.v_list); 9929 } 9930 9931 /* 9932 * "complete_add()" function 9933 */ 9934 static void 9935 f_complete_add(argvars, rettv) 9936 typval_T *argvars; 9937 typval_T *rettv; 9938 { 9939 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 9940 } 9941 9942 /* 9943 * "complete_check()" function 9944 */ 9945 static void 9946 f_complete_check(argvars, rettv) 9947 typval_T *argvars UNUSED; 9948 typval_T *rettv; 9949 { 9950 int saved = RedrawingDisabled; 9951 9952 RedrawingDisabled = 0; 9953 ins_compl_check_keys(0); 9954 rettv->vval.v_number = compl_interrupted; 9955 RedrawingDisabled = saved; 9956 } 9957 #endif 9958 9959 /* 9960 * "confirm(message, buttons[, default [, type]])" function 9961 */ 9962 static void 9963 f_confirm(argvars, rettv) 9964 typval_T *argvars UNUSED; 9965 typval_T *rettv UNUSED; 9966 { 9967 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 9968 char_u *message; 9969 char_u *buttons = NULL; 9970 char_u buf[NUMBUFLEN]; 9971 char_u buf2[NUMBUFLEN]; 9972 int def = 1; 9973 int type = VIM_GENERIC; 9974 char_u *typestr; 9975 int error = FALSE; 9976 9977 message = get_tv_string_chk(&argvars[0]); 9978 if (message == NULL) 9979 error = TRUE; 9980 if (argvars[1].v_type != VAR_UNKNOWN) 9981 { 9982 buttons = get_tv_string_buf_chk(&argvars[1], buf); 9983 if (buttons == NULL) 9984 error = TRUE; 9985 if (argvars[2].v_type != VAR_UNKNOWN) 9986 { 9987 def = get_tv_number_chk(&argvars[2], &error); 9988 if (argvars[3].v_type != VAR_UNKNOWN) 9989 { 9990 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 9991 if (typestr == NULL) 9992 error = TRUE; 9993 else 9994 { 9995 switch (TOUPPER_ASC(*typestr)) 9996 { 9997 case 'E': type = VIM_ERROR; break; 9998 case 'Q': type = VIM_QUESTION; break; 9999 case 'I': type = VIM_INFO; break; 10000 case 'W': type = VIM_WARNING; break; 10001 case 'G': type = VIM_GENERIC; break; 10002 } 10003 } 10004 } 10005 } 10006 } 10007 10008 if (buttons == NULL || *buttons == NUL) 10009 buttons = (char_u *)_("&Ok"); 10010 10011 if (!error) 10012 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 10013 def, NULL, FALSE); 10014 #endif 10015 } 10016 10017 /* 10018 * "copy()" function 10019 */ 10020 static void 10021 f_copy(argvars, rettv) 10022 typval_T *argvars; 10023 typval_T *rettv; 10024 { 10025 item_copy(&argvars[0], rettv, FALSE, 0); 10026 } 10027 10028 #ifdef FEAT_FLOAT 10029 /* 10030 * "cos()" function 10031 */ 10032 static void 10033 f_cos(argvars, rettv) 10034 typval_T *argvars; 10035 typval_T *rettv; 10036 { 10037 float_T f; 10038 10039 rettv->v_type = VAR_FLOAT; 10040 if (get_float_arg(argvars, &f) == OK) 10041 rettv->vval.v_float = cos(f); 10042 else 10043 rettv->vval.v_float = 0.0; 10044 } 10045 10046 /* 10047 * "cosh()" function 10048 */ 10049 static void 10050 f_cosh(argvars, rettv) 10051 typval_T *argvars; 10052 typval_T *rettv; 10053 { 10054 float_T f; 10055 10056 rettv->v_type = VAR_FLOAT; 10057 if (get_float_arg(argvars, &f) == OK) 10058 rettv->vval.v_float = cosh(f); 10059 else 10060 rettv->vval.v_float = 0.0; 10061 } 10062 #endif 10063 10064 /* 10065 * "count()" function 10066 */ 10067 static void 10068 f_count(argvars, rettv) 10069 typval_T *argvars; 10070 typval_T *rettv; 10071 { 10072 long n = 0; 10073 int ic = FALSE; 10074 10075 if (argvars[0].v_type == VAR_LIST) 10076 { 10077 listitem_T *li; 10078 list_T *l; 10079 long idx; 10080 10081 if ((l = argvars[0].vval.v_list) != NULL) 10082 { 10083 li = l->lv_first; 10084 if (argvars[2].v_type != VAR_UNKNOWN) 10085 { 10086 int error = FALSE; 10087 10088 ic = get_tv_number_chk(&argvars[2], &error); 10089 if (argvars[3].v_type != VAR_UNKNOWN) 10090 { 10091 idx = get_tv_number_chk(&argvars[3], &error); 10092 if (!error) 10093 { 10094 li = list_find(l, idx); 10095 if (li == NULL) 10096 EMSGN(_(e_listidx), idx); 10097 } 10098 } 10099 if (error) 10100 li = NULL; 10101 } 10102 10103 for ( ; li != NULL; li = li->li_next) 10104 if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE)) 10105 ++n; 10106 } 10107 } 10108 else if (argvars[0].v_type == VAR_DICT) 10109 { 10110 int todo; 10111 dict_T *d; 10112 hashitem_T *hi; 10113 10114 if ((d = argvars[0].vval.v_dict) != NULL) 10115 { 10116 int error = FALSE; 10117 10118 if (argvars[2].v_type != VAR_UNKNOWN) 10119 { 10120 ic = get_tv_number_chk(&argvars[2], &error); 10121 if (argvars[3].v_type != VAR_UNKNOWN) 10122 EMSG(_(e_invarg)); 10123 } 10124 10125 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 10126 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 10127 { 10128 if (!HASHITEM_EMPTY(hi)) 10129 { 10130 --todo; 10131 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE)) 10132 ++n; 10133 } 10134 } 10135 } 10136 } 10137 else 10138 EMSG2(_(e_listdictarg), "count()"); 10139 rettv->vval.v_number = n; 10140 } 10141 10142 /* 10143 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 10144 * 10145 * Checks the existence of a cscope connection. 10146 */ 10147 static void 10148 f_cscope_connection(argvars, rettv) 10149 typval_T *argvars UNUSED; 10150 typval_T *rettv UNUSED; 10151 { 10152 #ifdef FEAT_CSCOPE 10153 int num = 0; 10154 char_u *dbpath = NULL; 10155 char_u *prepend = NULL; 10156 char_u buf[NUMBUFLEN]; 10157 10158 if (argvars[0].v_type != VAR_UNKNOWN 10159 && argvars[1].v_type != VAR_UNKNOWN) 10160 { 10161 num = (int)get_tv_number(&argvars[0]); 10162 dbpath = get_tv_string(&argvars[1]); 10163 if (argvars[2].v_type != VAR_UNKNOWN) 10164 prepend = get_tv_string_buf(&argvars[2], buf); 10165 } 10166 10167 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 10168 #endif 10169 } 10170 10171 /* 10172 * "cursor(lnum, col)" function 10173 * 10174 * Moves the cursor to the specified line and column. 10175 * Returns 0 when the position could be set, -1 otherwise. 10176 */ 10177 static void 10178 f_cursor(argvars, rettv) 10179 typval_T *argvars; 10180 typval_T *rettv; 10181 { 10182 long line, col; 10183 #ifdef FEAT_VIRTUALEDIT 10184 long coladd = 0; 10185 #endif 10186 int set_curswant = TRUE; 10187 10188 rettv->vval.v_number = -1; 10189 if (argvars[1].v_type == VAR_UNKNOWN) 10190 { 10191 pos_T pos; 10192 colnr_T curswant = -1; 10193 10194 if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL) 10195 return; 10196 line = pos.lnum; 10197 col = pos.col; 10198 #ifdef FEAT_VIRTUALEDIT 10199 coladd = pos.coladd; 10200 #endif 10201 if (curswant >= 0) 10202 { 10203 curwin->w_curswant = curswant - 1; 10204 set_curswant = FALSE; 10205 } 10206 } 10207 else 10208 { 10209 line = get_tv_lnum(argvars); 10210 col = get_tv_number_chk(&argvars[1], NULL); 10211 #ifdef FEAT_VIRTUALEDIT 10212 if (argvars[2].v_type != VAR_UNKNOWN) 10213 coladd = get_tv_number_chk(&argvars[2], NULL); 10214 #endif 10215 } 10216 if (line < 0 || col < 0 10217 #ifdef FEAT_VIRTUALEDIT 10218 || coladd < 0 10219 #endif 10220 ) 10221 return; /* type error; errmsg already given */ 10222 if (line > 0) 10223 curwin->w_cursor.lnum = line; 10224 if (col > 0) 10225 curwin->w_cursor.col = col - 1; 10226 #ifdef FEAT_VIRTUALEDIT 10227 curwin->w_cursor.coladd = coladd; 10228 #endif 10229 10230 /* Make sure the cursor is in a valid position. */ 10231 check_cursor(); 10232 #ifdef FEAT_MBYTE 10233 /* Correct cursor for multi-byte character. */ 10234 if (has_mbyte) 10235 mb_adjust_cursor(); 10236 #endif 10237 10238 curwin->w_set_curswant = set_curswant; 10239 rettv->vval.v_number = 0; 10240 } 10241 10242 /* 10243 * "deepcopy()" function 10244 */ 10245 static void 10246 f_deepcopy(argvars, rettv) 10247 typval_T *argvars; 10248 typval_T *rettv; 10249 { 10250 int noref = 0; 10251 10252 if (argvars[1].v_type != VAR_UNKNOWN) 10253 noref = get_tv_number_chk(&argvars[1], NULL); 10254 if (noref < 0 || noref > 1) 10255 EMSG(_(e_invarg)); 10256 else 10257 { 10258 current_copyID += COPYID_INC; 10259 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 10260 } 10261 } 10262 10263 /* 10264 * "delete()" function 10265 */ 10266 static void 10267 f_delete(argvars, rettv) 10268 typval_T *argvars; 10269 typval_T *rettv; 10270 { 10271 if (check_restricted() || check_secure()) 10272 rettv->vval.v_number = -1; 10273 else 10274 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 10275 } 10276 10277 /* 10278 * "did_filetype()" function 10279 */ 10280 static void 10281 f_did_filetype(argvars, rettv) 10282 typval_T *argvars UNUSED; 10283 typval_T *rettv UNUSED; 10284 { 10285 #ifdef FEAT_AUTOCMD 10286 rettv->vval.v_number = did_filetype; 10287 #endif 10288 } 10289 10290 /* 10291 * "diff_filler()" function 10292 */ 10293 static void 10294 f_diff_filler(argvars, rettv) 10295 typval_T *argvars UNUSED; 10296 typval_T *rettv UNUSED; 10297 { 10298 #ifdef FEAT_DIFF 10299 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 10300 #endif 10301 } 10302 10303 /* 10304 * "diff_hlID()" function 10305 */ 10306 static void 10307 f_diff_hlID(argvars, rettv) 10308 typval_T *argvars UNUSED; 10309 typval_T *rettv UNUSED; 10310 { 10311 #ifdef FEAT_DIFF 10312 linenr_T lnum = get_tv_lnum(argvars); 10313 static linenr_T prev_lnum = 0; 10314 static int changedtick = 0; 10315 static int fnum = 0; 10316 static int change_start = 0; 10317 static int change_end = 0; 10318 static hlf_T hlID = (hlf_T)0; 10319 int filler_lines; 10320 int col; 10321 10322 if (lnum < 0) /* ignore type error in {lnum} arg */ 10323 lnum = 0; 10324 if (lnum != prev_lnum 10325 || changedtick != curbuf->b_changedtick 10326 || fnum != curbuf->b_fnum) 10327 { 10328 /* New line, buffer, change: need to get the values. */ 10329 filler_lines = diff_check(curwin, lnum); 10330 if (filler_lines < 0) 10331 { 10332 if (filler_lines == -1) 10333 { 10334 change_start = MAXCOL; 10335 change_end = -1; 10336 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 10337 hlID = HLF_ADD; /* added line */ 10338 else 10339 hlID = HLF_CHD; /* changed line */ 10340 } 10341 else 10342 hlID = HLF_ADD; /* added line */ 10343 } 10344 else 10345 hlID = (hlf_T)0; 10346 prev_lnum = lnum; 10347 changedtick = curbuf->b_changedtick; 10348 fnum = curbuf->b_fnum; 10349 } 10350 10351 if (hlID == HLF_CHD || hlID == HLF_TXD) 10352 { 10353 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 10354 if (col >= change_start && col <= change_end) 10355 hlID = HLF_TXD; /* changed text */ 10356 else 10357 hlID = HLF_CHD; /* changed line */ 10358 } 10359 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 10360 #endif 10361 } 10362 10363 /* 10364 * "empty({expr})" function 10365 */ 10366 static void 10367 f_empty(argvars, rettv) 10368 typval_T *argvars; 10369 typval_T *rettv; 10370 { 10371 int n; 10372 10373 switch (argvars[0].v_type) 10374 { 10375 case VAR_STRING: 10376 case VAR_FUNC: 10377 n = argvars[0].vval.v_string == NULL 10378 || *argvars[0].vval.v_string == NUL; 10379 break; 10380 case VAR_NUMBER: 10381 n = argvars[0].vval.v_number == 0; 10382 break; 10383 #ifdef FEAT_FLOAT 10384 case VAR_FLOAT: 10385 n = argvars[0].vval.v_float == 0.0; 10386 break; 10387 #endif 10388 case VAR_LIST: 10389 n = argvars[0].vval.v_list == NULL 10390 || argvars[0].vval.v_list->lv_first == NULL; 10391 break; 10392 case VAR_DICT: 10393 n = argvars[0].vval.v_dict == NULL 10394 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 10395 break; 10396 default: 10397 EMSG2(_(e_intern2), "f_empty()"); 10398 n = 0; 10399 } 10400 10401 rettv->vval.v_number = n; 10402 } 10403 10404 /* 10405 * "escape({string}, {chars})" function 10406 */ 10407 static void 10408 f_escape(argvars, rettv) 10409 typval_T *argvars; 10410 typval_T *rettv; 10411 { 10412 char_u buf[NUMBUFLEN]; 10413 10414 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 10415 get_tv_string_buf(&argvars[1], buf)); 10416 rettv->v_type = VAR_STRING; 10417 } 10418 10419 /* 10420 * "eval()" function 10421 */ 10422 static void 10423 f_eval(argvars, rettv) 10424 typval_T *argvars; 10425 typval_T *rettv; 10426 { 10427 char_u *s, *p; 10428 10429 s = get_tv_string_chk(&argvars[0]); 10430 if (s != NULL) 10431 s = skipwhite(s); 10432 10433 p = s; 10434 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 10435 { 10436 if (p != NULL && !aborting()) 10437 EMSG2(_(e_invexpr2), p); 10438 need_clr_eos = FALSE; 10439 rettv->v_type = VAR_NUMBER; 10440 rettv->vval.v_number = 0; 10441 } 10442 else if (*s != NUL) 10443 EMSG(_(e_trailing)); 10444 } 10445 10446 /* 10447 * "eventhandler()" function 10448 */ 10449 static void 10450 f_eventhandler(argvars, rettv) 10451 typval_T *argvars UNUSED; 10452 typval_T *rettv; 10453 { 10454 rettv->vval.v_number = vgetc_busy; 10455 } 10456 10457 /* 10458 * "executable()" function 10459 */ 10460 static void 10461 f_executable(argvars, rettv) 10462 typval_T *argvars; 10463 typval_T *rettv; 10464 { 10465 char_u *name = get_tv_string(&argvars[0]); 10466 10467 /* Check in $PATH and also check directly if there is a directory name. */ 10468 rettv->vval.v_number = mch_can_exe(name, NULL, TRUE) 10469 || (gettail(name) != name && mch_can_exe(name, NULL, FALSE)); 10470 } 10471 10472 /* 10473 * "exepath()" function 10474 */ 10475 static void 10476 f_exepath(argvars, rettv) 10477 typval_T *argvars; 10478 typval_T *rettv; 10479 { 10480 char_u *p = NULL; 10481 10482 (void)mch_can_exe(get_tv_string(&argvars[0]), &p, TRUE); 10483 rettv->v_type = VAR_STRING; 10484 rettv->vval.v_string = p; 10485 } 10486 10487 /* 10488 * "exists()" function 10489 */ 10490 static void 10491 f_exists(argvars, rettv) 10492 typval_T *argvars; 10493 typval_T *rettv; 10494 { 10495 char_u *p; 10496 char_u *name; 10497 int n = FALSE; 10498 int len = 0; 10499 10500 p = get_tv_string(&argvars[0]); 10501 if (*p == '$') /* environment variable */ 10502 { 10503 /* first try "normal" environment variables (fast) */ 10504 if (mch_getenv(p + 1) != NULL) 10505 n = TRUE; 10506 else 10507 { 10508 /* try expanding things like $VIM and ${HOME} */ 10509 p = expand_env_save(p); 10510 if (p != NULL && *p != '$') 10511 n = TRUE; 10512 vim_free(p); 10513 } 10514 } 10515 else if (*p == '&' || *p == '+') /* option */ 10516 { 10517 n = (get_option_tv(&p, NULL, TRUE) == OK); 10518 if (*skipwhite(p) != NUL) 10519 n = FALSE; /* trailing garbage */ 10520 } 10521 else if (*p == '*') /* internal or user defined function */ 10522 { 10523 n = function_exists(p + 1); 10524 } 10525 else if (*p == ':') 10526 { 10527 n = cmd_exists(p + 1); 10528 } 10529 else if (*p == '#') 10530 { 10531 #ifdef FEAT_AUTOCMD 10532 if (p[1] == '#') 10533 n = autocmd_supported(p + 2); 10534 else 10535 n = au_exists(p + 1); 10536 #endif 10537 } 10538 else /* internal variable */ 10539 { 10540 char_u *tofree; 10541 typval_T tv; 10542 10543 /* get_name_len() takes care of expanding curly braces */ 10544 name = p; 10545 len = get_name_len(&p, &tofree, TRUE, FALSE); 10546 if (len > 0) 10547 { 10548 if (tofree != NULL) 10549 name = tofree; 10550 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK); 10551 if (n) 10552 { 10553 /* handle d.key, l[idx], f(expr) */ 10554 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 10555 if (n) 10556 clear_tv(&tv); 10557 } 10558 } 10559 if (*p != NUL) 10560 n = FALSE; 10561 10562 vim_free(tofree); 10563 } 10564 10565 rettv->vval.v_number = n; 10566 } 10567 10568 #ifdef FEAT_FLOAT 10569 /* 10570 * "exp()" function 10571 */ 10572 static void 10573 f_exp(argvars, rettv) 10574 typval_T *argvars; 10575 typval_T *rettv; 10576 { 10577 float_T f; 10578 10579 rettv->v_type = VAR_FLOAT; 10580 if (get_float_arg(argvars, &f) == OK) 10581 rettv->vval.v_float = exp(f); 10582 else 10583 rettv->vval.v_float = 0.0; 10584 } 10585 #endif 10586 10587 /* 10588 * "expand()" function 10589 */ 10590 static void 10591 f_expand(argvars, rettv) 10592 typval_T *argvars; 10593 typval_T *rettv; 10594 { 10595 char_u *s; 10596 int len; 10597 char_u *errormsg; 10598 int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 10599 expand_T xpc; 10600 int error = FALSE; 10601 char_u *result; 10602 10603 rettv->v_type = VAR_STRING; 10604 if (argvars[1].v_type != VAR_UNKNOWN 10605 && argvars[2].v_type != VAR_UNKNOWN 10606 && get_tv_number_chk(&argvars[2], &error) 10607 && !error) 10608 { 10609 rettv->v_type = VAR_LIST; 10610 rettv->vval.v_list = NULL; 10611 } 10612 10613 s = get_tv_string(&argvars[0]); 10614 if (*s == '%' || *s == '#' || *s == '<') 10615 { 10616 ++emsg_off; 10617 result = eval_vars(s, s, &len, NULL, &errormsg, NULL); 10618 --emsg_off; 10619 if (rettv->v_type == VAR_LIST) 10620 { 10621 if (rettv_list_alloc(rettv) != FAIL && result != NULL) 10622 list_append_string(rettv->vval.v_list, result, -1); 10623 else 10624 vim_free(result); 10625 } 10626 else 10627 rettv->vval.v_string = result; 10628 } 10629 else 10630 { 10631 /* When the optional second argument is non-zero, don't remove matches 10632 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 10633 if (argvars[1].v_type != VAR_UNKNOWN 10634 && get_tv_number_chk(&argvars[1], &error)) 10635 options |= WILD_KEEP_ALL; 10636 if (!error) 10637 { 10638 ExpandInit(&xpc); 10639 xpc.xp_context = EXPAND_FILES; 10640 if (p_wic) 10641 options += WILD_ICASE; 10642 if (rettv->v_type == VAR_STRING) 10643 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, 10644 options, WILD_ALL); 10645 else if (rettv_list_alloc(rettv) != FAIL) 10646 { 10647 int i; 10648 10649 ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP); 10650 for (i = 0; i < xpc.xp_numfiles; i++) 10651 list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); 10652 ExpandCleanup(&xpc); 10653 } 10654 } 10655 else 10656 rettv->vval.v_string = NULL; 10657 } 10658 } 10659 10660 /* 10661 * Go over all entries in "d2" and add them to "d1". 10662 * When "action" is "error" then a duplicate key is an error. 10663 * When "action" is "force" then a duplicate key is overwritten. 10664 * Otherwise duplicate keys are ignored ("action" is "keep"). 10665 */ 10666 void 10667 dict_extend(d1, d2, action) 10668 dict_T *d1; 10669 dict_T *d2; 10670 char_u *action; 10671 { 10672 dictitem_T *di1; 10673 hashitem_T *hi2; 10674 int todo; 10675 char_u *arg_errmsg = (char_u *)N_("extend() argument"); 10676 10677 todo = (int)d2->dv_hashtab.ht_used; 10678 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 10679 { 10680 if (!HASHITEM_EMPTY(hi2)) 10681 { 10682 --todo; 10683 di1 = dict_find(d1, hi2->hi_key, -1); 10684 if (d1->dv_scope != 0) 10685 { 10686 /* Disallow replacing a builtin function in l: and g:. 10687 * Check the key to be valid when adding to any 10688 * scope. */ 10689 if (d1->dv_scope == VAR_DEF_SCOPE 10690 && HI2DI(hi2)->di_tv.v_type == VAR_FUNC 10691 && var_check_func_name(hi2->hi_key, 10692 di1 == NULL)) 10693 break; 10694 if (!valid_varname(hi2->hi_key)) 10695 break; 10696 } 10697 if (di1 == NULL) 10698 { 10699 di1 = dictitem_copy(HI2DI(hi2)); 10700 if (di1 != NULL && dict_add(d1, di1) == FAIL) 10701 dictitem_free(di1); 10702 } 10703 else if (*action == 'e') 10704 { 10705 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 10706 break; 10707 } 10708 else if (*action == 'f' && HI2DI(hi2) != di1) 10709 { 10710 if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE) 10711 || var_check_ro(di1->di_flags, arg_errmsg, TRUE)) 10712 break; 10713 clear_tv(&di1->di_tv); 10714 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 10715 } 10716 } 10717 } 10718 } 10719 10720 /* 10721 * "extend(list, list [, idx])" function 10722 * "extend(dict, dict [, action])" function 10723 */ 10724 static void 10725 f_extend(argvars, rettv) 10726 typval_T *argvars; 10727 typval_T *rettv; 10728 { 10729 char_u *arg_errmsg = (char_u *)N_("extend() argument"); 10730 10731 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 10732 { 10733 list_T *l1, *l2; 10734 listitem_T *item; 10735 long before; 10736 int error = FALSE; 10737 10738 l1 = argvars[0].vval.v_list; 10739 l2 = argvars[1].vval.v_list; 10740 if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, TRUE) 10741 && l2 != NULL) 10742 { 10743 if (argvars[2].v_type != VAR_UNKNOWN) 10744 { 10745 before = get_tv_number_chk(&argvars[2], &error); 10746 if (error) 10747 return; /* type error; errmsg already given */ 10748 10749 if (before == l1->lv_len) 10750 item = NULL; 10751 else 10752 { 10753 item = list_find(l1, before); 10754 if (item == NULL) 10755 { 10756 EMSGN(_(e_listidx), before); 10757 return; 10758 } 10759 } 10760 } 10761 else 10762 item = NULL; 10763 list_extend(l1, l2, item); 10764 10765 copy_tv(&argvars[0], rettv); 10766 } 10767 } 10768 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 10769 { 10770 dict_T *d1, *d2; 10771 char_u *action; 10772 int i; 10773 10774 d1 = argvars[0].vval.v_dict; 10775 d2 = argvars[1].vval.v_dict; 10776 if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE) 10777 && d2 != NULL) 10778 { 10779 /* Check the third argument. */ 10780 if (argvars[2].v_type != VAR_UNKNOWN) 10781 { 10782 static char *(av[]) = {"keep", "force", "error"}; 10783 10784 action = get_tv_string_chk(&argvars[2]); 10785 if (action == NULL) 10786 return; /* type error; errmsg already given */ 10787 for (i = 0; i < 3; ++i) 10788 if (STRCMP(action, av[i]) == 0) 10789 break; 10790 if (i == 3) 10791 { 10792 EMSG2(_(e_invarg2), action); 10793 return; 10794 } 10795 } 10796 else 10797 action = (char_u *)"force"; 10798 10799 dict_extend(d1, d2, action); 10800 10801 copy_tv(&argvars[0], rettv); 10802 } 10803 } 10804 else 10805 EMSG2(_(e_listdictarg), "extend()"); 10806 } 10807 10808 /* 10809 * "feedkeys()" function 10810 */ 10811 static void 10812 f_feedkeys(argvars, rettv) 10813 typval_T *argvars; 10814 typval_T *rettv UNUSED; 10815 { 10816 int remap = TRUE; 10817 int insert = FALSE; 10818 char_u *keys, *flags; 10819 char_u nbuf[NUMBUFLEN]; 10820 int typed = FALSE; 10821 char_u *keys_esc; 10822 10823 /* This is not allowed in the sandbox. If the commands would still be 10824 * executed in the sandbox it would be OK, but it probably happens later, 10825 * when "sandbox" is no longer set. */ 10826 if (check_secure()) 10827 return; 10828 10829 keys = get_tv_string(&argvars[0]); 10830 if (*keys != NUL) 10831 { 10832 if (argvars[1].v_type != VAR_UNKNOWN) 10833 { 10834 flags = get_tv_string_buf(&argvars[1], nbuf); 10835 for ( ; *flags != NUL; ++flags) 10836 { 10837 switch (*flags) 10838 { 10839 case 'n': remap = FALSE; break; 10840 case 'm': remap = TRUE; break; 10841 case 't': typed = TRUE; break; 10842 case 'i': insert = TRUE; break; 10843 } 10844 } 10845 } 10846 10847 /* Need to escape K_SPECIAL and CSI before putting the string in the 10848 * typeahead buffer. */ 10849 keys_esc = vim_strsave_escape_csi(keys); 10850 if (keys_esc != NULL) 10851 { 10852 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 10853 insert ? 0 : typebuf.tb_len, !typed, FALSE); 10854 vim_free(keys_esc); 10855 if (vgetc_busy) 10856 typebuf_was_filled = TRUE; 10857 } 10858 } 10859 } 10860 10861 /* 10862 * "filereadable()" function 10863 */ 10864 static void 10865 f_filereadable(argvars, rettv) 10866 typval_T *argvars; 10867 typval_T *rettv; 10868 { 10869 int fd; 10870 char_u *p; 10871 int n; 10872 10873 #ifndef O_NONBLOCK 10874 # define O_NONBLOCK 0 10875 #endif 10876 p = get_tv_string(&argvars[0]); 10877 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 10878 O_RDONLY | O_NONBLOCK, 0)) >= 0) 10879 { 10880 n = TRUE; 10881 close(fd); 10882 } 10883 else 10884 n = FALSE; 10885 10886 rettv->vval.v_number = n; 10887 } 10888 10889 /* 10890 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 10891 * rights to write into. 10892 */ 10893 static void 10894 f_filewritable(argvars, rettv) 10895 typval_T *argvars; 10896 typval_T *rettv; 10897 { 10898 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 10899 } 10900 10901 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what)); 10902 10903 static void 10904 findfilendir(argvars, rettv, find_what) 10905 typval_T *argvars UNUSED; 10906 typval_T *rettv; 10907 int find_what UNUSED; 10908 { 10909 #ifdef FEAT_SEARCHPATH 10910 char_u *fname; 10911 char_u *fresult = NULL; 10912 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 10913 char_u *p; 10914 char_u pathbuf[NUMBUFLEN]; 10915 int count = 1; 10916 int first = TRUE; 10917 int error = FALSE; 10918 #endif 10919 10920 rettv->vval.v_string = NULL; 10921 rettv->v_type = VAR_STRING; 10922 10923 #ifdef FEAT_SEARCHPATH 10924 fname = get_tv_string(&argvars[0]); 10925 10926 if (argvars[1].v_type != VAR_UNKNOWN) 10927 { 10928 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 10929 if (p == NULL) 10930 error = TRUE; 10931 else 10932 { 10933 if (*p != NUL) 10934 path = p; 10935 10936 if (argvars[2].v_type != VAR_UNKNOWN) 10937 count = get_tv_number_chk(&argvars[2], &error); 10938 } 10939 } 10940 10941 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 10942 error = TRUE; 10943 10944 if (*fname != NUL && !error) 10945 { 10946 do 10947 { 10948 if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) 10949 vim_free(fresult); 10950 fresult = find_file_in_path_option(first ? fname : NULL, 10951 first ? (int)STRLEN(fname) : 0, 10952 0, first, path, 10953 find_what, 10954 curbuf->b_ffname, 10955 find_what == FINDFILE_DIR 10956 ? (char_u *)"" : curbuf->b_p_sua); 10957 first = FALSE; 10958 10959 if (fresult != NULL && rettv->v_type == VAR_LIST) 10960 list_append_string(rettv->vval.v_list, fresult, -1); 10961 10962 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 10963 } 10964 10965 if (rettv->v_type == VAR_STRING) 10966 rettv->vval.v_string = fresult; 10967 #endif 10968 } 10969 10970 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 10971 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 10972 10973 /* 10974 * Implementation of map() and filter(). 10975 */ 10976 static void 10977 filter_map(argvars, rettv, map) 10978 typval_T *argvars; 10979 typval_T *rettv; 10980 int map; 10981 { 10982 char_u buf[NUMBUFLEN]; 10983 char_u *expr; 10984 listitem_T *li, *nli; 10985 list_T *l = NULL; 10986 dictitem_T *di; 10987 hashtab_T *ht; 10988 hashitem_T *hi; 10989 dict_T *d = NULL; 10990 typval_T save_val; 10991 typval_T save_key; 10992 int rem; 10993 int todo; 10994 char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); 10995 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument") 10996 : N_("filter() argument")); 10997 int save_did_emsg; 10998 int idx = 0; 10999 11000 if (argvars[0].v_type == VAR_LIST) 11001 { 11002 if ((l = argvars[0].vval.v_list) == NULL 11003 || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE))) 11004 return; 11005 } 11006 else if (argvars[0].v_type == VAR_DICT) 11007 { 11008 if ((d = argvars[0].vval.v_dict) == NULL 11009 || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TRUE))) 11010 return; 11011 } 11012 else 11013 { 11014 EMSG2(_(e_listdictarg), ermsg); 11015 return; 11016 } 11017 11018 expr = get_tv_string_buf_chk(&argvars[1], buf); 11019 /* On type errors, the preceding call has already displayed an error 11020 * message. Avoid a misleading error message for an empty string that 11021 * was not passed as argument. */ 11022 if (expr != NULL) 11023 { 11024 prepare_vimvar(VV_VAL, &save_val); 11025 expr = skipwhite(expr); 11026 11027 /* We reset "did_emsg" to be able to detect whether an error 11028 * occurred during evaluation of the expression. */ 11029 save_did_emsg = did_emsg; 11030 did_emsg = FALSE; 11031 11032 prepare_vimvar(VV_KEY, &save_key); 11033 if (argvars[0].v_type == VAR_DICT) 11034 { 11035 vimvars[VV_KEY].vv_type = VAR_STRING; 11036 11037 ht = &d->dv_hashtab; 11038 hash_lock(ht); 11039 todo = (int)ht->ht_used; 11040 for (hi = ht->ht_array; todo > 0; ++hi) 11041 { 11042 if (!HASHITEM_EMPTY(hi)) 11043 { 11044 int r; 11045 11046 --todo; 11047 di = HI2DI(hi); 11048 if (map && 11049 (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TRUE) 11050 || var_check_ro(di->di_flags, arg_errmsg, TRUE))) 11051 break; 11052 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 11053 r = filter_map_one(&di->di_tv, expr, map, &rem); 11054 clear_tv(&vimvars[VV_KEY].vv_tv); 11055 if (r == FAIL || did_emsg) 11056 break; 11057 if (!map && rem) 11058 { 11059 if (var_check_fixed(di->di_flags, arg_errmsg, TRUE) 11060 || var_check_ro(di->di_flags, arg_errmsg, TRUE)) 11061 break; 11062 dictitem_remove(d, di); 11063 } 11064 } 11065 } 11066 hash_unlock(ht); 11067 } 11068 else 11069 { 11070 vimvars[VV_KEY].vv_type = VAR_NUMBER; 11071 11072 for (li = l->lv_first; li != NULL; li = nli) 11073 { 11074 if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) 11075 break; 11076 nli = li->li_next; 11077 vimvars[VV_KEY].vv_nr = idx; 11078 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 11079 || did_emsg) 11080 break; 11081 if (!map && rem) 11082 listitem_remove(l, li); 11083 ++idx; 11084 } 11085 } 11086 11087 restore_vimvar(VV_KEY, &save_key); 11088 restore_vimvar(VV_VAL, &save_val); 11089 11090 did_emsg |= save_did_emsg; 11091 } 11092 11093 copy_tv(&argvars[0], rettv); 11094 } 11095 11096 static int 11097 filter_map_one(tv, expr, map, remp) 11098 typval_T *tv; 11099 char_u *expr; 11100 int map; 11101 int *remp; 11102 { 11103 typval_T rettv; 11104 char_u *s; 11105 int retval = FAIL; 11106 11107 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 11108 s = expr; 11109 if (eval1(&s, &rettv, TRUE) == FAIL) 11110 goto theend; 11111 if (*s != NUL) /* check for trailing chars after expr */ 11112 { 11113 EMSG2(_(e_invexpr2), s); 11114 clear_tv(&rettv); 11115 goto theend; 11116 } 11117 if (map) 11118 { 11119 /* map(): replace the list item value */ 11120 clear_tv(tv); 11121 rettv.v_lock = 0; 11122 *tv = rettv; 11123 } 11124 else 11125 { 11126 int error = FALSE; 11127 11128 /* filter(): when expr is zero remove the item */ 11129 *remp = (get_tv_number_chk(&rettv, &error) == 0); 11130 clear_tv(&rettv); 11131 /* On type error, nothing has been removed; return FAIL to stop the 11132 * loop. The error message was given by get_tv_number_chk(). */ 11133 if (error) 11134 goto theend; 11135 } 11136 retval = OK; 11137 theend: 11138 clear_tv(&vimvars[VV_VAL].vv_tv); 11139 return retval; 11140 } 11141 11142 /* 11143 * "filter()" function 11144 */ 11145 static void 11146 f_filter(argvars, rettv) 11147 typval_T *argvars; 11148 typval_T *rettv; 11149 { 11150 filter_map(argvars, rettv, FALSE); 11151 } 11152 11153 /* 11154 * "finddir({fname}[, {path}[, {count}]])" function 11155 */ 11156 static void 11157 f_finddir(argvars, rettv) 11158 typval_T *argvars; 11159 typval_T *rettv; 11160 { 11161 findfilendir(argvars, rettv, FINDFILE_DIR); 11162 } 11163 11164 /* 11165 * "findfile({fname}[, {path}[, {count}]])" function 11166 */ 11167 static void 11168 f_findfile(argvars, rettv) 11169 typval_T *argvars; 11170 typval_T *rettv; 11171 { 11172 findfilendir(argvars, rettv, FINDFILE_FILE); 11173 } 11174 11175 #ifdef FEAT_FLOAT 11176 /* 11177 * "float2nr({float})" function 11178 */ 11179 static void 11180 f_float2nr(argvars, rettv) 11181 typval_T *argvars; 11182 typval_T *rettv; 11183 { 11184 float_T f; 11185 11186 if (get_float_arg(argvars, &f) == OK) 11187 { 11188 if (f < -0x7fffffff) 11189 rettv->vval.v_number = -0x7fffffff; 11190 else if (f > 0x7fffffff) 11191 rettv->vval.v_number = 0x7fffffff; 11192 else 11193 rettv->vval.v_number = (varnumber_T)f; 11194 } 11195 } 11196 11197 /* 11198 * "floor({float})" function 11199 */ 11200 static void 11201 f_floor(argvars, rettv) 11202 typval_T *argvars; 11203 typval_T *rettv; 11204 { 11205 float_T f; 11206 11207 rettv->v_type = VAR_FLOAT; 11208 if (get_float_arg(argvars, &f) == OK) 11209 rettv->vval.v_float = floor(f); 11210 else 11211 rettv->vval.v_float = 0.0; 11212 } 11213 11214 /* 11215 * "fmod()" function 11216 */ 11217 static void 11218 f_fmod(argvars, rettv) 11219 typval_T *argvars; 11220 typval_T *rettv; 11221 { 11222 float_T fx, fy; 11223 11224 rettv->v_type = VAR_FLOAT; 11225 if (get_float_arg(argvars, &fx) == OK 11226 && get_float_arg(&argvars[1], &fy) == OK) 11227 rettv->vval.v_float = fmod(fx, fy); 11228 else 11229 rettv->vval.v_float = 0.0; 11230 } 11231 #endif 11232 11233 /* 11234 * "fnameescape({string})" function 11235 */ 11236 static void 11237 f_fnameescape(argvars, rettv) 11238 typval_T *argvars; 11239 typval_T *rettv; 11240 { 11241 rettv->vval.v_string = vim_strsave_fnameescape( 11242 get_tv_string(&argvars[0]), FALSE); 11243 rettv->v_type = VAR_STRING; 11244 } 11245 11246 /* 11247 * "fnamemodify({fname}, {mods})" function 11248 */ 11249 static void 11250 f_fnamemodify(argvars, rettv) 11251 typval_T *argvars; 11252 typval_T *rettv; 11253 { 11254 char_u *fname; 11255 char_u *mods; 11256 int usedlen = 0; 11257 int len; 11258 char_u *fbuf = NULL; 11259 char_u buf[NUMBUFLEN]; 11260 11261 fname = get_tv_string_chk(&argvars[0]); 11262 mods = get_tv_string_buf_chk(&argvars[1], buf); 11263 if (fname == NULL || mods == NULL) 11264 fname = NULL; 11265 else 11266 { 11267 len = (int)STRLEN(fname); 11268 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 11269 } 11270 11271 rettv->v_type = VAR_STRING; 11272 if (fname == NULL) 11273 rettv->vval.v_string = NULL; 11274 else 11275 rettv->vval.v_string = vim_strnsave(fname, len); 11276 vim_free(fbuf); 11277 } 11278 11279 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 11280 11281 /* 11282 * "foldclosed()" function 11283 */ 11284 static void 11285 foldclosed_both(argvars, rettv, end) 11286 typval_T *argvars UNUSED; 11287 typval_T *rettv; 11288 int end UNUSED; 11289 { 11290 #ifdef FEAT_FOLDING 11291 linenr_T lnum; 11292 linenr_T first, last; 11293 11294 lnum = get_tv_lnum(argvars); 11295 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11296 { 11297 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 11298 { 11299 if (end) 11300 rettv->vval.v_number = (varnumber_T)last; 11301 else 11302 rettv->vval.v_number = (varnumber_T)first; 11303 return; 11304 } 11305 } 11306 #endif 11307 rettv->vval.v_number = -1; 11308 } 11309 11310 /* 11311 * "foldclosed()" function 11312 */ 11313 static void 11314 f_foldclosed(argvars, rettv) 11315 typval_T *argvars; 11316 typval_T *rettv; 11317 { 11318 foldclosed_both(argvars, rettv, FALSE); 11319 } 11320 11321 /* 11322 * "foldclosedend()" function 11323 */ 11324 static void 11325 f_foldclosedend(argvars, rettv) 11326 typval_T *argvars; 11327 typval_T *rettv; 11328 { 11329 foldclosed_both(argvars, rettv, TRUE); 11330 } 11331 11332 /* 11333 * "foldlevel()" function 11334 */ 11335 static void 11336 f_foldlevel(argvars, rettv) 11337 typval_T *argvars UNUSED; 11338 typval_T *rettv UNUSED; 11339 { 11340 #ifdef FEAT_FOLDING 11341 linenr_T lnum; 11342 11343 lnum = get_tv_lnum(argvars); 11344 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11345 rettv->vval.v_number = foldLevel(lnum); 11346 #endif 11347 } 11348 11349 /* 11350 * "foldtext()" function 11351 */ 11352 static void 11353 f_foldtext(argvars, rettv) 11354 typval_T *argvars UNUSED; 11355 typval_T *rettv; 11356 { 11357 #ifdef FEAT_FOLDING 11358 linenr_T lnum; 11359 char_u *s; 11360 char_u *r; 11361 int len; 11362 char *txt; 11363 #endif 11364 11365 rettv->v_type = VAR_STRING; 11366 rettv->vval.v_string = NULL; 11367 #ifdef FEAT_FOLDING 11368 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 11369 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 11370 <= curbuf->b_ml.ml_line_count 11371 && vimvars[VV_FOLDDASHES].vv_str != NULL) 11372 { 11373 /* Find first non-empty line in the fold. */ 11374 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 11375 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 11376 { 11377 if (!linewhite(lnum)) 11378 break; 11379 ++lnum; 11380 } 11381 11382 /* Find interesting text in this line. */ 11383 s = skipwhite(ml_get(lnum)); 11384 /* skip C comment-start */ 11385 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 11386 { 11387 s = skipwhite(s + 2); 11388 if (*skipwhite(s) == NUL 11389 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 11390 { 11391 s = skipwhite(ml_get(lnum + 1)); 11392 if (*s == '*') 11393 s = skipwhite(s + 1); 11394 } 11395 } 11396 txt = _("+-%s%3ld lines: "); 11397 r = alloc((unsigned)(STRLEN(txt) 11398 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 11399 + 20 /* for %3ld */ 11400 + STRLEN(s))); /* concatenated */ 11401 if (r != NULL) 11402 { 11403 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 11404 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 11405 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 11406 len = (int)STRLEN(r); 11407 STRCAT(r, s); 11408 /* remove 'foldmarker' and 'commentstring' */ 11409 foldtext_cleanup(r + len); 11410 rettv->vval.v_string = r; 11411 } 11412 } 11413 #endif 11414 } 11415 11416 /* 11417 * "foldtextresult(lnum)" function 11418 */ 11419 static void 11420 f_foldtextresult(argvars, rettv) 11421 typval_T *argvars UNUSED; 11422 typval_T *rettv; 11423 { 11424 #ifdef FEAT_FOLDING 11425 linenr_T lnum; 11426 char_u *text; 11427 char_u buf[51]; 11428 foldinfo_T foldinfo; 11429 int fold_count; 11430 #endif 11431 11432 rettv->v_type = VAR_STRING; 11433 rettv->vval.v_string = NULL; 11434 #ifdef FEAT_FOLDING 11435 lnum = get_tv_lnum(argvars); 11436 /* treat illegal types and illegal string values for {lnum} the same */ 11437 if (lnum < 0) 11438 lnum = 0; 11439 fold_count = foldedCount(curwin, lnum, &foldinfo); 11440 if (fold_count > 0) 11441 { 11442 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 11443 &foldinfo, buf); 11444 if (text == buf) 11445 text = vim_strsave(text); 11446 rettv->vval.v_string = text; 11447 } 11448 #endif 11449 } 11450 11451 /* 11452 * "foreground()" function 11453 */ 11454 static void 11455 f_foreground(argvars, rettv) 11456 typval_T *argvars UNUSED; 11457 typval_T *rettv UNUSED; 11458 { 11459 #ifdef FEAT_GUI 11460 if (gui.in_use) 11461 gui_mch_set_foreground(); 11462 #else 11463 # ifdef WIN32 11464 win32_set_foreground(); 11465 # endif 11466 #endif 11467 } 11468 11469 /* 11470 * "function()" function 11471 */ 11472 static void 11473 f_function(argvars, rettv) 11474 typval_T *argvars; 11475 typval_T *rettv; 11476 { 11477 char_u *s; 11478 11479 s = get_tv_string(&argvars[0]); 11480 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 11481 EMSG2(_(e_invarg2), s); 11482 /* Don't check an autoload name for existence here. */ 11483 else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) 11484 EMSG2(_("E700: Unknown function: %s"), s); 11485 else 11486 { 11487 if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0) 11488 { 11489 char sid_buf[25]; 11490 int off = *s == 's' ? 2 : 5; 11491 11492 /* Expand s: and <SID> into <SNR>nr_, so that the function can 11493 * also be called from another script. Using trans_function_name() 11494 * would also work, but some plugins depend on the name being 11495 * printable text. */ 11496 sprintf(sid_buf, "<SNR>%ld_", (long)current_SID); 11497 rettv->vval.v_string = 11498 alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); 11499 if (rettv->vval.v_string != NULL) 11500 { 11501 STRCPY(rettv->vval.v_string, sid_buf); 11502 STRCAT(rettv->vval.v_string, s + off); 11503 } 11504 } 11505 else 11506 rettv->vval.v_string = vim_strsave(s); 11507 rettv->v_type = VAR_FUNC; 11508 } 11509 } 11510 11511 /* 11512 * "garbagecollect()" function 11513 */ 11514 static void 11515 f_garbagecollect(argvars, rettv) 11516 typval_T *argvars; 11517 typval_T *rettv UNUSED; 11518 { 11519 /* This is postponed until we are back at the toplevel, because we may be 11520 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 11521 want_garbage_collect = TRUE; 11522 11523 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 11524 garbage_collect_at_exit = TRUE; 11525 } 11526 11527 /* 11528 * "get()" function 11529 */ 11530 static void 11531 f_get(argvars, rettv) 11532 typval_T *argvars; 11533 typval_T *rettv; 11534 { 11535 listitem_T *li; 11536 list_T *l; 11537 dictitem_T *di; 11538 dict_T *d; 11539 typval_T *tv = NULL; 11540 11541 if (argvars[0].v_type == VAR_LIST) 11542 { 11543 if ((l = argvars[0].vval.v_list) != NULL) 11544 { 11545 int error = FALSE; 11546 11547 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 11548 if (!error && li != NULL) 11549 tv = &li->li_tv; 11550 } 11551 } 11552 else if (argvars[0].v_type == VAR_DICT) 11553 { 11554 if ((d = argvars[0].vval.v_dict) != NULL) 11555 { 11556 di = dict_find(d, get_tv_string(&argvars[1]), -1); 11557 if (di != NULL) 11558 tv = &di->di_tv; 11559 } 11560 } 11561 else 11562 EMSG2(_(e_listdictarg), "get()"); 11563 11564 if (tv == NULL) 11565 { 11566 if (argvars[2].v_type != VAR_UNKNOWN) 11567 copy_tv(&argvars[2], rettv); 11568 } 11569 else 11570 copy_tv(tv, rettv); 11571 } 11572 11573 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 11574 11575 /* 11576 * Get line or list of lines from buffer "buf" into "rettv". 11577 * Return a range (from start to end) of lines in rettv from the specified 11578 * buffer. 11579 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 11580 */ 11581 static void 11582 get_buffer_lines(buf, start, end, retlist, rettv) 11583 buf_T *buf; 11584 linenr_T start; 11585 linenr_T end; 11586 int retlist; 11587 typval_T *rettv; 11588 { 11589 char_u *p; 11590 11591 rettv->v_type = VAR_STRING; 11592 rettv->vval.v_string = NULL; 11593 if (retlist && rettv_list_alloc(rettv) == FAIL) 11594 return; 11595 11596 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 11597 return; 11598 11599 if (!retlist) 11600 { 11601 if (start >= 1 && start <= buf->b_ml.ml_line_count) 11602 p = ml_get_buf(buf, start, FALSE); 11603 else 11604 p = (char_u *)""; 11605 rettv->vval.v_string = vim_strsave(p); 11606 } 11607 else 11608 { 11609 if (end < start) 11610 return; 11611 11612 if (start < 1) 11613 start = 1; 11614 if (end > buf->b_ml.ml_line_count) 11615 end = buf->b_ml.ml_line_count; 11616 while (start <= end) 11617 if (list_append_string(rettv->vval.v_list, 11618 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 11619 break; 11620 } 11621 } 11622 11623 /* 11624 * "getbufline()" function 11625 */ 11626 static void 11627 f_getbufline(argvars, rettv) 11628 typval_T *argvars; 11629 typval_T *rettv; 11630 { 11631 linenr_T lnum; 11632 linenr_T end; 11633 buf_T *buf; 11634 11635 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 11636 ++emsg_off; 11637 buf = get_buf_tv(&argvars[0], FALSE); 11638 --emsg_off; 11639 11640 lnum = get_tv_lnum_buf(&argvars[1], buf); 11641 if (argvars[2].v_type == VAR_UNKNOWN) 11642 end = lnum; 11643 else 11644 end = get_tv_lnum_buf(&argvars[2], buf); 11645 11646 get_buffer_lines(buf, lnum, end, TRUE, rettv); 11647 } 11648 11649 /* 11650 * "getbufvar()" function 11651 */ 11652 static void 11653 f_getbufvar(argvars, rettv) 11654 typval_T *argvars; 11655 typval_T *rettv; 11656 { 11657 buf_T *buf; 11658 buf_T *save_curbuf; 11659 char_u *varname; 11660 dictitem_T *v; 11661 int done = FALSE; 11662 11663 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 11664 varname = get_tv_string_chk(&argvars[1]); 11665 ++emsg_off; 11666 buf = get_buf_tv(&argvars[0], FALSE); 11667 11668 rettv->v_type = VAR_STRING; 11669 rettv->vval.v_string = NULL; 11670 11671 if (buf != NULL && varname != NULL) 11672 { 11673 /* set curbuf to be our buf, temporarily */ 11674 save_curbuf = curbuf; 11675 curbuf = buf; 11676 11677 if (*varname == '&') /* buffer-local-option */ 11678 { 11679 if (get_option_tv(&varname, rettv, TRUE) == OK) 11680 done = TRUE; 11681 } 11682 else if (STRCMP(varname, "changedtick") == 0) 11683 { 11684 rettv->v_type = VAR_NUMBER; 11685 rettv->vval.v_number = curbuf->b_changedtick; 11686 done = TRUE; 11687 } 11688 else 11689 { 11690 /* Look up the variable. */ 11691 /* Let getbufvar({nr}, "") return the "b:" dictionary. */ 11692 v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 11693 'b', varname, FALSE); 11694 if (v != NULL) 11695 { 11696 copy_tv(&v->di_tv, rettv); 11697 done = TRUE; 11698 } 11699 } 11700 11701 /* restore previous notion of curbuf */ 11702 curbuf = save_curbuf; 11703 } 11704 11705 if (!done && argvars[2].v_type != VAR_UNKNOWN) 11706 /* use the default value */ 11707 copy_tv(&argvars[2], rettv); 11708 11709 --emsg_off; 11710 } 11711 11712 /* 11713 * "getchar()" function 11714 */ 11715 static void 11716 f_getchar(argvars, rettv) 11717 typval_T *argvars; 11718 typval_T *rettv; 11719 { 11720 varnumber_T n; 11721 int error = FALSE; 11722 11723 /* Position the cursor. Needed after a message that ends in a space. */ 11724 windgoto(msg_row, msg_col); 11725 11726 ++no_mapping; 11727 ++allow_keys; 11728 for (;;) 11729 { 11730 if (argvars[0].v_type == VAR_UNKNOWN) 11731 /* getchar(): blocking wait. */ 11732 n = safe_vgetc(); 11733 else if (get_tv_number_chk(&argvars[0], &error) == 1) 11734 /* getchar(1): only check if char avail */ 11735 n = vpeekc_any(); 11736 else if (error || vpeekc_any() == NUL) 11737 /* illegal argument or getchar(0) and no char avail: return zero */ 11738 n = 0; 11739 else 11740 /* getchar(0) and char avail: return char */ 11741 n = safe_vgetc(); 11742 11743 if (n == K_IGNORE) 11744 continue; 11745 break; 11746 } 11747 --no_mapping; 11748 --allow_keys; 11749 11750 vimvars[VV_MOUSE_WIN].vv_nr = 0; 11751 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 11752 vimvars[VV_MOUSE_COL].vv_nr = 0; 11753 11754 rettv->vval.v_number = n; 11755 if (IS_SPECIAL(n) || mod_mask != 0) 11756 { 11757 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 11758 int i = 0; 11759 11760 /* Turn a special key into three bytes, plus modifier. */ 11761 if (mod_mask != 0) 11762 { 11763 temp[i++] = K_SPECIAL; 11764 temp[i++] = KS_MODIFIER; 11765 temp[i++] = mod_mask; 11766 } 11767 if (IS_SPECIAL(n)) 11768 { 11769 temp[i++] = K_SPECIAL; 11770 temp[i++] = K_SECOND(n); 11771 temp[i++] = K_THIRD(n); 11772 } 11773 #ifdef FEAT_MBYTE 11774 else if (has_mbyte) 11775 i += (*mb_char2bytes)(n, temp + i); 11776 #endif 11777 else 11778 temp[i++] = n; 11779 temp[i++] = NUL; 11780 rettv->v_type = VAR_STRING; 11781 rettv->vval.v_string = vim_strsave(temp); 11782 11783 #ifdef FEAT_MOUSE 11784 if (is_mouse_key(n)) 11785 { 11786 int row = mouse_row; 11787 int col = mouse_col; 11788 win_T *win; 11789 linenr_T lnum; 11790 # ifdef FEAT_WINDOWS 11791 win_T *wp; 11792 # endif 11793 int winnr = 1; 11794 11795 if (row >= 0 && col >= 0) 11796 { 11797 /* Find the window at the mouse coordinates and compute the 11798 * text position. */ 11799 win = mouse_find_win(&row, &col); 11800 (void)mouse_comp_pos(win, &row, &col, &lnum); 11801 # ifdef FEAT_WINDOWS 11802 for (wp = firstwin; wp != win; wp = wp->w_next) 11803 ++winnr; 11804 # endif 11805 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 11806 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 11807 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 11808 } 11809 } 11810 #endif 11811 } 11812 } 11813 11814 /* 11815 * "getcharmod()" function 11816 */ 11817 static void 11818 f_getcharmod(argvars, rettv) 11819 typval_T *argvars UNUSED; 11820 typval_T *rettv; 11821 { 11822 rettv->vval.v_number = mod_mask; 11823 } 11824 11825 /* 11826 * "getcharsearch()" function 11827 */ 11828 static void 11829 f_getcharsearch(argvars, rettv) 11830 typval_T *argvars UNUSED; 11831 typval_T *rettv; 11832 { 11833 if (rettv_dict_alloc(rettv) != FAIL) 11834 { 11835 dict_T *dict = rettv->vval.v_dict; 11836 11837 dict_add_nr_str(dict, "char", 0L, last_csearch()); 11838 dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL); 11839 dict_add_nr_str(dict, "until", last_csearch_until(), NULL); 11840 } 11841 } 11842 11843 /* 11844 * "getcmdline()" function 11845 */ 11846 static void 11847 f_getcmdline(argvars, rettv) 11848 typval_T *argvars UNUSED; 11849 typval_T *rettv; 11850 { 11851 rettv->v_type = VAR_STRING; 11852 rettv->vval.v_string = get_cmdline_str(); 11853 } 11854 11855 /* 11856 * "getcmdpos()" function 11857 */ 11858 static void 11859 f_getcmdpos(argvars, rettv) 11860 typval_T *argvars UNUSED; 11861 typval_T *rettv; 11862 { 11863 rettv->vval.v_number = get_cmdline_pos() + 1; 11864 } 11865 11866 /* 11867 * "getcmdtype()" function 11868 */ 11869 static void 11870 f_getcmdtype(argvars, rettv) 11871 typval_T *argvars UNUSED; 11872 typval_T *rettv; 11873 { 11874 rettv->v_type = VAR_STRING; 11875 rettv->vval.v_string = alloc(2); 11876 if (rettv->vval.v_string != NULL) 11877 { 11878 rettv->vval.v_string[0] = get_cmdline_type(); 11879 rettv->vval.v_string[1] = NUL; 11880 } 11881 } 11882 11883 /* 11884 * "getcmdwintype()" function 11885 */ 11886 static void 11887 f_getcmdwintype(argvars, rettv) 11888 typval_T *argvars UNUSED; 11889 typval_T *rettv; 11890 { 11891 rettv->v_type = VAR_STRING; 11892 rettv->vval.v_string = NULL; 11893 #ifdef FEAT_CMDWIN 11894 rettv->vval.v_string = alloc(2); 11895 if (rettv->vval.v_string != NULL) 11896 { 11897 rettv->vval.v_string[0] = cmdwin_type; 11898 rettv->vval.v_string[1] = NUL; 11899 } 11900 #endif 11901 } 11902 11903 /* 11904 * "getcwd()" function 11905 */ 11906 static void 11907 f_getcwd(argvars, rettv) 11908 typval_T *argvars UNUSED; 11909 typval_T *rettv; 11910 { 11911 char_u *cwd; 11912 11913 rettv->v_type = VAR_STRING; 11914 rettv->vval.v_string = NULL; 11915 cwd = alloc(MAXPATHL); 11916 if (cwd != NULL) 11917 { 11918 if (mch_dirname(cwd, MAXPATHL) != FAIL) 11919 { 11920 rettv->vval.v_string = vim_strsave(cwd); 11921 #ifdef BACKSLASH_IN_FILENAME 11922 if (rettv->vval.v_string != NULL) 11923 slash_adjust(rettv->vval.v_string); 11924 #endif 11925 } 11926 vim_free(cwd); 11927 } 11928 } 11929 11930 /* 11931 * "getfontname()" function 11932 */ 11933 static void 11934 f_getfontname(argvars, rettv) 11935 typval_T *argvars UNUSED; 11936 typval_T *rettv; 11937 { 11938 rettv->v_type = VAR_STRING; 11939 rettv->vval.v_string = NULL; 11940 #ifdef FEAT_GUI 11941 if (gui.in_use) 11942 { 11943 GuiFont font; 11944 char_u *name = NULL; 11945 11946 if (argvars[0].v_type == VAR_UNKNOWN) 11947 { 11948 /* Get the "Normal" font. Either the name saved by 11949 * hl_set_font_name() or from the font ID. */ 11950 font = gui.norm_font; 11951 name = hl_get_font_name(); 11952 } 11953 else 11954 { 11955 name = get_tv_string(&argvars[0]); 11956 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 11957 return; 11958 font = gui_mch_get_font(name, FALSE); 11959 if (font == NOFONT) 11960 return; /* Invalid font name, return empty string. */ 11961 } 11962 rettv->vval.v_string = gui_mch_get_fontname(font, name); 11963 if (argvars[0].v_type != VAR_UNKNOWN) 11964 gui_mch_free_font(font); 11965 } 11966 #endif 11967 } 11968 11969 /* 11970 * "getfperm({fname})" function 11971 */ 11972 static void 11973 f_getfperm(argvars, rettv) 11974 typval_T *argvars; 11975 typval_T *rettv; 11976 { 11977 char_u *fname; 11978 struct stat st; 11979 char_u *perm = NULL; 11980 char_u flags[] = "rwx"; 11981 int i; 11982 11983 fname = get_tv_string(&argvars[0]); 11984 11985 rettv->v_type = VAR_STRING; 11986 if (mch_stat((char *)fname, &st) >= 0) 11987 { 11988 perm = vim_strsave((char_u *)"---------"); 11989 if (perm != NULL) 11990 { 11991 for (i = 0; i < 9; i++) 11992 { 11993 if (st.st_mode & (1 << (8 - i))) 11994 perm[i] = flags[i % 3]; 11995 } 11996 } 11997 } 11998 rettv->vval.v_string = perm; 11999 } 12000 12001 /* 12002 * "getfsize({fname})" function 12003 */ 12004 static void 12005 f_getfsize(argvars, rettv) 12006 typval_T *argvars; 12007 typval_T *rettv; 12008 { 12009 char_u *fname; 12010 struct stat st; 12011 12012 fname = get_tv_string(&argvars[0]); 12013 12014 rettv->v_type = VAR_NUMBER; 12015 12016 if (mch_stat((char *)fname, &st) >= 0) 12017 { 12018 if (mch_isdir(fname)) 12019 rettv->vval.v_number = 0; 12020 else 12021 { 12022 rettv->vval.v_number = (varnumber_T)st.st_size; 12023 12024 /* non-perfect check for overflow */ 12025 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 12026 rettv->vval.v_number = -2; 12027 } 12028 } 12029 else 12030 rettv->vval.v_number = -1; 12031 } 12032 12033 /* 12034 * "getftime({fname})" function 12035 */ 12036 static void 12037 f_getftime(argvars, rettv) 12038 typval_T *argvars; 12039 typval_T *rettv; 12040 { 12041 char_u *fname; 12042 struct stat st; 12043 12044 fname = get_tv_string(&argvars[0]); 12045 12046 if (mch_stat((char *)fname, &st) >= 0) 12047 rettv->vval.v_number = (varnumber_T)st.st_mtime; 12048 else 12049 rettv->vval.v_number = -1; 12050 } 12051 12052 /* 12053 * "getftype({fname})" function 12054 */ 12055 static void 12056 f_getftype(argvars, rettv) 12057 typval_T *argvars; 12058 typval_T *rettv; 12059 { 12060 char_u *fname; 12061 struct stat st; 12062 char_u *type = NULL; 12063 char *t; 12064 12065 fname = get_tv_string(&argvars[0]); 12066 12067 rettv->v_type = VAR_STRING; 12068 if (mch_lstat((char *)fname, &st) >= 0) 12069 { 12070 #ifdef S_ISREG 12071 if (S_ISREG(st.st_mode)) 12072 t = "file"; 12073 else if (S_ISDIR(st.st_mode)) 12074 t = "dir"; 12075 # ifdef S_ISLNK 12076 else if (S_ISLNK(st.st_mode)) 12077 t = "link"; 12078 # endif 12079 # ifdef S_ISBLK 12080 else if (S_ISBLK(st.st_mode)) 12081 t = "bdev"; 12082 # endif 12083 # ifdef S_ISCHR 12084 else if (S_ISCHR(st.st_mode)) 12085 t = "cdev"; 12086 # endif 12087 # ifdef S_ISFIFO 12088 else if (S_ISFIFO(st.st_mode)) 12089 t = "fifo"; 12090 # endif 12091 # ifdef S_ISSOCK 12092 else if (S_ISSOCK(st.st_mode)) 12093 t = "fifo"; 12094 # endif 12095 else 12096 t = "other"; 12097 #else 12098 # ifdef S_IFMT 12099 switch (st.st_mode & S_IFMT) 12100 { 12101 case S_IFREG: t = "file"; break; 12102 case S_IFDIR: t = "dir"; break; 12103 # ifdef S_IFLNK 12104 case S_IFLNK: t = "link"; break; 12105 # endif 12106 # ifdef S_IFBLK 12107 case S_IFBLK: t = "bdev"; break; 12108 # endif 12109 # ifdef S_IFCHR 12110 case S_IFCHR: t = "cdev"; break; 12111 # endif 12112 # ifdef S_IFIFO 12113 case S_IFIFO: t = "fifo"; break; 12114 # endif 12115 # ifdef S_IFSOCK 12116 case S_IFSOCK: t = "socket"; break; 12117 # endif 12118 default: t = "other"; 12119 } 12120 # else 12121 if (mch_isdir(fname)) 12122 t = "dir"; 12123 else 12124 t = "file"; 12125 # endif 12126 #endif 12127 type = vim_strsave((char_u *)t); 12128 } 12129 rettv->vval.v_string = type; 12130 } 12131 12132 /* 12133 * "getline(lnum, [end])" function 12134 */ 12135 static void 12136 f_getline(argvars, rettv) 12137 typval_T *argvars; 12138 typval_T *rettv; 12139 { 12140 linenr_T lnum; 12141 linenr_T end; 12142 int retlist; 12143 12144 lnum = get_tv_lnum(argvars); 12145 if (argvars[1].v_type == VAR_UNKNOWN) 12146 { 12147 end = 0; 12148 retlist = FALSE; 12149 } 12150 else 12151 { 12152 end = get_tv_lnum(&argvars[1]); 12153 retlist = TRUE; 12154 } 12155 12156 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 12157 } 12158 12159 /* 12160 * "getmatches()" function 12161 */ 12162 static void 12163 f_getmatches(argvars, rettv) 12164 typval_T *argvars UNUSED; 12165 typval_T *rettv UNUSED; 12166 { 12167 #ifdef FEAT_SEARCH_EXTRA 12168 dict_T *dict; 12169 matchitem_T *cur = curwin->w_match_head; 12170 int i; 12171 12172 if (rettv_list_alloc(rettv) == OK) 12173 { 12174 while (cur != NULL) 12175 { 12176 dict = dict_alloc(); 12177 if (dict == NULL) 12178 return; 12179 if (cur->match.regprog == NULL) 12180 { 12181 /* match added with matchaddpos() */ 12182 for (i = 0; i < MAXPOSMATCH; ++i) 12183 { 12184 llpos_T *llpos; 12185 char buf[6]; 12186 list_T *l; 12187 12188 llpos = &cur->pos.pos[i]; 12189 if (llpos->lnum == 0) 12190 break; 12191 l = list_alloc(); 12192 if (l == NULL) 12193 break; 12194 list_append_number(l, (varnumber_T)llpos->lnum); 12195 if (llpos->col > 0) 12196 { 12197 list_append_number(l, (varnumber_T)llpos->col); 12198 list_append_number(l, (varnumber_T)llpos->len); 12199 } 12200 sprintf(buf, "pos%d", i + 1); 12201 dict_add_list(dict, buf, l); 12202 } 12203 } 12204 else 12205 { 12206 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 12207 } 12208 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 12209 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 12210 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 12211 # ifdef FEAT_CONCEAL 12212 if (cur->conceal_char) 12213 { 12214 char_u buf[MB_MAXBYTES + 1]; 12215 12216 buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL; 12217 dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf); 12218 } 12219 # endif 12220 list_append_dict(rettv->vval.v_list, dict); 12221 cur = cur->next; 12222 } 12223 } 12224 #endif 12225 } 12226 12227 /* 12228 * "getpid()" function 12229 */ 12230 static void 12231 f_getpid(argvars, rettv) 12232 typval_T *argvars UNUSED; 12233 typval_T *rettv; 12234 { 12235 rettv->vval.v_number = mch_get_pid(); 12236 } 12237 12238 static void getpos_both __ARGS((typval_T *argvars, typval_T *rettv, int getcurpos)); 12239 12240 /* 12241 * "getcurpos()" function 12242 */ 12243 static void 12244 f_getcurpos(argvars, rettv) 12245 typval_T *argvars; 12246 typval_T *rettv; 12247 { 12248 getpos_both(argvars, rettv, TRUE); 12249 } 12250 12251 /* 12252 * "getpos(string)" function 12253 */ 12254 static void 12255 f_getpos(argvars, rettv) 12256 typval_T *argvars; 12257 typval_T *rettv; 12258 { 12259 getpos_both(argvars, rettv, FALSE); 12260 } 12261 12262 static void 12263 getpos_both(argvars, rettv, getcurpos) 12264 typval_T *argvars; 12265 typval_T *rettv; 12266 int getcurpos; 12267 { 12268 pos_T *fp; 12269 list_T *l; 12270 int fnum = -1; 12271 12272 if (rettv_list_alloc(rettv) == OK) 12273 { 12274 l = rettv->vval.v_list; 12275 if (getcurpos) 12276 fp = &curwin->w_cursor; 12277 else 12278 fp = var2fpos(&argvars[0], TRUE, &fnum); 12279 if (fnum != -1) 12280 list_append_number(l, (varnumber_T)fnum); 12281 else 12282 list_append_number(l, (varnumber_T)0); 12283 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 12284 : (varnumber_T)0); 12285 list_append_number(l, (fp != NULL) 12286 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 12287 : (varnumber_T)0); 12288 list_append_number(l, 12289 #ifdef FEAT_VIRTUALEDIT 12290 (fp != NULL) ? (varnumber_T)fp->coladd : 12291 #endif 12292 (varnumber_T)0); 12293 if (getcurpos) 12294 list_append_number(l, curwin->w_curswant == MAXCOL ? 12295 (varnumber_T)MAXCOL : (varnumber_T)curwin->w_curswant + 1); 12296 } 12297 else 12298 rettv->vval.v_number = FALSE; 12299 } 12300 12301 /* 12302 * "getqflist()" and "getloclist()" functions 12303 */ 12304 static void 12305 f_getqflist(argvars, rettv) 12306 typval_T *argvars UNUSED; 12307 typval_T *rettv UNUSED; 12308 { 12309 #ifdef FEAT_QUICKFIX 12310 win_T *wp; 12311 #endif 12312 12313 #ifdef FEAT_QUICKFIX 12314 if (rettv_list_alloc(rettv) == OK) 12315 { 12316 wp = NULL; 12317 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 12318 { 12319 wp = find_win_by_nr(&argvars[0], NULL); 12320 if (wp == NULL) 12321 return; 12322 } 12323 12324 (void)get_errorlist(wp, rettv->vval.v_list); 12325 } 12326 #endif 12327 } 12328 12329 /* 12330 * "getreg()" function 12331 */ 12332 static void 12333 f_getreg(argvars, rettv) 12334 typval_T *argvars; 12335 typval_T *rettv; 12336 { 12337 char_u *strregname; 12338 int regname; 12339 int arg2 = FALSE; 12340 int return_list = FALSE; 12341 int error = FALSE; 12342 12343 if (argvars[0].v_type != VAR_UNKNOWN) 12344 { 12345 strregname = get_tv_string_chk(&argvars[0]); 12346 error = strregname == NULL; 12347 if (argvars[1].v_type != VAR_UNKNOWN) 12348 { 12349 arg2 = get_tv_number_chk(&argvars[1], &error); 12350 if (!error && argvars[2].v_type != VAR_UNKNOWN) 12351 return_list = get_tv_number_chk(&argvars[2], &error); 12352 } 12353 } 12354 else 12355 strregname = vimvars[VV_REG].vv_str; 12356 12357 if (error) 12358 return; 12359 12360 regname = (strregname == NULL ? '"' : *strregname); 12361 if (regname == 0) 12362 regname = '"'; 12363 12364 if (return_list) 12365 { 12366 rettv->v_type = VAR_LIST; 12367 rettv->vval.v_list = (list_T *)get_reg_contents(regname, 12368 (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST); 12369 if (rettv->vval.v_list != NULL) 12370 ++rettv->vval.v_list->lv_refcount; 12371 } 12372 else 12373 { 12374 rettv->v_type = VAR_STRING; 12375 rettv->vval.v_string = get_reg_contents(regname, 12376 arg2 ? GREG_EXPR_SRC : 0); 12377 } 12378 } 12379 12380 /* 12381 * "getregtype()" function 12382 */ 12383 static void 12384 f_getregtype(argvars, rettv) 12385 typval_T *argvars; 12386 typval_T *rettv; 12387 { 12388 char_u *strregname; 12389 int regname; 12390 char_u buf[NUMBUFLEN + 2]; 12391 long reglen = 0; 12392 12393 if (argvars[0].v_type != VAR_UNKNOWN) 12394 { 12395 strregname = get_tv_string_chk(&argvars[0]); 12396 if (strregname == NULL) /* type error; errmsg already given */ 12397 { 12398 rettv->v_type = VAR_STRING; 12399 rettv->vval.v_string = NULL; 12400 return; 12401 } 12402 } 12403 else 12404 /* Default to v:register */ 12405 strregname = vimvars[VV_REG].vv_str; 12406 12407 regname = (strregname == NULL ? '"' : *strregname); 12408 if (regname == 0) 12409 regname = '"'; 12410 12411 buf[0] = NUL; 12412 buf[1] = NUL; 12413 switch (get_reg_type(regname, ®len)) 12414 { 12415 case MLINE: buf[0] = 'V'; break; 12416 case MCHAR: buf[0] = 'v'; break; 12417 case MBLOCK: 12418 buf[0] = Ctrl_V; 12419 sprintf((char *)buf + 1, "%ld", reglen + 1); 12420 break; 12421 } 12422 rettv->v_type = VAR_STRING; 12423 rettv->vval.v_string = vim_strsave(buf); 12424 } 12425 12426 /* 12427 * "gettabvar()" function 12428 */ 12429 static void 12430 f_gettabvar(argvars, rettv) 12431 typval_T *argvars; 12432 typval_T *rettv; 12433 { 12434 win_T *oldcurwin; 12435 tabpage_T *tp, *oldtabpage; 12436 dictitem_T *v; 12437 char_u *varname; 12438 int done = FALSE; 12439 12440 rettv->v_type = VAR_STRING; 12441 rettv->vval.v_string = NULL; 12442 12443 varname = get_tv_string_chk(&argvars[1]); 12444 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 12445 if (tp != NULL && varname != NULL) 12446 { 12447 /* Set tp to be our tabpage, temporarily. Also set the window to the 12448 * first window in the tabpage, otherwise the window is not valid. */ 12449 if (switch_win(&oldcurwin, &oldtabpage, 12450 tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE) 12451 == OK) 12452 { 12453 /* look up the variable */ 12454 /* Let gettabvar({nr}, "") return the "t:" dictionary. */ 12455 v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); 12456 if (v != NULL) 12457 { 12458 copy_tv(&v->di_tv, rettv); 12459 done = TRUE; 12460 } 12461 } 12462 12463 /* restore previous notion of curwin */ 12464 restore_win(oldcurwin, oldtabpage, TRUE); 12465 } 12466 12467 if (!done && argvars[2].v_type != VAR_UNKNOWN) 12468 copy_tv(&argvars[2], rettv); 12469 } 12470 12471 /* 12472 * "gettabwinvar()" function 12473 */ 12474 static void 12475 f_gettabwinvar(argvars, rettv) 12476 typval_T *argvars; 12477 typval_T *rettv; 12478 { 12479 getwinvar(argvars, rettv, 1); 12480 } 12481 12482 /* 12483 * "getwinposx()" function 12484 */ 12485 static void 12486 f_getwinposx(argvars, rettv) 12487 typval_T *argvars UNUSED; 12488 typval_T *rettv; 12489 { 12490 rettv->vval.v_number = -1; 12491 #ifdef FEAT_GUI 12492 if (gui.in_use) 12493 { 12494 int x, y; 12495 12496 if (gui_mch_get_winpos(&x, &y) == OK) 12497 rettv->vval.v_number = x; 12498 } 12499 #endif 12500 } 12501 12502 /* 12503 * "getwinposy()" function 12504 */ 12505 static void 12506 f_getwinposy(argvars, rettv) 12507 typval_T *argvars UNUSED; 12508 typval_T *rettv; 12509 { 12510 rettv->vval.v_number = -1; 12511 #ifdef FEAT_GUI 12512 if (gui.in_use) 12513 { 12514 int x, y; 12515 12516 if (gui_mch_get_winpos(&x, &y) == OK) 12517 rettv->vval.v_number = y; 12518 } 12519 #endif 12520 } 12521 12522 /* 12523 * Find window specified by "vp" in tabpage "tp". 12524 */ 12525 static win_T * 12526 find_win_by_nr(vp, tp) 12527 typval_T *vp; 12528 tabpage_T *tp UNUSED; /* NULL for current tab page */ 12529 { 12530 #ifdef FEAT_WINDOWS 12531 win_T *wp; 12532 #endif 12533 int nr; 12534 12535 nr = get_tv_number_chk(vp, NULL); 12536 12537 #ifdef FEAT_WINDOWS 12538 if (nr < 0) 12539 return NULL; 12540 if (nr == 0) 12541 return curwin; 12542 12543 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 12544 wp != NULL; wp = wp->w_next) 12545 if (--nr <= 0) 12546 break; 12547 return wp; 12548 #else 12549 if (nr == 0 || nr == 1) 12550 return curwin; 12551 return NULL; 12552 #endif 12553 } 12554 12555 /* 12556 * "getwinvar()" function 12557 */ 12558 static void 12559 f_getwinvar(argvars, rettv) 12560 typval_T *argvars; 12561 typval_T *rettv; 12562 { 12563 getwinvar(argvars, rettv, 0); 12564 } 12565 12566 /* 12567 * getwinvar() and gettabwinvar() 12568 */ 12569 static void 12570 getwinvar(argvars, rettv, off) 12571 typval_T *argvars; 12572 typval_T *rettv; 12573 int off; /* 1 for gettabwinvar() */ 12574 { 12575 win_T *win; 12576 char_u *varname; 12577 dictitem_T *v; 12578 tabpage_T *tp = NULL; 12579 int done = FALSE; 12580 #ifdef FEAT_WINDOWS 12581 win_T *oldcurwin; 12582 tabpage_T *oldtabpage; 12583 int need_switch_win; 12584 #endif 12585 12586 #ifdef FEAT_WINDOWS 12587 if (off == 1) 12588 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 12589 else 12590 tp = curtab; 12591 #endif 12592 win = find_win_by_nr(&argvars[off], tp); 12593 varname = get_tv_string_chk(&argvars[off + 1]); 12594 ++emsg_off; 12595 12596 rettv->v_type = VAR_STRING; 12597 rettv->vval.v_string = NULL; 12598 12599 if (win != NULL && varname != NULL) 12600 { 12601 #ifdef FEAT_WINDOWS 12602 /* Set curwin to be our win, temporarily. Also set the tabpage, 12603 * otherwise the window is not valid. Only do this when needed, 12604 * autocommands get blocked. */ 12605 need_switch_win = !(tp == curtab && win == curwin); 12606 if (!need_switch_win 12607 || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) 12608 #endif 12609 { 12610 if (*varname == '&') /* window-local-option */ 12611 { 12612 if (get_option_tv(&varname, rettv, 1) == OK) 12613 done = TRUE; 12614 } 12615 else 12616 { 12617 /* Look up the variable. */ 12618 /* Let getwinvar({nr}, "") return the "w:" dictionary. */ 12619 v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', 12620 varname, FALSE); 12621 if (v != NULL) 12622 { 12623 copy_tv(&v->di_tv, rettv); 12624 done = TRUE; 12625 } 12626 } 12627 } 12628 12629 #ifdef FEAT_WINDOWS 12630 if (need_switch_win) 12631 /* restore previous notion of curwin */ 12632 restore_win(oldcurwin, oldtabpage, TRUE); 12633 #endif 12634 } 12635 12636 if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) 12637 /* use the default return value */ 12638 copy_tv(&argvars[off + 2], rettv); 12639 12640 --emsg_off; 12641 } 12642 12643 /* 12644 * "glob()" function 12645 */ 12646 static void 12647 f_glob(argvars, rettv) 12648 typval_T *argvars; 12649 typval_T *rettv; 12650 { 12651 int options = WILD_SILENT|WILD_USE_NL; 12652 expand_T xpc; 12653 int error = FALSE; 12654 12655 /* When the optional second argument is non-zero, don't remove matches 12656 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 12657 rettv->v_type = VAR_STRING; 12658 if (argvars[1].v_type != VAR_UNKNOWN) 12659 { 12660 if (get_tv_number_chk(&argvars[1], &error)) 12661 options |= WILD_KEEP_ALL; 12662 if (argvars[2].v_type != VAR_UNKNOWN) 12663 { 12664 if (get_tv_number_chk(&argvars[2], &error)) 12665 { 12666 rettv->v_type = VAR_LIST; 12667 rettv->vval.v_list = NULL; 12668 } 12669 if (argvars[3].v_type != VAR_UNKNOWN 12670 && get_tv_number_chk(&argvars[3], &error)) 12671 options |= WILD_ALLLINKS; 12672 } 12673 } 12674 if (!error) 12675 { 12676 ExpandInit(&xpc); 12677 xpc.xp_context = EXPAND_FILES; 12678 if (p_wic) 12679 options += WILD_ICASE; 12680 if (rettv->v_type == VAR_STRING) 12681 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 12682 NULL, options, WILD_ALL); 12683 else if (rettv_list_alloc(rettv) != FAIL) 12684 { 12685 int i; 12686 12687 ExpandOne(&xpc, get_tv_string(&argvars[0]), 12688 NULL, options, WILD_ALL_KEEP); 12689 for (i = 0; i < xpc.xp_numfiles; i++) 12690 list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); 12691 12692 ExpandCleanup(&xpc); 12693 } 12694 } 12695 else 12696 rettv->vval.v_string = NULL; 12697 } 12698 12699 /* 12700 * "globpath()" function 12701 */ 12702 static void 12703 f_globpath(argvars, rettv) 12704 typval_T *argvars; 12705 typval_T *rettv; 12706 { 12707 int flags = 0; 12708 char_u buf1[NUMBUFLEN]; 12709 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 12710 int error = FALSE; 12711 garray_T ga; 12712 int i; 12713 12714 /* When the optional second argument is non-zero, don't remove matches 12715 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 12716 rettv->v_type = VAR_STRING; 12717 if (argvars[2].v_type != VAR_UNKNOWN) 12718 { 12719 if (get_tv_number_chk(&argvars[2], &error)) 12720 flags |= WILD_KEEP_ALL; 12721 if (argvars[3].v_type != VAR_UNKNOWN) 12722 { 12723 if (get_tv_number_chk(&argvars[3], &error)) 12724 { 12725 rettv->v_type = VAR_LIST; 12726 rettv->vval.v_list = NULL; 12727 } 12728 if (argvars[4].v_type != VAR_UNKNOWN 12729 && get_tv_number_chk(&argvars[4], &error)) 12730 flags |= WILD_ALLLINKS; 12731 } 12732 } 12733 if (file != NULL && !error) 12734 { 12735 ga_init2(&ga, (int)sizeof(char_u *), 10); 12736 globpath(get_tv_string(&argvars[0]), file, &ga, flags); 12737 if (rettv->v_type == VAR_STRING) 12738 rettv->vval.v_string = ga_concat_strings(&ga, "\n"); 12739 else if (rettv_list_alloc(rettv) != FAIL) 12740 for (i = 0; i < ga.ga_len; ++i) 12741 list_append_string(rettv->vval.v_list, 12742 ((char_u **)(ga.ga_data))[i], -1); 12743 ga_clear_strings(&ga); 12744 } 12745 else 12746 rettv->vval.v_string = NULL; 12747 } 12748 12749 /* 12750 * "glob2regpat()" function 12751 */ 12752 static void 12753 f_glob2regpat(argvars, rettv) 12754 typval_T *argvars; 12755 typval_T *rettv; 12756 { 12757 char_u *pat = get_tv_string_chk(&argvars[0]); 12758 12759 rettv->v_type = VAR_STRING; 12760 rettv->vval.v_string = file_pat_to_reg_pat(pat, NULL, NULL, FALSE); 12761 } 12762 12763 /* 12764 * "has()" function 12765 */ 12766 static void 12767 f_has(argvars, rettv) 12768 typval_T *argvars; 12769 typval_T *rettv; 12770 { 12771 int i; 12772 char_u *name; 12773 int n = FALSE; 12774 static char *(has_list[]) = 12775 { 12776 #ifdef AMIGA 12777 "amiga", 12778 # ifdef FEAT_ARP 12779 "arp", 12780 # endif 12781 #endif 12782 #ifdef __BEOS__ 12783 "beos", 12784 #endif 12785 #ifdef MSDOS 12786 # ifdef DJGPP 12787 "dos32", 12788 # else 12789 "dos16", 12790 # endif 12791 #endif 12792 #ifdef MACOS 12793 "mac", 12794 #endif 12795 #if defined(MACOS_X_UNIX) 12796 "macunix", 12797 #endif 12798 #ifdef __QNX__ 12799 "qnx", 12800 #endif 12801 #ifdef UNIX 12802 "unix", 12803 #endif 12804 #ifdef VMS 12805 "vms", 12806 #endif 12807 #ifdef WIN16 12808 "win16", 12809 #endif 12810 #ifdef WIN32 12811 "win32", 12812 #endif 12813 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 12814 "win32unix", 12815 #endif 12816 #if defined(WIN64) || defined(_WIN64) 12817 "win64", 12818 #endif 12819 #ifdef EBCDIC 12820 "ebcdic", 12821 #endif 12822 #ifndef CASE_INSENSITIVE_FILENAME 12823 "fname_case", 12824 #endif 12825 #ifdef HAVE_ACL 12826 "acl", 12827 #endif 12828 #ifdef FEAT_ARABIC 12829 "arabic", 12830 #endif 12831 #ifdef FEAT_AUTOCMD 12832 "autocmd", 12833 #endif 12834 #ifdef FEAT_BEVAL 12835 "balloon_eval", 12836 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 12837 "balloon_multiline", 12838 # endif 12839 #endif 12840 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 12841 "builtin_terms", 12842 # ifdef ALL_BUILTIN_TCAPS 12843 "all_builtin_terms", 12844 # endif 12845 #endif 12846 #if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \ 12847 || defined(FEAT_GUI_W32) \ 12848 || defined(FEAT_GUI_MOTIF)) 12849 "browsefilter", 12850 #endif 12851 #ifdef FEAT_BYTEOFF 12852 "byte_offset", 12853 #endif 12854 #ifdef FEAT_CINDENT 12855 "cindent", 12856 #endif 12857 #ifdef FEAT_CLIENTSERVER 12858 "clientserver", 12859 #endif 12860 #ifdef FEAT_CLIPBOARD 12861 "clipboard", 12862 #endif 12863 #ifdef FEAT_CMDL_COMPL 12864 "cmdline_compl", 12865 #endif 12866 #ifdef FEAT_CMDHIST 12867 "cmdline_hist", 12868 #endif 12869 #ifdef FEAT_COMMENTS 12870 "comments", 12871 #endif 12872 #ifdef FEAT_CONCEAL 12873 "conceal", 12874 #endif 12875 #ifdef FEAT_CRYPT 12876 "cryptv", 12877 #endif 12878 #ifdef FEAT_CSCOPE 12879 "cscope", 12880 #endif 12881 #ifdef FEAT_CURSORBIND 12882 "cursorbind", 12883 #endif 12884 #ifdef CURSOR_SHAPE 12885 "cursorshape", 12886 #endif 12887 #ifdef DEBUG 12888 "debug", 12889 #endif 12890 #ifdef FEAT_CON_DIALOG 12891 "dialog_con", 12892 #endif 12893 #ifdef FEAT_GUI_DIALOG 12894 "dialog_gui", 12895 #endif 12896 #ifdef FEAT_DIFF 12897 "diff", 12898 #endif 12899 #ifdef FEAT_DIGRAPHS 12900 "digraphs", 12901 #endif 12902 #ifdef FEAT_DIRECTX 12903 "directx", 12904 #endif 12905 #ifdef FEAT_DND 12906 "dnd", 12907 #endif 12908 #ifdef FEAT_EMACS_TAGS 12909 "emacs_tags", 12910 #endif 12911 "eval", /* always present, of course! */ 12912 #ifdef FEAT_EX_EXTRA 12913 "ex_extra", 12914 #endif 12915 #ifdef FEAT_SEARCH_EXTRA 12916 "extra_search", 12917 #endif 12918 #ifdef FEAT_FKMAP 12919 "farsi", 12920 #endif 12921 #ifdef FEAT_SEARCHPATH 12922 "file_in_path", 12923 #endif 12924 #ifdef FEAT_FILTERPIPE 12925 "filterpipe", 12926 #endif 12927 #ifdef FEAT_FIND_ID 12928 "find_in_path", 12929 #endif 12930 #ifdef FEAT_FLOAT 12931 "float", 12932 #endif 12933 #ifdef FEAT_FOLDING 12934 "folding", 12935 #endif 12936 #ifdef FEAT_FOOTER 12937 "footer", 12938 #endif 12939 #if !defined(USE_SYSTEM) && defined(UNIX) 12940 "fork", 12941 #endif 12942 #ifdef FEAT_GETTEXT 12943 "gettext", 12944 #endif 12945 #ifdef FEAT_GUI 12946 "gui", 12947 #endif 12948 #ifdef FEAT_GUI_ATHENA 12949 # ifdef FEAT_GUI_NEXTAW 12950 "gui_neXtaw", 12951 # else 12952 "gui_athena", 12953 # endif 12954 #endif 12955 #ifdef FEAT_GUI_GTK 12956 "gui_gtk", 12957 "gui_gtk2", 12958 #endif 12959 #ifdef FEAT_GUI_GNOME 12960 "gui_gnome", 12961 #endif 12962 #ifdef FEAT_GUI_MAC 12963 "gui_mac", 12964 #endif 12965 #ifdef FEAT_GUI_MOTIF 12966 "gui_motif", 12967 #endif 12968 #ifdef FEAT_GUI_PHOTON 12969 "gui_photon", 12970 #endif 12971 #ifdef FEAT_GUI_W16 12972 "gui_win16", 12973 #endif 12974 #ifdef FEAT_GUI_W32 12975 "gui_win32", 12976 #endif 12977 #ifdef FEAT_HANGULIN 12978 "hangul_input", 12979 #endif 12980 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 12981 "iconv", 12982 #endif 12983 #ifdef FEAT_INS_EXPAND 12984 "insert_expand", 12985 #endif 12986 #ifdef FEAT_JUMPLIST 12987 "jumplist", 12988 #endif 12989 #ifdef FEAT_KEYMAP 12990 "keymap", 12991 #endif 12992 #ifdef FEAT_LANGMAP 12993 "langmap", 12994 #endif 12995 #ifdef FEAT_LIBCALL 12996 "libcall", 12997 #endif 12998 #ifdef FEAT_LINEBREAK 12999 "linebreak", 13000 #endif 13001 #ifdef FEAT_LISP 13002 "lispindent", 13003 #endif 13004 #ifdef FEAT_LISTCMDS 13005 "listcmds", 13006 #endif 13007 #ifdef FEAT_LOCALMAP 13008 "localmap", 13009 #endif 13010 #ifdef FEAT_LUA 13011 # ifndef DYNAMIC_LUA 13012 "lua", 13013 # endif 13014 #endif 13015 #ifdef FEAT_MENU 13016 "menu", 13017 #endif 13018 #ifdef FEAT_SESSION 13019 "mksession", 13020 #endif 13021 #ifdef FEAT_MODIFY_FNAME 13022 "modify_fname", 13023 #endif 13024 #ifdef FEAT_MOUSE 13025 "mouse", 13026 #endif 13027 #ifdef FEAT_MOUSESHAPE 13028 "mouseshape", 13029 #endif 13030 #if defined(UNIX) || defined(VMS) 13031 # ifdef FEAT_MOUSE_DEC 13032 "mouse_dec", 13033 # endif 13034 # ifdef FEAT_MOUSE_GPM 13035 "mouse_gpm", 13036 # endif 13037 # ifdef FEAT_MOUSE_JSB 13038 "mouse_jsbterm", 13039 # endif 13040 # ifdef FEAT_MOUSE_NET 13041 "mouse_netterm", 13042 # endif 13043 # ifdef FEAT_MOUSE_PTERM 13044 "mouse_pterm", 13045 # endif 13046 # ifdef FEAT_MOUSE_SGR 13047 "mouse_sgr", 13048 # endif 13049 # ifdef FEAT_SYSMOUSE 13050 "mouse_sysmouse", 13051 # endif 13052 # ifdef FEAT_MOUSE_URXVT 13053 "mouse_urxvt", 13054 # endif 13055 # ifdef FEAT_MOUSE_XTERM 13056 "mouse_xterm", 13057 # endif 13058 #endif 13059 #ifdef FEAT_MBYTE 13060 "multi_byte", 13061 #endif 13062 #ifdef FEAT_MBYTE_IME 13063 "multi_byte_ime", 13064 #endif 13065 #ifdef FEAT_MULTI_LANG 13066 "multi_lang", 13067 #endif 13068 #ifdef FEAT_MZSCHEME 13069 #ifndef DYNAMIC_MZSCHEME 13070 "mzscheme", 13071 #endif 13072 #endif 13073 #ifdef FEAT_OLE 13074 "ole", 13075 #endif 13076 #ifdef FEAT_PATH_EXTRA 13077 "path_extra", 13078 #endif 13079 #ifdef FEAT_PERL 13080 #ifndef DYNAMIC_PERL 13081 "perl", 13082 #endif 13083 #endif 13084 #ifdef FEAT_PERSISTENT_UNDO 13085 "persistent_undo", 13086 #endif 13087 #ifdef FEAT_PYTHON 13088 #ifndef DYNAMIC_PYTHON 13089 "python", 13090 #endif 13091 #endif 13092 #ifdef FEAT_PYTHON3 13093 #ifndef DYNAMIC_PYTHON3 13094 "python3", 13095 #endif 13096 #endif 13097 #ifdef FEAT_POSTSCRIPT 13098 "postscript", 13099 #endif 13100 #ifdef FEAT_PRINTER 13101 "printer", 13102 #endif 13103 #ifdef FEAT_PROFILE 13104 "profile", 13105 #endif 13106 #ifdef FEAT_RELTIME 13107 "reltime", 13108 #endif 13109 #ifdef FEAT_QUICKFIX 13110 "quickfix", 13111 #endif 13112 #ifdef FEAT_RIGHTLEFT 13113 "rightleft", 13114 #endif 13115 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 13116 "ruby", 13117 #endif 13118 #ifdef FEAT_SCROLLBIND 13119 "scrollbind", 13120 #endif 13121 #ifdef FEAT_CMDL_INFO 13122 "showcmd", 13123 "cmdline_info", 13124 #endif 13125 #ifdef FEAT_SIGNS 13126 "signs", 13127 #endif 13128 #ifdef FEAT_SMARTINDENT 13129 "smartindent", 13130 #endif 13131 #ifdef FEAT_SNIFF 13132 "sniff", 13133 #endif 13134 #ifdef STARTUPTIME 13135 "startuptime", 13136 #endif 13137 #ifdef FEAT_STL_OPT 13138 "statusline", 13139 #endif 13140 #ifdef FEAT_SUN_WORKSHOP 13141 "sun_workshop", 13142 #endif 13143 #ifdef FEAT_NETBEANS_INTG 13144 "netbeans_intg", 13145 #endif 13146 #ifdef FEAT_SPELL 13147 "spell", 13148 #endif 13149 #ifdef FEAT_SYN_HL 13150 "syntax", 13151 #endif 13152 #if defined(USE_SYSTEM) || !defined(UNIX) 13153 "system", 13154 #endif 13155 #ifdef FEAT_TAG_BINS 13156 "tag_binary", 13157 #endif 13158 #ifdef FEAT_TAG_OLDSTATIC 13159 "tag_old_static", 13160 #endif 13161 #ifdef FEAT_TAG_ANYWHITE 13162 "tag_any_white", 13163 #endif 13164 #ifdef FEAT_TCL 13165 # ifndef DYNAMIC_TCL 13166 "tcl", 13167 # endif 13168 #endif 13169 #ifdef TERMINFO 13170 "terminfo", 13171 #endif 13172 #ifdef FEAT_TERMRESPONSE 13173 "termresponse", 13174 #endif 13175 #ifdef FEAT_TEXTOBJ 13176 "textobjects", 13177 #endif 13178 #ifdef HAVE_TGETENT 13179 "tgetent", 13180 #endif 13181 #ifdef FEAT_TITLE 13182 "title", 13183 #endif 13184 #ifdef FEAT_TOOLBAR 13185 "toolbar", 13186 #endif 13187 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) 13188 "unnamedplus", 13189 #endif 13190 #ifdef FEAT_USR_CMDS 13191 "user-commands", /* was accidentally included in 5.4 */ 13192 "user_commands", 13193 #endif 13194 #ifdef FEAT_VIMINFO 13195 "viminfo", 13196 #endif 13197 #ifdef FEAT_VERTSPLIT 13198 "vertsplit", 13199 #endif 13200 #ifdef FEAT_VIRTUALEDIT 13201 "virtualedit", 13202 #endif 13203 "visual", 13204 #ifdef FEAT_VISUALEXTRA 13205 "visualextra", 13206 #endif 13207 #ifdef FEAT_VREPLACE 13208 "vreplace", 13209 #endif 13210 #ifdef FEAT_WILDIGN 13211 "wildignore", 13212 #endif 13213 #ifdef FEAT_WILDMENU 13214 "wildmenu", 13215 #endif 13216 #ifdef FEAT_WINDOWS 13217 "windows", 13218 #endif 13219 #ifdef FEAT_WAK 13220 "winaltkeys", 13221 #endif 13222 #ifdef FEAT_WRITEBACKUP 13223 "writebackup", 13224 #endif 13225 #ifdef FEAT_XIM 13226 "xim", 13227 #endif 13228 #ifdef FEAT_XFONTSET 13229 "xfontset", 13230 #endif 13231 #ifdef FEAT_XPM_W32 13232 "xpm", 13233 "xpm_w32", /* for backward compatibility */ 13234 #else 13235 # if defined(HAVE_XPM) 13236 "xpm", 13237 # endif 13238 #endif 13239 #ifdef USE_XSMP 13240 "xsmp", 13241 #endif 13242 #ifdef USE_XSMP_INTERACT 13243 "xsmp_interact", 13244 #endif 13245 #ifdef FEAT_XCLIPBOARD 13246 "xterm_clipboard", 13247 #endif 13248 #ifdef FEAT_XTERM_SAVE 13249 "xterm_save", 13250 #endif 13251 #if defined(UNIX) && defined(FEAT_X11) 13252 "X11", 13253 #endif 13254 NULL 13255 }; 13256 13257 name = get_tv_string(&argvars[0]); 13258 for (i = 0; has_list[i] != NULL; ++i) 13259 if (STRICMP(name, has_list[i]) == 0) 13260 { 13261 n = TRUE; 13262 break; 13263 } 13264 13265 if (n == FALSE) 13266 { 13267 if (STRNICMP(name, "patch", 5) == 0) 13268 { 13269 if (name[5] == '-' 13270 && STRLEN(name) > 11 13271 && vim_isdigit(name[6]) 13272 && vim_isdigit(name[8]) 13273 && vim_isdigit(name[10])) 13274 { 13275 int major = atoi((char *)name + 6); 13276 int minor = atoi((char *)name + 8); 13277 13278 /* Expect "patch-9.9.01234". */ 13279 n = (major < VIM_VERSION_MAJOR 13280 || (major == VIM_VERSION_MAJOR 13281 && (minor < VIM_VERSION_MINOR 13282 || (minor == VIM_VERSION_MINOR 13283 && has_patch(atoi((char *)name + 10)))))); 13284 } 13285 else 13286 n = has_patch(atoi((char *)name + 5)); 13287 } 13288 else if (STRICMP(name, "vim_starting") == 0) 13289 n = (starting != 0); 13290 #ifdef FEAT_MBYTE 13291 else if (STRICMP(name, "multi_byte_encoding") == 0) 13292 n = has_mbyte; 13293 #endif 13294 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 13295 else if (STRICMP(name, "balloon_multiline") == 0) 13296 n = multiline_balloon_available(); 13297 #endif 13298 #ifdef DYNAMIC_TCL 13299 else if (STRICMP(name, "tcl") == 0) 13300 n = tcl_enabled(FALSE); 13301 #endif 13302 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 13303 else if (STRICMP(name, "iconv") == 0) 13304 n = iconv_enabled(FALSE); 13305 #endif 13306 #ifdef DYNAMIC_LUA 13307 else if (STRICMP(name, "lua") == 0) 13308 n = lua_enabled(FALSE); 13309 #endif 13310 #ifdef DYNAMIC_MZSCHEME 13311 else if (STRICMP(name, "mzscheme") == 0) 13312 n = mzscheme_enabled(FALSE); 13313 #endif 13314 #ifdef DYNAMIC_RUBY 13315 else if (STRICMP(name, "ruby") == 0) 13316 n = ruby_enabled(FALSE); 13317 #endif 13318 #ifdef FEAT_PYTHON 13319 #ifdef DYNAMIC_PYTHON 13320 else if (STRICMP(name, "python") == 0) 13321 n = python_enabled(FALSE); 13322 #endif 13323 #endif 13324 #ifdef FEAT_PYTHON3 13325 #ifdef DYNAMIC_PYTHON3 13326 else if (STRICMP(name, "python3") == 0) 13327 n = python3_enabled(FALSE); 13328 #endif 13329 #endif 13330 #ifdef DYNAMIC_PERL 13331 else if (STRICMP(name, "perl") == 0) 13332 n = perl_enabled(FALSE); 13333 #endif 13334 #ifdef FEAT_GUI 13335 else if (STRICMP(name, "gui_running") == 0) 13336 n = (gui.in_use || gui.starting); 13337 # ifdef FEAT_GUI_W32 13338 else if (STRICMP(name, "gui_win32s") == 0) 13339 n = gui_is_win32s(); 13340 # endif 13341 # ifdef FEAT_BROWSE 13342 else if (STRICMP(name, "browse") == 0) 13343 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 13344 # endif 13345 #endif 13346 #ifdef FEAT_SYN_HL 13347 else if (STRICMP(name, "syntax_items") == 0) 13348 n = syntax_present(curwin); 13349 #endif 13350 #if defined(WIN3264) 13351 else if (STRICMP(name, "win95") == 0) 13352 n = mch_windows95(); 13353 #endif 13354 #ifdef FEAT_NETBEANS_INTG 13355 else if (STRICMP(name, "netbeans_enabled") == 0) 13356 n = netbeans_active(); 13357 #endif 13358 } 13359 13360 rettv->vval.v_number = n; 13361 } 13362 13363 /* 13364 * "has_key()" function 13365 */ 13366 static void 13367 f_has_key(argvars, rettv) 13368 typval_T *argvars; 13369 typval_T *rettv; 13370 { 13371 if (argvars[0].v_type != VAR_DICT) 13372 { 13373 EMSG(_(e_dictreq)); 13374 return; 13375 } 13376 if (argvars[0].vval.v_dict == NULL) 13377 return; 13378 13379 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 13380 get_tv_string(&argvars[1]), -1) != NULL; 13381 } 13382 13383 /* 13384 * "haslocaldir()" function 13385 */ 13386 static void 13387 f_haslocaldir(argvars, rettv) 13388 typval_T *argvars UNUSED; 13389 typval_T *rettv; 13390 { 13391 rettv->vval.v_number = (curwin->w_localdir != NULL); 13392 } 13393 13394 /* 13395 * "hasmapto()" function 13396 */ 13397 static void 13398 f_hasmapto(argvars, rettv) 13399 typval_T *argvars; 13400 typval_T *rettv; 13401 { 13402 char_u *name; 13403 char_u *mode; 13404 char_u buf[NUMBUFLEN]; 13405 int abbr = FALSE; 13406 13407 name = get_tv_string(&argvars[0]); 13408 if (argvars[1].v_type == VAR_UNKNOWN) 13409 mode = (char_u *)"nvo"; 13410 else 13411 { 13412 mode = get_tv_string_buf(&argvars[1], buf); 13413 if (argvars[2].v_type != VAR_UNKNOWN) 13414 abbr = get_tv_number(&argvars[2]); 13415 } 13416 13417 if (map_to_exists(name, mode, abbr)) 13418 rettv->vval.v_number = TRUE; 13419 else 13420 rettv->vval.v_number = FALSE; 13421 } 13422 13423 /* 13424 * "histadd()" function 13425 */ 13426 static void 13427 f_histadd(argvars, rettv) 13428 typval_T *argvars UNUSED; 13429 typval_T *rettv; 13430 { 13431 #ifdef FEAT_CMDHIST 13432 int histype; 13433 char_u *str; 13434 char_u buf[NUMBUFLEN]; 13435 #endif 13436 13437 rettv->vval.v_number = FALSE; 13438 if (check_restricted() || check_secure()) 13439 return; 13440 #ifdef FEAT_CMDHIST 13441 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 13442 histype = str != NULL ? get_histtype(str) : -1; 13443 if (histype >= 0) 13444 { 13445 str = get_tv_string_buf(&argvars[1], buf); 13446 if (*str != NUL) 13447 { 13448 init_history(); 13449 add_to_history(histype, str, FALSE, NUL); 13450 rettv->vval.v_number = TRUE; 13451 return; 13452 } 13453 } 13454 #endif 13455 } 13456 13457 /* 13458 * "histdel()" function 13459 */ 13460 static void 13461 f_histdel(argvars, rettv) 13462 typval_T *argvars UNUSED; 13463 typval_T *rettv UNUSED; 13464 { 13465 #ifdef FEAT_CMDHIST 13466 int n; 13467 char_u buf[NUMBUFLEN]; 13468 char_u *str; 13469 13470 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 13471 if (str == NULL) 13472 n = 0; 13473 else if (argvars[1].v_type == VAR_UNKNOWN) 13474 /* only one argument: clear entire history */ 13475 n = clr_history(get_histtype(str)); 13476 else if (argvars[1].v_type == VAR_NUMBER) 13477 /* index given: remove that entry */ 13478 n = del_history_idx(get_histtype(str), 13479 (int)get_tv_number(&argvars[1])); 13480 else 13481 /* string given: remove all matching entries */ 13482 n = del_history_entry(get_histtype(str), 13483 get_tv_string_buf(&argvars[1], buf)); 13484 rettv->vval.v_number = n; 13485 #endif 13486 } 13487 13488 /* 13489 * "histget()" function 13490 */ 13491 static void 13492 f_histget(argvars, rettv) 13493 typval_T *argvars UNUSED; 13494 typval_T *rettv; 13495 { 13496 #ifdef FEAT_CMDHIST 13497 int type; 13498 int idx; 13499 char_u *str; 13500 13501 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 13502 if (str == NULL) 13503 rettv->vval.v_string = NULL; 13504 else 13505 { 13506 type = get_histtype(str); 13507 if (argvars[1].v_type == VAR_UNKNOWN) 13508 idx = get_history_idx(type); 13509 else 13510 idx = (int)get_tv_number_chk(&argvars[1], NULL); 13511 /* -1 on type error */ 13512 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 13513 } 13514 #else 13515 rettv->vval.v_string = NULL; 13516 #endif 13517 rettv->v_type = VAR_STRING; 13518 } 13519 13520 /* 13521 * "histnr()" function 13522 */ 13523 static void 13524 f_histnr(argvars, rettv) 13525 typval_T *argvars UNUSED; 13526 typval_T *rettv; 13527 { 13528 int i; 13529 13530 #ifdef FEAT_CMDHIST 13531 char_u *history = get_tv_string_chk(&argvars[0]); 13532 13533 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 13534 if (i >= HIST_CMD && i < HIST_COUNT) 13535 i = get_history_idx(i); 13536 else 13537 #endif 13538 i = -1; 13539 rettv->vval.v_number = i; 13540 } 13541 13542 /* 13543 * "highlightID(name)" function 13544 */ 13545 static void 13546 f_hlID(argvars, rettv) 13547 typval_T *argvars; 13548 typval_T *rettv; 13549 { 13550 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 13551 } 13552 13553 /* 13554 * "highlight_exists()" function 13555 */ 13556 static void 13557 f_hlexists(argvars, rettv) 13558 typval_T *argvars; 13559 typval_T *rettv; 13560 { 13561 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 13562 } 13563 13564 /* 13565 * "hostname()" function 13566 */ 13567 static void 13568 f_hostname(argvars, rettv) 13569 typval_T *argvars UNUSED; 13570 typval_T *rettv; 13571 { 13572 char_u hostname[256]; 13573 13574 mch_get_host_name(hostname, 256); 13575 rettv->v_type = VAR_STRING; 13576 rettv->vval.v_string = vim_strsave(hostname); 13577 } 13578 13579 /* 13580 * iconv() function 13581 */ 13582 static void 13583 f_iconv(argvars, rettv) 13584 typval_T *argvars UNUSED; 13585 typval_T *rettv; 13586 { 13587 #ifdef FEAT_MBYTE 13588 char_u buf1[NUMBUFLEN]; 13589 char_u buf2[NUMBUFLEN]; 13590 char_u *from, *to, *str; 13591 vimconv_T vimconv; 13592 #endif 13593 13594 rettv->v_type = VAR_STRING; 13595 rettv->vval.v_string = NULL; 13596 13597 #ifdef FEAT_MBYTE 13598 str = get_tv_string(&argvars[0]); 13599 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 13600 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 13601 vimconv.vc_type = CONV_NONE; 13602 convert_setup(&vimconv, from, to); 13603 13604 /* If the encodings are equal, no conversion needed. */ 13605 if (vimconv.vc_type == CONV_NONE) 13606 rettv->vval.v_string = vim_strsave(str); 13607 else 13608 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 13609 13610 convert_setup(&vimconv, NULL, NULL); 13611 vim_free(from); 13612 vim_free(to); 13613 #endif 13614 } 13615 13616 /* 13617 * "indent()" function 13618 */ 13619 static void 13620 f_indent(argvars, rettv) 13621 typval_T *argvars; 13622 typval_T *rettv; 13623 { 13624 linenr_T lnum; 13625 13626 lnum = get_tv_lnum(argvars); 13627 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 13628 rettv->vval.v_number = get_indent_lnum(lnum); 13629 else 13630 rettv->vval.v_number = -1; 13631 } 13632 13633 /* 13634 * "index()" function 13635 */ 13636 static void 13637 f_index(argvars, rettv) 13638 typval_T *argvars; 13639 typval_T *rettv; 13640 { 13641 list_T *l; 13642 listitem_T *item; 13643 long idx = 0; 13644 int ic = FALSE; 13645 13646 rettv->vval.v_number = -1; 13647 if (argvars[0].v_type != VAR_LIST) 13648 { 13649 EMSG(_(e_listreq)); 13650 return; 13651 } 13652 l = argvars[0].vval.v_list; 13653 if (l != NULL) 13654 { 13655 item = l->lv_first; 13656 if (argvars[2].v_type != VAR_UNKNOWN) 13657 { 13658 int error = FALSE; 13659 13660 /* Start at specified item. Use the cached index that list_find() 13661 * sets, so that a negative number also works. */ 13662 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 13663 idx = l->lv_idx; 13664 if (argvars[3].v_type != VAR_UNKNOWN) 13665 ic = get_tv_number_chk(&argvars[3], &error); 13666 if (error) 13667 item = NULL; 13668 } 13669 13670 for ( ; item != NULL; item = item->li_next, ++idx) 13671 if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) 13672 { 13673 rettv->vval.v_number = idx; 13674 break; 13675 } 13676 } 13677 } 13678 13679 static int inputsecret_flag = 0; 13680 13681 static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); 13682 13683 /* 13684 * This function is used by f_input() and f_inputdialog() functions. The third 13685 * argument to f_input() specifies the type of completion to use at the 13686 * prompt. The third argument to f_inputdialog() specifies the value to return 13687 * when the user cancels the prompt. 13688 */ 13689 static void 13690 get_user_input(argvars, rettv, inputdialog) 13691 typval_T *argvars; 13692 typval_T *rettv; 13693 int inputdialog; 13694 { 13695 char_u *prompt = get_tv_string_chk(&argvars[0]); 13696 char_u *p = NULL; 13697 int c; 13698 char_u buf[NUMBUFLEN]; 13699 int cmd_silent_save = cmd_silent; 13700 char_u *defstr = (char_u *)""; 13701 int xp_type = EXPAND_NOTHING; 13702 char_u *xp_arg = NULL; 13703 13704 rettv->v_type = VAR_STRING; 13705 rettv->vval.v_string = NULL; 13706 13707 #ifdef NO_CONSOLE_INPUT 13708 /* While starting up, there is no place to enter text. */ 13709 if (no_console_input()) 13710 return; 13711 #endif 13712 13713 cmd_silent = FALSE; /* Want to see the prompt. */ 13714 if (prompt != NULL) 13715 { 13716 /* Only the part of the message after the last NL is considered as 13717 * prompt for the command line */ 13718 p = vim_strrchr(prompt, '\n'); 13719 if (p == NULL) 13720 p = prompt; 13721 else 13722 { 13723 ++p; 13724 c = *p; 13725 *p = NUL; 13726 msg_start(); 13727 msg_clr_eos(); 13728 msg_puts_attr(prompt, echo_attr); 13729 msg_didout = FALSE; 13730 msg_starthere(); 13731 *p = c; 13732 } 13733 cmdline_row = msg_row; 13734 13735 if (argvars[1].v_type != VAR_UNKNOWN) 13736 { 13737 defstr = get_tv_string_buf_chk(&argvars[1], buf); 13738 if (defstr != NULL) 13739 stuffReadbuffSpec(defstr); 13740 13741 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 13742 { 13743 char_u *xp_name; 13744 int xp_namelen; 13745 long argt; 13746 13747 /* input() with a third argument: completion */ 13748 rettv->vval.v_string = NULL; 13749 13750 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 13751 if (xp_name == NULL) 13752 return; 13753 13754 xp_namelen = (int)STRLEN(xp_name); 13755 13756 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 13757 &xp_arg) == FAIL) 13758 return; 13759 } 13760 } 13761 13762 if (defstr != NULL) 13763 { 13764 # ifdef FEAT_EX_EXTRA 13765 int save_ex_normal_busy = ex_normal_busy; 13766 ex_normal_busy = 0; 13767 # endif 13768 rettv->vval.v_string = 13769 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 13770 xp_type, xp_arg); 13771 # ifdef FEAT_EX_EXTRA 13772 ex_normal_busy = save_ex_normal_busy; 13773 # endif 13774 } 13775 if (inputdialog && rettv->vval.v_string == NULL 13776 && argvars[1].v_type != VAR_UNKNOWN 13777 && argvars[2].v_type != VAR_UNKNOWN) 13778 rettv->vval.v_string = vim_strsave(get_tv_string_buf( 13779 &argvars[2], buf)); 13780 13781 vim_free(xp_arg); 13782 13783 /* since the user typed this, no need to wait for return */ 13784 need_wait_return = FALSE; 13785 msg_didout = FALSE; 13786 } 13787 cmd_silent = cmd_silent_save; 13788 } 13789 13790 /* 13791 * "input()" function 13792 * Also handles inputsecret() when inputsecret is set. 13793 */ 13794 static void 13795 f_input(argvars, rettv) 13796 typval_T *argvars; 13797 typval_T *rettv; 13798 { 13799 get_user_input(argvars, rettv, FALSE); 13800 } 13801 13802 /* 13803 * "inputdialog()" function 13804 */ 13805 static void 13806 f_inputdialog(argvars, rettv) 13807 typval_T *argvars; 13808 typval_T *rettv; 13809 { 13810 #if defined(FEAT_GUI_TEXTDIALOG) 13811 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 13812 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 13813 { 13814 char_u *message; 13815 char_u buf[NUMBUFLEN]; 13816 char_u *defstr = (char_u *)""; 13817 13818 message = get_tv_string_chk(&argvars[0]); 13819 if (argvars[1].v_type != VAR_UNKNOWN 13820 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 13821 vim_strncpy(IObuff, defstr, IOSIZE - 1); 13822 else 13823 IObuff[0] = NUL; 13824 if (message != NULL && defstr != NULL 13825 && do_dialog(VIM_QUESTION, NULL, message, 13826 (char_u *)_("&OK\n&Cancel"), 1, IObuff, FALSE) == 1) 13827 rettv->vval.v_string = vim_strsave(IObuff); 13828 else 13829 { 13830 if (message != NULL && defstr != NULL 13831 && argvars[1].v_type != VAR_UNKNOWN 13832 && argvars[2].v_type != VAR_UNKNOWN) 13833 rettv->vval.v_string = vim_strsave( 13834 get_tv_string_buf(&argvars[2], buf)); 13835 else 13836 rettv->vval.v_string = NULL; 13837 } 13838 rettv->v_type = VAR_STRING; 13839 } 13840 else 13841 #endif 13842 get_user_input(argvars, rettv, TRUE); 13843 } 13844 13845 /* 13846 * "inputlist()" function 13847 */ 13848 static void 13849 f_inputlist(argvars, rettv) 13850 typval_T *argvars; 13851 typval_T *rettv; 13852 { 13853 listitem_T *li; 13854 int selected; 13855 int mouse_used; 13856 13857 #ifdef NO_CONSOLE_INPUT 13858 /* While starting up, there is no place to enter text. */ 13859 if (no_console_input()) 13860 return; 13861 #endif 13862 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 13863 { 13864 EMSG2(_(e_listarg), "inputlist()"); 13865 return; 13866 } 13867 13868 msg_start(); 13869 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 13870 lines_left = Rows; /* avoid more prompt */ 13871 msg_scroll = TRUE; 13872 msg_clr_eos(); 13873 13874 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 13875 { 13876 msg_puts(get_tv_string(&li->li_tv)); 13877 msg_putchar('\n'); 13878 } 13879 13880 /* Ask for choice. */ 13881 selected = prompt_for_number(&mouse_used); 13882 if (mouse_used) 13883 selected -= lines_left; 13884 13885 rettv->vval.v_number = selected; 13886 } 13887 13888 13889 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 13890 13891 /* 13892 * "inputrestore()" function 13893 */ 13894 static void 13895 f_inputrestore(argvars, rettv) 13896 typval_T *argvars UNUSED; 13897 typval_T *rettv; 13898 { 13899 if (ga_userinput.ga_len > 0) 13900 { 13901 --ga_userinput.ga_len; 13902 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 13903 + ga_userinput.ga_len); 13904 /* default return is zero == OK */ 13905 } 13906 else if (p_verbose > 1) 13907 { 13908 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 13909 rettv->vval.v_number = 1; /* Failed */ 13910 } 13911 } 13912 13913 /* 13914 * "inputsave()" function 13915 */ 13916 static void 13917 f_inputsave(argvars, rettv) 13918 typval_T *argvars UNUSED; 13919 typval_T *rettv; 13920 { 13921 /* Add an entry to the stack of typeahead storage. */ 13922 if (ga_grow(&ga_userinput, 1) == OK) 13923 { 13924 save_typeahead((tasave_T *)(ga_userinput.ga_data) 13925 + ga_userinput.ga_len); 13926 ++ga_userinput.ga_len; 13927 /* default return is zero == OK */ 13928 } 13929 else 13930 rettv->vval.v_number = 1; /* Failed */ 13931 } 13932 13933 /* 13934 * "inputsecret()" function 13935 */ 13936 static void 13937 f_inputsecret(argvars, rettv) 13938 typval_T *argvars; 13939 typval_T *rettv; 13940 { 13941 ++cmdline_star; 13942 ++inputsecret_flag; 13943 f_input(argvars, rettv); 13944 --cmdline_star; 13945 --inputsecret_flag; 13946 } 13947 13948 /* 13949 * "insert()" function 13950 */ 13951 static void 13952 f_insert(argvars, rettv) 13953 typval_T *argvars; 13954 typval_T *rettv; 13955 { 13956 long before = 0; 13957 listitem_T *item; 13958 list_T *l; 13959 int error = FALSE; 13960 13961 if (argvars[0].v_type != VAR_LIST) 13962 EMSG2(_(e_listarg), "insert()"); 13963 else if ((l = argvars[0].vval.v_list) != NULL 13964 && !tv_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE)) 13965 { 13966 if (argvars[2].v_type != VAR_UNKNOWN) 13967 before = get_tv_number_chk(&argvars[2], &error); 13968 if (error) 13969 return; /* type error; errmsg already given */ 13970 13971 if (before == l->lv_len) 13972 item = NULL; 13973 else 13974 { 13975 item = list_find(l, before); 13976 if (item == NULL) 13977 { 13978 EMSGN(_(e_listidx), before); 13979 l = NULL; 13980 } 13981 } 13982 if (l != NULL) 13983 { 13984 list_insert_tv(l, &argvars[1], item); 13985 copy_tv(&argvars[0], rettv); 13986 } 13987 } 13988 } 13989 13990 /* 13991 * "invert(expr)" function 13992 */ 13993 static void 13994 f_invert(argvars, rettv) 13995 typval_T *argvars; 13996 typval_T *rettv; 13997 { 13998 rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL); 13999 } 14000 14001 /* 14002 * "isdirectory()" function 14003 */ 14004 static void 14005 f_isdirectory(argvars, rettv) 14006 typval_T *argvars; 14007 typval_T *rettv; 14008 { 14009 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 14010 } 14011 14012 /* 14013 * "islocked()" function 14014 */ 14015 static void 14016 f_islocked(argvars, rettv) 14017 typval_T *argvars; 14018 typval_T *rettv; 14019 { 14020 lval_T lv; 14021 char_u *end; 14022 dictitem_T *di; 14023 14024 rettv->vval.v_number = -1; 14025 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, 14026 GLV_NO_AUTOLOAD, FNE_CHECK_START); 14027 if (end != NULL && lv.ll_name != NULL) 14028 { 14029 if (*end != NUL) 14030 EMSG(_(e_trailing)); 14031 else 14032 { 14033 if (lv.ll_tv == NULL) 14034 { 14035 if (check_changedtick(lv.ll_name)) 14036 rettv->vval.v_number = 1; /* always locked */ 14037 else 14038 { 14039 di = find_var(lv.ll_name, NULL, TRUE); 14040 if (di != NULL) 14041 { 14042 /* Consider a variable locked when: 14043 * 1. the variable itself is locked 14044 * 2. the value of the variable is locked. 14045 * 3. the List or Dict value is locked. 14046 */ 14047 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 14048 || tv_islocked(&di->di_tv)); 14049 } 14050 } 14051 } 14052 else if (lv.ll_range) 14053 EMSG(_("E786: Range not allowed")); 14054 else if (lv.ll_newkey != NULL) 14055 EMSG2(_(e_dictkey), lv.ll_newkey); 14056 else if (lv.ll_list != NULL) 14057 /* List item. */ 14058 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 14059 else 14060 /* Dictionary item. */ 14061 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 14062 } 14063 } 14064 14065 clear_lval(&lv); 14066 } 14067 14068 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 14069 14070 /* 14071 * Turn a dict into a list: 14072 * "what" == 0: list of keys 14073 * "what" == 1: list of values 14074 * "what" == 2: list of items 14075 */ 14076 static void 14077 dict_list(argvars, rettv, what) 14078 typval_T *argvars; 14079 typval_T *rettv; 14080 int what; 14081 { 14082 list_T *l2; 14083 dictitem_T *di; 14084 hashitem_T *hi; 14085 listitem_T *li; 14086 listitem_T *li2; 14087 dict_T *d; 14088 int todo; 14089 14090 if (argvars[0].v_type != VAR_DICT) 14091 { 14092 EMSG(_(e_dictreq)); 14093 return; 14094 } 14095 if ((d = argvars[0].vval.v_dict) == NULL) 14096 return; 14097 14098 if (rettv_list_alloc(rettv) == FAIL) 14099 return; 14100 14101 todo = (int)d->dv_hashtab.ht_used; 14102 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 14103 { 14104 if (!HASHITEM_EMPTY(hi)) 14105 { 14106 --todo; 14107 di = HI2DI(hi); 14108 14109 li = listitem_alloc(); 14110 if (li == NULL) 14111 break; 14112 list_append(rettv->vval.v_list, li); 14113 14114 if (what == 0) 14115 { 14116 /* keys() */ 14117 li->li_tv.v_type = VAR_STRING; 14118 li->li_tv.v_lock = 0; 14119 li->li_tv.vval.v_string = vim_strsave(di->di_key); 14120 } 14121 else if (what == 1) 14122 { 14123 /* values() */ 14124 copy_tv(&di->di_tv, &li->li_tv); 14125 } 14126 else 14127 { 14128 /* items() */ 14129 l2 = list_alloc(); 14130 li->li_tv.v_type = VAR_LIST; 14131 li->li_tv.v_lock = 0; 14132 li->li_tv.vval.v_list = l2; 14133 if (l2 == NULL) 14134 break; 14135 ++l2->lv_refcount; 14136 14137 li2 = listitem_alloc(); 14138 if (li2 == NULL) 14139 break; 14140 list_append(l2, li2); 14141 li2->li_tv.v_type = VAR_STRING; 14142 li2->li_tv.v_lock = 0; 14143 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 14144 14145 li2 = listitem_alloc(); 14146 if (li2 == NULL) 14147 break; 14148 list_append(l2, li2); 14149 copy_tv(&di->di_tv, &li2->li_tv); 14150 } 14151 } 14152 } 14153 } 14154 14155 /* 14156 * "items(dict)" function 14157 */ 14158 static void 14159 f_items(argvars, rettv) 14160 typval_T *argvars; 14161 typval_T *rettv; 14162 { 14163 dict_list(argvars, rettv, 2); 14164 } 14165 14166 /* 14167 * "join()" function 14168 */ 14169 static void 14170 f_join(argvars, rettv) 14171 typval_T *argvars; 14172 typval_T *rettv; 14173 { 14174 garray_T ga; 14175 char_u *sep; 14176 14177 if (argvars[0].v_type != VAR_LIST) 14178 { 14179 EMSG(_(e_listreq)); 14180 return; 14181 } 14182 if (argvars[0].vval.v_list == NULL) 14183 return; 14184 if (argvars[1].v_type == VAR_UNKNOWN) 14185 sep = (char_u *)" "; 14186 else 14187 sep = get_tv_string_chk(&argvars[1]); 14188 14189 rettv->v_type = VAR_STRING; 14190 14191 if (sep != NULL) 14192 { 14193 ga_init2(&ga, (int)sizeof(char), 80); 14194 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 14195 ga_append(&ga, NUL); 14196 rettv->vval.v_string = (char_u *)ga.ga_data; 14197 } 14198 else 14199 rettv->vval.v_string = NULL; 14200 } 14201 14202 /* 14203 * "keys()" function 14204 */ 14205 static void 14206 f_keys(argvars, rettv) 14207 typval_T *argvars; 14208 typval_T *rettv; 14209 { 14210 dict_list(argvars, rettv, 0); 14211 } 14212 14213 /* 14214 * "last_buffer_nr()" function. 14215 */ 14216 static void 14217 f_last_buffer_nr(argvars, rettv) 14218 typval_T *argvars UNUSED; 14219 typval_T *rettv; 14220 { 14221 int n = 0; 14222 buf_T *buf; 14223 14224 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 14225 if (n < buf->b_fnum) 14226 n = buf->b_fnum; 14227 14228 rettv->vval.v_number = n; 14229 } 14230 14231 /* 14232 * "len()" function 14233 */ 14234 static void 14235 f_len(argvars, rettv) 14236 typval_T *argvars; 14237 typval_T *rettv; 14238 { 14239 switch (argvars[0].v_type) 14240 { 14241 case VAR_STRING: 14242 case VAR_NUMBER: 14243 rettv->vval.v_number = (varnumber_T)STRLEN( 14244 get_tv_string(&argvars[0])); 14245 break; 14246 case VAR_LIST: 14247 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 14248 break; 14249 case VAR_DICT: 14250 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 14251 break; 14252 default: 14253 EMSG(_("E701: Invalid type for len()")); 14254 break; 14255 } 14256 } 14257 14258 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 14259 14260 static void 14261 libcall_common(argvars, rettv, type) 14262 typval_T *argvars; 14263 typval_T *rettv; 14264 int type; 14265 { 14266 #ifdef FEAT_LIBCALL 14267 char_u *string_in; 14268 char_u **string_result; 14269 int nr_result; 14270 #endif 14271 14272 rettv->v_type = type; 14273 if (type != VAR_NUMBER) 14274 rettv->vval.v_string = NULL; 14275 14276 if (check_restricted() || check_secure()) 14277 return; 14278 14279 #ifdef FEAT_LIBCALL 14280 /* The first two args must be strings, otherwise its meaningless */ 14281 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 14282 { 14283 string_in = NULL; 14284 if (argvars[2].v_type == VAR_STRING) 14285 string_in = argvars[2].vval.v_string; 14286 if (type == VAR_NUMBER) 14287 string_result = NULL; 14288 else 14289 string_result = &rettv->vval.v_string; 14290 if (mch_libcall(argvars[0].vval.v_string, 14291 argvars[1].vval.v_string, 14292 string_in, 14293 argvars[2].vval.v_number, 14294 string_result, 14295 &nr_result) == OK 14296 && type == VAR_NUMBER) 14297 rettv->vval.v_number = nr_result; 14298 } 14299 #endif 14300 } 14301 14302 /* 14303 * "libcall()" function 14304 */ 14305 static void 14306 f_libcall(argvars, rettv) 14307 typval_T *argvars; 14308 typval_T *rettv; 14309 { 14310 libcall_common(argvars, rettv, VAR_STRING); 14311 } 14312 14313 /* 14314 * "libcallnr()" function 14315 */ 14316 static void 14317 f_libcallnr(argvars, rettv) 14318 typval_T *argvars; 14319 typval_T *rettv; 14320 { 14321 libcall_common(argvars, rettv, VAR_NUMBER); 14322 } 14323 14324 /* 14325 * "line(string)" function 14326 */ 14327 static void 14328 f_line(argvars, rettv) 14329 typval_T *argvars; 14330 typval_T *rettv; 14331 { 14332 linenr_T lnum = 0; 14333 pos_T *fp; 14334 int fnum; 14335 14336 fp = var2fpos(&argvars[0], TRUE, &fnum); 14337 if (fp != NULL) 14338 lnum = fp->lnum; 14339 rettv->vval.v_number = lnum; 14340 } 14341 14342 /* 14343 * "line2byte(lnum)" function 14344 */ 14345 static void 14346 f_line2byte(argvars, rettv) 14347 typval_T *argvars UNUSED; 14348 typval_T *rettv; 14349 { 14350 #ifndef FEAT_BYTEOFF 14351 rettv->vval.v_number = -1; 14352 #else 14353 linenr_T lnum; 14354 14355 lnum = get_tv_lnum(argvars); 14356 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 14357 rettv->vval.v_number = -1; 14358 else 14359 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 14360 if (rettv->vval.v_number >= 0) 14361 ++rettv->vval.v_number; 14362 #endif 14363 } 14364 14365 /* 14366 * "lispindent(lnum)" function 14367 */ 14368 static void 14369 f_lispindent(argvars, rettv) 14370 typval_T *argvars UNUSED; 14371 typval_T *rettv; 14372 { 14373 #ifdef FEAT_LISP 14374 pos_T pos; 14375 linenr_T lnum; 14376 14377 pos = curwin->w_cursor; 14378 lnum = get_tv_lnum(argvars); 14379 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 14380 { 14381 curwin->w_cursor.lnum = lnum; 14382 rettv->vval.v_number = get_lisp_indent(); 14383 curwin->w_cursor = pos; 14384 } 14385 else 14386 #endif 14387 rettv->vval.v_number = -1; 14388 } 14389 14390 /* 14391 * "localtime()" function 14392 */ 14393 static void 14394 f_localtime(argvars, rettv) 14395 typval_T *argvars UNUSED; 14396 typval_T *rettv; 14397 { 14398 rettv->vval.v_number = (varnumber_T)time(NULL); 14399 } 14400 14401 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 14402 14403 static void 14404 get_maparg(argvars, rettv, exact) 14405 typval_T *argvars; 14406 typval_T *rettv; 14407 int exact; 14408 { 14409 char_u *keys; 14410 char_u *which; 14411 char_u buf[NUMBUFLEN]; 14412 char_u *keys_buf = NULL; 14413 char_u *rhs; 14414 int mode; 14415 int abbr = FALSE; 14416 int get_dict = FALSE; 14417 mapblock_T *mp; 14418 int buffer_local; 14419 14420 /* return empty string for failure */ 14421 rettv->v_type = VAR_STRING; 14422 rettv->vval.v_string = NULL; 14423 14424 keys = get_tv_string(&argvars[0]); 14425 if (*keys == NUL) 14426 return; 14427 14428 if (argvars[1].v_type != VAR_UNKNOWN) 14429 { 14430 which = get_tv_string_buf_chk(&argvars[1], buf); 14431 if (argvars[2].v_type != VAR_UNKNOWN) 14432 { 14433 abbr = get_tv_number(&argvars[2]); 14434 if (argvars[3].v_type != VAR_UNKNOWN) 14435 get_dict = get_tv_number(&argvars[3]); 14436 } 14437 } 14438 else 14439 which = (char_u *)""; 14440 if (which == NULL) 14441 return; 14442 14443 mode = get_map_mode(&which, 0); 14444 14445 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 14446 rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); 14447 vim_free(keys_buf); 14448 14449 if (!get_dict) 14450 { 14451 /* Return a string. */ 14452 if (rhs != NULL) 14453 rettv->vval.v_string = str2special_save(rhs, FALSE); 14454 14455 } 14456 else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL) 14457 { 14458 /* Return a dictionary. */ 14459 char_u *lhs = str2special_save(mp->m_keys, TRUE); 14460 char_u *mapmode = map_mode_to_chars(mp->m_mode); 14461 dict_T *dict = rettv->vval.v_dict; 14462 14463 dict_add_nr_str(dict, "lhs", 0L, lhs); 14464 dict_add_nr_str(dict, "rhs", 0L, mp->m_orig_str); 14465 dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL); 14466 dict_add_nr_str(dict, "expr", mp->m_expr ? 1L : 0L, NULL); 14467 dict_add_nr_str(dict, "silent", mp->m_silent ? 1L : 0L, NULL); 14468 dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL); 14469 dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL); 14470 dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL); 14471 dict_add_nr_str(dict, "mode", 0L, mapmode); 14472 14473 vim_free(lhs); 14474 vim_free(mapmode); 14475 } 14476 } 14477 14478 #ifdef FEAT_FLOAT 14479 /* 14480 * "log()" function 14481 */ 14482 static void 14483 f_log(argvars, rettv) 14484 typval_T *argvars; 14485 typval_T *rettv; 14486 { 14487 float_T f; 14488 14489 rettv->v_type = VAR_FLOAT; 14490 if (get_float_arg(argvars, &f) == OK) 14491 rettv->vval.v_float = log(f); 14492 else 14493 rettv->vval.v_float = 0.0; 14494 } 14495 14496 /* 14497 * "log10()" function 14498 */ 14499 static void 14500 f_log10(argvars, rettv) 14501 typval_T *argvars; 14502 typval_T *rettv; 14503 { 14504 float_T f; 14505 14506 rettv->v_type = VAR_FLOAT; 14507 if (get_float_arg(argvars, &f) == OK) 14508 rettv->vval.v_float = log10(f); 14509 else 14510 rettv->vval.v_float = 0.0; 14511 } 14512 #endif 14513 14514 #ifdef FEAT_LUA 14515 /* 14516 * "luaeval()" function 14517 */ 14518 static void 14519 f_luaeval(argvars, rettv) 14520 typval_T *argvars; 14521 typval_T *rettv; 14522 { 14523 char_u *str; 14524 char_u buf[NUMBUFLEN]; 14525 14526 str = get_tv_string_buf(&argvars[0], buf); 14527 do_luaeval(str, argvars + 1, rettv); 14528 } 14529 #endif 14530 14531 /* 14532 * "map()" function 14533 */ 14534 static void 14535 f_map(argvars, rettv) 14536 typval_T *argvars; 14537 typval_T *rettv; 14538 { 14539 filter_map(argvars, rettv, TRUE); 14540 } 14541 14542 /* 14543 * "maparg()" function 14544 */ 14545 static void 14546 f_maparg(argvars, rettv) 14547 typval_T *argvars; 14548 typval_T *rettv; 14549 { 14550 get_maparg(argvars, rettv, TRUE); 14551 } 14552 14553 /* 14554 * "mapcheck()" function 14555 */ 14556 static void 14557 f_mapcheck(argvars, rettv) 14558 typval_T *argvars; 14559 typval_T *rettv; 14560 { 14561 get_maparg(argvars, rettv, FALSE); 14562 } 14563 14564 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 14565 14566 static void 14567 find_some_match(argvars, rettv, type) 14568 typval_T *argvars; 14569 typval_T *rettv; 14570 int type; 14571 { 14572 char_u *str = NULL; 14573 long len = 0; 14574 char_u *expr = NULL; 14575 char_u *pat; 14576 regmatch_T regmatch; 14577 char_u patbuf[NUMBUFLEN]; 14578 char_u strbuf[NUMBUFLEN]; 14579 char_u *save_cpo; 14580 long start = 0; 14581 long nth = 1; 14582 colnr_T startcol = 0; 14583 int match = 0; 14584 list_T *l = NULL; 14585 listitem_T *li = NULL; 14586 long idx = 0; 14587 char_u *tofree = NULL; 14588 14589 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14590 save_cpo = p_cpo; 14591 p_cpo = (char_u *)""; 14592 14593 rettv->vval.v_number = -1; 14594 if (type == 3) 14595 { 14596 /* return empty list when there are no matches */ 14597 if (rettv_list_alloc(rettv) == FAIL) 14598 goto theend; 14599 } 14600 else if (type == 2) 14601 { 14602 rettv->v_type = VAR_STRING; 14603 rettv->vval.v_string = NULL; 14604 } 14605 14606 if (argvars[0].v_type == VAR_LIST) 14607 { 14608 if ((l = argvars[0].vval.v_list) == NULL) 14609 goto theend; 14610 li = l->lv_first; 14611 } 14612 else 14613 { 14614 expr = str = get_tv_string(&argvars[0]); 14615 len = (long)STRLEN(str); 14616 } 14617 14618 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14619 if (pat == NULL) 14620 goto theend; 14621 14622 if (argvars[2].v_type != VAR_UNKNOWN) 14623 { 14624 int error = FALSE; 14625 14626 start = get_tv_number_chk(&argvars[2], &error); 14627 if (error) 14628 goto theend; 14629 if (l != NULL) 14630 { 14631 li = list_find(l, start); 14632 if (li == NULL) 14633 goto theend; 14634 idx = l->lv_idx; /* use the cached index */ 14635 } 14636 else 14637 { 14638 if (start < 0) 14639 start = 0; 14640 if (start > len) 14641 goto theend; 14642 /* When "count" argument is there ignore matches before "start", 14643 * otherwise skip part of the string. Differs when pattern is "^" 14644 * or "\<". */ 14645 if (argvars[3].v_type != VAR_UNKNOWN) 14646 startcol = start; 14647 else 14648 { 14649 str += start; 14650 len -= start; 14651 } 14652 } 14653 14654 if (argvars[3].v_type != VAR_UNKNOWN) 14655 nth = get_tv_number_chk(&argvars[3], &error); 14656 if (error) 14657 goto theend; 14658 } 14659 14660 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14661 if (regmatch.regprog != NULL) 14662 { 14663 regmatch.rm_ic = p_ic; 14664 14665 for (;;) 14666 { 14667 if (l != NULL) 14668 { 14669 if (li == NULL) 14670 { 14671 match = FALSE; 14672 break; 14673 } 14674 vim_free(tofree); 14675 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 14676 if (str == NULL) 14677 break; 14678 } 14679 14680 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 14681 14682 if (match && --nth <= 0) 14683 break; 14684 if (l == NULL && !match) 14685 break; 14686 14687 /* Advance to just after the match. */ 14688 if (l != NULL) 14689 { 14690 li = li->li_next; 14691 ++idx; 14692 } 14693 else 14694 { 14695 #ifdef FEAT_MBYTE 14696 startcol = (colnr_T)(regmatch.startp[0] 14697 + (*mb_ptr2len)(regmatch.startp[0]) - str); 14698 #else 14699 startcol = (colnr_T)(regmatch.startp[0] + 1 - str); 14700 #endif 14701 if (startcol > (colnr_T)len 14702 || str + startcol <= regmatch.startp[0]) 14703 { 14704 match = FALSE; 14705 break; 14706 } 14707 } 14708 } 14709 14710 if (match) 14711 { 14712 if (type == 3) 14713 { 14714 int i; 14715 14716 /* return list with matched string and submatches */ 14717 for (i = 0; i < NSUBEXP; ++i) 14718 { 14719 if (regmatch.endp[i] == NULL) 14720 { 14721 if (list_append_string(rettv->vval.v_list, 14722 (char_u *)"", 0) == FAIL) 14723 break; 14724 } 14725 else if (list_append_string(rettv->vval.v_list, 14726 regmatch.startp[i], 14727 (int)(regmatch.endp[i] - regmatch.startp[i])) 14728 == FAIL) 14729 break; 14730 } 14731 } 14732 else if (type == 2) 14733 { 14734 /* return matched string */ 14735 if (l != NULL) 14736 copy_tv(&li->li_tv, rettv); 14737 else 14738 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 14739 (int)(regmatch.endp[0] - regmatch.startp[0])); 14740 } 14741 else if (l != NULL) 14742 rettv->vval.v_number = idx; 14743 else 14744 { 14745 if (type != 0) 14746 rettv->vval.v_number = 14747 (varnumber_T)(regmatch.startp[0] - str); 14748 else 14749 rettv->vval.v_number = 14750 (varnumber_T)(regmatch.endp[0] - str); 14751 rettv->vval.v_number += (varnumber_T)(str - expr); 14752 } 14753 } 14754 vim_regfree(regmatch.regprog); 14755 } 14756 14757 theend: 14758 vim_free(tofree); 14759 p_cpo = save_cpo; 14760 } 14761 14762 /* 14763 * "match()" function 14764 */ 14765 static void 14766 f_match(argvars, rettv) 14767 typval_T *argvars; 14768 typval_T *rettv; 14769 { 14770 find_some_match(argvars, rettv, 1); 14771 } 14772 14773 /* 14774 * "matchadd()" function 14775 */ 14776 static void 14777 f_matchadd(argvars, rettv) 14778 typval_T *argvars UNUSED; 14779 typval_T *rettv UNUSED; 14780 { 14781 #ifdef FEAT_SEARCH_EXTRA 14782 char_u buf[NUMBUFLEN]; 14783 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 14784 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 14785 int prio = 10; /* default priority */ 14786 int id = -1; 14787 int error = FALSE; 14788 char_u *conceal_char = NULL; 14789 14790 rettv->vval.v_number = -1; 14791 14792 if (grp == NULL || pat == NULL) 14793 return; 14794 if (argvars[2].v_type != VAR_UNKNOWN) 14795 { 14796 prio = get_tv_number_chk(&argvars[2], &error); 14797 if (argvars[3].v_type != VAR_UNKNOWN) 14798 { 14799 id = get_tv_number_chk(&argvars[3], &error); 14800 if (argvars[4].v_type != VAR_UNKNOWN) 14801 { 14802 if (argvars[4].v_type != VAR_DICT) 14803 { 14804 EMSG(_(e_dictreq)); 14805 return; 14806 } 14807 if (dict_find(argvars[4].vval.v_dict, 14808 (char_u *)"conceal", -1) != NULL) 14809 conceal_char = get_dict_string(argvars[4].vval.v_dict, 14810 (char_u *)"conceal", FALSE); 14811 } 14812 } 14813 } 14814 if (error == TRUE) 14815 return; 14816 if (id >= 1 && id <= 3) 14817 { 14818 EMSGN("E798: ID is reserved for \":match\": %ld", id); 14819 return; 14820 } 14821 14822 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL, 14823 conceal_char); 14824 #endif 14825 } 14826 14827 /* 14828 * "matchaddpos()" function 14829 */ 14830 static void 14831 f_matchaddpos(argvars, rettv) 14832 typval_T *argvars UNUSED; 14833 typval_T *rettv UNUSED; 14834 { 14835 #ifdef FEAT_SEARCH_EXTRA 14836 char_u buf[NUMBUFLEN]; 14837 char_u *group; 14838 int prio = 10; 14839 int id = -1; 14840 int error = FALSE; 14841 list_T *l; 14842 char_u *conceal_char = NULL; 14843 14844 rettv->vval.v_number = -1; 14845 14846 group = get_tv_string_buf_chk(&argvars[0], buf); 14847 if (group == NULL) 14848 return; 14849 14850 if (argvars[1].v_type != VAR_LIST) 14851 { 14852 EMSG2(_(e_listarg), "matchaddpos()"); 14853 return; 14854 } 14855 l = argvars[1].vval.v_list; 14856 if (l == NULL) 14857 return; 14858 14859 if (argvars[2].v_type != VAR_UNKNOWN) 14860 { 14861 prio = get_tv_number_chk(&argvars[2], &error); 14862 if (argvars[3].v_type != VAR_UNKNOWN) 14863 { 14864 id = get_tv_number_chk(&argvars[3], &error); 14865 if (argvars[4].v_type != VAR_UNKNOWN) 14866 { 14867 if (argvars[4].v_type != VAR_DICT) 14868 { 14869 EMSG(_(e_dictreq)); 14870 return; 14871 } 14872 if (dict_find(argvars[4].vval.v_dict, 14873 (char_u *)"conceal", -1) != NULL) 14874 conceal_char = get_dict_string(argvars[4].vval.v_dict, 14875 (char_u *)"conceal", FALSE); 14876 } 14877 } 14878 } 14879 if (error == TRUE) 14880 return; 14881 14882 /* id == 3 is ok because matchaddpos() is supposed to substitute :3match */ 14883 if (id == 1 || id == 2) 14884 { 14885 EMSGN("E798: ID is reserved for \":match\": %ld", id); 14886 return; 14887 } 14888 14889 rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l, 14890 conceal_char); 14891 #endif 14892 } 14893 14894 /* 14895 * "matcharg()" function 14896 */ 14897 static void 14898 f_matcharg(argvars, rettv) 14899 typval_T *argvars UNUSED; 14900 typval_T *rettv; 14901 { 14902 if (rettv_list_alloc(rettv) == OK) 14903 { 14904 #ifdef FEAT_SEARCH_EXTRA 14905 int id = get_tv_number(&argvars[0]); 14906 matchitem_T *m; 14907 14908 if (id >= 1 && id <= 3) 14909 { 14910 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 14911 { 14912 list_append_string(rettv->vval.v_list, 14913 syn_id2name(m->hlg_id), -1); 14914 list_append_string(rettv->vval.v_list, m->pattern, -1); 14915 } 14916 else 14917 { 14918 list_append_string(rettv->vval.v_list, NULL, -1); 14919 list_append_string(rettv->vval.v_list, NULL, -1); 14920 } 14921 } 14922 #endif 14923 } 14924 } 14925 14926 /* 14927 * "matchdelete()" function 14928 */ 14929 static void 14930 f_matchdelete(argvars, rettv) 14931 typval_T *argvars UNUSED; 14932 typval_T *rettv UNUSED; 14933 { 14934 #ifdef FEAT_SEARCH_EXTRA 14935 rettv->vval.v_number = match_delete(curwin, 14936 (int)get_tv_number(&argvars[0]), TRUE); 14937 #endif 14938 } 14939 14940 /* 14941 * "matchend()" function 14942 */ 14943 static void 14944 f_matchend(argvars, rettv) 14945 typval_T *argvars; 14946 typval_T *rettv; 14947 { 14948 find_some_match(argvars, rettv, 0); 14949 } 14950 14951 /* 14952 * "matchlist()" function 14953 */ 14954 static void 14955 f_matchlist(argvars, rettv) 14956 typval_T *argvars; 14957 typval_T *rettv; 14958 { 14959 find_some_match(argvars, rettv, 3); 14960 } 14961 14962 /* 14963 * "matchstr()" function 14964 */ 14965 static void 14966 f_matchstr(argvars, rettv) 14967 typval_T *argvars; 14968 typval_T *rettv; 14969 { 14970 find_some_match(argvars, rettv, 2); 14971 } 14972 14973 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 14974 14975 static void 14976 max_min(argvars, rettv, domax) 14977 typval_T *argvars; 14978 typval_T *rettv; 14979 int domax; 14980 { 14981 long n = 0; 14982 long i; 14983 int error = FALSE; 14984 14985 if (argvars[0].v_type == VAR_LIST) 14986 { 14987 list_T *l; 14988 listitem_T *li; 14989 14990 l = argvars[0].vval.v_list; 14991 if (l != NULL) 14992 { 14993 li = l->lv_first; 14994 if (li != NULL) 14995 { 14996 n = get_tv_number_chk(&li->li_tv, &error); 14997 for (;;) 14998 { 14999 li = li->li_next; 15000 if (li == NULL) 15001 break; 15002 i = get_tv_number_chk(&li->li_tv, &error); 15003 if (domax ? i > n : i < n) 15004 n = i; 15005 } 15006 } 15007 } 15008 } 15009 else if (argvars[0].v_type == VAR_DICT) 15010 { 15011 dict_T *d; 15012 int first = TRUE; 15013 hashitem_T *hi; 15014 int todo; 15015 15016 d = argvars[0].vval.v_dict; 15017 if (d != NULL) 15018 { 15019 todo = (int)d->dv_hashtab.ht_used; 15020 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 15021 { 15022 if (!HASHITEM_EMPTY(hi)) 15023 { 15024 --todo; 15025 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 15026 if (first) 15027 { 15028 n = i; 15029 first = FALSE; 15030 } 15031 else if (domax ? i > n : i < n) 15032 n = i; 15033 } 15034 } 15035 } 15036 } 15037 else 15038 EMSG(_(e_listdictarg)); 15039 rettv->vval.v_number = error ? 0 : n; 15040 } 15041 15042 /* 15043 * "max()" function 15044 */ 15045 static void 15046 f_max(argvars, rettv) 15047 typval_T *argvars; 15048 typval_T *rettv; 15049 { 15050 max_min(argvars, rettv, TRUE); 15051 } 15052 15053 /* 15054 * "min()" function 15055 */ 15056 static void 15057 f_min(argvars, rettv) 15058 typval_T *argvars; 15059 typval_T *rettv; 15060 { 15061 max_min(argvars, rettv, FALSE); 15062 } 15063 15064 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 15065 15066 /* 15067 * Create the directory in which "dir" is located, and higher levels when 15068 * needed. 15069 */ 15070 static int 15071 mkdir_recurse(dir, prot) 15072 char_u *dir; 15073 int prot; 15074 { 15075 char_u *p; 15076 char_u *updir; 15077 int r = FAIL; 15078 15079 /* Get end of directory name in "dir". 15080 * We're done when it's "/" or "c:/". */ 15081 p = gettail_sep(dir); 15082 if (p <= get_past_head(dir)) 15083 return OK; 15084 15085 /* If the directory exists we're done. Otherwise: create it.*/ 15086 updir = vim_strnsave(dir, (int)(p - dir)); 15087 if (updir == NULL) 15088 return FAIL; 15089 if (mch_isdir(updir)) 15090 r = OK; 15091 else if (mkdir_recurse(updir, prot) == OK) 15092 r = vim_mkdir_emsg(updir, prot); 15093 vim_free(updir); 15094 return r; 15095 } 15096 15097 #ifdef vim_mkdir 15098 /* 15099 * "mkdir()" function 15100 */ 15101 static void 15102 f_mkdir(argvars, rettv) 15103 typval_T *argvars; 15104 typval_T *rettv; 15105 { 15106 char_u *dir; 15107 char_u buf[NUMBUFLEN]; 15108 int prot = 0755; 15109 15110 rettv->vval.v_number = FAIL; 15111 if (check_restricted() || check_secure()) 15112 return; 15113 15114 dir = get_tv_string_buf(&argvars[0], buf); 15115 if (*dir == NUL) 15116 rettv->vval.v_number = FAIL; 15117 else 15118 { 15119 if (*gettail(dir) == NUL) 15120 /* remove trailing slashes */ 15121 *gettail_sep(dir) = NUL; 15122 15123 if (argvars[1].v_type != VAR_UNKNOWN) 15124 { 15125 if (argvars[2].v_type != VAR_UNKNOWN) 15126 prot = get_tv_number_chk(&argvars[2], NULL); 15127 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 15128 mkdir_recurse(dir, prot); 15129 } 15130 rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); 15131 } 15132 } 15133 #endif 15134 15135 /* 15136 * "mode()" function 15137 */ 15138 static void 15139 f_mode(argvars, rettv) 15140 typval_T *argvars; 15141 typval_T *rettv; 15142 { 15143 char_u buf[3]; 15144 15145 buf[1] = NUL; 15146 buf[2] = NUL; 15147 15148 if (VIsual_active) 15149 { 15150 if (VIsual_select) 15151 buf[0] = VIsual_mode + 's' - 'v'; 15152 else 15153 buf[0] = VIsual_mode; 15154 } 15155 else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 15156 || State == CONFIRM) 15157 { 15158 buf[0] = 'r'; 15159 if (State == ASKMORE) 15160 buf[1] = 'm'; 15161 else if (State == CONFIRM) 15162 buf[1] = '?'; 15163 } 15164 else if (State == EXTERNCMD) 15165 buf[0] = '!'; 15166 else if (State & INSERT) 15167 { 15168 #ifdef FEAT_VREPLACE 15169 if (State & VREPLACE_FLAG) 15170 { 15171 buf[0] = 'R'; 15172 buf[1] = 'v'; 15173 } 15174 else 15175 #endif 15176 if (State & REPLACE_FLAG) 15177 buf[0] = 'R'; 15178 else 15179 buf[0] = 'i'; 15180 } 15181 else if (State & CMDLINE) 15182 { 15183 buf[0] = 'c'; 15184 if (exmode_active) 15185 buf[1] = 'v'; 15186 } 15187 else if (exmode_active) 15188 { 15189 buf[0] = 'c'; 15190 buf[1] = 'e'; 15191 } 15192 else 15193 { 15194 buf[0] = 'n'; 15195 if (finish_op) 15196 buf[1] = 'o'; 15197 } 15198 15199 /* Clear out the minor mode when the argument is not a non-zero number or 15200 * non-empty string. */ 15201 if (!non_zero_arg(&argvars[0])) 15202 buf[1] = NUL; 15203 15204 rettv->vval.v_string = vim_strsave(buf); 15205 rettv->v_type = VAR_STRING; 15206 } 15207 15208 #if defined(FEAT_MZSCHEME) || defined(PROTO) 15209 /* 15210 * "mzeval()" function 15211 */ 15212 static void 15213 f_mzeval(argvars, rettv) 15214 typval_T *argvars; 15215 typval_T *rettv; 15216 { 15217 char_u *str; 15218 char_u buf[NUMBUFLEN]; 15219 15220 str = get_tv_string_buf(&argvars[0], buf); 15221 do_mzeval(str, rettv); 15222 } 15223 15224 void 15225 mzscheme_call_vim(name, args, rettv) 15226 char_u *name; 15227 typval_T *args; 15228 typval_T *rettv; 15229 { 15230 typval_T argvars[3]; 15231 15232 argvars[0].v_type = VAR_STRING; 15233 argvars[0].vval.v_string = name; 15234 copy_tv(args, &argvars[1]); 15235 argvars[2].v_type = VAR_UNKNOWN; 15236 f_call(argvars, rettv); 15237 clear_tv(&argvars[1]); 15238 } 15239 #endif 15240 15241 /* 15242 * "nextnonblank()" function 15243 */ 15244 static void 15245 f_nextnonblank(argvars, rettv) 15246 typval_T *argvars; 15247 typval_T *rettv; 15248 { 15249 linenr_T lnum; 15250 15251 for (lnum = get_tv_lnum(argvars); ; ++lnum) 15252 { 15253 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 15254 { 15255 lnum = 0; 15256 break; 15257 } 15258 if (*skipwhite(ml_get(lnum)) != NUL) 15259 break; 15260 } 15261 rettv->vval.v_number = lnum; 15262 } 15263 15264 /* 15265 * "nr2char()" function 15266 */ 15267 static void 15268 f_nr2char(argvars, rettv) 15269 typval_T *argvars; 15270 typval_T *rettv; 15271 { 15272 char_u buf[NUMBUFLEN]; 15273 15274 #ifdef FEAT_MBYTE 15275 if (has_mbyte) 15276 { 15277 int utf8 = 0; 15278 15279 if (argvars[1].v_type != VAR_UNKNOWN) 15280 utf8 = get_tv_number_chk(&argvars[1], NULL); 15281 if (utf8) 15282 buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 15283 else 15284 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 15285 } 15286 else 15287 #endif 15288 { 15289 buf[0] = (char_u)get_tv_number(&argvars[0]); 15290 buf[1] = NUL; 15291 } 15292 rettv->v_type = VAR_STRING; 15293 rettv->vval.v_string = vim_strsave(buf); 15294 } 15295 15296 /* 15297 * "or(expr, expr)" function 15298 */ 15299 static void 15300 f_or(argvars, rettv) 15301 typval_T *argvars; 15302 typval_T *rettv; 15303 { 15304 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 15305 | get_tv_number_chk(&argvars[1], NULL); 15306 } 15307 15308 /* 15309 * "pathshorten()" function 15310 */ 15311 static void 15312 f_pathshorten(argvars, rettv) 15313 typval_T *argvars; 15314 typval_T *rettv; 15315 { 15316 char_u *p; 15317 15318 rettv->v_type = VAR_STRING; 15319 p = get_tv_string_chk(&argvars[0]); 15320 if (p == NULL) 15321 rettv->vval.v_string = NULL; 15322 else 15323 { 15324 p = vim_strsave(p); 15325 rettv->vval.v_string = p; 15326 if (p != NULL) 15327 shorten_dir(p); 15328 } 15329 } 15330 15331 #ifdef FEAT_FLOAT 15332 /* 15333 * "pow()" function 15334 */ 15335 static void 15336 f_pow(argvars, rettv) 15337 typval_T *argvars; 15338 typval_T *rettv; 15339 { 15340 float_T fx, fy; 15341 15342 rettv->v_type = VAR_FLOAT; 15343 if (get_float_arg(argvars, &fx) == OK 15344 && get_float_arg(&argvars[1], &fy) == OK) 15345 rettv->vval.v_float = pow(fx, fy); 15346 else 15347 rettv->vval.v_float = 0.0; 15348 } 15349 #endif 15350 15351 /* 15352 * "prevnonblank()" function 15353 */ 15354 static void 15355 f_prevnonblank(argvars, rettv) 15356 typval_T *argvars; 15357 typval_T *rettv; 15358 { 15359 linenr_T lnum; 15360 15361 lnum = get_tv_lnum(argvars); 15362 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 15363 lnum = 0; 15364 else 15365 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 15366 --lnum; 15367 rettv->vval.v_number = lnum; 15368 } 15369 15370 #ifdef HAVE_STDARG_H 15371 /* This dummy va_list is here because: 15372 * - passing a NULL pointer doesn't work when va_list isn't a pointer 15373 * - locally in the function results in a "used before set" warning 15374 * - using va_start() to initialize it gives "function with fixed args" error */ 15375 static va_list ap; 15376 #endif 15377 15378 /* 15379 * "printf()" function 15380 */ 15381 static void 15382 f_printf(argvars, rettv) 15383 typval_T *argvars; 15384 typval_T *rettv; 15385 { 15386 rettv->v_type = VAR_STRING; 15387 rettv->vval.v_string = NULL; 15388 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 15389 { 15390 char_u buf[NUMBUFLEN]; 15391 int len; 15392 char_u *s; 15393 int saved_did_emsg = did_emsg; 15394 char *fmt; 15395 15396 /* Get the required length, allocate the buffer and do it for real. */ 15397 did_emsg = FALSE; 15398 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 15399 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 15400 if (!did_emsg) 15401 { 15402 s = alloc(len + 1); 15403 if (s != NULL) 15404 { 15405 rettv->vval.v_string = s; 15406 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 15407 } 15408 } 15409 did_emsg |= saved_did_emsg; 15410 } 15411 #endif 15412 } 15413 15414 /* 15415 * "pumvisible()" function 15416 */ 15417 static void 15418 f_pumvisible(argvars, rettv) 15419 typval_T *argvars UNUSED; 15420 typval_T *rettv UNUSED; 15421 { 15422 #ifdef FEAT_INS_EXPAND 15423 if (pum_visible()) 15424 rettv->vval.v_number = 1; 15425 #endif 15426 } 15427 15428 #ifdef FEAT_PYTHON3 15429 /* 15430 * "py3eval()" function 15431 */ 15432 static void 15433 f_py3eval(argvars, rettv) 15434 typval_T *argvars; 15435 typval_T *rettv; 15436 { 15437 char_u *str; 15438 char_u buf[NUMBUFLEN]; 15439 15440 str = get_tv_string_buf(&argvars[0], buf); 15441 do_py3eval(str, rettv); 15442 } 15443 #endif 15444 15445 #ifdef FEAT_PYTHON 15446 /* 15447 * "pyeval()" function 15448 */ 15449 static void 15450 f_pyeval(argvars, rettv) 15451 typval_T *argvars; 15452 typval_T *rettv; 15453 { 15454 char_u *str; 15455 char_u buf[NUMBUFLEN]; 15456 15457 str = get_tv_string_buf(&argvars[0], buf); 15458 do_pyeval(str, rettv); 15459 } 15460 #endif 15461 15462 /* 15463 * "range()" function 15464 */ 15465 static void 15466 f_range(argvars, rettv) 15467 typval_T *argvars; 15468 typval_T *rettv; 15469 { 15470 long start; 15471 long end; 15472 long stride = 1; 15473 long i; 15474 int error = FALSE; 15475 15476 start = get_tv_number_chk(&argvars[0], &error); 15477 if (argvars[1].v_type == VAR_UNKNOWN) 15478 { 15479 end = start - 1; 15480 start = 0; 15481 } 15482 else 15483 { 15484 end = get_tv_number_chk(&argvars[1], &error); 15485 if (argvars[2].v_type != VAR_UNKNOWN) 15486 stride = get_tv_number_chk(&argvars[2], &error); 15487 } 15488 15489 if (error) 15490 return; /* type error; errmsg already given */ 15491 if (stride == 0) 15492 EMSG(_("E726: Stride is zero")); 15493 else if (stride > 0 ? end + 1 < start : end - 1 > start) 15494 EMSG(_("E727: Start past end")); 15495 else 15496 { 15497 if (rettv_list_alloc(rettv) == OK) 15498 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 15499 if (list_append_number(rettv->vval.v_list, 15500 (varnumber_T)i) == FAIL) 15501 break; 15502 } 15503 } 15504 15505 /* 15506 * "readfile()" function 15507 */ 15508 static void 15509 f_readfile(argvars, rettv) 15510 typval_T *argvars; 15511 typval_T *rettv; 15512 { 15513 int binary = FALSE; 15514 int failed = FALSE; 15515 char_u *fname; 15516 FILE *fd; 15517 char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */ 15518 int io_size = sizeof(buf); 15519 int readlen; /* size of last fread() */ 15520 char_u *prev = NULL; /* previously read bytes, if any */ 15521 long prevlen = 0; /* length of data in prev */ 15522 long prevsize = 0; /* size of prev buffer */ 15523 long maxline = MAXLNUM; 15524 long cnt = 0; 15525 char_u *p; /* position in buf */ 15526 char_u *start; /* start of current line */ 15527 15528 if (argvars[1].v_type != VAR_UNKNOWN) 15529 { 15530 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 15531 binary = TRUE; 15532 if (argvars[2].v_type != VAR_UNKNOWN) 15533 maxline = get_tv_number(&argvars[2]); 15534 } 15535 15536 if (rettv_list_alloc(rettv) == FAIL) 15537 return; 15538 15539 /* Always open the file in binary mode, library functions have a mind of 15540 * their own about CR-LF conversion. */ 15541 fname = get_tv_string(&argvars[0]); 15542 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 15543 { 15544 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 15545 return; 15546 } 15547 15548 while (cnt < maxline || maxline < 0) 15549 { 15550 readlen = (int)fread(buf, 1, io_size, fd); 15551 15552 /* This for loop processes what was read, but is also entered at end 15553 * of file so that either: 15554 * - an incomplete line gets written 15555 * - a "binary" file gets an empty line at the end if it ends in a 15556 * newline. */ 15557 for (p = buf, start = buf; 15558 p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary)); 15559 ++p) 15560 { 15561 if (*p == '\n' || readlen <= 0) 15562 { 15563 listitem_T *li; 15564 char_u *s = NULL; 15565 long_u len = p - start; 15566 15567 /* Finished a line. Remove CRs before NL. */ 15568 if (readlen > 0 && !binary) 15569 { 15570 while (len > 0 && start[len - 1] == '\r') 15571 --len; 15572 /* removal may cross back to the "prev" string */ 15573 if (len == 0) 15574 while (prevlen > 0 && prev[prevlen - 1] == '\r') 15575 --prevlen; 15576 } 15577 if (prevlen == 0) 15578 s = vim_strnsave(start, (int)len); 15579 else 15580 { 15581 /* Change "prev" buffer to be the right size. This way 15582 * the bytes are only copied once, and very long lines are 15583 * allocated only once. */ 15584 if ((s = vim_realloc(prev, prevlen + len + 1)) != NULL) 15585 { 15586 mch_memmove(s + prevlen, start, len); 15587 s[prevlen + len] = NUL; 15588 prev = NULL; /* the list will own the string */ 15589 prevlen = prevsize = 0; 15590 } 15591 } 15592 if (s == NULL) 15593 { 15594 do_outofmem_msg((long_u) prevlen + len + 1); 15595 failed = TRUE; 15596 break; 15597 } 15598 15599 if ((li = listitem_alloc()) == NULL) 15600 { 15601 vim_free(s); 15602 failed = TRUE; 15603 break; 15604 } 15605 li->li_tv.v_type = VAR_STRING; 15606 li->li_tv.v_lock = 0; 15607 li->li_tv.vval.v_string = s; 15608 list_append(rettv->vval.v_list, li); 15609 15610 start = p + 1; /* step over newline */ 15611 if ((++cnt >= maxline && maxline >= 0) || readlen <= 0) 15612 break; 15613 } 15614 else if (*p == NUL) 15615 *p = '\n'; 15616 #ifdef FEAT_MBYTE 15617 /* Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this 15618 * when finding the BF and check the previous two bytes. */ 15619 else if (*p == 0xbf && enc_utf8 && !binary) 15620 { 15621 /* Find the two bytes before the 0xbf. If p is at buf, or buf 15622 * + 1, these may be in the "prev" string. */ 15623 char_u back1 = p >= buf + 1 ? p[-1] 15624 : prevlen >= 1 ? prev[prevlen - 1] : NUL; 15625 char_u back2 = p >= buf + 2 ? p[-2] 15626 : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1] 15627 : prevlen >= 2 ? prev[prevlen - 2] : NUL; 15628 15629 if (back2 == 0xef && back1 == 0xbb) 15630 { 15631 char_u *dest = p - 2; 15632 15633 /* Usually a BOM is at the beginning of a file, and so at 15634 * the beginning of a line; then we can just step over it. 15635 */ 15636 if (start == dest) 15637 start = p + 1; 15638 else 15639 { 15640 /* have to shuffle buf to close gap */ 15641 int adjust_prevlen = 0; 15642 15643 if (dest < buf) 15644 { 15645 adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */ 15646 dest = buf; 15647 } 15648 if (readlen > p - buf + 1) 15649 mch_memmove(dest, p + 1, readlen - (p - buf) - 1); 15650 readlen -= 3 - adjust_prevlen; 15651 prevlen -= adjust_prevlen; 15652 p = dest - 1; 15653 } 15654 } 15655 } 15656 #endif 15657 } /* for */ 15658 15659 if (failed || (cnt >= maxline && maxline >= 0) || readlen <= 0) 15660 break; 15661 if (start < p) 15662 { 15663 /* There's part of a line in buf, store it in "prev". */ 15664 if (p - start + prevlen >= prevsize) 15665 { 15666 /* need bigger "prev" buffer */ 15667 char_u *newprev; 15668 15669 /* A common use case is ordinary text files and "prev" gets a 15670 * fragment of a line, so the first allocation is made 15671 * small, to avoid repeatedly 'allocing' large and 15672 * 'reallocing' small. */ 15673 if (prevsize == 0) 15674 prevsize = (long)(p - start); 15675 else 15676 { 15677 long grow50pc = (prevsize * 3) / 2; 15678 long growmin = (long)((p - start) * 2 + prevlen); 15679 prevsize = grow50pc > growmin ? grow50pc : growmin; 15680 } 15681 newprev = prev == NULL ? alloc(prevsize) 15682 : vim_realloc(prev, prevsize); 15683 if (newprev == NULL) 15684 { 15685 do_outofmem_msg((long_u)prevsize); 15686 failed = TRUE; 15687 break; 15688 } 15689 prev = newprev; 15690 } 15691 /* Add the line part to end of "prev". */ 15692 mch_memmove(prev + prevlen, start, p - start); 15693 prevlen += (long)(p - start); 15694 } 15695 } /* while */ 15696 15697 /* 15698 * For a negative line count use only the lines at the end of the file, 15699 * free the rest. 15700 */ 15701 if (!failed && maxline < 0) 15702 while (cnt > -maxline) 15703 { 15704 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 15705 --cnt; 15706 } 15707 15708 if (failed) 15709 { 15710 list_free(rettv->vval.v_list, TRUE); 15711 /* readfile doc says an empty list is returned on error */ 15712 rettv->vval.v_list = list_alloc(); 15713 } 15714 15715 vim_free(prev); 15716 fclose(fd); 15717 } 15718 15719 #if defined(FEAT_RELTIME) 15720 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 15721 15722 /* 15723 * Convert a List to proftime_T. 15724 * Return FAIL when there is something wrong. 15725 */ 15726 static int 15727 list2proftime(arg, tm) 15728 typval_T *arg; 15729 proftime_T *tm; 15730 { 15731 long n1, n2; 15732 int error = FALSE; 15733 15734 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 15735 || arg->vval.v_list->lv_len != 2) 15736 return FAIL; 15737 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 15738 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 15739 # ifdef WIN3264 15740 tm->HighPart = n1; 15741 tm->LowPart = n2; 15742 # else 15743 tm->tv_sec = n1; 15744 tm->tv_usec = n2; 15745 # endif 15746 return error ? FAIL : OK; 15747 } 15748 #endif /* FEAT_RELTIME */ 15749 15750 /* 15751 * "reltime()" function 15752 */ 15753 static void 15754 f_reltime(argvars, rettv) 15755 typval_T *argvars UNUSED; 15756 typval_T *rettv UNUSED; 15757 { 15758 #ifdef FEAT_RELTIME 15759 proftime_T res; 15760 proftime_T start; 15761 15762 if (argvars[0].v_type == VAR_UNKNOWN) 15763 { 15764 /* No arguments: get current time. */ 15765 profile_start(&res); 15766 } 15767 else if (argvars[1].v_type == VAR_UNKNOWN) 15768 { 15769 if (list2proftime(&argvars[0], &res) == FAIL) 15770 return; 15771 profile_end(&res); 15772 } 15773 else 15774 { 15775 /* Two arguments: compute the difference. */ 15776 if (list2proftime(&argvars[0], &start) == FAIL 15777 || list2proftime(&argvars[1], &res) == FAIL) 15778 return; 15779 profile_sub(&res, &start); 15780 } 15781 15782 if (rettv_list_alloc(rettv) == OK) 15783 { 15784 long n1, n2; 15785 15786 # ifdef WIN3264 15787 n1 = res.HighPart; 15788 n2 = res.LowPart; 15789 # else 15790 n1 = res.tv_sec; 15791 n2 = res.tv_usec; 15792 # endif 15793 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 15794 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 15795 } 15796 #endif 15797 } 15798 15799 /* 15800 * "reltimestr()" function 15801 */ 15802 static void 15803 f_reltimestr(argvars, rettv) 15804 typval_T *argvars UNUSED; 15805 typval_T *rettv; 15806 { 15807 #ifdef FEAT_RELTIME 15808 proftime_T tm; 15809 #endif 15810 15811 rettv->v_type = VAR_STRING; 15812 rettv->vval.v_string = NULL; 15813 #ifdef FEAT_RELTIME 15814 if (list2proftime(&argvars[0], &tm) == OK) 15815 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 15816 #endif 15817 } 15818 15819 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 15820 static void make_connection __ARGS((void)); 15821 static int check_connection __ARGS((void)); 15822 15823 static void 15824 make_connection() 15825 { 15826 if (X_DISPLAY == NULL 15827 # ifdef FEAT_GUI 15828 && !gui.in_use 15829 # endif 15830 ) 15831 { 15832 x_force_connect = TRUE; 15833 setup_term_clip(); 15834 x_force_connect = FALSE; 15835 } 15836 } 15837 15838 static int 15839 check_connection() 15840 { 15841 make_connection(); 15842 if (X_DISPLAY == NULL) 15843 { 15844 EMSG(_("E240: No connection to Vim server")); 15845 return FAIL; 15846 } 15847 return OK; 15848 } 15849 #endif 15850 15851 #ifdef FEAT_CLIENTSERVER 15852 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 15853 15854 static void 15855 remote_common(argvars, rettv, expr) 15856 typval_T *argvars; 15857 typval_T *rettv; 15858 int expr; 15859 { 15860 char_u *server_name; 15861 char_u *keys; 15862 char_u *r = NULL; 15863 char_u buf[NUMBUFLEN]; 15864 # ifdef WIN32 15865 HWND w; 15866 # else 15867 Window w; 15868 # endif 15869 15870 if (check_restricted() || check_secure()) 15871 return; 15872 15873 # ifdef FEAT_X11 15874 if (check_connection() == FAIL) 15875 return; 15876 # endif 15877 15878 server_name = get_tv_string_chk(&argvars[0]); 15879 if (server_name == NULL) 15880 return; /* type error; errmsg already given */ 15881 keys = get_tv_string_buf(&argvars[1], buf); 15882 # ifdef WIN32 15883 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 15884 # else 15885 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 15886 < 0) 15887 # endif 15888 { 15889 if (r != NULL) 15890 EMSG(r); /* sending worked but evaluation failed */ 15891 else 15892 EMSG2(_("E241: Unable to send to %s"), server_name); 15893 return; 15894 } 15895 15896 rettv->vval.v_string = r; 15897 15898 if (argvars[2].v_type != VAR_UNKNOWN) 15899 { 15900 dictitem_T v; 15901 char_u str[30]; 15902 char_u *idvar; 15903 15904 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 15905 v.di_tv.v_type = VAR_STRING; 15906 v.di_tv.vval.v_string = vim_strsave(str); 15907 idvar = get_tv_string_chk(&argvars[2]); 15908 if (idvar != NULL) 15909 set_var(idvar, &v.di_tv, FALSE); 15910 vim_free(v.di_tv.vval.v_string); 15911 } 15912 } 15913 #endif 15914 15915 /* 15916 * "remote_expr()" function 15917 */ 15918 static void 15919 f_remote_expr(argvars, rettv) 15920 typval_T *argvars UNUSED; 15921 typval_T *rettv; 15922 { 15923 rettv->v_type = VAR_STRING; 15924 rettv->vval.v_string = NULL; 15925 #ifdef FEAT_CLIENTSERVER 15926 remote_common(argvars, rettv, TRUE); 15927 #endif 15928 } 15929 15930 /* 15931 * "remote_foreground()" function 15932 */ 15933 static void 15934 f_remote_foreground(argvars, rettv) 15935 typval_T *argvars UNUSED; 15936 typval_T *rettv UNUSED; 15937 { 15938 #ifdef FEAT_CLIENTSERVER 15939 # ifdef WIN32 15940 /* On Win32 it's done in this application. */ 15941 { 15942 char_u *server_name = get_tv_string_chk(&argvars[0]); 15943 15944 if (server_name != NULL) 15945 serverForeground(server_name); 15946 } 15947 # else 15948 /* Send a foreground() expression to the server. */ 15949 argvars[1].v_type = VAR_STRING; 15950 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 15951 argvars[2].v_type = VAR_UNKNOWN; 15952 remote_common(argvars, rettv, TRUE); 15953 vim_free(argvars[1].vval.v_string); 15954 # endif 15955 #endif 15956 } 15957 15958 static void 15959 f_remote_peek(argvars, rettv) 15960 typval_T *argvars UNUSED; 15961 typval_T *rettv; 15962 { 15963 #ifdef FEAT_CLIENTSERVER 15964 dictitem_T v; 15965 char_u *s = NULL; 15966 # ifdef WIN32 15967 long_u n = 0; 15968 # endif 15969 char_u *serverid; 15970 15971 if (check_restricted() || check_secure()) 15972 { 15973 rettv->vval.v_number = -1; 15974 return; 15975 } 15976 serverid = get_tv_string_chk(&argvars[0]); 15977 if (serverid == NULL) 15978 { 15979 rettv->vval.v_number = -1; 15980 return; /* type error; errmsg already given */ 15981 } 15982 # ifdef WIN32 15983 sscanf(serverid, SCANF_HEX_LONG_U, &n); 15984 if (n == 0) 15985 rettv->vval.v_number = -1; 15986 else 15987 { 15988 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 15989 rettv->vval.v_number = (s != NULL); 15990 } 15991 # else 15992 if (check_connection() == FAIL) 15993 return; 15994 15995 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 15996 serverStrToWin(serverid), &s); 15997 # endif 15998 15999 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 16000 { 16001 char_u *retvar; 16002 16003 v.di_tv.v_type = VAR_STRING; 16004 v.di_tv.vval.v_string = vim_strsave(s); 16005 retvar = get_tv_string_chk(&argvars[1]); 16006 if (retvar != NULL) 16007 set_var(retvar, &v.di_tv, FALSE); 16008 vim_free(v.di_tv.vval.v_string); 16009 } 16010 #else 16011 rettv->vval.v_number = -1; 16012 #endif 16013 } 16014 16015 static void 16016 f_remote_read(argvars, rettv) 16017 typval_T *argvars UNUSED; 16018 typval_T *rettv; 16019 { 16020 char_u *r = NULL; 16021 16022 #ifdef FEAT_CLIENTSERVER 16023 char_u *serverid = get_tv_string_chk(&argvars[0]); 16024 16025 if (serverid != NULL && !check_restricted() && !check_secure()) 16026 { 16027 # ifdef WIN32 16028 /* The server's HWND is encoded in the 'id' parameter */ 16029 long_u n = 0; 16030 16031 sscanf(serverid, SCANF_HEX_LONG_U, &n); 16032 if (n != 0) 16033 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 16034 if (r == NULL) 16035 # else 16036 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 16037 serverStrToWin(serverid), &r, FALSE) < 0) 16038 # endif 16039 EMSG(_("E277: Unable to read a server reply")); 16040 } 16041 #endif 16042 rettv->v_type = VAR_STRING; 16043 rettv->vval.v_string = r; 16044 } 16045 16046 /* 16047 * "remote_send()" function 16048 */ 16049 static void 16050 f_remote_send(argvars, rettv) 16051 typval_T *argvars UNUSED; 16052 typval_T *rettv; 16053 { 16054 rettv->v_type = VAR_STRING; 16055 rettv->vval.v_string = NULL; 16056 #ifdef FEAT_CLIENTSERVER 16057 remote_common(argvars, rettv, FALSE); 16058 #endif 16059 } 16060 16061 /* 16062 * "remove()" function 16063 */ 16064 static void 16065 f_remove(argvars, rettv) 16066 typval_T *argvars; 16067 typval_T *rettv; 16068 { 16069 list_T *l; 16070 listitem_T *item, *item2; 16071 listitem_T *li; 16072 long idx; 16073 long end; 16074 char_u *key; 16075 dict_T *d; 16076 dictitem_T *di; 16077 char_u *arg_errmsg = (char_u *)N_("remove() argument"); 16078 16079 if (argvars[0].v_type == VAR_DICT) 16080 { 16081 if (argvars[2].v_type != VAR_UNKNOWN) 16082 EMSG2(_(e_toomanyarg), "remove()"); 16083 else if ((d = argvars[0].vval.v_dict) != NULL 16084 && !tv_check_lock(d->dv_lock, arg_errmsg, TRUE)) 16085 { 16086 key = get_tv_string_chk(&argvars[1]); 16087 if (key != NULL) 16088 { 16089 di = dict_find(d, key, -1); 16090 if (di == NULL) 16091 EMSG2(_(e_dictkey), key); 16092 else if (!var_check_fixed(di->di_flags, arg_errmsg, TRUE) 16093 && !var_check_ro(di->di_flags, arg_errmsg, TRUE)) 16094 { 16095 *rettv = di->di_tv; 16096 init_tv(&di->di_tv); 16097 dictitem_remove(d, di); 16098 } 16099 } 16100 } 16101 } 16102 else if (argvars[0].v_type != VAR_LIST) 16103 EMSG2(_(e_listdictarg), "remove()"); 16104 else if ((l = argvars[0].vval.v_list) != NULL 16105 && !tv_check_lock(l->lv_lock, arg_errmsg, TRUE)) 16106 { 16107 int error = FALSE; 16108 16109 idx = get_tv_number_chk(&argvars[1], &error); 16110 if (error) 16111 ; /* type error: do nothing, errmsg already given */ 16112 else if ((item = list_find(l, idx)) == NULL) 16113 EMSGN(_(e_listidx), idx); 16114 else 16115 { 16116 if (argvars[2].v_type == VAR_UNKNOWN) 16117 { 16118 /* Remove one item, return its value. */ 16119 vimlist_remove(l, item, item); 16120 *rettv = item->li_tv; 16121 vim_free(item); 16122 } 16123 else 16124 { 16125 /* Remove range of items, return list with values. */ 16126 end = get_tv_number_chk(&argvars[2], &error); 16127 if (error) 16128 ; /* type error: do nothing */ 16129 else if ((item2 = list_find(l, end)) == NULL) 16130 EMSGN(_(e_listidx), end); 16131 else 16132 { 16133 int cnt = 0; 16134 16135 for (li = item; li != NULL; li = li->li_next) 16136 { 16137 ++cnt; 16138 if (li == item2) 16139 break; 16140 } 16141 if (li == NULL) /* didn't find "item2" after "item" */ 16142 EMSG(_(e_invrange)); 16143 else 16144 { 16145 vimlist_remove(l, item, item2); 16146 if (rettv_list_alloc(rettv) == OK) 16147 { 16148 l = rettv->vval.v_list; 16149 l->lv_first = item; 16150 l->lv_last = item2; 16151 item->li_prev = NULL; 16152 item2->li_next = NULL; 16153 l->lv_len = cnt; 16154 } 16155 } 16156 } 16157 } 16158 } 16159 } 16160 } 16161 16162 /* 16163 * "rename({from}, {to})" function 16164 */ 16165 static void 16166 f_rename(argvars, rettv) 16167 typval_T *argvars; 16168 typval_T *rettv; 16169 { 16170 char_u buf[NUMBUFLEN]; 16171 16172 if (check_restricted() || check_secure()) 16173 rettv->vval.v_number = -1; 16174 else 16175 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 16176 get_tv_string_buf(&argvars[1], buf)); 16177 } 16178 16179 /* 16180 * "repeat()" function 16181 */ 16182 static void 16183 f_repeat(argvars, rettv) 16184 typval_T *argvars; 16185 typval_T *rettv; 16186 { 16187 char_u *p; 16188 int n; 16189 int slen; 16190 int len; 16191 char_u *r; 16192 int i; 16193 16194 n = get_tv_number(&argvars[1]); 16195 if (argvars[0].v_type == VAR_LIST) 16196 { 16197 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 16198 while (n-- > 0) 16199 if (list_extend(rettv->vval.v_list, 16200 argvars[0].vval.v_list, NULL) == FAIL) 16201 break; 16202 } 16203 else 16204 { 16205 p = get_tv_string(&argvars[0]); 16206 rettv->v_type = VAR_STRING; 16207 rettv->vval.v_string = NULL; 16208 16209 slen = (int)STRLEN(p); 16210 len = slen * n; 16211 if (len <= 0) 16212 return; 16213 16214 r = alloc(len + 1); 16215 if (r != NULL) 16216 { 16217 for (i = 0; i < n; i++) 16218 mch_memmove(r + i * slen, p, (size_t)slen); 16219 r[len] = NUL; 16220 } 16221 16222 rettv->vval.v_string = r; 16223 } 16224 } 16225 16226 /* 16227 * "resolve()" function 16228 */ 16229 static void 16230 f_resolve(argvars, rettv) 16231 typval_T *argvars; 16232 typval_T *rettv; 16233 { 16234 char_u *p; 16235 #ifdef HAVE_READLINK 16236 char_u *buf = NULL; 16237 #endif 16238 16239 p = get_tv_string(&argvars[0]); 16240 #ifdef FEAT_SHORTCUT 16241 { 16242 char_u *v = NULL; 16243 16244 v = mch_resolve_shortcut(p); 16245 if (v != NULL) 16246 rettv->vval.v_string = v; 16247 else 16248 rettv->vval.v_string = vim_strsave(p); 16249 } 16250 #else 16251 # ifdef HAVE_READLINK 16252 { 16253 char_u *cpy; 16254 int len; 16255 char_u *remain = NULL; 16256 char_u *q; 16257 int is_relative_to_current = FALSE; 16258 int has_trailing_pathsep = FALSE; 16259 int limit = 100; 16260 16261 p = vim_strsave(p); 16262 16263 if (p[0] == '.' && (vim_ispathsep(p[1]) 16264 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 16265 is_relative_to_current = TRUE; 16266 16267 len = STRLEN(p); 16268 if (len > 0 && after_pathsep(p, p + len)) 16269 { 16270 has_trailing_pathsep = TRUE; 16271 p[len - 1] = NUL; /* the trailing slash breaks readlink() */ 16272 } 16273 16274 q = getnextcomp(p); 16275 if (*q != NUL) 16276 { 16277 /* Separate the first path component in "p", and keep the 16278 * remainder (beginning with the path separator). */ 16279 remain = vim_strsave(q - 1); 16280 q[-1] = NUL; 16281 } 16282 16283 buf = alloc(MAXPATHL + 1); 16284 if (buf == NULL) 16285 goto fail; 16286 16287 for (;;) 16288 { 16289 for (;;) 16290 { 16291 len = readlink((char *)p, (char *)buf, MAXPATHL); 16292 if (len <= 0) 16293 break; 16294 buf[len] = NUL; 16295 16296 if (limit-- == 0) 16297 { 16298 vim_free(p); 16299 vim_free(remain); 16300 EMSG(_("E655: Too many symbolic links (cycle?)")); 16301 rettv->vval.v_string = NULL; 16302 goto fail; 16303 } 16304 16305 /* Ensure that the result will have a trailing path separator 16306 * if the argument has one. */ 16307 if (remain == NULL && has_trailing_pathsep) 16308 add_pathsep(buf); 16309 16310 /* Separate the first path component in the link value and 16311 * concatenate the remainders. */ 16312 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 16313 if (*q != NUL) 16314 { 16315 if (remain == NULL) 16316 remain = vim_strsave(q - 1); 16317 else 16318 { 16319 cpy = concat_str(q - 1, remain); 16320 if (cpy != NULL) 16321 { 16322 vim_free(remain); 16323 remain = cpy; 16324 } 16325 } 16326 q[-1] = NUL; 16327 } 16328 16329 q = gettail(p); 16330 if (q > p && *q == NUL) 16331 { 16332 /* Ignore trailing path separator. */ 16333 q[-1] = NUL; 16334 q = gettail(p); 16335 } 16336 if (q > p && !mch_isFullName(buf)) 16337 { 16338 /* symlink is relative to directory of argument */ 16339 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 16340 if (cpy != NULL) 16341 { 16342 STRCPY(cpy, p); 16343 STRCPY(gettail(cpy), buf); 16344 vim_free(p); 16345 p = cpy; 16346 } 16347 } 16348 else 16349 { 16350 vim_free(p); 16351 p = vim_strsave(buf); 16352 } 16353 } 16354 16355 if (remain == NULL) 16356 break; 16357 16358 /* Append the first path component of "remain" to "p". */ 16359 q = getnextcomp(remain + 1); 16360 len = q - remain - (*q != NUL); 16361 cpy = vim_strnsave(p, STRLEN(p) + len); 16362 if (cpy != NULL) 16363 { 16364 STRNCAT(cpy, remain, len); 16365 vim_free(p); 16366 p = cpy; 16367 } 16368 /* Shorten "remain". */ 16369 if (*q != NUL) 16370 STRMOVE(remain, q - 1); 16371 else 16372 { 16373 vim_free(remain); 16374 remain = NULL; 16375 } 16376 } 16377 16378 /* If the result is a relative path name, make it explicitly relative to 16379 * the current directory if and only if the argument had this form. */ 16380 if (!vim_ispathsep(*p)) 16381 { 16382 if (is_relative_to_current 16383 && *p != NUL 16384 && !(p[0] == '.' 16385 && (p[1] == NUL 16386 || vim_ispathsep(p[1]) 16387 || (p[1] == '.' 16388 && (p[2] == NUL 16389 || vim_ispathsep(p[2])))))) 16390 { 16391 /* Prepend "./". */ 16392 cpy = concat_str((char_u *)"./", p); 16393 if (cpy != NULL) 16394 { 16395 vim_free(p); 16396 p = cpy; 16397 } 16398 } 16399 else if (!is_relative_to_current) 16400 { 16401 /* Strip leading "./". */ 16402 q = p; 16403 while (q[0] == '.' && vim_ispathsep(q[1])) 16404 q += 2; 16405 if (q > p) 16406 STRMOVE(p, p + 2); 16407 } 16408 } 16409 16410 /* Ensure that the result will have no trailing path separator 16411 * if the argument had none. But keep "/" or "//". */ 16412 if (!has_trailing_pathsep) 16413 { 16414 q = p + STRLEN(p); 16415 if (after_pathsep(p, q)) 16416 *gettail_sep(p) = NUL; 16417 } 16418 16419 rettv->vval.v_string = p; 16420 } 16421 # else 16422 rettv->vval.v_string = vim_strsave(p); 16423 # endif 16424 #endif 16425 16426 simplify_filename(rettv->vval.v_string); 16427 16428 #ifdef HAVE_READLINK 16429 fail: 16430 vim_free(buf); 16431 #endif 16432 rettv->v_type = VAR_STRING; 16433 } 16434 16435 /* 16436 * "reverse({list})" function 16437 */ 16438 static void 16439 f_reverse(argvars, rettv) 16440 typval_T *argvars; 16441 typval_T *rettv; 16442 { 16443 list_T *l; 16444 listitem_T *li, *ni; 16445 16446 if (argvars[0].v_type != VAR_LIST) 16447 EMSG2(_(e_listarg), "reverse()"); 16448 else if ((l = argvars[0].vval.v_list) != NULL 16449 && !tv_check_lock(l->lv_lock, 16450 (char_u *)N_("reverse() argument"), TRUE)) 16451 { 16452 li = l->lv_last; 16453 l->lv_first = l->lv_last = NULL; 16454 l->lv_len = 0; 16455 while (li != NULL) 16456 { 16457 ni = li->li_prev; 16458 list_append(l, li); 16459 li = ni; 16460 } 16461 rettv->vval.v_list = l; 16462 rettv->v_type = VAR_LIST; 16463 ++l->lv_refcount; 16464 l->lv_idx = l->lv_len - l->lv_idx - 1; 16465 } 16466 } 16467 16468 #define SP_NOMOVE 0x01 /* don't move cursor */ 16469 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 16470 #define SP_RETCOUNT 0x04 /* return matchcount */ 16471 #define SP_SETPCMARK 0x08 /* set previous context mark */ 16472 #define SP_START 0x10 /* accept match at start position */ 16473 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 16474 #define SP_END 0x40 /* leave cursor at end of match */ 16475 #define SP_COLUMN 0x80 /* start at cursor column */ 16476 16477 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 16478 16479 /* 16480 * Get flags for a search function. 16481 * Possibly sets "p_ws". 16482 * Returns BACKWARD, FORWARD or zero (for an error). 16483 */ 16484 static int 16485 get_search_arg(varp, flagsp) 16486 typval_T *varp; 16487 int *flagsp; 16488 { 16489 int dir = FORWARD; 16490 char_u *flags; 16491 char_u nbuf[NUMBUFLEN]; 16492 int mask; 16493 16494 if (varp->v_type != VAR_UNKNOWN) 16495 { 16496 flags = get_tv_string_buf_chk(varp, nbuf); 16497 if (flags == NULL) 16498 return 0; /* type error; errmsg already given */ 16499 while (*flags != NUL) 16500 { 16501 switch (*flags) 16502 { 16503 case 'b': dir = BACKWARD; break; 16504 case 'w': p_ws = TRUE; break; 16505 case 'W': p_ws = FALSE; break; 16506 default: mask = 0; 16507 if (flagsp != NULL) 16508 switch (*flags) 16509 { 16510 case 'c': mask = SP_START; break; 16511 case 'e': mask = SP_END; break; 16512 case 'm': mask = SP_RETCOUNT; break; 16513 case 'n': mask = SP_NOMOVE; break; 16514 case 'p': mask = SP_SUBPAT; break; 16515 case 'r': mask = SP_REPEAT; break; 16516 case 's': mask = SP_SETPCMARK; break; 16517 case 'z': mask = SP_COLUMN; break; 16518 } 16519 if (mask == 0) 16520 { 16521 EMSG2(_(e_invarg2), flags); 16522 dir = 0; 16523 } 16524 else 16525 *flagsp |= mask; 16526 } 16527 if (dir == 0) 16528 break; 16529 ++flags; 16530 } 16531 } 16532 return dir; 16533 } 16534 16535 /* 16536 * Shared by search() and searchpos() functions. 16537 */ 16538 static int 16539 search_cmn(argvars, match_pos, flagsp) 16540 typval_T *argvars; 16541 pos_T *match_pos; 16542 int *flagsp; 16543 { 16544 int flags; 16545 char_u *pat; 16546 pos_T pos; 16547 pos_T save_cursor; 16548 int save_p_ws = p_ws; 16549 int dir; 16550 int retval = 0; /* default: FAIL */ 16551 long lnum_stop = 0; 16552 proftime_T tm; 16553 #ifdef FEAT_RELTIME 16554 long time_limit = 0; 16555 #endif 16556 int options = SEARCH_KEEP; 16557 int subpatnum; 16558 16559 pat = get_tv_string(&argvars[0]); 16560 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 16561 if (dir == 0) 16562 goto theend; 16563 flags = *flagsp; 16564 if (flags & SP_START) 16565 options |= SEARCH_START; 16566 if (flags & SP_END) 16567 options |= SEARCH_END; 16568 if (flags & SP_COLUMN) 16569 options |= SEARCH_COL; 16570 16571 /* Optional arguments: line number to stop searching and timeout. */ 16572 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 16573 { 16574 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 16575 if (lnum_stop < 0) 16576 goto theend; 16577 #ifdef FEAT_RELTIME 16578 if (argvars[3].v_type != VAR_UNKNOWN) 16579 { 16580 time_limit = get_tv_number_chk(&argvars[3], NULL); 16581 if (time_limit < 0) 16582 goto theend; 16583 } 16584 #endif 16585 } 16586 16587 #ifdef FEAT_RELTIME 16588 /* Set the time limit, if there is one. */ 16589 profile_setlimit(time_limit, &tm); 16590 #endif 16591 16592 /* 16593 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 16594 * Check to make sure only those flags are set. 16595 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 16596 * flags cannot be set. Check for that condition also. 16597 */ 16598 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 16599 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 16600 { 16601 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 16602 goto theend; 16603 } 16604 16605 pos = save_cursor = curwin->w_cursor; 16606 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 16607 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 16608 if (subpatnum != FAIL) 16609 { 16610 if (flags & SP_SUBPAT) 16611 retval = subpatnum; 16612 else 16613 retval = pos.lnum; 16614 if (flags & SP_SETPCMARK) 16615 setpcmark(); 16616 curwin->w_cursor = pos; 16617 if (match_pos != NULL) 16618 { 16619 /* Store the match cursor position */ 16620 match_pos->lnum = pos.lnum; 16621 match_pos->col = pos.col + 1; 16622 } 16623 /* "/$" will put the cursor after the end of the line, may need to 16624 * correct that here */ 16625 check_cursor(); 16626 } 16627 16628 /* If 'n' flag is used: restore cursor position. */ 16629 if (flags & SP_NOMOVE) 16630 curwin->w_cursor = save_cursor; 16631 else 16632 curwin->w_set_curswant = TRUE; 16633 theend: 16634 p_ws = save_p_ws; 16635 16636 return retval; 16637 } 16638 16639 #ifdef FEAT_FLOAT 16640 16641 /* 16642 * round() is not in C90, use ceil() or floor() instead. 16643 */ 16644 float_T 16645 vim_round(f) 16646 float_T f; 16647 { 16648 return f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 16649 } 16650 16651 /* 16652 * "round({float})" function 16653 */ 16654 static void 16655 f_round(argvars, rettv) 16656 typval_T *argvars; 16657 typval_T *rettv; 16658 { 16659 float_T f; 16660 16661 rettv->v_type = VAR_FLOAT; 16662 if (get_float_arg(argvars, &f) == OK) 16663 rettv->vval.v_float = vim_round(f); 16664 else 16665 rettv->vval.v_float = 0.0; 16666 } 16667 #endif 16668 16669 /* 16670 * "screenattr()" function 16671 */ 16672 static void 16673 f_screenattr(argvars, rettv) 16674 typval_T *argvars UNUSED; 16675 typval_T *rettv; 16676 { 16677 int row; 16678 int col; 16679 int c; 16680 16681 row = get_tv_number_chk(&argvars[0], NULL) - 1; 16682 col = get_tv_number_chk(&argvars[1], NULL) - 1; 16683 if (row < 0 || row >= screen_Rows 16684 || col < 0 || col >= screen_Columns) 16685 c = -1; 16686 else 16687 c = ScreenAttrs[LineOffset[row] + col]; 16688 rettv->vval.v_number = c; 16689 } 16690 16691 /* 16692 * "screenchar()" function 16693 */ 16694 static void 16695 f_screenchar(argvars, rettv) 16696 typval_T *argvars UNUSED; 16697 typval_T *rettv; 16698 { 16699 int row; 16700 int col; 16701 int off; 16702 int c; 16703 16704 row = get_tv_number_chk(&argvars[0], NULL) - 1; 16705 col = get_tv_number_chk(&argvars[1], NULL) - 1; 16706 if (row < 0 || row >= screen_Rows 16707 || col < 0 || col >= screen_Columns) 16708 c = -1; 16709 else 16710 { 16711 off = LineOffset[row] + col; 16712 #ifdef FEAT_MBYTE 16713 if (enc_utf8 && ScreenLinesUC[off] != 0) 16714 c = ScreenLinesUC[off]; 16715 else 16716 #endif 16717 c = ScreenLines[off]; 16718 } 16719 rettv->vval.v_number = c; 16720 } 16721 16722 /* 16723 * "screencol()" function 16724 * 16725 * First column is 1 to be consistent with virtcol(). 16726 */ 16727 static void 16728 f_screencol(argvars, rettv) 16729 typval_T *argvars UNUSED; 16730 typval_T *rettv; 16731 { 16732 rettv->vval.v_number = screen_screencol() + 1; 16733 } 16734 16735 /* 16736 * "screenrow()" function 16737 */ 16738 static void 16739 f_screenrow(argvars, rettv) 16740 typval_T *argvars UNUSED; 16741 typval_T *rettv; 16742 { 16743 rettv->vval.v_number = screen_screenrow() + 1; 16744 } 16745 16746 /* 16747 * "search()" function 16748 */ 16749 static void 16750 f_search(argvars, rettv) 16751 typval_T *argvars; 16752 typval_T *rettv; 16753 { 16754 int flags = 0; 16755 16756 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 16757 } 16758 16759 /* 16760 * "searchdecl()" function 16761 */ 16762 static void 16763 f_searchdecl(argvars, rettv) 16764 typval_T *argvars; 16765 typval_T *rettv; 16766 { 16767 int locally = 1; 16768 int thisblock = 0; 16769 int error = FALSE; 16770 char_u *name; 16771 16772 rettv->vval.v_number = 1; /* default: FAIL */ 16773 16774 name = get_tv_string_chk(&argvars[0]); 16775 if (argvars[1].v_type != VAR_UNKNOWN) 16776 { 16777 locally = get_tv_number_chk(&argvars[1], &error) == 0; 16778 if (!error && argvars[2].v_type != VAR_UNKNOWN) 16779 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 16780 } 16781 if (!error && name != NULL) 16782 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 16783 locally, thisblock, SEARCH_KEEP) == FAIL; 16784 } 16785 16786 /* 16787 * Used by searchpair() and searchpairpos() 16788 */ 16789 static int 16790 searchpair_cmn(argvars, match_pos) 16791 typval_T *argvars; 16792 pos_T *match_pos; 16793 { 16794 char_u *spat, *mpat, *epat; 16795 char_u *skip; 16796 int save_p_ws = p_ws; 16797 int dir; 16798 int flags = 0; 16799 char_u nbuf1[NUMBUFLEN]; 16800 char_u nbuf2[NUMBUFLEN]; 16801 char_u nbuf3[NUMBUFLEN]; 16802 int retval = 0; /* default: FAIL */ 16803 long lnum_stop = 0; 16804 long time_limit = 0; 16805 16806 /* Get the three pattern arguments: start, middle, end. */ 16807 spat = get_tv_string_chk(&argvars[0]); 16808 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 16809 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 16810 if (spat == NULL || mpat == NULL || epat == NULL) 16811 goto theend; /* type error */ 16812 16813 /* Handle the optional fourth argument: flags */ 16814 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 16815 if (dir == 0) 16816 goto theend; 16817 16818 /* Don't accept SP_END or SP_SUBPAT. 16819 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 16820 */ 16821 if ((flags & (SP_END | SP_SUBPAT)) != 0 16822 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 16823 { 16824 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 16825 goto theend; 16826 } 16827 16828 /* Using 'r' implies 'W', otherwise it doesn't work. */ 16829 if (flags & SP_REPEAT) 16830 p_ws = FALSE; 16831 16832 /* Optional fifth argument: skip expression */ 16833 if (argvars[3].v_type == VAR_UNKNOWN 16834 || argvars[4].v_type == VAR_UNKNOWN) 16835 skip = (char_u *)""; 16836 else 16837 { 16838 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 16839 if (argvars[5].v_type != VAR_UNKNOWN) 16840 { 16841 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 16842 if (lnum_stop < 0) 16843 goto theend; 16844 #ifdef FEAT_RELTIME 16845 if (argvars[6].v_type != VAR_UNKNOWN) 16846 { 16847 time_limit = get_tv_number_chk(&argvars[6], NULL); 16848 if (time_limit < 0) 16849 goto theend; 16850 } 16851 #endif 16852 } 16853 } 16854 if (skip == NULL) 16855 goto theend; /* type error */ 16856 16857 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 16858 match_pos, lnum_stop, time_limit); 16859 16860 theend: 16861 p_ws = save_p_ws; 16862 16863 return retval; 16864 } 16865 16866 /* 16867 * "searchpair()" function 16868 */ 16869 static void 16870 f_searchpair(argvars, rettv) 16871 typval_T *argvars; 16872 typval_T *rettv; 16873 { 16874 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 16875 } 16876 16877 /* 16878 * "searchpairpos()" function 16879 */ 16880 static void 16881 f_searchpairpos(argvars, rettv) 16882 typval_T *argvars; 16883 typval_T *rettv; 16884 { 16885 pos_T match_pos; 16886 int lnum = 0; 16887 int col = 0; 16888 16889 if (rettv_list_alloc(rettv) == FAIL) 16890 return; 16891 16892 if (searchpair_cmn(argvars, &match_pos) > 0) 16893 { 16894 lnum = match_pos.lnum; 16895 col = match_pos.col; 16896 } 16897 16898 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 16899 list_append_number(rettv->vval.v_list, (varnumber_T)col); 16900 } 16901 16902 /* 16903 * Search for a start/middle/end thing. 16904 * Used by searchpair(), see its documentation for the details. 16905 * Returns 0 or -1 for no match, 16906 */ 16907 long 16908 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, 16909 lnum_stop, time_limit) 16910 char_u *spat; /* start pattern */ 16911 char_u *mpat; /* middle pattern */ 16912 char_u *epat; /* end pattern */ 16913 int dir; /* BACKWARD or FORWARD */ 16914 char_u *skip; /* skip expression */ 16915 int flags; /* SP_SETPCMARK and other SP_ values */ 16916 pos_T *match_pos; 16917 linenr_T lnum_stop; /* stop at this line if not zero */ 16918 long time_limit UNUSED; /* stop after this many msec */ 16919 { 16920 char_u *save_cpo; 16921 char_u *pat, *pat2 = NULL, *pat3 = NULL; 16922 long retval = 0; 16923 pos_T pos; 16924 pos_T firstpos; 16925 pos_T foundpos; 16926 pos_T save_cursor; 16927 pos_T save_pos; 16928 int n; 16929 int r; 16930 int nest = 1; 16931 int err; 16932 int options = SEARCH_KEEP; 16933 proftime_T tm; 16934 16935 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 16936 save_cpo = p_cpo; 16937 p_cpo = empty_option; 16938 16939 #ifdef FEAT_RELTIME 16940 /* Set the time limit, if there is one. */ 16941 profile_setlimit(time_limit, &tm); 16942 #endif 16943 16944 /* Make two search patterns: start/end (pat2, for in nested pairs) and 16945 * start/middle/end (pat3, for the top pair). */ 16946 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 16947 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 16948 if (pat2 == NULL || pat3 == NULL) 16949 goto theend; 16950 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 16951 if (*mpat == NUL) 16952 STRCPY(pat3, pat2); 16953 else 16954 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 16955 spat, epat, mpat); 16956 if (flags & SP_START) 16957 options |= SEARCH_START; 16958 16959 save_cursor = curwin->w_cursor; 16960 pos = curwin->w_cursor; 16961 clearpos(&firstpos); 16962 clearpos(&foundpos); 16963 pat = pat3; 16964 for (;;) 16965 { 16966 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 16967 options, RE_SEARCH, lnum_stop, &tm); 16968 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 16969 /* didn't find it or found the first match again: FAIL */ 16970 break; 16971 16972 if (firstpos.lnum == 0) 16973 firstpos = pos; 16974 if (equalpos(pos, foundpos)) 16975 { 16976 /* Found the same position again. Can happen with a pattern that 16977 * has "\zs" at the end and searching backwards. Advance one 16978 * character and try again. */ 16979 if (dir == BACKWARD) 16980 decl(&pos); 16981 else 16982 incl(&pos); 16983 } 16984 foundpos = pos; 16985 16986 /* clear the start flag to avoid getting stuck here */ 16987 options &= ~SEARCH_START; 16988 16989 /* If the skip pattern matches, ignore this match. */ 16990 if (*skip != NUL) 16991 { 16992 save_pos = curwin->w_cursor; 16993 curwin->w_cursor = pos; 16994 r = eval_to_bool(skip, &err, NULL, FALSE); 16995 curwin->w_cursor = save_pos; 16996 if (err) 16997 { 16998 /* Evaluating {skip} caused an error, break here. */ 16999 curwin->w_cursor = save_cursor; 17000 retval = -1; 17001 break; 17002 } 17003 if (r) 17004 continue; 17005 } 17006 17007 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 17008 { 17009 /* Found end when searching backwards or start when searching 17010 * forward: nested pair. */ 17011 ++nest; 17012 pat = pat2; /* nested, don't search for middle */ 17013 } 17014 else 17015 { 17016 /* Found end when searching forward or start when searching 17017 * backward: end of (nested) pair; or found middle in outer pair. */ 17018 if (--nest == 1) 17019 pat = pat3; /* outer level, search for middle */ 17020 } 17021 17022 if (nest == 0) 17023 { 17024 /* Found the match: return matchcount or line number. */ 17025 if (flags & SP_RETCOUNT) 17026 ++retval; 17027 else 17028 retval = pos.lnum; 17029 if (flags & SP_SETPCMARK) 17030 setpcmark(); 17031 curwin->w_cursor = pos; 17032 if (!(flags & SP_REPEAT)) 17033 break; 17034 nest = 1; /* search for next unmatched */ 17035 } 17036 } 17037 17038 if (match_pos != NULL) 17039 { 17040 /* Store the match cursor position */ 17041 match_pos->lnum = curwin->w_cursor.lnum; 17042 match_pos->col = curwin->w_cursor.col + 1; 17043 } 17044 17045 /* If 'n' flag is used or search failed: restore cursor position. */ 17046 if ((flags & SP_NOMOVE) || retval == 0) 17047 curwin->w_cursor = save_cursor; 17048 17049 theend: 17050 vim_free(pat2); 17051 vim_free(pat3); 17052 if (p_cpo == empty_option) 17053 p_cpo = save_cpo; 17054 else 17055 /* Darn, evaluating the {skip} expression changed the value. */ 17056 free_string_option(save_cpo); 17057 17058 return retval; 17059 } 17060 17061 /* 17062 * "searchpos()" function 17063 */ 17064 static void 17065 f_searchpos(argvars, rettv) 17066 typval_T *argvars; 17067 typval_T *rettv; 17068 { 17069 pos_T match_pos; 17070 int lnum = 0; 17071 int col = 0; 17072 int n; 17073 int flags = 0; 17074 17075 if (rettv_list_alloc(rettv) == FAIL) 17076 return; 17077 17078 n = search_cmn(argvars, &match_pos, &flags); 17079 if (n > 0) 17080 { 17081 lnum = match_pos.lnum; 17082 col = match_pos.col; 17083 } 17084 17085 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 17086 list_append_number(rettv->vval.v_list, (varnumber_T)col); 17087 if (flags & SP_SUBPAT) 17088 list_append_number(rettv->vval.v_list, (varnumber_T)n); 17089 } 17090 17091 17092 static void 17093 f_server2client(argvars, rettv) 17094 typval_T *argvars UNUSED; 17095 typval_T *rettv; 17096 { 17097 #ifdef FEAT_CLIENTSERVER 17098 char_u buf[NUMBUFLEN]; 17099 char_u *server = get_tv_string_chk(&argvars[0]); 17100 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 17101 17102 rettv->vval.v_number = -1; 17103 if (server == NULL || reply == NULL) 17104 return; 17105 if (check_restricted() || check_secure()) 17106 return; 17107 # ifdef FEAT_X11 17108 if (check_connection() == FAIL) 17109 return; 17110 # endif 17111 17112 if (serverSendReply(server, reply) < 0) 17113 { 17114 EMSG(_("E258: Unable to send to client")); 17115 return; 17116 } 17117 rettv->vval.v_number = 0; 17118 #else 17119 rettv->vval.v_number = -1; 17120 #endif 17121 } 17122 17123 static void 17124 f_serverlist(argvars, rettv) 17125 typval_T *argvars UNUSED; 17126 typval_T *rettv; 17127 { 17128 char_u *r = NULL; 17129 17130 #ifdef FEAT_CLIENTSERVER 17131 # ifdef WIN32 17132 r = serverGetVimNames(); 17133 # else 17134 make_connection(); 17135 if (X_DISPLAY != NULL) 17136 r = serverGetVimNames(X_DISPLAY); 17137 # endif 17138 #endif 17139 rettv->v_type = VAR_STRING; 17140 rettv->vval.v_string = r; 17141 } 17142 17143 /* 17144 * "setbufvar()" function 17145 */ 17146 static void 17147 f_setbufvar(argvars, rettv) 17148 typval_T *argvars; 17149 typval_T *rettv UNUSED; 17150 { 17151 buf_T *buf; 17152 aco_save_T aco; 17153 char_u *varname, *bufvarname; 17154 typval_T *varp; 17155 char_u nbuf[NUMBUFLEN]; 17156 17157 if (check_restricted() || check_secure()) 17158 return; 17159 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 17160 varname = get_tv_string_chk(&argvars[1]); 17161 buf = get_buf_tv(&argvars[0], FALSE); 17162 varp = &argvars[2]; 17163 17164 if (buf != NULL && varname != NULL && varp != NULL) 17165 { 17166 /* set curbuf to be our buf, temporarily */ 17167 aucmd_prepbuf(&aco, buf); 17168 17169 if (*varname == '&') 17170 { 17171 long numval; 17172 char_u *strval; 17173 int error = FALSE; 17174 17175 ++varname; 17176 numval = get_tv_number_chk(varp, &error); 17177 strval = get_tv_string_buf_chk(varp, nbuf); 17178 if (!error && strval != NULL) 17179 set_option_value(varname, numval, strval, OPT_LOCAL); 17180 } 17181 else 17182 { 17183 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 17184 if (bufvarname != NULL) 17185 { 17186 STRCPY(bufvarname, "b:"); 17187 STRCPY(bufvarname + 2, varname); 17188 set_var(bufvarname, varp, TRUE); 17189 vim_free(bufvarname); 17190 } 17191 } 17192 17193 /* reset notion of buffer */ 17194 aucmd_restbuf(&aco); 17195 } 17196 } 17197 17198 static void 17199 f_setcharsearch(argvars, rettv) 17200 typval_T *argvars; 17201 typval_T *rettv UNUSED; 17202 { 17203 dict_T *d; 17204 dictitem_T *di; 17205 char_u *csearch; 17206 17207 if (argvars[0].v_type != VAR_DICT) 17208 { 17209 EMSG(_(e_dictreq)); 17210 return; 17211 } 17212 17213 if ((d = argvars[0].vval.v_dict) != NULL) 17214 { 17215 csearch = get_dict_string(d, (char_u *)"char", FALSE); 17216 if (csearch != NULL) 17217 { 17218 #ifdef FEAT_MBYTE 17219 if (enc_utf8) 17220 { 17221 int pcc[MAX_MCO]; 17222 int c = utfc_ptr2char(csearch, pcc); 17223 17224 set_last_csearch(c, csearch, utfc_ptr2len(csearch)); 17225 } 17226 else 17227 #endif 17228 set_last_csearch(PTR2CHAR(csearch), 17229 csearch, MB_PTR2LEN(csearch)); 17230 } 17231 17232 di = dict_find(d, (char_u *)"forward", -1); 17233 if (di != NULL) 17234 set_csearch_direction(get_tv_number(&di->di_tv) 17235 ? FORWARD : BACKWARD); 17236 17237 di = dict_find(d, (char_u *)"until", -1); 17238 if (di != NULL) 17239 set_csearch_until(!!get_tv_number(&di->di_tv)); 17240 } 17241 } 17242 17243 /* 17244 * "setcmdpos()" function 17245 */ 17246 static void 17247 f_setcmdpos(argvars, rettv) 17248 typval_T *argvars; 17249 typval_T *rettv; 17250 { 17251 int pos = (int)get_tv_number(&argvars[0]) - 1; 17252 17253 if (pos >= 0) 17254 rettv->vval.v_number = set_cmdline_pos(pos); 17255 } 17256 17257 /* 17258 * "setline()" function 17259 */ 17260 static void 17261 f_setline(argvars, rettv) 17262 typval_T *argvars; 17263 typval_T *rettv; 17264 { 17265 linenr_T lnum; 17266 char_u *line = NULL; 17267 list_T *l = NULL; 17268 listitem_T *li = NULL; 17269 long added = 0; 17270 linenr_T lcount = curbuf->b_ml.ml_line_count; 17271 17272 lnum = get_tv_lnum(&argvars[0]); 17273 if (argvars[1].v_type == VAR_LIST) 17274 { 17275 l = argvars[1].vval.v_list; 17276 li = l->lv_first; 17277 } 17278 else 17279 line = get_tv_string_chk(&argvars[1]); 17280 17281 /* default result is zero == OK */ 17282 for (;;) 17283 { 17284 if (l != NULL) 17285 { 17286 /* list argument, get next string */ 17287 if (li == NULL) 17288 break; 17289 line = get_tv_string_chk(&li->li_tv); 17290 li = li->li_next; 17291 } 17292 17293 rettv->vval.v_number = 1; /* FAIL */ 17294 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 17295 break; 17296 17297 /* When coming here from Insert mode, sync undo, so that this can be 17298 * undone separately from what was previously inserted. */ 17299 if (u_sync_once == 2) 17300 { 17301 u_sync_once = 1; /* notify that u_sync() was called */ 17302 u_sync(TRUE); 17303 } 17304 17305 if (lnum <= curbuf->b_ml.ml_line_count) 17306 { 17307 /* existing line, replace it */ 17308 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 17309 { 17310 changed_bytes(lnum, 0); 17311 if (lnum == curwin->w_cursor.lnum) 17312 check_cursor_col(); 17313 rettv->vval.v_number = 0; /* OK */ 17314 } 17315 } 17316 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 17317 { 17318 /* lnum is one past the last line, append the line */ 17319 ++added; 17320 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 17321 rettv->vval.v_number = 0; /* OK */ 17322 } 17323 17324 if (l == NULL) /* only one string argument */ 17325 break; 17326 ++lnum; 17327 } 17328 17329 if (added > 0) 17330 appended_lines_mark(lcount, added); 17331 } 17332 17333 static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)); 17334 17335 /* 17336 * Used by "setqflist()" and "setloclist()" functions 17337 */ 17338 static void 17339 set_qf_ll_list(wp, list_arg, action_arg, rettv) 17340 win_T *wp UNUSED; 17341 typval_T *list_arg UNUSED; 17342 typval_T *action_arg UNUSED; 17343 typval_T *rettv; 17344 { 17345 #ifdef FEAT_QUICKFIX 17346 char_u *act; 17347 int action = ' '; 17348 #endif 17349 17350 rettv->vval.v_number = -1; 17351 17352 #ifdef FEAT_QUICKFIX 17353 if (list_arg->v_type != VAR_LIST) 17354 EMSG(_(e_listreq)); 17355 else 17356 { 17357 list_T *l = list_arg->vval.v_list; 17358 17359 if (action_arg->v_type == VAR_STRING) 17360 { 17361 act = get_tv_string_chk(action_arg); 17362 if (act == NULL) 17363 return; /* type error; errmsg already given */ 17364 if (*act == 'a' || *act == 'r') 17365 action = *act; 17366 } 17367 17368 if (l != NULL && set_errorlist(wp, l, action, 17369 (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK) 17370 rettv->vval.v_number = 0; 17371 } 17372 #endif 17373 } 17374 17375 /* 17376 * "setloclist()" function 17377 */ 17378 static void 17379 f_setloclist(argvars, rettv) 17380 typval_T *argvars; 17381 typval_T *rettv; 17382 { 17383 win_T *win; 17384 17385 rettv->vval.v_number = -1; 17386 17387 win = find_win_by_nr(&argvars[0], NULL); 17388 if (win != NULL) 17389 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 17390 } 17391 17392 /* 17393 * "setmatches()" function 17394 */ 17395 static void 17396 f_setmatches(argvars, rettv) 17397 typval_T *argvars UNUSED; 17398 typval_T *rettv UNUSED; 17399 { 17400 #ifdef FEAT_SEARCH_EXTRA 17401 list_T *l; 17402 listitem_T *li; 17403 dict_T *d; 17404 list_T *s = NULL; 17405 17406 rettv->vval.v_number = -1; 17407 if (argvars[0].v_type != VAR_LIST) 17408 { 17409 EMSG(_(e_listreq)); 17410 return; 17411 } 17412 if ((l = argvars[0].vval.v_list) != NULL) 17413 { 17414 17415 /* To some extent make sure that we are dealing with a list from 17416 * "getmatches()". */ 17417 li = l->lv_first; 17418 while (li != NULL) 17419 { 17420 if (li->li_tv.v_type != VAR_DICT 17421 || (d = li->li_tv.vval.v_dict) == NULL) 17422 { 17423 EMSG(_(e_invarg)); 17424 return; 17425 } 17426 if (!(dict_find(d, (char_u *)"group", -1) != NULL 17427 && (dict_find(d, (char_u *)"pattern", -1) != NULL 17428 || dict_find(d, (char_u *)"pos1", -1) != NULL) 17429 && dict_find(d, (char_u *)"priority", -1) != NULL 17430 && dict_find(d, (char_u *)"id", -1) != NULL)) 17431 { 17432 EMSG(_(e_invarg)); 17433 return; 17434 } 17435 li = li->li_next; 17436 } 17437 17438 clear_matches(curwin); 17439 li = l->lv_first; 17440 while (li != NULL) 17441 { 17442 int i = 0; 17443 char_u buf[5]; 17444 dictitem_T *di; 17445 char_u *group; 17446 int priority; 17447 int id; 17448 char_u *conceal; 17449 17450 d = li->li_tv.vval.v_dict; 17451 if (dict_find(d, (char_u *)"pattern", -1) == NULL) 17452 { 17453 if (s == NULL) 17454 { 17455 s = list_alloc(); 17456 if (s == NULL) 17457 return; 17458 } 17459 17460 /* match from matchaddpos() */ 17461 for (i = 1; i < 9; i++) 17462 { 17463 sprintf((char *)buf, (char *)"pos%d", i); 17464 if ((di = dict_find(d, (char_u *)buf, -1)) != NULL) 17465 { 17466 if (di->di_tv.v_type != VAR_LIST) 17467 return; 17468 17469 list_append_tv(s, &di->di_tv); 17470 s->lv_refcount++; 17471 } 17472 else 17473 break; 17474 } 17475 } 17476 17477 group = get_dict_string(d, (char_u *)"group", FALSE); 17478 priority = (int)get_dict_number(d, (char_u *)"priority"); 17479 id = (int)get_dict_number(d, (char_u *)"id"); 17480 conceal = dict_find(d, (char_u *)"conceal", -1) != NULL 17481 ? get_dict_string(d, (char_u *)"conceal", FALSE) 17482 : NULL; 17483 if (i == 0) 17484 { 17485 match_add(curwin, group, 17486 get_dict_string(d, (char_u *)"pattern", FALSE), 17487 priority, id, NULL, conceal); 17488 } 17489 else 17490 { 17491 match_add(curwin, group, NULL, priority, id, s, conceal); 17492 list_unref(s); 17493 s = NULL; 17494 } 17495 17496 li = li->li_next; 17497 } 17498 rettv->vval.v_number = 0; 17499 } 17500 #endif 17501 } 17502 17503 /* 17504 * "setpos()" function 17505 */ 17506 static void 17507 f_setpos(argvars, rettv) 17508 typval_T *argvars; 17509 typval_T *rettv; 17510 { 17511 pos_T pos; 17512 int fnum; 17513 char_u *name; 17514 colnr_T curswant = -1; 17515 17516 rettv->vval.v_number = -1; 17517 name = get_tv_string_chk(argvars); 17518 if (name != NULL) 17519 { 17520 if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) 17521 { 17522 if (--pos.col < 0) 17523 pos.col = 0; 17524 if (name[0] == '.' && name[1] == NUL) 17525 { 17526 /* set cursor */ 17527 if (fnum == curbuf->b_fnum) 17528 { 17529 curwin->w_cursor = pos; 17530 if (curswant >= 0) 17531 { 17532 curwin->w_curswant = curswant - 1; 17533 curwin->w_set_curswant = FALSE; 17534 } 17535 check_cursor(); 17536 rettv->vval.v_number = 0; 17537 } 17538 else 17539 EMSG(_(e_invarg)); 17540 } 17541 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 17542 { 17543 /* set mark */ 17544 if (setmark_pos(name[1], &pos, fnum) == OK) 17545 rettv->vval.v_number = 0; 17546 } 17547 else 17548 EMSG(_(e_invarg)); 17549 } 17550 } 17551 } 17552 17553 /* 17554 * "setqflist()" function 17555 */ 17556 static void 17557 f_setqflist(argvars, rettv) 17558 typval_T *argvars; 17559 typval_T *rettv; 17560 { 17561 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 17562 } 17563 17564 /* 17565 * "setreg()" function 17566 */ 17567 static void 17568 f_setreg(argvars, rettv) 17569 typval_T *argvars; 17570 typval_T *rettv; 17571 { 17572 int regname; 17573 char_u *strregname; 17574 char_u *stropt; 17575 char_u *strval; 17576 int append; 17577 char_u yank_type; 17578 long block_len; 17579 17580 block_len = -1; 17581 yank_type = MAUTO; 17582 append = FALSE; 17583 17584 strregname = get_tv_string_chk(argvars); 17585 rettv->vval.v_number = 1; /* FAIL is default */ 17586 17587 if (strregname == NULL) 17588 return; /* type error; errmsg already given */ 17589 regname = *strregname; 17590 if (regname == 0 || regname == '@') 17591 regname = '"'; 17592 17593 if (argvars[2].v_type != VAR_UNKNOWN) 17594 { 17595 stropt = get_tv_string_chk(&argvars[2]); 17596 if (stropt == NULL) 17597 return; /* type error */ 17598 for (; *stropt != NUL; ++stropt) 17599 switch (*stropt) 17600 { 17601 case 'a': case 'A': /* append */ 17602 append = TRUE; 17603 break; 17604 case 'v': case 'c': /* character-wise selection */ 17605 yank_type = MCHAR; 17606 break; 17607 case 'V': case 'l': /* line-wise selection */ 17608 yank_type = MLINE; 17609 break; 17610 case 'b': case Ctrl_V: /* block-wise selection */ 17611 yank_type = MBLOCK; 17612 if (VIM_ISDIGIT(stropt[1])) 17613 { 17614 ++stropt; 17615 block_len = getdigits(&stropt) - 1; 17616 --stropt; 17617 } 17618 break; 17619 } 17620 } 17621 17622 if (argvars[1].v_type == VAR_LIST) 17623 { 17624 char_u **lstval; 17625 char_u **allocval; 17626 char_u buf[NUMBUFLEN]; 17627 char_u **curval; 17628 char_u **curallocval; 17629 int len = argvars[1].vval.v_list->lv_len; 17630 listitem_T *li; 17631 17632 /* First half: use for pointers to result lines; second half: use for 17633 * pointers to allocated copies. */ 17634 lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2)); 17635 if (lstval == NULL) 17636 return; 17637 curval = lstval; 17638 allocval = lstval + len + 2; 17639 curallocval = allocval; 17640 17641 for (li = argvars[1].vval.v_list->lv_first; li != NULL; 17642 li = li->li_next) 17643 { 17644 strval = get_tv_string_buf_chk(&li->li_tv, buf); 17645 if (strval == NULL) 17646 goto free_lstval; 17647 if (strval == buf) 17648 { 17649 /* Need to make a copy, next get_tv_string_buf_chk() will 17650 * overwrite the string. */ 17651 strval = vim_strsave(buf); 17652 if (strval == NULL) 17653 goto free_lstval; 17654 *curallocval++ = strval; 17655 } 17656 *curval++ = strval; 17657 } 17658 *curval++ = NULL; 17659 17660 write_reg_contents_lst(regname, lstval, -1, 17661 append, yank_type, block_len); 17662 free_lstval: 17663 while (curallocval > allocval) 17664 vim_free(*--curallocval); 17665 vim_free(lstval); 17666 } 17667 else 17668 { 17669 strval = get_tv_string_chk(&argvars[1]); 17670 if (strval == NULL) 17671 return; 17672 write_reg_contents_ex(regname, strval, -1, 17673 append, yank_type, block_len); 17674 } 17675 rettv->vval.v_number = 0; 17676 } 17677 17678 /* 17679 * "settabvar()" function 17680 */ 17681 static void 17682 f_settabvar(argvars, rettv) 17683 typval_T *argvars; 17684 typval_T *rettv; 17685 { 17686 #ifdef FEAT_WINDOWS 17687 tabpage_T *save_curtab; 17688 tabpage_T *tp; 17689 #endif 17690 char_u *varname, *tabvarname; 17691 typval_T *varp; 17692 17693 rettv->vval.v_number = 0; 17694 17695 if (check_restricted() || check_secure()) 17696 return; 17697 17698 #ifdef FEAT_WINDOWS 17699 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 17700 #endif 17701 varname = get_tv_string_chk(&argvars[1]); 17702 varp = &argvars[2]; 17703 17704 if (varname != NULL && varp != NULL 17705 #ifdef FEAT_WINDOWS 17706 && tp != NULL 17707 #endif 17708 ) 17709 { 17710 #ifdef FEAT_WINDOWS 17711 save_curtab = curtab; 17712 goto_tabpage_tp(tp, FALSE, FALSE); 17713 #endif 17714 17715 tabvarname = alloc((unsigned)STRLEN(varname) + 3); 17716 if (tabvarname != NULL) 17717 { 17718 STRCPY(tabvarname, "t:"); 17719 STRCPY(tabvarname + 2, varname); 17720 set_var(tabvarname, varp, TRUE); 17721 vim_free(tabvarname); 17722 } 17723 17724 #ifdef FEAT_WINDOWS 17725 /* Restore current tabpage */ 17726 if (valid_tabpage(save_curtab)) 17727 goto_tabpage_tp(save_curtab, FALSE, FALSE); 17728 #endif 17729 } 17730 } 17731 17732 /* 17733 * "settabwinvar()" function 17734 */ 17735 static void 17736 f_settabwinvar(argvars, rettv) 17737 typval_T *argvars; 17738 typval_T *rettv; 17739 { 17740 setwinvar(argvars, rettv, 1); 17741 } 17742 17743 /* 17744 * "setwinvar()" function 17745 */ 17746 static void 17747 f_setwinvar(argvars, rettv) 17748 typval_T *argvars; 17749 typval_T *rettv; 17750 { 17751 setwinvar(argvars, rettv, 0); 17752 } 17753 17754 /* 17755 * "setwinvar()" and "settabwinvar()" functions 17756 */ 17757 17758 static void 17759 setwinvar(argvars, rettv, off) 17760 typval_T *argvars; 17761 typval_T *rettv UNUSED; 17762 int off; 17763 { 17764 win_T *win; 17765 #ifdef FEAT_WINDOWS 17766 win_T *save_curwin; 17767 tabpage_T *save_curtab; 17768 int need_switch_win; 17769 #endif 17770 char_u *varname, *winvarname; 17771 typval_T *varp; 17772 char_u nbuf[NUMBUFLEN]; 17773 tabpage_T *tp = NULL; 17774 17775 if (check_restricted() || check_secure()) 17776 return; 17777 17778 #ifdef FEAT_WINDOWS 17779 if (off == 1) 17780 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 17781 else 17782 tp = curtab; 17783 #endif 17784 win = find_win_by_nr(&argvars[off], tp); 17785 varname = get_tv_string_chk(&argvars[off + 1]); 17786 varp = &argvars[off + 2]; 17787 17788 if (win != NULL && varname != NULL && varp != NULL) 17789 { 17790 #ifdef FEAT_WINDOWS 17791 need_switch_win = !(tp == curtab && win == curwin); 17792 if (!need_switch_win 17793 || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) 17794 #endif 17795 { 17796 if (*varname == '&') 17797 { 17798 long numval; 17799 char_u *strval; 17800 int error = FALSE; 17801 17802 ++varname; 17803 numval = get_tv_number_chk(varp, &error); 17804 strval = get_tv_string_buf_chk(varp, nbuf); 17805 if (!error && strval != NULL) 17806 set_option_value(varname, numval, strval, OPT_LOCAL); 17807 } 17808 else 17809 { 17810 winvarname = alloc((unsigned)STRLEN(varname) + 3); 17811 if (winvarname != NULL) 17812 { 17813 STRCPY(winvarname, "w:"); 17814 STRCPY(winvarname + 2, varname); 17815 set_var(winvarname, varp, TRUE); 17816 vim_free(winvarname); 17817 } 17818 } 17819 } 17820 #ifdef FEAT_WINDOWS 17821 if (need_switch_win) 17822 restore_win(save_curwin, save_curtab, TRUE); 17823 #endif 17824 } 17825 } 17826 17827 #ifdef FEAT_CRYPT 17828 /* 17829 * "sha256({string})" function 17830 */ 17831 static void 17832 f_sha256(argvars, rettv) 17833 typval_T *argvars; 17834 typval_T *rettv; 17835 { 17836 char_u *p; 17837 17838 p = get_tv_string(&argvars[0]); 17839 rettv->vval.v_string = vim_strsave( 17840 sha256_bytes(p, (int)STRLEN(p), NULL, 0)); 17841 rettv->v_type = VAR_STRING; 17842 } 17843 #endif /* FEAT_CRYPT */ 17844 17845 /* 17846 * "shellescape({string})" function 17847 */ 17848 static void 17849 f_shellescape(argvars, rettv) 17850 typval_T *argvars; 17851 typval_T *rettv; 17852 { 17853 rettv->vval.v_string = vim_strsave_shellescape( 17854 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), TRUE); 17855 rettv->v_type = VAR_STRING; 17856 } 17857 17858 /* 17859 * shiftwidth() function 17860 */ 17861 static void 17862 f_shiftwidth(argvars, rettv) 17863 typval_T *argvars UNUSED; 17864 typval_T *rettv; 17865 { 17866 rettv->vval.v_number = get_sw_value(curbuf); 17867 } 17868 17869 /* 17870 * "simplify()" function 17871 */ 17872 static void 17873 f_simplify(argvars, rettv) 17874 typval_T *argvars; 17875 typval_T *rettv; 17876 { 17877 char_u *p; 17878 17879 p = get_tv_string(&argvars[0]); 17880 rettv->vval.v_string = vim_strsave(p); 17881 simplify_filename(rettv->vval.v_string); /* simplify in place */ 17882 rettv->v_type = VAR_STRING; 17883 } 17884 17885 #ifdef FEAT_FLOAT 17886 /* 17887 * "sin()" function 17888 */ 17889 static void 17890 f_sin(argvars, rettv) 17891 typval_T *argvars; 17892 typval_T *rettv; 17893 { 17894 float_T f; 17895 17896 rettv->v_type = VAR_FLOAT; 17897 if (get_float_arg(argvars, &f) == OK) 17898 rettv->vval.v_float = sin(f); 17899 else 17900 rettv->vval.v_float = 0.0; 17901 } 17902 17903 /* 17904 * "sinh()" function 17905 */ 17906 static void 17907 f_sinh(argvars, rettv) 17908 typval_T *argvars; 17909 typval_T *rettv; 17910 { 17911 float_T f; 17912 17913 rettv->v_type = VAR_FLOAT; 17914 if (get_float_arg(argvars, &f) == OK) 17915 rettv->vval.v_float = sinh(f); 17916 else 17917 rettv->vval.v_float = 0.0; 17918 } 17919 #endif 17920 17921 static int 17922 #ifdef __BORLANDC__ 17923 _RTLENTRYF 17924 #endif 17925 item_compare __ARGS((const void *s1, const void *s2)); 17926 static int 17927 #ifdef __BORLANDC__ 17928 _RTLENTRYF 17929 #endif 17930 item_compare2 __ARGS((const void *s1, const void *s2)); 17931 17932 /* struct used in the array that's given to qsort() */ 17933 typedef struct 17934 { 17935 listitem_T *item; 17936 int idx; 17937 } sortItem_T; 17938 17939 static int item_compare_ic; 17940 static int item_compare_numeric; 17941 static int item_compare_numbers; 17942 static char_u *item_compare_func; 17943 static dict_T *item_compare_selfdict; 17944 static int item_compare_func_err; 17945 static int item_compare_keep_zero; 17946 static void do_sort_uniq __ARGS((typval_T *argvars, typval_T *rettv, int sort)); 17947 #define ITEM_COMPARE_FAIL 999 17948 17949 /* 17950 * Compare functions for f_sort() and f_uniq() below. 17951 */ 17952 static int 17953 #ifdef __BORLANDC__ 17954 _RTLENTRYF 17955 #endif 17956 item_compare(s1, s2) 17957 const void *s1; 17958 const void *s2; 17959 { 17960 sortItem_T *si1, *si2; 17961 typval_T *tv1, *tv2; 17962 char_u *p1, *p2; 17963 char_u *tofree1 = NULL, *tofree2 = NULL; 17964 int res; 17965 char_u numbuf1[NUMBUFLEN]; 17966 char_u numbuf2[NUMBUFLEN]; 17967 17968 si1 = (sortItem_T *)s1; 17969 si2 = (sortItem_T *)s2; 17970 tv1 = &si1->item->li_tv; 17971 tv2 = &si2->item->li_tv; 17972 17973 if (item_compare_numbers) 17974 { 17975 long v1 = get_tv_number(tv1); 17976 long v2 = get_tv_number(tv2); 17977 17978 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 17979 } 17980 17981 /* tv2string() puts quotes around a string and allocates memory. Don't do 17982 * that for string variables. Use a single quote when comparing with a 17983 * non-string to do what the docs promise. */ 17984 if (tv1->v_type == VAR_STRING) 17985 { 17986 if (tv2->v_type != VAR_STRING || item_compare_numeric) 17987 p1 = (char_u *)"'"; 17988 else 17989 p1 = tv1->vval.v_string; 17990 } 17991 else 17992 p1 = tv2string(tv1, &tofree1, numbuf1, 0); 17993 if (tv2->v_type == VAR_STRING) 17994 { 17995 if (tv1->v_type != VAR_STRING || item_compare_numeric) 17996 p2 = (char_u *)"'"; 17997 else 17998 p2 = tv2->vval.v_string; 17999 } 18000 else 18001 p2 = tv2string(tv2, &tofree2, numbuf2, 0); 18002 if (p1 == NULL) 18003 p1 = (char_u *)""; 18004 if (p2 == NULL) 18005 p2 = (char_u *)""; 18006 if (!item_compare_numeric) 18007 { 18008 if (item_compare_ic) 18009 res = STRICMP(p1, p2); 18010 else 18011 res = STRCMP(p1, p2); 18012 } 18013 else 18014 { 18015 double n1, n2; 18016 n1 = strtod((char *)p1, (char **)&p1); 18017 n2 = strtod((char *)p2, (char **)&p2); 18018 res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1; 18019 } 18020 18021 /* When the result would be zero, compare the item indexes. Makes the 18022 * sort stable. */ 18023 if (res == 0 && !item_compare_keep_zero) 18024 res = si1->idx > si2->idx ? 1 : -1; 18025 18026 vim_free(tofree1); 18027 vim_free(tofree2); 18028 return res; 18029 } 18030 18031 static int 18032 #ifdef __BORLANDC__ 18033 _RTLENTRYF 18034 #endif 18035 item_compare2(s1, s2) 18036 const void *s1; 18037 const void *s2; 18038 { 18039 sortItem_T *si1, *si2; 18040 int res; 18041 typval_T rettv; 18042 typval_T argv[3]; 18043 int dummy; 18044 18045 /* shortcut after failure in previous call; compare all items equal */ 18046 if (item_compare_func_err) 18047 return 0; 18048 18049 si1 = (sortItem_T *)s1; 18050 si2 = (sortItem_T *)s2; 18051 18052 /* Copy the values. This is needed to be able to set v_lock to VAR_FIXED 18053 * in the copy without changing the original list items. */ 18054 copy_tv(&si1->item->li_tv, &argv[0]); 18055 copy_tv(&si2->item->li_tv, &argv[1]); 18056 18057 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 18058 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 18059 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, 18060 item_compare_selfdict); 18061 clear_tv(&argv[0]); 18062 clear_tv(&argv[1]); 18063 18064 if (res == FAIL) 18065 res = ITEM_COMPARE_FAIL; 18066 else 18067 res = get_tv_number_chk(&rettv, &item_compare_func_err); 18068 if (item_compare_func_err) 18069 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 18070 clear_tv(&rettv); 18071 18072 /* When the result would be zero, compare the pointers themselves. Makes 18073 * the sort stable. */ 18074 if (res == 0 && !item_compare_keep_zero) 18075 res = si1->idx > si2->idx ? 1 : -1; 18076 18077 return res; 18078 } 18079 18080 /* 18081 * "sort({list})" function 18082 */ 18083 static void 18084 do_sort_uniq(argvars, rettv, sort) 18085 typval_T *argvars; 18086 typval_T *rettv; 18087 int sort; 18088 { 18089 list_T *l; 18090 listitem_T *li; 18091 sortItem_T *ptrs; 18092 long len; 18093 long i; 18094 18095 if (argvars[0].v_type != VAR_LIST) 18096 EMSG2(_(e_listarg), sort ? "sort()" : "uniq()"); 18097 else 18098 { 18099 l = argvars[0].vval.v_list; 18100 if (l == NULL || tv_check_lock(l->lv_lock, 18101 (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")), 18102 TRUE)) 18103 return; 18104 rettv->vval.v_list = l; 18105 rettv->v_type = VAR_LIST; 18106 ++l->lv_refcount; 18107 18108 len = list_len(l); 18109 if (len <= 1) 18110 return; /* short list sorts pretty quickly */ 18111 18112 item_compare_ic = FALSE; 18113 item_compare_numeric = FALSE; 18114 item_compare_numbers = FALSE; 18115 item_compare_func = NULL; 18116 item_compare_selfdict = NULL; 18117 if (argvars[1].v_type != VAR_UNKNOWN) 18118 { 18119 /* optional second argument: {func} */ 18120 if (argvars[1].v_type == VAR_FUNC) 18121 item_compare_func = argvars[1].vval.v_string; 18122 else 18123 { 18124 int error = FALSE; 18125 18126 i = get_tv_number_chk(&argvars[1], &error); 18127 if (error) 18128 return; /* type error; errmsg already given */ 18129 if (i == 1) 18130 item_compare_ic = TRUE; 18131 else 18132 item_compare_func = get_tv_string(&argvars[1]); 18133 if (item_compare_func != NULL) 18134 { 18135 if (STRCMP(item_compare_func, "n") == 0) 18136 { 18137 item_compare_func = NULL; 18138 item_compare_numeric = TRUE; 18139 } 18140 else if (STRCMP(item_compare_func, "N") == 0) 18141 { 18142 item_compare_func = NULL; 18143 item_compare_numbers = TRUE; 18144 } 18145 else if (STRCMP(item_compare_func, "i") == 0) 18146 { 18147 item_compare_func = NULL; 18148 item_compare_ic = TRUE; 18149 } 18150 } 18151 } 18152 18153 if (argvars[2].v_type != VAR_UNKNOWN) 18154 { 18155 /* optional third argument: {dict} */ 18156 if (argvars[2].v_type != VAR_DICT) 18157 { 18158 EMSG(_(e_dictreq)); 18159 return; 18160 } 18161 item_compare_selfdict = argvars[2].vval.v_dict; 18162 } 18163 } 18164 18165 /* Make an array with each entry pointing to an item in the List. */ 18166 ptrs = (sortItem_T *)alloc((int)(len * sizeof(sortItem_T))); 18167 if (ptrs == NULL) 18168 return; 18169 18170 i = 0; 18171 if (sort) 18172 { 18173 /* sort(): ptrs will be the list to sort */ 18174 for (li = l->lv_first; li != NULL; li = li->li_next) 18175 { 18176 ptrs[i].item = li; 18177 ptrs[i].idx = i; 18178 ++i; 18179 } 18180 18181 item_compare_func_err = FALSE; 18182 item_compare_keep_zero = FALSE; 18183 /* test the compare function */ 18184 if (item_compare_func != NULL 18185 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 18186 == ITEM_COMPARE_FAIL) 18187 EMSG(_("E702: Sort compare function failed")); 18188 else 18189 { 18190 /* Sort the array with item pointers. */ 18191 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T), 18192 item_compare_func == NULL ? item_compare : item_compare2); 18193 18194 if (!item_compare_func_err) 18195 { 18196 /* Clear the List and append the items in sorted order. */ 18197 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 18198 l->lv_len = 0; 18199 for (i = 0; i < len; ++i) 18200 list_append(l, ptrs[i].item); 18201 } 18202 } 18203 } 18204 else 18205 { 18206 int (*item_compare_func_ptr)__ARGS((const void *, const void *)); 18207 18208 /* f_uniq(): ptrs will be a stack of items to remove */ 18209 item_compare_func_err = FALSE; 18210 item_compare_keep_zero = TRUE; 18211 item_compare_func_ptr = item_compare_func 18212 ? item_compare2 : item_compare; 18213 18214 for (li = l->lv_first; li != NULL && li->li_next != NULL; 18215 li = li->li_next) 18216 { 18217 if (item_compare_func_ptr((void *)&li, (void *)&li->li_next) 18218 == 0) 18219 ptrs[i++].item = li; 18220 if (item_compare_func_err) 18221 { 18222 EMSG(_("E882: Uniq compare function failed")); 18223 break; 18224 } 18225 } 18226 18227 if (!item_compare_func_err) 18228 { 18229 while (--i >= 0) 18230 { 18231 li = ptrs[i].item->li_next; 18232 ptrs[i].item->li_next = li->li_next; 18233 if (li->li_next != NULL) 18234 li->li_next->li_prev = ptrs[i].item; 18235 else 18236 l->lv_last = ptrs[i].item; 18237 list_fix_watch(l, li); 18238 listitem_free(li); 18239 l->lv_len--; 18240 } 18241 } 18242 } 18243 18244 vim_free(ptrs); 18245 } 18246 } 18247 18248 /* 18249 * "sort({list})" function 18250 */ 18251 static void 18252 f_sort(argvars, rettv) 18253 typval_T *argvars; 18254 typval_T *rettv; 18255 { 18256 do_sort_uniq(argvars, rettv, TRUE); 18257 } 18258 18259 /* 18260 * "uniq({list})" function 18261 */ 18262 static void 18263 f_uniq(argvars, rettv) 18264 typval_T *argvars; 18265 typval_T *rettv; 18266 { 18267 do_sort_uniq(argvars, rettv, FALSE); 18268 } 18269 18270 /* 18271 * "soundfold({word})" function 18272 */ 18273 static void 18274 f_soundfold(argvars, rettv) 18275 typval_T *argvars; 18276 typval_T *rettv; 18277 { 18278 char_u *s; 18279 18280 rettv->v_type = VAR_STRING; 18281 s = get_tv_string(&argvars[0]); 18282 #ifdef FEAT_SPELL 18283 rettv->vval.v_string = eval_soundfold(s); 18284 #else 18285 rettv->vval.v_string = vim_strsave(s); 18286 #endif 18287 } 18288 18289 /* 18290 * "spellbadword()" function 18291 */ 18292 static void 18293 f_spellbadword(argvars, rettv) 18294 typval_T *argvars UNUSED; 18295 typval_T *rettv; 18296 { 18297 char_u *word = (char_u *)""; 18298 hlf_T attr = HLF_COUNT; 18299 int len = 0; 18300 18301 if (rettv_list_alloc(rettv) == FAIL) 18302 return; 18303 18304 #ifdef FEAT_SPELL 18305 if (argvars[0].v_type == VAR_UNKNOWN) 18306 { 18307 /* Find the start and length of the badly spelled word. */ 18308 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 18309 if (len != 0) 18310 word = ml_get_cursor(); 18311 } 18312 else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) 18313 { 18314 char_u *str = get_tv_string_chk(&argvars[0]); 18315 int capcol = -1; 18316 18317 if (str != NULL) 18318 { 18319 /* Check the argument for spelling. */ 18320 while (*str != NUL) 18321 { 18322 len = spell_check(curwin, str, &attr, &capcol, FALSE); 18323 if (attr != HLF_COUNT) 18324 { 18325 word = str; 18326 break; 18327 } 18328 str += len; 18329 } 18330 } 18331 } 18332 #endif 18333 18334 list_append_string(rettv->vval.v_list, word, len); 18335 list_append_string(rettv->vval.v_list, (char_u *)( 18336 attr == HLF_SPB ? "bad" : 18337 attr == HLF_SPR ? "rare" : 18338 attr == HLF_SPL ? "local" : 18339 attr == HLF_SPC ? "caps" : 18340 ""), -1); 18341 } 18342 18343 /* 18344 * "spellsuggest()" function 18345 */ 18346 static void 18347 f_spellsuggest(argvars, rettv) 18348 typval_T *argvars UNUSED; 18349 typval_T *rettv; 18350 { 18351 #ifdef FEAT_SPELL 18352 char_u *str; 18353 int typeerr = FALSE; 18354 int maxcount; 18355 garray_T ga; 18356 int i; 18357 listitem_T *li; 18358 int need_capital = FALSE; 18359 #endif 18360 18361 if (rettv_list_alloc(rettv) == FAIL) 18362 return; 18363 18364 #ifdef FEAT_SPELL 18365 if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) 18366 { 18367 str = get_tv_string(&argvars[0]); 18368 if (argvars[1].v_type != VAR_UNKNOWN) 18369 { 18370 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 18371 if (maxcount <= 0) 18372 return; 18373 if (argvars[2].v_type != VAR_UNKNOWN) 18374 { 18375 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 18376 if (typeerr) 18377 return; 18378 } 18379 } 18380 else 18381 maxcount = 25; 18382 18383 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 18384 18385 for (i = 0; i < ga.ga_len; ++i) 18386 { 18387 str = ((char_u **)ga.ga_data)[i]; 18388 18389 li = listitem_alloc(); 18390 if (li == NULL) 18391 vim_free(str); 18392 else 18393 { 18394 li->li_tv.v_type = VAR_STRING; 18395 li->li_tv.v_lock = 0; 18396 li->li_tv.vval.v_string = str; 18397 list_append(rettv->vval.v_list, li); 18398 } 18399 } 18400 ga_clear(&ga); 18401 } 18402 #endif 18403 } 18404 18405 static void 18406 f_split(argvars, rettv) 18407 typval_T *argvars; 18408 typval_T *rettv; 18409 { 18410 char_u *str; 18411 char_u *end; 18412 char_u *pat = NULL; 18413 regmatch_T regmatch; 18414 char_u patbuf[NUMBUFLEN]; 18415 char_u *save_cpo; 18416 int match; 18417 colnr_T col = 0; 18418 int keepempty = FALSE; 18419 int typeerr = FALSE; 18420 18421 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 18422 save_cpo = p_cpo; 18423 p_cpo = (char_u *)""; 18424 18425 str = get_tv_string(&argvars[0]); 18426 if (argvars[1].v_type != VAR_UNKNOWN) 18427 { 18428 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 18429 if (pat == NULL) 18430 typeerr = TRUE; 18431 if (argvars[2].v_type != VAR_UNKNOWN) 18432 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 18433 } 18434 if (pat == NULL || *pat == NUL) 18435 pat = (char_u *)"[\\x01- ]\\+"; 18436 18437 if (rettv_list_alloc(rettv) == FAIL) 18438 return; 18439 if (typeerr) 18440 return; 18441 18442 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 18443 if (regmatch.regprog != NULL) 18444 { 18445 regmatch.rm_ic = FALSE; 18446 while (*str != NUL || keepempty) 18447 { 18448 if (*str == NUL) 18449 match = FALSE; /* empty item at the end */ 18450 else 18451 match = vim_regexec_nl(®match, str, col); 18452 if (match) 18453 end = regmatch.startp[0]; 18454 else 18455 end = str + STRLEN(str); 18456 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 18457 && *str != NUL && match && end < regmatch.endp[0])) 18458 { 18459 if (list_append_string(rettv->vval.v_list, str, 18460 (int)(end - str)) == FAIL) 18461 break; 18462 } 18463 if (!match) 18464 break; 18465 /* Advance to just after the match. */ 18466 if (regmatch.endp[0] > str) 18467 col = 0; 18468 else 18469 { 18470 /* Don't get stuck at the same match. */ 18471 #ifdef FEAT_MBYTE 18472 col = (*mb_ptr2len)(regmatch.endp[0]); 18473 #else 18474 col = 1; 18475 #endif 18476 } 18477 str = regmatch.endp[0]; 18478 } 18479 18480 vim_regfree(regmatch.regprog); 18481 } 18482 18483 p_cpo = save_cpo; 18484 } 18485 18486 #ifdef FEAT_FLOAT 18487 /* 18488 * "sqrt()" function 18489 */ 18490 static void 18491 f_sqrt(argvars, rettv) 18492 typval_T *argvars; 18493 typval_T *rettv; 18494 { 18495 float_T f; 18496 18497 rettv->v_type = VAR_FLOAT; 18498 if (get_float_arg(argvars, &f) == OK) 18499 rettv->vval.v_float = sqrt(f); 18500 else 18501 rettv->vval.v_float = 0.0; 18502 } 18503 18504 /* 18505 * "str2float()" function 18506 */ 18507 static void 18508 f_str2float(argvars, rettv) 18509 typval_T *argvars; 18510 typval_T *rettv; 18511 { 18512 char_u *p = skipwhite(get_tv_string(&argvars[0])); 18513 18514 if (*p == '+') 18515 p = skipwhite(p + 1); 18516 (void)string2float(p, &rettv->vval.v_float); 18517 rettv->v_type = VAR_FLOAT; 18518 } 18519 #endif 18520 18521 /* 18522 * "str2nr()" function 18523 */ 18524 static void 18525 f_str2nr(argvars, rettv) 18526 typval_T *argvars; 18527 typval_T *rettv; 18528 { 18529 int base = 10; 18530 char_u *p; 18531 long n; 18532 18533 if (argvars[1].v_type != VAR_UNKNOWN) 18534 { 18535 base = get_tv_number(&argvars[1]); 18536 if (base != 8 && base != 10 && base != 16) 18537 { 18538 EMSG(_(e_invarg)); 18539 return; 18540 } 18541 } 18542 18543 p = skipwhite(get_tv_string(&argvars[0])); 18544 if (*p == '+') 18545 p = skipwhite(p + 1); 18546 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL, 0); 18547 rettv->vval.v_number = n; 18548 } 18549 18550 #ifdef HAVE_STRFTIME 18551 /* 18552 * "strftime({format}[, {time}])" function 18553 */ 18554 static void 18555 f_strftime(argvars, rettv) 18556 typval_T *argvars; 18557 typval_T *rettv; 18558 { 18559 char_u result_buf[256]; 18560 struct tm *curtime; 18561 time_t seconds; 18562 char_u *p; 18563 18564 rettv->v_type = VAR_STRING; 18565 18566 p = get_tv_string(&argvars[0]); 18567 if (argvars[1].v_type == VAR_UNKNOWN) 18568 seconds = time(NULL); 18569 else 18570 seconds = (time_t)get_tv_number(&argvars[1]); 18571 curtime = localtime(&seconds); 18572 /* MSVC returns NULL for an invalid value of seconds. */ 18573 if (curtime == NULL) 18574 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 18575 else 18576 { 18577 # ifdef FEAT_MBYTE 18578 vimconv_T conv; 18579 char_u *enc; 18580 18581 conv.vc_type = CONV_NONE; 18582 enc = enc_locale(); 18583 convert_setup(&conv, p_enc, enc); 18584 if (conv.vc_type != CONV_NONE) 18585 p = string_convert(&conv, p, NULL); 18586 # endif 18587 if (p != NULL) 18588 (void)strftime((char *)result_buf, sizeof(result_buf), 18589 (char *)p, curtime); 18590 else 18591 result_buf[0] = NUL; 18592 18593 # ifdef FEAT_MBYTE 18594 if (conv.vc_type != CONV_NONE) 18595 vim_free(p); 18596 convert_setup(&conv, enc, p_enc); 18597 if (conv.vc_type != CONV_NONE) 18598 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 18599 else 18600 # endif 18601 rettv->vval.v_string = vim_strsave(result_buf); 18602 18603 # ifdef FEAT_MBYTE 18604 /* Release conversion descriptors */ 18605 convert_setup(&conv, NULL, NULL); 18606 vim_free(enc); 18607 # endif 18608 } 18609 } 18610 #endif 18611 18612 /* 18613 * "stridx()" function 18614 */ 18615 static void 18616 f_stridx(argvars, rettv) 18617 typval_T *argvars; 18618 typval_T *rettv; 18619 { 18620 char_u buf[NUMBUFLEN]; 18621 char_u *needle; 18622 char_u *haystack; 18623 char_u *save_haystack; 18624 char_u *pos; 18625 int start_idx; 18626 18627 needle = get_tv_string_chk(&argvars[1]); 18628 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 18629 rettv->vval.v_number = -1; 18630 if (needle == NULL || haystack == NULL) 18631 return; /* type error; errmsg already given */ 18632 18633 if (argvars[2].v_type != VAR_UNKNOWN) 18634 { 18635 int error = FALSE; 18636 18637 start_idx = get_tv_number_chk(&argvars[2], &error); 18638 if (error || start_idx >= (int)STRLEN(haystack)) 18639 return; 18640 if (start_idx >= 0) 18641 haystack += start_idx; 18642 } 18643 18644 pos = (char_u *)strstr((char *)haystack, (char *)needle); 18645 if (pos != NULL) 18646 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 18647 } 18648 18649 /* 18650 * "string()" function 18651 */ 18652 static void 18653 f_string(argvars, rettv) 18654 typval_T *argvars; 18655 typval_T *rettv; 18656 { 18657 char_u *tofree; 18658 char_u numbuf[NUMBUFLEN]; 18659 18660 rettv->v_type = VAR_STRING; 18661 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 18662 /* Make a copy if we have a value but it's not in allocated memory. */ 18663 if (rettv->vval.v_string != NULL && tofree == NULL) 18664 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 18665 } 18666 18667 /* 18668 * "strlen()" function 18669 */ 18670 static void 18671 f_strlen(argvars, rettv) 18672 typval_T *argvars; 18673 typval_T *rettv; 18674 { 18675 rettv->vval.v_number = (varnumber_T)(STRLEN( 18676 get_tv_string(&argvars[0]))); 18677 } 18678 18679 /* 18680 * "strchars()" function 18681 */ 18682 static void 18683 f_strchars(argvars, rettv) 18684 typval_T *argvars; 18685 typval_T *rettv; 18686 { 18687 char_u *s = get_tv_string(&argvars[0]); 18688 int skipcc = 0; 18689 #ifdef FEAT_MBYTE 18690 varnumber_T len = 0; 18691 int (*func_mb_ptr2char_adv)(char_u **pp); 18692 #endif 18693 18694 if (argvars[1].v_type != VAR_UNKNOWN) 18695 skipcc = get_tv_number_chk(&argvars[1], NULL); 18696 if (skipcc < 0 || skipcc > 1) 18697 EMSG(_(e_invarg)); 18698 else 18699 { 18700 #ifdef FEAT_MBYTE 18701 func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv; 18702 while (*s != NUL) 18703 { 18704 func_mb_ptr2char_adv(&s); 18705 ++len; 18706 } 18707 rettv->vval.v_number = len; 18708 #else 18709 rettv->vval.v_number = (varnumber_T)(STRLEN(s)); 18710 #endif 18711 } 18712 } 18713 18714 /* 18715 * "strdisplaywidth()" function 18716 */ 18717 static void 18718 f_strdisplaywidth(argvars, rettv) 18719 typval_T *argvars; 18720 typval_T *rettv; 18721 { 18722 char_u *s = get_tv_string(&argvars[0]); 18723 int col = 0; 18724 18725 if (argvars[1].v_type != VAR_UNKNOWN) 18726 col = get_tv_number(&argvars[1]); 18727 18728 rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col); 18729 } 18730 18731 /* 18732 * "strwidth()" function 18733 */ 18734 static void 18735 f_strwidth(argvars, rettv) 18736 typval_T *argvars; 18737 typval_T *rettv; 18738 { 18739 char_u *s = get_tv_string(&argvars[0]); 18740 18741 rettv->vval.v_number = (varnumber_T)( 18742 #ifdef FEAT_MBYTE 18743 mb_string2cells(s, -1) 18744 #else 18745 STRLEN(s) 18746 #endif 18747 ); 18748 } 18749 18750 /* 18751 * "strpart()" function 18752 */ 18753 static void 18754 f_strpart(argvars, rettv) 18755 typval_T *argvars; 18756 typval_T *rettv; 18757 { 18758 char_u *p; 18759 int n; 18760 int len; 18761 int slen; 18762 int error = FALSE; 18763 18764 p = get_tv_string(&argvars[0]); 18765 slen = (int)STRLEN(p); 18766 18767 n = get_tv_number_chk(&argvars[1], &error); 18768 if (error) 18769 len = 0; 18770 else if (argvars[2].v_type != VAR_UNKNOWN) 18771 len = get_tv_number(&argvars[2]); 18772 else 18773 len = slen - n; /* default len: all bytes that are available. */ 18774 18775 /* 18776 * Only return the overlap between the specified part and the actual 18777 * string. 18778 */ 18779 if (n < 0) 18780 { 18781 len += n; 18782 n = 0; 18783 } 18784 else if (n > slen) 18785 n = slen; 18786 if (len < 0) 18787 len = 0; 18788 else if (n + len > slen) 18789 len = slen - n; 18790 18791 rettv->v_type = VAR_STRING; 18792 rettv->vval.v_string = vim_strnsave(p + n, len); 18793 } 18794 18795 /* 18796 * "strridx()" function 18797 */ 18798 static void 18799 f_strridx(argvars, rettv) 18800 typval_T *argvars; 18801 typval_T *rettv; 18802 { 18803 char_u buf[NUMBUFLEN]; 18804 char_u *needle; 18805 char_u *haystack; 18806 char_u *rest; 18807 char_u *lastmatch = NULL; 18808 int haystack_len, end_idx; 18809 18810 needle = get_tv_string_chk(&argvars[1]); 18811 haystack = get_tv_string_buf_chk(&argvars[0], buf); 18812 18813 rettv->vval.v_number = -1; 18814 if (needle == NULL || haystack == NULL) 18815 return; /* type error; errmsg already given */ 18816 18817 haystack_len = (int)STRLEN(haystack); 18818 if (argvars[2].v_type != VAR_UNKNOWN) 18819 { 18820 /* Third argument: upper limit for index */ 18821 end_idx = get_tv_number_chk(&argvars[2], NULL); 18822 if (end_idx < 0) 18823 return; /* can never find a match */ 18824 } 18825 else 18826 end_idx = haystack_len; 18827 18828 if (*needle == NUL) 18829 { 18830 /* Empty string matches past the end. */ 18831 lastmatch = haystack + end_idx; 18832 } 18833 else 18834 { 18835 for (rest = haystack; *rest != '\0'; ++rest) 18836 { 18837 rest = (char_u *)strstr((char *)rest, (char *)needle); 18838 if (rest == NULL || rest > haystack + end_idx) 18839 break; 18840 lastmatch = rest; 18841 } 18842 } 18843 18844 if (lastmatch == NULL) 18845 rettv->vval.v_number = -1; 18846 else 18847 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 18848 } 18849 18850 /* 18851 * "strtrans()" function 18852 */ 18853 static void 18854 f_strtrans(argvars, rettv) 18855 typval_T *argvars; 18856 typval_T *rettv; 18857 { 18858 rettv->v_type = VAR_STRING; 18859 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 18860 } 18861 18862 /* 18863 * "submatch()" function 18864 */ 18865 static void 18866 f_submatch(argvars, rettv) 18867 typval_T *argvars; 18868 typval_T *rettv; 18869 { 18870 int error = FALSE; 18871 int no; 18872 int retList = 0; 18873 18874 no = (int)get_tv_number_chk(&argvars[0], &error); 18875 if (error) 18876 return; 18877 error = FALSE; 18878 if (argvars[1].v_type != VAR_UNKNOWN) 18879 retList = get_tv_number_chk(&argvars[1], &error); 18880 if (error) 18881 return; 18882 18883 if (retList == 0) 18884 { 18885 rettv->v_type = VAR_STRING; 18886 rettv->vval.v_string = reg_submatch(no); 18887 } 18888 else 18889 { 18890 rettv->v_type = VAR_LIST; 18891 rettv->vval.v_list = reg_submatch_list(no); 18892 } 18893 } 18894 18895 /* 18896 * "substitute()" function 18897 */ 18898 static void 18899 f_substitute(argvars, rettv) 18900 typval_T *argvars; 18901 typval_T *rettv; 18902 { 18903 char_u patbuf[NUMBUFLEN]; 18904 char_u subbuf[NUMBUFLEN]; 18905 char_u flagsbuf[NUMBUFLEN]; 18906 18907 char_u *str = get_tv_string_chk(&argvars[0]); 18908 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 18909 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 18910 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 18911 18912 rettv->v_type = VAR_STRING; 18913 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 18914 rettv->vval.v_string = NULL; 18915 else 18916 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 18917 } 18918 18919 /* 18920 * "synID(lnum, col, trans)" function 18921 */ 18922 static void 18923 f_synID(argvars, rettv) 18924 typval_T *argvars UNUSED; 18925 typval_T *rettv; 18926 { 18927 int id = 0; 18928 #ifdef FEAT_SYN_HL 18929 long lnum; 18930 long col; 18931 int trans; 18932 int transerr = FALSE; 18933 18934 lnum = get_tv_lnum(argvars); /* -1 on type error */ 18935 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 18936 trans = get_tv_number_chk(&argvars[2], &transerr); 18937 18938 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 18939 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 18940 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 18941 #endif 18942 18943 rettv->vval.v_number = id; 18944 } 18945 18946 /* 18947 * "synIDattr(id, what [, mode])" function 18948 */ 18949 static void 18950 f_synIDattr(argvars, rettv) 18951 typval_T *argvars UNUSED; 18952 typval_T *rettv; 18953 { 18954 char_u *p = NULL; 18955 #ifdef FEAT_SYN_HL 18956 int id; 18957 char_u *what; 18958 char_u *mode; 18959 char_u modebuf[NUMBUFLEN]; 18960 int modec; 18961 18962 id = get_tv_number(&argvars[0]); 18963 what = get_tv_string(&argvars[1]); 18964 if (argvars[2].v_type != VAR_UNKNOWN) 18965 { 18966 mode = get_tv_string_buf(&argvars[2], modebuf); 18967 modec = TOLOWER_ASC(mode[0]); 18968 if (modec != 't' && modec != 'c' && modec != 'g') 18969 modec = 0; /* replace invalid with current */ 18970 } 18971 else 18972 { 18973 #ifdef FEAT_GUI 18974 if (gui.in_use) 18975 modec = 'g'; 18976 else 18977 #endif 18978 if (t_colors > 1) 18979 modec = 'c'; 18980 else 18981 modec = 't'; 18982 } 18983 18984 18985 switch (TOLOWER_ASC(what[0])) 18986 { 18987 case 'b': 18988 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 18989 p = highlight_color(id, what, modec); 18990 else /* bold */ 18991 p = highlight_has_attr(id, HL_BOLD, modec); 18992 break; 18993 18994 case 'f': /* fg[#] or font */ 18995 p = highlight_color(id, what, modec); 18996 break; 18997 18998 case 'i': 18999 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 19000 p = highlight_has_attr(id, HL_INVERSE, modec); 19001 else /* italic */ 19002 p = highlight_has_attr(id, HL_ITALIC, modec); 19003 break; 19004 19005 case 'n': /* name */ 19006 p = get_highlight_name(NULL, id - 1); 19007 break; 19008 19009 case 'r': /* reverse */ 19010 p = highlight_has_attr(id, HL_INVERSE, modec); 19011 break; 19012 19013 case 's': 19014 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 19015 p = highlight_color(id, what, modec); 19016 else /* standout */ 19017 p = highlight_has_attr(id, HL_STANDOUT, modec); 19018 break; 19019 19020 case 'u': 19021 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 19022 /* underline */ 19023 p = highlight_has_attr(id, HL_UNDERLINE, modec); 19024 else 19025 /* undercurl */ 19026 p = highlight_has_attr(id, HL_UNDERCURL, modec); 19027 break; 19028 } 19029 19030 if (p != NULL) 19031 p = vim_strsave(p); 19032 #endif 19033 rettv->v_type = VAR_STRING; 19034 rettv->vval.v_string = p; 19035 } 19036 19037 /* 19038 * "synIDtrans(id)" function 19039 */ 19040 static void 19041 f_synIDtrans(argvars, rettv) 19042 typval_T *argvars UNUSED; 19043 typval_T *rettv; 19044 { 19045 int id; 19046 19047 #ifdef FEAT_SYN_HL 19048 id = get_tv_number(&argvars[0]); 19049 19050 if (id > 0) 19051 id = syn_get_final_id(id); 19052 else 19053 #endif 19054 id = 0; 19055 19056 rettv->vval.v_number = id; 19057 } 19058 19059 /* 19060 * "synconcealed(lnum, col)" function 19061 */ 19062 static void 19063 f_synconcealed(argvars, rettv) 19064 typval_T *argvars UNUSED; 19065 typval_T *rettv; 19066 { 19067 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 19068 long lnum; 19069 long col; 19070 int syntax_flags = 0; 19071 int cchar; 19072 int matchid = 0; 19073 char_u str[NUMBUFLEN]; 19074 #endif 19075 19076 rettv->v_type = VAR_LIST; 19077 rettv->vval.v_list = NULL; 19078 19079 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 19080 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19081 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19082 19083 vim_memset(str, NUL, sizeof(str)); 19084 19085 if (rettv_list_alloc(rettv) != FAIL) 19086 { 19087 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19088 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 19089 && curwin->w_p_cole > 0) 19090 { 19091 (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE); 19092 syntax_flags = get_syntax_info(&matchid); 19093 19094 /* get the conceal character */ 19095 if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) 19096 { 19097 cchar = syn_get_sub_char(); 19098 if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL) 19099 cchar = lcs_conceal; 19100 if (cchar != NUL) 19101 { 19102 # ifdef FEAT_MBYTE 19103 if (has_mbyte) 19104 (*mb_char2bytes)(cchar, str); 19105 else 19106 # endif 19107 str[0] = cchar; 19108 } 19109 } 19110 } 19111 19112 list_append_number(rettv->vval.v_list, 19113 (syntax_flags & HL_CONCEAL) != 0); 19114 /* -1 to auto-determine strlen */ 19115 list_append_string(rettv->vval.v_list, str, -1); 19116 list_append_number(rettv->vval.v_list, matchid); 19117 } 19118 #endif 19119 } 19120 19121 /* 19122 * "synstack(lnum, col)" function 19123 */ 19124 static void 19125 f_synstack(argvars, rettv) 19126 typval_T *argvars UNUSED; 19127 typval_T *rettv; 19128 { 19129 #ifdef FEAT_SYN_HL 19130 long lnum; 19131 long col; 19132 int i; 19133 int id; 19134 #endif 19135 19136 rettv->v_type = VAR_LIST; 19137 rettv->vval.v_list = NULL; 19138 19139 #ifdef FEAT_SYN_HL 19140 lnum = get_tv_lnum(argvars); /* -1 on type error */ 19141 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 19142 19143 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 19144 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 19145 && rettv_list_alloc(rettv) != FAIL) 19146 { 19147 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 19148 for (i = 0; ; ++i) 19149 { 19150 id = syn_get_stack_item(i); 19151 if (id < 0) 19152 break; 19153 if (list_append_number(rettv->vval.v_list, id) == FAIL) 19154 break; 19155 } 19156 } 19157 #endif 19158 } 19159 19160 static void 19161 get_cmd_output_as_rettv(argvars, rettv, retlist) 19162 typval_T *argvars; 19163 typval_T *rettv; 19164 int retlist; 19165 { 19166 char_u *res = NULL; 19167 char_u *p; 19168 char_u *infile = NULL; 19169 char_u buf[NUMBUFLEN]; 19170 int err = FALSE; 19171 FILE *fd; 19172 list_T *list = NULL; 19173 int flags = SHELL_SILENT; 19174 19175 rettv->v_type = VAR_STRING; 19176 rettv->vval.v_string = NULL; 19177 if (check_restricted() || check_secure()) 19178 goto errret; 19179 19180 if (argvars[1].v_type != VAR_UNKNOWN) 19181 { 19182 /* 19183 * Write the string to a temp file, to be used for input of the shell 19184 * command. 19185 */ 19186 if ((infile = vim_tempname('i', TRUE)) == NULL) 19187 { 19188 EMSG(_(e_notmp)); 19189 goto errret; 19190 } 19191 19192 fd = mch_fopen((char *)infile, WRITEBIN); 19193 if (fd == NULL) 19194 { 19195 EMSG2(_(e_notopen), infile); 19196 goto errret; 19197 } 19198 if (argvars[1].v_type == VAR_LIST) 19199 { 19200 if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL) 19201 err = TRUE; 19202 } 19203 else 19204 { 19205 size_t len; 19206 19207 p = get_tv_string_buf_chk(&argvars[1], buf); 19208 if (p == NULL) 19209 { 19210 fclose(fd); 19211 goto errret; /* type error; errmsg already given */ 19212 } 19213 len = STRLEN(p); 19214 if (len > 0 && fwrite(p, len, 1, fd) != 1) 19215 err = TRUE; 19216 } 19217 if (fclose(fd) != 0) 19218 err = TRUE; 19219 if (err) 19220 { 19221 EMSG(_("E677: Error writing temp file")); 19222 goto errret; 19223 } 19224 } 19225 19226 /* Omit SHELL_COOKED when invoked with ":silent". Avoids that the shell 19227 * echoes typeahead, that messes up the display. */ 19228 if (!msg_silent) 19229 flags += SHELL_COOKED; 19230 19231 if (retlist) 19232 { 19233 int len; 19234 listitem_T *li; 19235 char_u *s = NULL; 19236 char_u *start; 19237 char_u *end; 19238 int i; 19239 19240 res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, &len); 19241 if (res == NULL) 19242 goto errret; 19243 19244 list = list_alloc(); 19245 if (list == NULL) 19246 goto errret; 19247 19248 for (i = 0; i < len; ++i) 19249 { 19250 start = res + i; 19251 while (i < len && res[i] != NL) 19252 ++i; 19253 end = res + i; 19254 19255 s = alloc((unsigned)(end - start + 1)); 19256 if (s == NULL) 19257 goto errret; 19258 19259 for (p = s; start < end; ++p, ++start) 19260 *p = *start == NUL ? NL : *start; 19261 *p = NUL; 19262 19263 li = listitem_alloc(); 19264 if (li == NULL) 19265 { 19266 vim_free(s); 19267 goto errret; 19268 } 19269 li->li_tv.v_type = VAR_STRING; 19270 li->li_tv.v_lock = 0; 19271 li->li_tv.vval.v_string = s; 19272 list_append(list, li); 19273 } 19274 19275 ++list->lv_refcount; 19276 rettv->v_type = VAR_LIST; 19277 rettv->vval.v_list = list; 19278 list = NULL; 19279 } 19280 else 19281 { 19282 res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, NULL); 19283 #ifdef USE_CR 19284 /* translate <CR> into <NL> */ 19285 if (res != NULL) 19286 { 19287 char_u *s; 19288 19289 for (s = res; *s; ++s) 19290 { 19291 if (*s == CAR) 19292 *s = NL; 19293 } 19294 } 19295 #else 19296 # ifdef USE_CRNL 19297 /* translate <CR><NL> into <NL> */ 19298 if (res != NULL) 19299 { 19300 char_u *s, *d; 19301 19302 d = res; 19303 for (s = res; *s; ++s) 19304 { 19305 if (s[0] == CAR && s[1] == NL) 19306 ++s; 19307 *d++ = *s; 19308 } 19309 *d = NUL; 19310 } 19311 # endif 19312 #endif 19313 rettv->vval.v_string = res; 19314 res = NULL; 19315 } 19316 19317 errret: 19318 if (infile != NULL) 19319 { 19320 mch_remove(infile); 19321 vim_free(infile); 19322 } 19323 if (res != NULL) 19324 vim_free(res); 19325 if (list != NULL) 19326 list_free(list, TRUE); 19327 } 19328 19329 /* 19330 * "system()" function 19331 */ 19332 static void 19333 f_system(argvars, rettv) 19334 typval_T *argvars; 19335 typval_T *rettv; 19336 { 19337 get_cmd_output_as_rettv(argvars, rettv, FALSE); 19338 } 19339 19340 /* 19341 * "systemlist()" function 19342 */ 19343 static void 19344 f_systemlist(argvars, rettv) 19345 typval_T *argvars; 19346 typval_T *rettv; 19347 { 19348 get_cmd_output_as_rettv(argvars, rettv, TRUE); 19349 } 19350 19351 /* 19352 * "tabpagebuflist()" function 19353 */ 19354 static void 19355 f_tabpagebuflist(argvars, rettv) 19356 typval_T *argvars UNUSED; 19357 typval_T *rettv UNUSED; 19358 { 19359 #ifdef FEAT_WINDOWS 19360 tabpage_T *tp; 19361 win_T *wp = NULL; 19362 19363 if (argvars[0].v_type == VAR_UNKNOWN) 19364 wp = firstwin; 19365 else 19366 { 19367 tp = find_tabpage((int)get_tv_number(&argvars[0])); 19368 if (tp != NULL) 19369 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 19370 } 19371 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 19372 { 19373 for (; wp != NULL; wp = wp->w_next) 19374 if (list_append_number(rettv->vval.v_list, 19375 wp->w_buffer->b_fnum) == FAIL) 19376 break; 19377 } 19378 #endif 19379 } 19380 19381 19382 /* 19383 * "tabpagenr()" function 19384 */ 19385 static void 19386 f_tabpagenr(argvars, rettv) 19387 typval_T *argvars UNUSED; 19388 typval_T *rettv; 19389 { 19390 int nr = 1; 19391 #ifdef FEAT_WINDOWS 19392 char_u *arg; 19393 19394 if (argvars[0].v_type != VAR_UNKNOWN) 19395 { 19396 arg = get_tv_string_chk(&argvars[0]); 19397 nr = 0; 19398 if (arg != NULL) 19399 { 19400 if (STRCMP(arg, "$") == 0) 19401 nr = tabpage_index(NULL) - 1; 19402 else 19403 EMSG2(_(e_invexpr2), arg); 19404 } 19405 } 19406 else 19407 nr = tabpage_index(curtab); 19408 #endif 19409 rettv->vval.v_number = nr; 19410 } 19411 19412 19413 #ifdef FEAT_WINDOWS 19414 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 19415 19416 /* 19417 * Common code for tabpagewinnr() and winnr(). 19418 */ 19419 static int 19420 get_winnr(tp, argvar) 19421 tabpage_T *tp; 19422 typval_T *argvar; 19423 { 19424 win_T *twin; 19425 int nr = 1; 19426 win_T *wp; 19427 char_u *arg; 19428 19429 twin = (tp == curtab) ? curwin : tp->tp_curwin; 19430 if (argvar->v_type != VAR_UNKNOWN) 19431 { 19432 arg = get_tv_string_chk(argvar); 19433 if (arg == NULL) 19434 nr = 0; /* type error; errmsg already given */ 19435 else if (STRCMP(arg, "$") == 0) 19436 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 19437 else if (STRCMP(arg, "#") == 0) 19438 { 19439 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 19440 if (twin == NULL) 19441 nr = 0; 19442 } 19443 else 19444 { 19445 EMSG2(_(e_invexpr2), arg); 19446 nr = 0; 19447 } 19448 } 19449 19450 if (nr > 0) 19451 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 19452 wp != twin; wp = wp->w_next) 19453 { 19454 if (wp == NULL) 19455 { 19456 /* didn't find it in this tabpage */ 19457 nr = 0; 19458 break; 19459 } 19460 ++nr; 19461 } 19462 return nr; 19463 } 19464 #endif 19465 19466 /* 19467 * "tabpagewinnr()" function 19468 */ 19469 static void 19470 f_tabpagewinnr(argvars, rettv) 19471 typval_T *argvars UNUSED; 19472 typval_T *rettv; 19473 { 19474 int nr = 1; 19475 #ifdef FEAT_WINDOWS 19476 tabpage_T *tp; 19477 19478 tp = find_tabpage((int)get_tv_number(&argvars[0])); 19479 if (tp == NULL) 19480 nr = 0; 19481 else 19482 nr = get_winnr(tp, &argvars[1]); 19483 #endif 19484 rettv->vval.v_number = nr; 19485 } 19486 19487 19488 /* 19489 * "tagfiles()" function 19490 */ 19491 static void 19492 f_tagfiles(argvars, rettv) 19493 typval_T *argvars UNUSED; 19494 typval_T *rettv; 19495 { 19496 char_u *fname; 19497 tagname_T tn; 19498 int first; 19499 19500 if (rettv_list_alloc(rettv) == FAIL) 19501 return; 19502 fname = alloc(MAXPATHL); 19503 if (fname == NULL) 19504 return; 19505 19506 for (first = TRUE; ; first = FALSE) 19507 if (get_tagfname(&tn, first, fname) == FAIL 19508 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 19509 break; 19510 tagname_free(&tn); 19511 vim_free(fname); 19512 } 19513 19514 /* 19515 * "taglist()" function 19516 */ 19517 static void 19518 f_taglist(argvars, rettv) 19519 typval_T *argvars; 19520 typval_T *rettv; 19521 { 19522 char_u *tag_pattern; 19523 19524 tag_pattern = get_tv_string(&argvars[0]); 19525 19526 rettv->vval.v_number = FALSE; 19527 if (*tag_pattern == NUL) 19528 return; 19529 19530 if (rettv_list_alloc(rettv) == OK) 19531 (void)get_tags(rettv->vval.v_list, tag_pattern); 19532 } 19533 19534 /* 19535 * "tempname()" function 19536 */ 19537 static void 19538 f_tempname(argvars, rettv) 19539 typval_T *argvars UNUSED; 19540 typval_T *rettv; 19541 { 19542 static int x = 'A'; 19543 19544 rettv->v_type = VAR_STRING; 19545 rettv->vval.v_string = vim_tempname(x, FALSE); 19546 19547 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 19548 * names. Skip 'I' and 'O', they are used for shell redirection. */ 19549 do 19550 { 19551 if (x == 'Z') 19552 x = '0'; 19553 else if (x == '9') 19554 x = 'A'; 19555 else 19556 { 19557 #ifdef EBCDIC 19558 if (x == 'I') 19559 x = 'J'; 19560 else if (x == 'R') 19561 x = 'S'; 19562 else 19563 #endif 19564 ++x; 19565 } 19566 } while (x == 'I' || x == 'O'); 19567 } 19568 19569 /* 19570 * "test(list)" function: Just checking the walls... 19571 */ 19572 static void 19573 f_test(argvars, rettv) 19574 typval_T *argvars UNUSED; 19575 typval_T *rettv UNUSED; 19576 { 19577 /* Used for unit testing. Change the code below to your liking. */ 19578 #if 0 19579 listitem_T *li; 19580 list_T *l; 19581 char_u *bad, *good; 19582 19583 if (argvars[0].v_type != VAR_LIST) 19584 return; 19585 l = argvars[0].vval.v_list; 19586 if (l == NULL) 19587 return; 19588 li = l->lv_first; 19589 if (li == NULL) 19590 return; 19591 bad = get_tv_string(&li->li_tv); 19592 li = li->li_next; 19593 if (li == NULL) 19594 return; 19595 good = get_tv_string(&li->li_tv); 19596 rettv->vval.v_number = test_edit_score(bad, good); 19597 #endif 19598 } 19599 19600 #ifdef FEAT_FLOAT 19601 /* 19602 * "tan()" function 19603 */ 19604 static void 19605 f_tan(argvars, rettv) 19606 typval_T *argvars; 19607 typval_T *rettv; 19608 { 19609 float_T f; 19610 19611 rettv->v_type = VAR_FLOAT; 19612 if (get_float_arg(argvars, &f) == OK) 19613 rettv->vval.v_float = tan(f); 19614 else 19615 rettv->vval.v_float = 0.0; 19616 } 19617 19618 /* 19619 * "tanh()" function 19620 */ 19621 static void 19622 f_tanh(argvars, rettv) 19623 typval_T *argvars; 19624 typval_T *rettv; 19625 { 19626 float_T f; 19627 19628 rettv->v_type = VAR_FLOAT; 19629 if (get_float_arg(argvars, &f) == OK) 19630 rettv->vval.v_float = tanh(f); 19631 else 19632 rettv->vval.v_float = 0.0; 19633 } 19634 #endif 19635 19636 /* 19637 * "tolower(string)" function 19638 */ 19639 static void 19640 f_tolower(argvars, rettv) 19641 typval_T *argvars; 19642 typval_T *rettv; 19643 { 19644 char_u *p; 19645 19646 p = vim_strsave(get_tv_string(&argvars[0])); 19647 rettv->v_type = VAR_STRING; 19648 rettv->vval.v_string = p; 19649 19650 if (p != NULL) 19651 while (*p != NUL) 19652 { 19653 #ifdef FEAT_MBYTE 19654 int l; 19655 19656 if (enc_utf8) 19657 { 19658 int c, lc; 19659 19660 c = utf_ptr2char(p); 19661 lc = utf_tolower(c); 19662 l = utf_ptr2len(p); 19663 /* TODO: reallocate string when byte count changes. */ 19664 if (utf_char2len(lc) == l) 19665 utf_char2bytes(lc, p); 19666 p += l; 19667 } 19668 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 19669 p += l; /* skip multi-byte character */ 19670 else 19671 #endif 19672 { 19673 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 19674 ++p; 19675 } 19676 } 19677 } 19678 19679 /* 19680 * "toupper(string)" function 19681 */ 19682 static void 19683 f_toupper(argvars, rettv) 19684 typval_T *argvars; 19685 typval_T *rettv; 19686 { 19687 rettv->v_type = VAR_STRING; 19688 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 19689 } 19690 19691 /* 19692 * "tr(string, fromstr, tostr)" function 19693 */ 19694 static void 19695 f_tr(argvars, rettv) 19696 typval_T *argvars; 19697 typval_T *rettv; 19698 { 19699 char_u *in_str; 19700 char_u *fromstr; 19701 char_u *tostr; 19702 char_u *p; 19703 #ifdef FEAT_MBYTE 19704 int inlen; 19705 int fromlen; 19706 int tolen; 19707 int idx; 19708 char_u *cpstr; 19709 int cplen; 19710 int first = TRUE; 19711 #endif 19712 char_u buf[NUMBUFLEN]; 19713 char_u buf2[NUMBUFLEN]; 19714 garray_T ga; 19715 19716 in_str = get_tv_string(&argvars[0]); 19717 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 19718 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 19719 19720 /* Default return value: empty string. */ 19721 rettv->v_type = VAR_STRING; 19722 rettv->vval.v_string = NULL; 19723 if (fromstr == NULL || tostr == NULL) 19724 return; /* type error; errmsg already given */ 19725 ga_init2(&ga, (int)sizeof(char), 80); 19726 19727 #ifdef FEAT_MBYTE 19728 if (!has_mbyte) 19729 #endif 19730 /* not multi-byte: fromstr and tostr must be the same length */ 19731 if (STRLEN(fromstr) != STRLEN(tostr)) 19732 { 19733 #ifdef FEAT_MBYTE 19734 error: 19735 #endif 19736 EMSG2(_(e_invarg2), fromstr); 19737 ga_clear(&ga); 19738 return; 19739 } 19740 19741 /* fromstr and tostr have to contain the same number of chars */ 19742 while (*in_str != NUL) 19743 { 19744 #ifdef FEAT_MBYTE 19745 if (has_mbyte) 19746 { 19747 inlen = (*mb_ptr2len)(in_str); 19748 cpstr = in_str; 19749 cplen = inlen; 19750 idx = 0; 19751 for (p = fromstr; *p != NUL; p += fromlen) 19752 { 19753 fromlen = (*mb_ptr2len)(p); 19754 if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) 19755 { 19756 for (p = tostr; *p != NUL; p += tolen) 19757 { 19758 tolen = (*mb_ptr2len)(p); 19759 if (idx-- == 0) 19760 { 19761 cplen = tolen; 19762 cpstr = p; 19763 break; 19764 } 19765 } 19766 if (*p == NUL) /* tostr is shorter than fromstr */ 19767 goto error; 19768 break; 19769 } 19770 ++idx; 19771 } 19772 19773 if (first && cpstr == in_str) 19774 { 19775 /* Check that fromstr and tostr have the same number of 19776 * (multi-byte) characters. Done only once when a character 19777 * of in_str doesn't appear in fromstr. */ 19778 first = FALSE; 19779 for (p = tostr; *p != NUL; p += tolen) 19780 { 19781 tolen = (*mb_ptr2len)(p); 19782 --idx; 19783 } 19784 if (idx != 0) 19785 goto error; 19786 } 19787 19788 (void)ga_grow(&ga, cplen); 19789 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 19790 ga.ga_len += cplen; 19791 19792 in_str += inlen; 19793 } 19794 else 19795 #endif 19796 { 19797 /* When not using multi-byte chars we can do it faster. */ 19798 p = vim_strchr(fromstr, *in_str); 19799 if (p != NULL) 19800 ga_append(&ga, tostr[p - fromstr]); 19801 else 19802 ga_append(&ga, *in_str); 19803 ++in_str; 19804 } 19805 } 19806 19807 /* add a terminating NUL */ 19808 (void)ga_grow(&ga, 1); 19809 ga_append(&ga, NUL); 19810 19811 rettv->vval.v_string = ga.ga_data; 19812 } 19813 19814 #ifdef FEAT_FLOAT 19815 /* 19816 * "trunc({float})" function 19817 */ 19818 static void 19819 f_trunc(argvars, rettv) 19820 typval_T *argvars; 19821 typval_T *rettv; 19822 { 19823 float_T f; 19824 19825 rettv->v_type = VAR_FLOAT; 19826 if (get_float_arg(argvars, &f) == OK) 19827 /* trunc() is not in C90, use floor() or ceil() instead. */ 19828 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 19829 else 19830 rettv->vval.v_float = 0.0; 19831 } 19832 #endif 19833 19834 /* 19835 * "type(expr)" function 19836 */ 19837 static void 19838 f_type(argvars, rettv) 19839 typval_T *argvars; 19840 typval_T *rettv; 19841 { 19842 int n; 19843 19844 switch (argvars[0].v_type) 19845 { 19846 case VAR_NUMBER: n = 0; break; 19847 case VAR_STRING: n = 1; break; 19848 case VAR_FUNC: n = 2; break; 19849 case VAR_LIST: n = 3; break; 19850 case VAR_DICT: n = 4; break; 19851 #ifdef FEAT_FLOAT 19852 case VAR_FLOAT: n = 5; break; 19853 #endif 19854 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 19855 } 19856 rettv->vval.v_number = n; 19857 } 19858 19859 /* 19860 * "undofile(name)" function 19861 */ 19862 static void 19863 f_undofile(argvars, rettv) 19864 typval_T *argvars UNUSED; 19865 typval_T *rettv; 19866 { 19867 rettv->v_type = VAR_STRING; 19868 #ifdef FEAT_PERSISTENT_UNDO 19869 { 19870 char_u *fname = get_tv_string(&argvars[0]); 19871 19872 if (*fname == NUL) 19873 { 19874 /* If there is no file name there will be no undo file. */ 19875 rettv->vval.v_string = NULL; 19876 } 19877 else 19878 { 19879 char_u *ffname = FullName_save(fname, FALSE); 19880 19881 if (ffname != NULL) 19882 rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); 19883 vim_free(ffname); 19884 } 19885 } 19886 #else 19887 rettv->vval.v_string = NULL; 19888 #endif 19889 } 19890 19891 /* 19892 * "undotree()" function 19893 */ 19894 static void 19895 f_undotree(argvars, rettv) 19896 typval_T *argvars UNUSED; 19897 typval_T *rettv; 19898 { 19899 if (rettv_dict_alloc(rettv) == OK) 19900 { 19901 dict_T *dict = rettv->vval.v_dict; 19902 list_T *list; 19903 19904 dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL); 19905 dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL); 19906 dict_add_nr_str(dict, "save_last", 19907 (long)curbuf->b_u_save_nr_last, NULL); 19908 dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL); 19909 dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL); 19910 dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL); 19911 19912 list = list_alloc(); 19913 if (list != NULL) 19914 { 19915 u_eval_tree(curbuf->b_u_oldhead, list); 19916 dict_add_list(dict, "entries", list); 19917 } 19918 } 19919 } 19920 19921 /* 19922 * "values(dict)" function 19923 */ 19924 static void 19925 f_values(argvars, rettv) 19926 typval_T *argvars; 19927 typval_T *rettv; 19928 { 19929 dict_list(argvars, rettv, 1); 19930 } 19931 19932 /* 19933 * "virtcol(string)" function 19934 */ 19935 static void 19936 f_virtcol(argvars, rettv) 19937 typval_T *argvars; 19938 typval_T *rettv; 19939 { 19940 colnr_T vcol = 0; 19941 pos_T *fp; 19942 int fnum = curbuf->b_fnum; 19943 19944 fp = var2fpos(&argvars[0], FALSE, &fnum); 19945 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 19946 && fnum == curbuf->b_fnum) 19947 { 19948 getvvcol(curwin, fp, NULL, NULL, &vcol); 19949 ++vcol; 19950 } 19951 19952 rettv->vval.v_number = vcol; 19953 } 19954 19955 /* 19956 * "visualmode()" function 19957 */ 19958 static void 19959 f_visualmode(argvars, rettv) 19960 typval_T *argvars UNUSED; 19961 typval_T *rettv UNUSED; 19962 { 19963 char_u str[2]; 19964 19965 rettv->v_type = VAR_STRING; 19966 str[0] = curbuf->b_visual_mode_eval; 19967 str[1] = NUL; 19968 rettv->vval.v_string = vim_strsave(str); 19969 19970 /* A non-zero number or non-empty string argument: reset mode. */ 19971 if (non_zero_arg(&argvars[0])) 19972 curbuf->b_visual_mode_eval = NUL; 19973 } 19974 19975 /* 19976 * "wildmenumode()" function 19977 */ 19978 static void 19979 f_wildmenumode(argvars, rettv) 19980 typval_T *argvars UNUSED; 19981 typval_T *rettv UNUSED; 19982 { 19983 #ifdef FEAT_WILDMENU 19984 if (wild_menu_showing) 19985 rettv->vval.v_number = 1; 19986 #endif 19987 } 19988 19989 /* 19990 * "winbufnr(nr)" function 19991 */ 19992 static void 19993 f_winbufnr(argvars, rettv) 19994 typval_T *argvars; 19995 typval_T *rettv; 19996 { 19997 win_T *wp; 19998 19999 wp = find_win_by_nr(&argvars[0], NULL); 20000 if (wp == NULL) 20001 rettv->vval.v_number = -1; 20002 else 20003 rettv->vval.v_number = wp->w_buffer->b_fnum; 20004 } 20005 20006 /* 20007 * "wincol()" function 20008 */ 20009 static void 20010 f_wincol(argvars, rettv) 20011 typval_T *argvars UNUSED; 20012 typval_T *rettv; 20013 { 20014 validate_cursor(); 20015 rettv->vval.v_number = curwin->w_wcol + 1; 20016 } 20017 20018 /* 20019 * "winheight(nr)" function 20020 */ 20021 static void 20022 f_winheight(argvars, rettv) 20023 typval_T *argvars; 20024 typval_T *rettv; 20025 { 20026 win_T *wp; 20027 20028 wp = find_win_by_nr(&argvars[0], NULL); 20029 if (wp == NULL) 20030 rettv->vval.v_number = -1; 20031 else 20032 rettv->vval.v_number = wp->w_height; 20033 } 20034 20035 /* 20036 * "winline()" function 20037 */ 20038 static void 20039 f_winline(argvars, rettv) 20040 typval_T *argvars UNUSED; 20041 typval_T *rettv; 20042 { 20043 validate_cursor(); 20044 rettv->vval.v_number = curwin->w_wrow + 1; 20045 } 20046 20047 /* 20048 * "winnr()" function 20049 */ 20050 static void 20051 f_winnr(argvars, rettv) 20052 typval_T *argvars UNUSED; 20053 typval_T *rettv; 20054 { 20055 int nr = 1; 20056 20057 #ifdef FEAT_WINDOWS 20058 nr = get_winnr(curtab, &argvars[0]); 20059 #endif 20060 rettv->vval.v_number = nr; 20061 } 20062 20063 /* 20064 * "winrestcmd()" function 20065 */ 20066 static void 20067 f_winrestcmd(argvars, rettv) 20068 typval_T *argvars UNUSED; 20069 typval_T *rettv; 20070 { 20071 #ifdef FEAT_WINDOWS 20072 win_T *wp; 20073 int winnr = 1; 20074 garray_T ga; 20075 char_u buf[50]; 20076 20077 ga_init2(&ga, (int)sizeof(char), 70); 20078 for (wp = firstwin; wp != NULL; wp = wp->w_next) 20079 { 20080 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 20081 ga_concat(&ga, buf); 20082 # ifdef FEAT_VERTSPLIT 20083 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 20084 ga_concat(&ga, buf); 20085 # endif 20086 ++winnr; 20087 } 20088 ga_append(&ga, NUL); 20089 20090 rettv->vval.v_string = ga.ga_data; 20091 #else 20092 rettv->vval.v_string = NULL; 20093 #endif 20094 rettv->v_type = VAR_STRING; 20095 } 20096 20097 /* 20098 * "winrestview()" function 20099 */ 20100 static void 20101 f_winrestview(argvars, rettv) 20102 typval_T *argvars; 20103 typval_T *rettv UNUSED; 20104 { 20105 dict_T *dict; 20106 20107 if (argvars[0].v_type != VAR_DICT 20108 || (dict = argvars[0].vval.v_dict) == NULL) 20109 EMSG(_(e_invarg)); 20110 else 20111 { 20112 if (dict_find(dict, (char_u *)"lnum", -1) != NULL) 20113 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 20114 if (dict_find(dict, (char_u *)"col", -1) != NULL) 20115 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 20116 #ifdef FEAT_VIRTUALEDIT 20117 if (dict_find(dict, (char_u *)"coladd", -1) != NULL) 20118 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 20119 #endif 20120 if (dict_find(dict, (char_u *)"curswant", -1) != NULL) 20121 { 20122 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 20123 curwin->w_set_curswant = FALSE; 20124 } 20125 20126 if (dict_find(dict, (char_u *)"topline", -1) != NULL) 20127 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 20128 #ifdef FEAT_DIFF 20129 if (dict_find(dict, (char_u *)"topfill", -1) != NULL) 20130 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 20131 #endif 20132 if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) 20133 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 20134 if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) 20135 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 20136 20137 check_cursor(); 20138 win_new_height(curwin, curwin->w_height); 20139 # ifdef FEAT_VERTSPLIT 20140 win_new_width(curwin, W_WIDTH(curwin)); 20141 # endif 20142 changed_window_setting(); 20143 20144 if (curwin->w_topline <= 0) 20145 curwin->w_topline = 1; 20146 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 20147 curwin->w_topline = curbuf->b_ml.ml_line_count; 20148 #ifdef FEAT_DIFF 20149 check_topfill(curwin, TRUE); 20150 #endif 20151 } 20152 } 20153 20154 /* 20155 * "winsaveview()" function 20156 */ 20157 static void 20158 f_winsaveview(argvars, rettv) 20159 typval_T *argvars UNUSED; 20160 typval_T *rettv; 20161 { 20162 dict_T *dict; 20163 20164 if (rettv_dict_alloc(rettv) == FAIL) 20165 return; 20166 dict = rettv->vval.v_dict; 20167 20168 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 20169 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 20170 #ifdef FEAT_VIRTUALEDIT 20171 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 20172 #endif 20173 update_curswant(); 20174 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 20175 20176 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 20177 #ifdef FEAT_DIFF 20178 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 20179 #endif 20180 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 20181 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 20182 } 20183 20184 /* 20185 * "winwidth(nr)" function 20186 */ 20187 static void 20188 f_winwidth(argvars, rettv) 20189 typval_T *argvars; 20190 typval_T *rettv; 20191 { 20192 win_T *wp; 20193 20194 wp = find_win_by_nr(&argvars[0], NULL); 20195 if (wp == NULL) 20196 rettv->vval.v_number = -1; 20197 else 20198 #ifdef FEAT_VERTSPLIT 20199 rettv->vval.v_number = wp->w_width; 20200 #else 20201 rettv->vval.v_number = Columns; 20202 #endif 20203 } 20204 20205 /* 20206 * Write list of strings to file 20207 */ 20208 static int 20209 write_list(fd, list, binary) 20210 FILE *fd; 20211 list_T *list; 20212 int binary; 20213 { 20214 listitem_T *li; 20215 int c; 20216 int ret = OK; 20217 char_u *s; 20218 20219 for (li = list->lv_first; li != NULL; li = li->li_next) 20220 { 20221 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 20222 { 20223 if (*s == '\n') 20224 c = putc(NUL, fd); 20225 else 20226 c = putc(*s, fd); 20227 if (c == EOF) 20228 { 20229 ret = FAIL; 20230 break; 20231 } 20232 } 20233 if (!binary || li->li_next != NULL) 20234 if (putc('\n', fd) == EOF) 20235 { 20236 ret = FAIL; 20237 break; 20238 } 20239 if (ret == FAIL) 20240 { 20241 EMSG(_(e_write)); 20242 break; 20243 } 20244 } 20245 return ret; 20246 } 20247 20248 /* 20249 * "writefile()" function 20250 */ 20251 static void 20252 f_writefile(argvars, rettv) 20253 typval_T *argvars; 20254 typval_T *rettv; 20255 { 20256 int binary = FALSE; 20257 int append = FALSE; 20258 char_u *fname; 20259 FILE *fd; 20260 int ret = 0; 20261 20262 if (check_restricted() || check_secure()) 20263 return; 20264 20265 if (argvars[0].v_type != VAR_LIST) 20266 { 20267 EMSG2(_(e_listarg), "writefile()"); 20268 return; 20269 } 20270 if (argvars[0].vval.v_list == NULL) 20271 return; 20272 20273 if (argvars[2].v_type != VAR_UNKNOWN) 20274 { 20275 if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL) 20276 binary = TRUE; 20277 if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL) 20278 append = TRUE; 20279 } 20280 20281 /* Always open the file in binary mode, library functions have a mind of 20282 * their own about CR-LF conversion. */ 20283 fname = get_tv_string(&argvars[1]); 20284 if (*fname == NUL || (fd = mch_fopen((char *)fname, 20285 append ? APPENDBIN : WRITEBIN)) == NULL) 20286 { 20287 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 20288 ret = -1; 20289 } 20290 else 20291 { 20292 if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL) 20293 ret = -1; 20294 fclose(fd); 20295 } 20296 20297 rettv->vval.v_number = ret; 20298 } 20299 20300 /* 20301 * "xor(expr, expr)" function 20302 */ 20303 static void 20304 f_xor(argvars, rettv) 20305 typval_T *argvars; 20306 typval_T *rettv; 20307 { 20308 rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) 20309 ^ get_tv_number_chk(&argvars[1], NULL); 20310 } 20311 20312 20313 /* 20314 * Translate a String variable into a position. 20315 * Returns NULL when there is an error. 20316 */ 20317 static pos_T * 20318 var2fpos(varp, dollar_lnum, fnum) 20319 typval_T *varp; 20320 int dollar_lnum; /* TRUE when $ is last line */ 20321 int *fnum; /* set to fnum for '0, 'A, etc. */ 20322 { 20323 char_u *name; 20324 static pos_T pos; 20325 pos_T *pp; 20326 20327 /* Argument can be [lnum, col, coladd]. */ 20328 if (varp->v_type == VAR_LIST) 20329 { 20330 list_T *l; 20331 int len; 20332 int error = FALSE; 20333 listitem_T *li; 20334 20335 l = varp->vval.v_list; 20336 if (l == NULL) 20337 return NULL; 20338 20339 /* Get the line number */ 20340 pos.lnum = list_find_nr(l, 0L, &error); 20341 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 20342 return NULL; /* invalid line number */ 20343 20344 /* Get the column number */ 20345 pos.col = list_find_nr(l, 1L, &error); 20346 if (error) 20347 return NULL; 20348 len = (long)STRLEN(ml_get(pos.lnum)); 20349 20350 /* We accept "$" for the column number: last column. */ 20351 li = list_find(l, 1L); 20352 if (li != NULL && li->li_tv.v_type == VAR_STRING 20353 && li->li_tv.vval.v_string != NULL 20354 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 20355 pos.col = len + 1; 20356 20357 /* Accept a position up to the NUL after the line. */ 20358 if (pos.col == 0 || (int)pos.col > len + 1) 20359 return NULL; /* invalid column number */ 20360 --pos.col; 20361 20362 #ifdef FEAT_VIRTUALEDIT 20363 /* Get the virtual offset. Defaults to zero. */ 20364 pos.coladd = list_find_nr(l, 2L, &error); 20365 if (error) 20366 pos.coladd = 0; 20367 #endif 20368 20369 return &pos; 20370 } 20371 20372 name = get_tv_string_chk(varp); 20373 if (name == NULL) 20374 return NULL; 20375 if (name[0] == '.') /* cursor */ 20376 return &curwin->w_cursor; 20377 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 20378 { 20379 if (VIsual_active) 20380 return &VIsual; 20381 return &curwin->w_cursor; 20382 } 20383 if (name[0] == '\'') /* mark */ 20384 { 20385 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); 20386 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 20387 return NULL; 20388 return pp; 20389 } 20390 20391 #ifdef FEAT_VIRTUALEDIT 20392 pos.coladd = 0; 20393 #endif 20394 20395 if (name[0] == 'w' && dollar_lnum) 20396 { 20397 pos.col = 0; 20398 if (name[1] == '0') /* "w0": first visible line */ 20399 { 20400 update_topline(); 20401 pos.lnum = curwin->w_topline; 20402 return &pos; 20403 } 20404 else if (name[1] == '$') /* "w$": last visible line */ 20405 { 20406 validate_botline(); 20407 pos.lnum = curwin->w_botline - 1; 20408 return &pos; 20409 } 20410 } 20411 else if (name[0] == '$') /* last column or line */ 20412 { 20413 if (dollar_lnum) 20414 { 20415 pos.lnum = curbuf->b_ml.ml_line_count; 20416 pos.col = 0; 20417 } 20418 else 20419 { 20420 pos.lnum = curwin->w_cursor.lnum; 20421 pos.col = (colnr_T)STRLEN(ml_get_curline()); 20422 } 20423 return &pos; 20424 } 20425 return NULL; 20426 } 20427 20428 /* 20429 * Convert list in "arg" into a position and optional file number. 20430 * When "fnump" is NULL there is no file number, only 3 items. 20431 * Note that the column is passed on as-is, the caller may want to decrement 20432 * it to use 1 for the first column. 20433 * Return FAIL when conversion is not possible, doesn't check the position for 20434 * validity. 20435 */ 20436 static int 20437 list2fpos(arg, posp, fnump, curswantp) 20438 typval_T *arg; 20439 pos_T *posp; 20440 int *fnump; 20441 colnr_T *curswantp; 20442 { 20443 list_T *l = arg->vval.v_list; 20444 long i = 0; 20445 long n; 20446 20447 /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only 20448 * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */ 20449 if (arg->v_type != VAR_LIST 20450 || l == NULL 20451 || l->lv_len < (fnump == NULL ? 2 : 3) 20452 || l->lv_len > (fnump == NULL ? 4 : 5)) 20453 return FAIL; 20454 20455 if (fnump != NULL) 20456 { 20457 n = list_find_nr(l, i++, NULL); /* fnum */ 20458 if (n < 0) 20459 return FAIL; 20460 if (n == 0) 20461 n = curbuf->b_fnum; /* current buffer */ 20462 *fnump = n; 20463 } 20464 20465 n = list_find_nr(l, i++, NULL); /* lnum */ 20466 if (n < 0) 20467 return FAIL; 20468 posp->lnum = n; 20469 20470 n = list_find_nr(l, i++, NULL); /* col */ 20471 if (n < 0) 20472 return FAIL; 20473 posp->col = n; 20474 20475 #ifdef FEAT_VIRTUALEDIT 20476 n = list_find_nr(l, i, NULL); /* off */ 20477 if (n < 0) 20478 posp->coladd = 0; 20479 else 20480 posp->coladd = n; 20481 #endif 20482 20483 if (curswantp != NULL) 20484 *curswantp = list_find_nr(l, i + 1, NULL); /* curswant */ 20485 20486 return OK; 20487 } 20488 20489 /* 20490 * Get the length of an environment variable name. 20491 * Advance "arg" to the first character after the name. 20492 * Return 0 for error. 20493 */ 20494 static int 20495 get_env_len(arg) 20496 char_u **arg; 20497 { 20498 char_u *p; 20499 int len; 20500 20501 for (p = *arg; vim_isIDc(*p); ++p) 20502 ; 20503 if (p == *arg) /* no name found */ 20504 return 0; 20505 20506 len = (int)(p - *arg); 20507 *arg = p; 20508 return len; 20509 } 20510 20511 /* 20512 * Get the length of the name of a function or internal variable. 20513 * "arg" is advanced to the first non-white character after the name. 20514 * Return 0 if something is wrong. 20515 */ 20516 static int 20517 get_id_len(arg) 20518 char_u **arg; 20519 { 20520 char_u *p; 20521 int len; 20522 20523 /* Find the end of the name. */ 20524 for (p = *arg; eval_isnamec(*p); ++p) 20525 ; 20526 if (p == *arg) /* no name found */ 20527 return 0; 20528 20529 len = (int)(p - *arg); 20530 *arg = skipwhite(p); 20531 20532 return len; 20533 } 20534 20535 /* 20536 * Get the length of the name of a variable or function. 20537 * Only the name is recognized, does not handle ".key" or "[idx]". 20538 * "arg" is advanced to the first non-white character after the name. 20539 * Return -1 if curly braces expansion failed. 20540 * Return 0 if something else is wrong. 20541 * If the name contains 'magic' {}'s, expand them and return the 20542 * expanded name in an allocated string via 'alias' - caller must free. 20543 */ 20544 static int 20545 get_name_len(arg, alias, evaluate, verbose) 20546 char_u **arg; 20547 char_u **alias; 20548 int evaluate; 20549 int verbose; 20550 { 20551 int len; 20552 char_u *p; 20553 char_u *expr_start; 20554 char_u *expr_end; 20555 20556 *alias = NULL; /* default to no alias */ 20557 20558 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 20559 && (*arg)[2] == (int)KE_SNR) 20560 { 20561 /* hard coded <SNR>, already translated */ 20562 *arg += 3; 20563 return get_id_len(arg) + 3; 20564 } 20565 len = eval_fname_script(*arg); 20566 if (len > 0) 20567 { 20568 /* literal "<SID>", "s:" or "<SNR>" */ 20569 *arg += len; 20570 } 20571 20572 /* 20573 * Find the end of the name; check for {} construction. 20574 */ 20575 p = find_name_end(*arg, &expr_start, &expr_end, 20576 len > 0 ? 0 : FNE_CHECK_START); 20577 if (expr_start != NULL) 20578 { 20579 char_u *temp_string; 20580 20581 if (!evaluate) 20582 { 20583 len += (int)(p - *arg); 20584 *arg = skipwhite(p); 20585 return len; 20586 } 20587 20588 /* 20589 * Include any <SID> etc in the expanded string: 20590 * Thus the -len here. 20591 */ 20592 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 20593 if (temp_string == NULL) 20594 return -1; 20595 *alias = temp_string; 20596 *arg = skipwhite(p); 20597 return (int)STRLEN(temp_string); 20598 } 20599 20600 len += get_id_len(arg); 20601 if (len == 0 && verbose) 20602 EMSG2(_(e_invexpr2), *arg); 20603 20604 return len; 20605 } 20606 20607 /* 20608 * Find the end of a variable or function name, taking care of magic braces. 20609 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 20610 * start and end of the first magic braces item. 20611 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 20612 * Return a pointer to just after the name. Equal to "arg" if there is no 20613 * valid name. 20614 */ 20615 static char_u * 20616 find_name_end(arg, expr_start, expr_end, flags) 20617 char_u *arg; 20618 char_u **expr_start; 20619 char_u **expr_end; 20620 int flags; 20621 { 20622 int mb_nest = 0; 20623 int br_nest = 0; 20624 char_u *p; 20625 20626 if (expr_start != NULL) 20627 { 20628 *expr_start = NULL; 20629 *expr_end = NULL; 20630 } 20631 20632 /* Quick check for valid starting character. */ 20633 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 20634 return arg; 20635 20636 for (p = arg; *p != NUL 20637 && (eval_isnamec(*p) 20638 || *p == '{' 20639 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 20640 || mb_nest != 0 20641 || br_nest != 0); mb_ptr_adv(p)) 20642 { 20643 if (*p == '\'') 20644 { 20645 /* skip over 'string' to avoid counting [ and ] inside it. */ 20646 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 20647 ; 20648 if (*p == NUL) 20649 break; 20650 } 20651 else if (*p == '"') 20652 { 20653 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 20654 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 20655 if (*p == '\\' && p[1] != NUL) 20656 ++p; 20657 if (*p == NUL) 20658 break; 20659 } 20660 20661 if (mb_nest == 0) 20662 { 20663 if (*p == '[') 20664 ++br_nest; 20665 else if (*p == ']') 20666 --br_nest; 20667 } 20668 20669 if (br_nest == 0) 20670 { 20671 if (*p == '{') 20672 { 20673 mb_nest++; 20674 if (expr_start != NULL && *expr_start == NULL) 20675 *expr_start = p; 20676 } 20677 else if (*p == '}') 20678 { 20679 mb_nest--; 20680 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 20681 *expr_end = p; 20682 } 20683 } 20684 } 20685 20686 return p; 20687 } 20688 20689 /* 20690 * Expands out the 'magic' {}'s in a variable/function name. 20691 * Note that this can call itself recursively, to deal with 20692 * constructs like foo{bar}{baz}{bam} 20693 * The four pointer arguments point to "foo{expre}ss{ion}bar" 20694 * "in_start" ^ 20695 * "expr_start" ^ 20696 * "expr_end" ^ 20697 * "in_end" ^ 20698 * 20699 * Returns a new allocated string, which the caller must free. 20700 * Returns NULL for failure. 20701 */ 20702 static char_u * 20703 make_expanded_name(in_start, expr_start, expr_end, in_end) 20704 char_u *in_start; 20705 char_u *expr_start; 20706 char_u *expr_end; 20707 char_u *in_end; 20708 { 20709 char_u c1; 20710 char_u *retval = NULL; 20711 char_u *temp_result; 20712 char_u *nextcmd = NULL; 20713 20714 if (expr_end == NULL || in_end == NULL) 20715 return NULL; 20716 *expr_start = NUL; 20717 *expr_end = NUL; 20718 c1 = *in_end; 20719 *in_end = NUL; 20720 20721 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 20722 if (temp_result != NULL && nextcmd == NULL) 20723 { 20724 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 20725 + (in_end - expr_end) + 1)); 20726 if (retval != NULL) 20727 { 20728 STRCPY(retval, in_start); 20729 STRCAT(retval, temp_result); 20730 STRCAT(retval, expr_end + 1); 20731 } 20732 } 20733 vim_free(temp_result); 20734 20735 *in_end = c1; /* put char back for error messages */ 20736 *expr_start = '{'; 20737 *expr_end = '}'; 20738 20739 if (retval != NULL) 20740 { 20741 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 20742 if (expr_start != NULL) 20743 { 20744 /* Further expansion! */ 20745 temp_result = make_expanded_name(retval, expr_start, 20746 expr_end, temp_result); 20747 vim_free(retval); 20748 retval = temp_result; 20749 } 20750 } 20751 20752 return retval; 20753 } 20754 20755 /* 20756 * Return TRUE if character "c" can be used in a variable or function name. 20757 * Does not include '{' or '}' for magic braces. 20758 */ 20759 static int 20760 eval_isnamec(c) 20761 int c; 20762 { 20763 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 20764 } 20765 20766 /* 20767 * Return TRUE if character "c" can be used as the first character in a 20768 * variable or function name (excluding '{' and '}'). 20769 */ 20770 static int 20771 eval_isnamec1(c) 20772 int c; 20773 { 20774 return (ASCII_ISALPHA(c) || c == '_'); 20775 } 20776 20777 /* 20778 * Set number v: variable to "val". 20779 */ 20780 void 20781 set_vim_var_nr(idx, val) 20782 int idx; 20783 long val; 20784 { 20785 vimvars[idx].vv_nr = val; 20786 } 20787 20788 /* 20789 * Get number v: variable value. 20790 */ 20791 long 20792 get_vim_var_nr(idx) 20793 int idx; 20794 { 20795 return vimvars[idx].vv_nr; 20796 } 20797 20798 /* 20799 * Get string v: variable value. Uses a static buffer, can only be used once. 20800 */ 20801 char_u * 20802 get_vim_var_str(idx) 20803 int idx; 20804 { 20805 return get_tv_string(&vimvars[idx].vv_tv); 20806 } 20807 20808 /* 20809 * Get List v: variable value. Caller must take care of reference count when 20810 * needed. 20811 */ 20812 list_T * 20813 get_vim_var_list(idx) 20814 int idx; 20815 { 20816 return vimvars[idx].vv_list; 20817 } 20818 20819 /* 20820 * Set v:char to character "c". 20821 */ 20822 void 20823 set_vim_var_char(c) 20824 int c; 20825 { 20826 char_u buf[MB_MAXBYTES + 1]; 20827 20828 #ifdef FEAT_MBYTE 20829 if (has_mbyte) 20830 buf[(*mb_char2bytes)(c, buf)] = NUL; 20831 else 20832 #endif 20833 { 20834 buf[0] = c; 20835 buf[1] = NUL; 20836 } 20837 set_vim_var_string(VV_CHAR, buf, -1); 20838 } 20839 20840 /* 20841 * Set v:count to "count" and v:count1 to "count1". 20842 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 20843 */ 20844 void 20845 set_vcount(count, count1, set_prevcount) 20846 long count; 20847 long count1; 20848 int set_prevcount; 20849 { 20850 if (set_prevcount) 20851 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 20852 vimvars[VV_COUNT].vv_nr = count; 20853 vimvars[VV_COUNT1].vv_nr = count1; 20854 } 20855 20856 /* 20857 * Set string v: variable to a copy of "val". 20858 */ 20859 void 20860 set_vim_var_string(idx, val, len) 20861 int idx; 20862 char_u *val; 20863 int len; /* length of "val" to use or -1 (whole string) */ 20864 { 20865 /* Need to do this (at least) once, since we can't initialize a union. 20866 * Will always be invoked when "v:progname" is set. */ 20867 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 20868 20869 vim_free(vimvars[idx].vv_str); 20870 if (val == NULL) 20871 vimvars[idx].vv_str = NULL; 20872 else if (len == -1) 20873 vimvars[idx].vv_str = vim_strsave(val); 20874 else 20875 vimvars[idx].vv_str = vim_strnsave(val, len); 20876 } 20877 20878 /* 20879 * Set List v: variable to "val". 20880 */ 20881 void 20882 set_vim_var_list(idx, val) 20883 int idx; 20884 list_T *val; 20885 { 20886 list_unref(vimvars[idx].vv_list); 20887 vimvars[idx].vv_list = val; 20888 if (val != NULL) 20889 ++val->lv_refcount; 20890 } 20891 20892 /* 20893 * Set Dictionary v: variable to "val". 20894 */ 20895 void 20896 set_vim_var_dict(idx, val) 20897 int idx; 20898 dict_T *val; 20899 { 20900 int todo; 20901 hashitem_T *hi; 20902 20903 dict_unref(vimvars[idx].vv_dict); 20904 vimvars[idx].vv_dict = val; 20905 if (val != NULL) 20906 { 20907 ++val->dv_refcount; 20908 20909 /* Set readonly */ 20910 todo = (int)val->dv_hashtab.ht_used; 20911 for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) 20912 { 20913 if (HASHITEM_EMPTY(hi)) 20914 continue; 20915 --todo; 20916 HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 20917 } 20918 } 20919 } 20920 20921 /* 20922 * Set v:register if needed. 20923 */ 20924 void 20925 set_reg_var(c) 20926 int c; 20927 { 20928 char_u regname; 20929 20930 if (c == 0 || c == ' ') 20931 regname = '"'; 20932 else 20933 regname = c; 20934 /* Avoid free/alloc when the value is already right. */ 20935 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 20936 set_vim_var_string(VV_REG, ®name, 1); 20937 } 20938 20939 /* 20940 * Get or set v:exception. If "oldval" == NULL, return the current value. 20941 * Otherwise, restore the value to "oldval" and return NULL. 20942 * Must always be called in pairs to save and restore v:exception! Does not 20943 * take care of memory allocations. 20944 */ 20945 char_u * 20946 v_exception(oldval) 20947 char_u *oldval; 20948 { 20949 if (oldval == NULL) 20950 return vimvars[VV_EXCEPTION].vv_str; 20951 20952 vimvars[VV_EXCEPTION].vv_str = oldval; 20953 return NULL; 20954 } 20955 20956 /* 20957 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 20958 * Otherwise, restore the value to "oldval" and return NULL. 20959 * Must always be called in pairs to save and restore v:throwpoint! Does not 20960 * take care of memory allocations. 20961 */ 20962 char_u * 20963 v_throwpoint(oldval) 20964 char_u *oldval; 20965 { 20966 if (oldval == NULL) 20967 return vimvars[VV_THROWPOINT].vv_str; 20968 20969 vimvars[VV_THROWPOINT].vv_str = oldval; 20970 return NULL; 20971 } 20972 20973 #if defined(FEAT_AUTOCMD) || defined(PROTO) 20974 /* 20975 * Set v:cmdarg. 20976 * If "eap" != NULL, use "eap" to generate the value and return the old value. 20977 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 20978 * Must always be called in pairs! 20979 */ 20980 char_u * 20981 set_cmdarg(eap, oldarg) 20982 exarg_T *eap; 20983 char_u *oldarg; 20984 { 20985 char_u *oldval; 20986 char_u *newval; 20987 unsigned len; 20988 20989 oldval = vimvars[VV_CMDARG].vv_str; 20990 if (eap == NULL) 20991 { 20992 vim_free(oldval); 20993 vimvars[VV_CMDARG].vv_str = oldarg; 20994 return NULL; 20995 } 20996 20997 if (eap->force_bin == FORCE_BIN) 20998 len = 6; 20999 else if (eap->force_bin == FORCE_NOBIN) 21000 len = 8; 21001 else 21002 len = 0; 21003 21004 if (eap->read_edit) 21005 len += 7; 21006 21007 if (eap->force_ff != 0) 21008 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 21009 # ifdef FEAT_MBYTE 21010 if (eap->force_enc != 0) 21011 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 21012 if (eap->bad_char != 0) 21013 len += 7 + 4; /* " ++bad=" + "keep" or "drop" */ 21014 # endif 21015 21016 newval = alloc(len + 1); 21017 if (newval == NULL) 21018 return NULL; 21019 21020 if (eap->force_bin == FORCE_BIN) 21021 sprintf((char *)newval, " ++bin"); 21022 else if (eap->force_bin == FORCE_NOBIN) 21023 sprintf((char *)newval, " ++nobin"); 21024 else 21025 *newval = NUL; 21026 21027 if (eap->read_edit) 21028 STRCAT(newval, " ++edit"); 21029 21030 if (eap->force_ff != 0) 21031 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 21032 eap->cmd + eap->force_ff); 21033 # ifdef FEAT_MBYTE 21034 if (eap->force_enc != 0) 21035 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 21036 eap->cmd + eap->force_enc); 21037 if (eap->bad_char == BAD_KEEP) 21038 STRCPY(newval + STRLEN(newval), " ++bad=keep"); 21039 else if (eap->bad_char == BAD_DROP) 21040 STRCPY(newval + STRLEN(newval), " ++bad=drop"); 21041 else if (eap->bad_char != 0) 21042 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); 21043 # endif 21044 vimvars[VV_CMDARG].vv_str = newval; 21045 return oldval; 21046 } 21047 #endif 21048 21049 /* 21050 * Get the value of internal variable "name". 21051 * Return OK or FAIL. 21052 */ 21053 static int 21054 get_var_tv(name, len, rettv, dip, verbose, no_autoload) 21055 char_u *name; 21056 int len; /* length of "name" */ 21057 typval_T *rettv; /* NULL when only checking existence */ 21058 dictitem_T **dip; /* non-NULL when typval's dict item is needed */ 21059 int verbose; /* may give error message */ 21060 int no_autoload; /* do not use script autoloading */ 21061 { 21062 int ret = OK; 21063 typval_T *tv = NULL; 21064 typval_T atv; 21065 dictitem_T *v; 21066 int cc; 21067 21068 /* truncate the name, so that we can use strcmp() */ 21069 cc = name[len]; 21070 name[len] = NUL; 21071 21072 /* 21073 * Check for "b:changedtick". 21074 */ 21075 if (STRCMP(name, "b:changedtick") == 0) 21076 { 21077 atv.v_type = VAR_NUMBER; 21078 atv.vval.v_number = curbuf->b_changedtick; 21079 tv = &atv; 21080 } 21081 21082 /* 21083 * Check for user-defined variables. 21084 */ 21085 else 21086 { 21087 v = find_var(name, NULL, no_autoload); 21088 if (v != NULL) 21089 { 21090 tv = &v->di_tv; 21091 if (dip != NULL) 21092 *dip = v; 21093 } 21094 } 21095 21096 if (tv == NULL) 21097 { 21098 if (rettv != NULL && verbose) 21099 EMSG2(_(e_undefvar), name); 21100 ret = FAIL; 21101 } 21102 else if (rettv != NULL) 21103 copy_tv(tv, rettv); 21104 21105 name[len] = cc; 21106 21107 return ret; 21108 } 21109 21110 /* 21111 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 21112 * Also handle function call with Funcref variable: func(expr) 21113 * Can all be combined: dict.func(expr)[idx]['func'](expr) 21114 */ 21115 static int 21116 handle_subscript(arg, rettv, evaluate, verbose) 21117 char_u **arg; 21118 typval_T *rettv; 21119 int evaluate; /* do more than finding the end */ 21120 int verbose; /* give error messages */ 21121 { 21122 int ret = OK; 21123 dict_T *selfdict = NULL; 21124 char_u *s; 21125 int len; 21126 typval_T functv; 21127 21128 while (ret == OK 21129 && (**arg == '[' 21130 || (**arg == '.' && rettv->v_type == VAR_DICT) 21131 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC))) 21132 && !vim_iswhite(*(*arg - 1))) 21133 { 21134 if (**arg == '(') 21135 { 21136 /* need to copy the funcref so that we can clear rettv */ 21137 if (evaluate) 21138 { 21139 functv = *rettv; 21140 rettv->v_type = VAR_UNKNOWN; 21141 21142 /* Invoke the function. Recursive! */ 21143 s = functv.vval.v_string; 21144 } 21145 else 21146 s = (char_u *)""; 21147 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 21148 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 21149 &len, evaluate, selfdict); 21150 21151 /* Clear the funcref afterwards, so that deleting it while 21152 * evaluating the arguments is possible (see test55). */ 21153 if (evaluate) 21154 clear_tv(&functv); 21155 21156 /* Stop the expression evaluation when immediately aborting on 21157 * error, or when an interrupt occurred or an exception was thrown 21158 * but not caught. */ 21159 if (aborting()) 21160 { 21161 if (ret == OK) 21162 clear_tv(rettv); 21163 ret = FAIL; 21164 } 21165 dict_unref(selfdict); 21166 selfdict = NULL; 21167 } 21168 else /* **arg == '[' || **arg == '.' */ 21169 { 21170 dict_unref(selfdict); 21171 if (rettv->v_type == VAR_DICT) 21172 { 21173 selfdict = rettv->vval.v_dict; 21174 if (selfdict != NULL) 21175 ++selfdict->dv_refcount; 21176 } 21177 else 21178 selfdict = NULL; 21179 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 21180 { 21181 clear_tv(rettv); 21182 ret = FAIL; 21183 } 21184 } 21185 } 21186 dict_unref(selfdict); 21187 return ret; 21188 } 21189 21190 /* 21191 * Allocate memory for a variable type-value, and make it empty (0 or NULL 21192 * value). 21193 */ 21194 static typval_T * 21195 alloc_tv() 21196 { 21197 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 21198 } 21199 21200 /* 21201 * Allocate memory for a variable type-value, and assign a string to it. 21202 * The string "s" must have been allocated, it is consumed. 21203 * Return NULL for out of memory, the variable otherwise. 21204 */ 21205 static typval_T * 21206 alloc_string_tv(s) 21207 char_u *s; 21208 { 21209 typval_T *rettv; 21210 21211 rettv = alloc_tv(); 21212 if (rettv != NULL) 21213 { 21214 rettv->v_type = VAR_STRING; 21215 rettv->vval.v_string = s; 21216 } 21217 else 21218 vim_free(s); 21219 return rettv; 21220 } 21221 21222 /* 21223 * Free the memory for a variable type-value. 21224 */ 21225 void 21226 free_tv(varp) 21227 typval_T *varp; 21228 { 21229 if (varp != NULL) 21230 { 21231 switch (varp->v_type) 21232 { 21233 case VAR_FUNC: 21234 func_unref(varp->vval.v_string); 21235 /*FALLTHROUGH*/ 21236 case VAR_STRING: 21237 vim_free(varp->vval.v_string); 21238 break; 21239 case VAR_LIST: 21240 list_unref(varp->vval.v_list); 21241 break; 21242 case VAR_DICT: 21243 dict_unref(varp->vval.v_dict); 21244 break; 21245 case VAR_NUMBER: 21246 #ifdef FEAT_FLOAT 21247 case VAR_FLOAT: 21248 #endif 21249 case VAR_UNKNOWN: 21250 break; 21251 default: 21252 EMSG2(_(e_intern2), "free_tv()"); 21253 break; 21254 } 21255 vim_free(varp); 21256 } 21257 } 21258 21259 /* 21260 * Free the memory for a variable value and set the value to NULL or 0. 21261 */ 21262 void 21263 clear_tv(varp) 21264 typval_T *varp; 21265 { 21266 if (varp != NULL) 21267 { 21268 switch (varp->v_type) 21269 { 21270 case VAR_FUNC: 21271 func_unref(varp->vval.v_string); 21272 /*FALLTHROUGH*/ 21273 case VAR_STRING: 21274 vim_free(varp->vval.v_string); 21275 varp->vval.v_string = NULL; 21276 break; 21277 case VAR_LIST: 21278 list_unref(varp->vval.v_list); 21279 varp->vval.v_list = NULL; 21280 break; 21281 case VAR_DICT: 21282 dict_unref(varp->vval.v_dict); 21283 varp->vval.v_dict = NULL; 21284 break; 21285 case VAR_NUMBER: 21286 varp->vval.v_number = 0; 21287 break; 21288 #ifdef FEAT_FLOAT 21289 case VAR_FLOAT: 21290 varp->vval.v_float = 0.0; 21291 break; 21292 #endif 21293 case VAR_UNKNOWN: 21294 break; 21295 default: 21296 EMSG2(_(e_intern2), "clear_tv()"); 21297 } 21298 varp->v_lock = 0; 21299 } 21300 } 21301 21302 /* 21303 * Set the value of a variable to NULL without freeing items. 21304 */ 21305 static void 21306 init_tv(varp) 21307 typval_T *varp; 21308 { 21309 if (varp != NULL) 21310 vim_memset(varp, 0, sizeof(typval_T)); 21311 } 21312 21313 /* 21314 * Get the number value of a variable. 21315 * If it is a String variable, uses vim_str2nr(). 21316 * For incompatible types, return 0. 21317 * get_tv_number_chk() is similar to get_tv_number(), but informs the 21318 * caller of incompatible types: it sets *denote to TRUE if "denote" 21319 * is not NULL or returns -1 otherwise. 21320 */ 21321 static long 21322 get_tv_number(varp) 21323 typval_T *varp; 21324 { 21325 int error = FALSE; 21326 21327 return get_tv_number_chk(varp, &error); /* return 0L on error */ 21328 } 21329 21330 long 21331 get_tv_number_chk(varp, denote) 21332 typval_T *varp; 21333 int *denote; 21334 { 21335 long n = 0L; 21336 21337 switch (varp->v_type) 21338 { 21339 case VAR_NUMBER: 21340 return (long)(varp->vval.v_number); 21341 #ifdef FEAT_FLOAT 21342 case VAR_FLOAT: 21343 EMSG(_("E805: Using a Float as a Number")); 21344 break; 21345 #endif 21346 case VAR_FUNC: 21347 EMSG(_("E703: Using a Funcref as a Number")); 21348 break; 21349 case VAR_STRING: 21350 if (varp->vval.v_string != NULL) 21351 vim_str2nr(varp->vval.v_string, NULL, NULL, 21352 TRUE, TRUE, &n, NULL, 0); 21353 return n; 21354 case VAR_LIST: 21355 EMSG(_("E745: Using a List as a Number")); 21356 break; 21357 case VAR_DICT: 21358 EMSG(_("E728: Using a Dictionary as a Number")); 21359 break; 21360 default: 21361 EMSG2(_(e_intern2), "get_tv_number()"); 21362 break; 21363 } 21364 if (denote == NULL) /* useful for values that must be unsigned */ 21365 n = -1; 21366 else 21367 *denote = TRUE; 21368 return n; 21369 } 21370 21371 /* 21372 * Get the lnum from the first argument. 21373 * Also accepts ".", "$", etc., but that only works for the current buffer. 21374 * Returns -1 on error. 21375 */ 21376 static linenr_T 21377 get_tv_lnum(argvars) 21378 typval_T *argvars; 21379 { 21380 typval_T rettv; 21381 linenr_T lnum; 21382 21383 lnum = get_tv_number_chk(&argvars[0], NULL); 21384 if (lnum == 0) /* no valid number, try using line() */ 21385 { 21386 rettv.v_type = VAR_NUMBER; 21387 f_line(argvars, &rettv); 21388 lnum = rettv.vval.v_number; 21389 clear_tv(&rettv); 21390 } 21391 return lnum; 21392 } 21393 21394 /* 21395 * Get the lnum from the first argument. 21396 * Also accepts "$", then "buf" is used. 21397 * Returns 0 on error. 21398 */ 21399 static linenr_T 21400 get_tv_lnum_buf(argvars, buf) 21401 typval_T *argvars; 21402 buf_T *buf; 21403 { 21404 if (argvars[0].v_type == VAR_STRING 21405 && argvars[0].vval.v_string != NULL 21406 && argvars[0].vval.v_string[0] == '$' 21407 && buf != NULL) 21408 return buf->b_ml.ml_line_count; 21409 return get_tv_number_chk(&argvars[0], NULL); 21410 } 21411 21412 /* 21413 * Get the string value of a variable. 21414 * If it is a Number variable, the number is converted into a string. 21415 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 21416 * get_tv_string_buf() uses a given buffer. 21417 * If the String variable has never been set, return an empty string. 21418 * Never returns NULL; 21419 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 21420 * NULL on error. 21421 */ 21422 static char_u * 21423 get_tv_string(varp) 21424 typval_T *varp; 21425 { 21426 static char_u mybuf[NUMBUFLEN]; 21427 21428 return get_tv_string_buf(varp, mybuf); 21429 } 21430 21431 static char_u * 21432 get_tv_string_buf(varp, buf) 21433 typval_T *varp; 21434 char_u *buf; 21435 { 21436 char_u *res = get_tv_string_buf_chk(varp, buf); 21437 21438 return res != NULL ? res : (char_u *)""; 21439 } 21440 21441 /* 21442 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 21443 */ 21444 char_u * 21445 get_tv_string_chk(varp) 21446 typval_T *varp; 21447 { 21448 static char_u mybuf[NUMBUFLEN]; 21449 21450 return get_tv_string_buf_chk(varp, mybuf); 21451 } 21452 21453 static char_u * 21454 get_tv_string_buf_chk(varp, buf) 21455 typval_T *varp; 21456 char_u *buf; 21457 { 21458 switch (varp->v_type) 21459 { 21460 case VAR_NUMBER: 21461 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 21462 return buf; 21463 case VAR_FUNC: 21464 EMSG(_("E729: using Funcref as a String")); 21465 break; 21466 case VAR_LIST: 21467 EMSG(_("E730: using List as a String")); 21468 break; 21469 case VAR_DICT: 21470 EMSG(_("E731: using Dictionary as a String")); 21471 break; 21472 #ifdef FEAT_FLOAT 21473 case VAR_FLOAT: 21474 EMSG(_(e_float_as_string)); 21475 break; 21476 #endif 21477 case VAR_STRING: 21478 if (varp->vval.v_string != NULL) 21479 return varp->vval.v_string; 21480 return (char_u *)""; 21481 default: 21482 EMSG2(_(e_intern2), "get_tv_string_buf()"); 21483 break; 21484 } 21485 return NULL; 21486 } 21487 21488 /* 21489 * Find variable "name" in the list of variables. 21490 * Return a pointer to it if found, NULL if not found. 21491 * Careful: "a:0" variables don't have a name. 21492 * When "htp" is not NULL we are writing to the variable, set "htp" to the 21493 * hashtab_T used. 21494 */ 21495 static dictitem_T * 21496 find_var(name, htp, no_autoload) 21497 char_u *name; 21498 hashtab_T **htp; 21499 int no_autoload; 21500 { 21501 char_u *varname; 21502 hashtab_T *ht; 21503 21504 ht = find_var_ht(name, &varname); 21505 if (htp != NULL) 21506 *htp = ht; 21507 if (ht == NULL) 21508 return NULL; 21509 return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); 21510 } 21511 21512 /* 21513 * Find variable "varname" in hashtab "ht" with name "htname". 21514 * Returns NULL if not found. 21515 */ 21516 static dictitem_T * 21517 find_var_in_ht(ht, htname, varname, no_autoload) 21518 hashtab_T *ht; 21519 int htname; 21520 char_u *varname; 21521 int no_autoload; 21522 { 21523 hashitem_T *hi; 21524 21525 if (*varname == NUL) 21526 { 21527 /* Must be something like "s:", otherwise "ht" would be NULL. */ 21528 switch (htname) 21529 { 21530 case 's': return &SCRIPT_SV(current_SID)->sv_var; 21531 case 'g': return &globvars_var; 21532 case 'v': return &vimvars_var; 21533 case 'b': return &curbuf->b_bufvar; 21534 case 'w': return &curwin->w_winvar; 21535 #ifdef FEAT_WINDOWS 21536 case 't': return &curtab->tp_winvar; 21537 #endif 21538 case 'l': return current_funccal == NULL 21539 ? NULL : ¤t_funccal->l_vars_var; 21540 case 'a': return current_funccal == NULL 21541 ? NULL : ¤t_funccal->l_avars_var; 21542 } 21543 return NULL; 21544 } 21545 21546 hi = hash_find(ht, varname); 21547 if (HASHITEM_EMPTY(hi)) 21548 { 21549 /* For global variables we may try auto-loading the script. If it 21550 * worked find the variable again. Don't auto-load a script if it was 21551 * loaded already, otherwise it would be loaded every time when 21552 * checking if a function name is a Funcref variable. */ 21553 if (ht == &globvarht && !no_autoload) 21554 { 21555 /* Note: script_autoload() may make "hi" invalid. It must either 21556 * be obtained again or not used. */ 21557 if (!script_autoload(varname, FALSE) || aborting()) 21558 return NULL; 21559 hi = hash_find(ht, varname); 21560 } 21561 if (HASHITEM_EMPTY(hi)) 21562 return NULL; 21563 } 21564 return HI2DI(hi); 21565 } 21566 21567 /* 21568 * Find the hashtab used for a variable name. 21569 * Return NULL if the name is not valid. 21570 * Set "varname" to the start of name without ':'. 21571 */ 21572 static hashtab_T * 21573 find_var_ht(name, varname) 21574 char_u *name; 21575 char_u **varname; 21576 { 21577 hashitem_T *hi; 21578 21579 if (name[0] == NUL) 21580 return NULL; 21581 if (name[1] != ':') 21582 { 21583 /* The name must not start with a colon or #. */ 21584 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 21585 return NULL; 21586 *varname = name; 21587 21588 /* "version" is "v:version" in all scopes */ 21589 hi = hash_find(&compat_hashtab, name); 21590 if (!HASHITEM_EMPTY(hi)) 21591 return &compat_hashtab; 21592 21593 if (current_funccal == NULL) 21594 return &globvarht; /* global variable */ 21595 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 21596 } 21597 *varname = name + 2; 21598 if (*name == 'g') /* global variable */ 21599 return &globvarht; 21600 /* There must be no ':' or '#' in the rest of the name, unless g: is used 21601 */ 21602 if (vim_strchr(name + 2, ':') != NULL 21603 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 21604 return NULL; 21605 if (*name == 'b') /* buffer variable */ 21606 return &curbuf->b_vars->dv_hashtab; 21607 if (*name == 'w') /* window variable */ 21608 return &curwin->w_vars->dv_hashtab; 21609 #ifdef FEAT_WINDOWS 21610 if (*name == 't') /* tab page variable */ 21611 return &curtab->tp_vars->dv_hashtab; 21612 #endif 21613 if (*name == 'v') /* v: variable */ 21614 return &vimvarht; 21615 if (*name == 'a' && current_funccal != NULL) /* function argument */ 21616 return ¤t_funccal->l_avars.dv_hashtab; 21617 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 21618 return ¤t_funccal->l_vars.dv_hashtab; 21619 if (*name == 's' /* script variable */ 21620 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 21621 return &SCRIPT_VARS(current_SID); 21622 return NULL; 21623 } 21624 21625 /* 21626 * Get the string value of a (global/local) variable. 21627 * Note: see get_tv_string() for how long the pointer remains valid. 21628 * Returns NULL when it doesn't exist. 21629 */ 21630 char_u * 21631 get_var_value(name) 21632 char_u *name; 21633 { 21634 dictitem_T *v; 21635 21636 v = find_var(name, NULL, FALSE); 21637 if (v == NULL) 21638 return NULL; 21639 return get_tv_string(&v->di_tv); 21640 } 21641 21642 /* 21643 * Allocate a new hashtab for a sourced script. It will be used while 21644 * sourcing this script and when executing functions defined in the script. 21645 */ 21646 void 21647 new_script_vars(id) 21648 scid_T id; 21649 { 21650 int i; 21651 hashtab_T *ht; 21652 scriptvar_T *sv; 21653 21654 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 21655 { 21656 /* Re-allocating ga_data means that an ht_array pointing to 21657 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 21658 * at its init value. Also reset "v_dict", it's always the same. */ 21659 for (i = 1; i <= ga_scripts.ga_len; ++i) 21660 { 21661 ht = &SCRIPT_VARS(i); 21662 if (ht->ht_mask == HT_INIT_SIZE - 1) 21663 ht->ht_array = ht->ht_smallarray; 21664 sv = SCRIPT_SV(i); 21665 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 21666 } 21667 21668 while (ga_scripts.ga_len < id) 21669 { 21670 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = 21671 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); 21672 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); 21673 ++ga_scripts.ga_len; 21674 } 21675 } 21676 } 21677 21678 /* 21679 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 21680 * point to it. 21681 */ 21682 void 21683 init_var_dict(dict, dict_var, scope) 21684 dict_T *dict; 21685 dictitem_T *dict_var; 21686 int scope; 21687 { 21688 hash_init(&dict->dv_hashtab); 21689 dict->dv_lock = 0; 21690 dict->dv_scope = scope; 21691 dict->dv_refcount = DO_NOT_FREE_CNT; 21692 dict->dv_copyID = 0; 21693 dict_var->di_tv.vval.v_dict = dict; 21694 dict_var->di_tv.v_type = VAR_DICT; 21695 dict_var->di_tv.v_lock = VAR_FIXED; 21696 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21697 dict_var->di_key[0] = NUL; 21698 } 21699 21700 /* 21701 * Unreference a dictionary initialized by init_var_dict(). 21702 */ 21703 void 21704 unref_var_dict(dict) 21705 dict_T *dict; 21706 { 21707 /* Now the dict needs to be freed if no one else is using it, go back to 21708 * normal reference counting. */ 21709 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; 21710 dict_unref(dict); 21711 } 21712 21713 /* 21714 * Clean up a list of internal variables. 21715 * Frees all allocated variables and the value they contain. 21716 * Clears hashtab "ht", does not free it. 21717 */ 21718 void 21719 vars_clear(ht) 21720 hashtab_T *ht; 21721 { 21722 vars_clear_ext(ht, TRUE); 21723 } 21724 21725 /* 21726 * Like vars_clear(), but only free the value if "free_val" is TRUE. 21727 */ 21728 static void 21729 vars_clear_ext(ht, free_val) 21730 hashtab_T *ht; 21731 int free_val; 21732 { 21733 int todo; 21734 hashitem_T *hi; 21735 dictitem_T *v; 21736 21737 hash_lock(ht); 21738 todo = (int)ht->ht_used; 21739 for (hi = ht->ht_array; todo > 0; ++hi) 21740 { 21741 if (!HASHITEM_EMPTY(hi)) 21742 { 21743 --todo; 21744 21745 /* Free the variable. Don't remove it from the hashtab, 21746 * ht_array might change then. hash_clear() takes care of it 21747 * later. */ 21748 v = HI2DI(hi); 21749 if (free_val) 21750 clear_tv(&v->di_tv); 21751 if (v->di_flags & DI_FLAGS_ALLOC) 21752 vim_free(v); 21753 } 21754 } 21755 hash_clear(ht); 21756 ht->ht_used = 0; 21757 } 21758 21759 /* 21760 * Delete a variable from hashtab "ht" at item "hi". 21761 * Clear the variable value and free the dictitem. 21762 */ 21763 static void 21764 delete_var(ht, hi) 21765 hashtab_T *ht; 21766 hashitem_T *hi; 21767 { 21768 dictitem_T *di = HI2DI(hi); 21769 21770 hash_remove(ht, hi); 21771 clear_tv(&di->di_tv); 21772 vim_free(di); 21773 } 21774 21775 /* 21776 * List the value of one internal variable. 21777 */ 21778 static void 21779 list_one_var(v, prefix, first) 21780 dictitem_T *v; 21781 char_u *prefix; 21782 int *first; 21783 { 21784 char_u *tofree; 21785 char_u *s; 21786 char_u numbuf[NUMBUFLEN]; 21787 21788 current_copyID += COPYID_INC; 21789 s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID); 21790 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 21791 s == NULL ? (char_u *)"" : s, first); 21792 vim_free(tofree); 21793 } 21794 21795 static void 21796 list_one_var_a(prefix, name, type, string, first) 21797 char_u *prefix; 21798 char_u *name; 21799 int type; 21800 char_u *string; 21801 int *first; /* when TRUE clear rest of screen and set to FALSE */ 21802 { 21803 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 21804 msg_start(); 21805 msg_puts(prefix); 21806 if (name != NULL) /* "a:" vars don't have a name stored */ 21807 msg_puts(name); 21808 msg_putchar(' '); 21809 msg_advance(22); 21810 if (type == VAR_NUMBER) 21811 msg_putchar('#'); 21812 else if (type == VAR_FUNC) 21813 msg_putchar('*'); 21814 else if (type == VAR_LIST) 21815 { 21816 msg_putchar('['); 21817 if (*string == '[') 21818 ++string; 21819 } 21820 else if (type == VAR_DICT) 21821 { 21822 msg_putchar('{'); 21823 if (*string == '{') 21824 ++string; 21825 } 21826 else 21827 msg_putchar(' '); 21828 21829 msg_outtrans(string); 21830 21831 if (type == VAR_FUNC) 21832 msg_puts((char_u *)"()"); 21833 if (*first) 21834 { 21835 msg_clr_eos(); 21836 *first = FALSE; 21837 } 21838 } 21839 21840 /* 21841 * Set variable "name" to value in "tv". 21842 * If the variable already exists, the value is updated. 21843 * Otherwise the variable is created. 21844 */ 21845 static void 21846 set_var(name, tv, copy) 21847 char_u *name; 21848 typval_T *tv; 21849 int copy; /* make copy of value in "tv" */ 21850 { 21851 dictitem_T *v; 21852 char_u *varname; 21853 hashtab_T *ht; 21854 21855 ht = find_var_ht(name, &varname); 21856 if (ht == NULL || *varname == NUL) 21857 { 21858 EMSG2(_(e_illvar), name); 21859 return; 21860 } 21861 v = find_var_in_ht(ht, 0, varname, TRUE); 21862 21863 if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL)) 21864 return; 21865 21866 if (v != NULL) 21867 { 21868 /* existing variable, need to clear the value */ 21869 if (var_check_ro(v->di_flags, name, FALSE) 21870 || tv_check_lock(v->di_tv.v_lock, name, FALSE)) 21871 return; 21872 if (v->di_tv.v_type != tv->v_type 21873 && !((v->di_tv.v_type == VAR_STRING 21874 || v->di_tv.v_type == VAR_NUMBER) 21875 && (tv->v_type == VAR_STRING 21876 || tv->v_type == VAR_NUMBER)) 21877 #ifdef FEAT_FLOAT 21878 && !((v->di_tv.v_type == VAR_NUMBER 21879 || v->di_tv.v_type == VAR_FLOAT) 21880 && (tv->v_type == VAR_NUMBER 21881 || tv->v_type == VAR_FLOAT)) 21882 #endif 21883 ) 21884 { 21885 EMSG2(_("E706: Variable type mismatch for: %s"), name); 21886 return; 21887 } 21888 21889 /* 21890 * Handle setting internal v: variables separately where needed to 21891 * prevent changing the type. 21892 */ 21893 if (ht == &vimvarht) 21894 { 21895 if (v->di_tv.v_type == VAR_STRING) 21896 { 21897 vim_free(v->di_tv.vval.v_string); 21898 if (copy || tv->v_type != VAR_STRING) 21899 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 21900 else 21901 { 21902 /* Take over the string to avoid an extra alloc/free. */ 21903 v->di_tv.vval.v_string = tv->vval.v_string; 21904 tv->vval.v_string = NULL; 21905 } 21906 return; 21907 } 21908 else if (v->di_tv.v_type == VAR_NUMBER) 21909 { 21910 v->di_tv.vval.v_number = get_tv_number(tv); 21911 if (STRCMP(varname, "searchforward") == 0) 21912 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 21913 #ifdef FEAT_SEARCH_EXTRA 21914 else if (STRCMP(varname, "hlsearch") == 0) 21915 { 21916 no_hlsearch = !v->di_tv.vval.v_number; 21917 redraw_all_later(SOME_VALID); 21918 } 21919 #endif 21920 return; 21921 } 21922 else if (v->di_tv.v_type != tv->v_type) 21923 EMSG2(_(e_intern2), "set_var()"); 21924 } 21925 21926 clear_tv(&v->di_tv); 21927 } 21928 else /* add a new variable */ 21929 { 21930 /* Can't add "v:" variable. */ 21931 if (ht == &vimvarht) 21932 { 21933 EMSG2(_(e_illvar), name); 21934 return; 21935 } 21936 21937 /* Make sure the variable name is valid. */ 21938 if (!valid_varname(varname)) 21939 return; 21940 21941 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 21942 + STRLEN(varname))); 21943 if (v == NULL) 21944 return; 21945 STRCPY(v->di_key, varname); 21946 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 21947 { 21948 vim_free(v); 21949 return; 21950 } 21951 v->di_flags = DI_FLAGS_ALLOC; 21952 } 21953 21954 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 21955 copy_tv(tv, &v->di_tv); 21956 else 21957 { 21958 v->di_tv = *tv; 21959 v->di_tv.v_lock = 0; 21960 init_tv(tv); 21961 } 21962 } 21963 21964 /* 21965 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 21966 * Also give an error message. 21967 */ 21968 static int 21969 var_check_ro(flags, name, use_gettext) 21970 int flags; 21971 char_u *name; 21972 int use_gettext; 21973 { 21974 if (flags & DI_FLAGS_RO) 21975 { 21976 EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); 21977 return TRUE; 21978 } 21979 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 21980 { 21981 EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name); 21982 return TRUE; 21983 } 21984 return FALSE; 21985 } 21986 21987 /* 21988 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 21989 * Also give an error message. 21990 */ 21991 static int 21992 var_check_fixed(flags, name, use_gettext) 21993 int flags; 21994 char_u *name; 21995 int use_gettext; 21996 { 21997 if (flags & DI_FLAGS_FIX) 21998 { 21999 EMSG2(_("E795: Cannot delete variable %s"), 22000 use_gettext ? (char_u *)_(name) : name); 22001 return TRUE; 22002 } 22003 return FALSE; 22004 } 22005 22006 /* 22007 * Check if a funcref is assigned to a valid variable name. 22008 * Return TRUE and give an error if not. 22009 */ 22010 static int 22011 var_check_func_name(name, new_var) 22012 char_u *name; /* points to start of variable name */ 22013 int new_var; /* TRUE when creating the variable */ 22014 { 22015 /* Allow for w: b: s: and t:. */ 22016 if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':') 22017 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 22018 ? name[2] : name[0])) 22019 { 22020 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), 22021 name); 22022 return TRUE; 22023 } 22024 /* Don't allow hiding a function. When "v" is not NULL we might be 22025 * assigning another function to the same var, the type is checked 22026 * below. */ 22027 if (new_var && function_exists(name)) 22028 { 22029 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 22030 name); 22031 return TRUE; 22032 } 22033 return FALSE; 22034 } 22035 22036 /* 22037 * Check if a variable name is valid. 22038 * Return FALSE and give an error if not. 22039 */ 22040 static int 22041 valid_varname(varname) 22042 char_u *varname; 22043 { 22044 char_u *p; 22045 22046 for (p = varname; *p != NUL; ++p) 22047 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 22048 && *p != AUTOLOAD_CHAR) 22049 { 22050 EMSG2(_(e_illvar), varname); 22051 return FALSE; 22052 } 22053 return TRUE; 22054 } 22055 22056 /* 22057 * Return TRUE if typeval "tv" is set to be locked (immutable). 22058 * Also give an error message, using "name" or _("name") when use_gettext is 22059 * TRUE. 22060 */ 22061 static int 22062 tv_check_lock(lock, name, use_gettext) 22063 int lock; 22064 char_u *name; 22065 int use_gettext; 22066 { 22067 if (lock & VAR_LOCKED) 22068 { 22069 EMSG2(_("E741: Value is locked: %s"), 22070 name == NULL ? (char_u *)_("Unknown") 22071 : use_gettext ? (char_u *)_(name) 22072 : name); 22073 return TRUE; 22074 } 22075 if (lock & VAR_FIXED) 22076 { 22077 EMSG2(_("E742: Cannot change value of %s"), 22078 name == NULL ? (char_u *)_("Unknown") 22079 : use_gettext ? (char_u *)_(name) 22080 : name); 22081 return TRUE; 22082 } 22083 return FALSE; 22084 } 22085 22086 /* 22087 * Copy the values from typval_T "from" to typval_T "to". 22088 * When needed allocates string or increases reference count. 22089 * Does not make a copy of a list or dict but copies the reference! 22090 * It is OK for "from" and "to" to point to the same item. This is used to 22091 * make a copy later. 22092 */ 22093 void 22094 copy_tv(from, to) 22095 typval_T *from; 22096 typval_T *to; 22097 { 22098 to->v_type = from->v_type; 22099 to->v_lock = 0; 22100 switch (from->v_type) 22101 { 22102 case VAR_NUMBER: 22103 to->vval.v_number = from->vval.v_number; 22104 break; 22105 #ifdef FEAT_FLOAT 22106 case VAR_FLOAT: 22107 to->vval.v_float = from->vval.v_float; 22108 break; 22109 #endif 22110 case VAR_STRING: 22111 case VAR_FUNC: 22112 if (from->vval.v_string == NULL) 22113 to->vval.v_string = NULL; 22114 else 22115 { 22116 to->vval.v_string = vim_strsave(from->vval.v_string); 22117 if (from->v_type == VAR_FUNC) 22118 func_ref(to->vval.v_string); 22119 } 22120 break; 22121 case VAR_LIST: 22122 if (from->vval.v_list == NULL) 22123 to->vval.v_list = NULL; 22124 else 22125 { 22126 to->vval.v_list = from->vval.v_list; 22127 ++to->vval.v_list->lv_refcount; 22128 } 22129 break; 22130 case VAR_DICT: 22131 if (from->vval.v_dict == NULL) 22132 to->vval.v_dict = NULL; 22133 else 22134 { 22135 to->vval.v_dict = from->vval.v_dict; 22136 ++to->vval.v_dict->dv_refcount; 22137 } 22138 break; 22139 default: 22140 EMSG2(_(e_intern2), "copy_tv()"); 22141 break; 22142 } 22143 } 22144 22145 /* 22146 * Make a copy of an item. 22147 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 22148 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 22149 * reference to an already copied list/dict can be used. 22150 * Returns FAIL or OK. 22151 */ 22152 static int 22153 item_copy(from, to, deep, copyID) 22154 typval_T *from; 22155 typval_T *to; 22156 int deep; 22157 int copyID; 22158 { 22159 static int recurse = 0; 22160 int ret = OK; 22161 22162 if (recurse >= DICT_MAXNEST) 22163 { 22164 EMSG(_("E698: variable nested too deep for making a copy")); 22165 return FAIL; 22166 } 22167 ++recurse; 22168 22169 switch (from->v_type) 22170 { 22171 case VAR_NUMBER: 22172 #ifdef FEAT_FLOAT 22173 case VAR_FLOAT: 22174 #endif 22175 case VAR_STRING: 22176 case VAR_FUNC: 22177 copy_tv(from, to); 22178 break; 22179 case VAR_LIST: 22180 to->v_type = VAR_LIST; 22181 to->v_lock = 0; 22182 if (from->vval.v_list == NULL) 22183 to->vval.v_list = NULL; 22184 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 22185 { 22186 /* use the copy made earlier */ 22187 to->vval.v_list = from->vval.v_list->lv_copylist; 22188 ++to->vval.v_list->lv_refcount; 22189 } 22190 else 22191 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 22192 if (to->vval.v_list == NULL) 22193 ret = FAIL; 22194 break; 22195 case VAR_DICT: 22196 to->v_type = VAR_DICT; 22197 to->v_lock = 0; 22198 if (from->vval.v_dict == NULL) 22199 to->vval.v_dict = NULL; 22200 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 22201 { 22202 /* use the copy made earlier */ 22203 to->vval.v_dict = from->vval.v_dict->dv_copydict; 22204 ++to->vval.v_dict->dv_refcount; 22205 } 22206 else 22207 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 22208 if (to->vval.v_dict == NULL) 22209 ret = FAIL; 22210 break; 22211 default: 22212 EMSG2(_(e_intern2), "item_copy()"); 22213 ret = FAIL; 22214 } 22215 --recurse; 22216 return ret; 22217 } 22218 22219 /* 22220 * ":echo expr1 ..." print each argument separated with a space, add a 22221 * newline at the end. 22222 * ":echon expr1 ..." print each argument plain. 22223 */ 22224 void 22225 ex_echo(eap) 22226 exarg_T *eap; 22227 { 22228 char_u *arg = eap->arg; 22229 typval_T rettv; 22230 char_u *tofree; 22231 char_u *p; 22232 int needclr = TRUE; 22233 int atstart = TRUE; 22234 char_u numbuf[NUMBUFLEN]; 22235 22236 if (eap->skip) 22237 ++emsg_skip; 22238 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 22239 { 22240 /* If eval1() causes an error message the text from the command may 22241 * still need to be cleared. E.g., "echo 22,44". */ 22242 need_clr_eos = needclr; 22243 22244 p = arg; 22245 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 22246 { 22247 /* 22248 * Report the invalid expression unless the expression evaluation 22249 * has been cancelled due to an aborting error, an interrupt, or an 22250 * exception. 22251 */ 22252 if (!aborting()) 22253 EMSG2(_(e_invexpr2), p); 22254 need_clr_eos = FALSE; 22255 break; 22256 } 22257 need_clr_eos = FALSE; 22258 22259 if (!eap->skip) 22260 { 22261 if (atstart) 22262 { 22263 atstart = FALSE; 22264 /* Call msg_start() after eval1(), evaluating the expression 22265 * may cause a message to appear. */ 22266 if (eap->cmdidx == CMD_echo) 22267 { 22268 /* Mark the saved text as finishing the line, so that what 22269 * follows is displayed on a new line when scrolling back 22270 * at the more prompt. */ 22271 msg_sb_eol(); 22272 msg_start(); 22273 } 22274 } 22275 else if (eap->cmdidx == CMD_echo) 22276 msg_puts_attr((char_u *)" ", echo_attr); 22277 current_copyID += COPYID_INC; 22278 p = echo_string(&rettv, &tofree, numbuf, current_copyID); 22279 if (p != NULL) 22280 for ( ; *p != NUL && !got_int; ++p) 22281 { 22282 if (*p == '\n' || *p == '\r' || *p == TAB) 22283 { 22284 if (*p != TAB && needclr) 22285 { 22286 /* remove any text still there from the command */ 22287 msg_clr_eos(); 22288 needclr = FALSE; 22289 } 22290 msg_putchar_attr(*p, echo_attr); 22291 } 22292 else 22293 { 22294 #ifdef FEAT_MBYTE 22295 if (has_mbyte) 22296 { 22297 int i = (*mb_ptr2len)(p); 22298 22299 (void)msg_outtrans_len_attr(p, i, echo_attr); 22300 p += i - 1; 22301 } 22302 else 22303 #endif 22304 (void)msg_outtrans_len_attr(p, 1, echo_attr); 22305 } 22306 } 22307 vim_free(tofree); 22308 } 22309 clear_tv(&rettv); 22310 arg = skipwhite(arg); 22311 } 22312 eap->nextcmd = check_nextcmd(arg); 22313 22314 if (eap->skip) 22315 --emsg_skip; 22316 else 22317 { 22318 /* remove text that may still be there from the command */ 22319 if (needclr) 22320 msg_clr_eos(); 22321 if (eap->cmdidx == CMD_echo) 22322 msg_end(); 22323 } 22324 } 22325 22326 /* 22327 * ":echohl {name}". 22328 */ 22329 void 22330 ex_echohl(eap) 22331 exarg_T *eap; 22332 { 22333 int id; 22334 22335 id = syn_name2id(eap->arg); 22336 if (id == 0) 22337 echo_attr = 0; 22338 else 22339 echo_attr = syn_id2attr(id); 22340 } 22341 22342 /* 22343 * ":execute expr1 ..." execute the result of an expression. 22344 * ":echomsg expr1 ..." Print a message 22345 * ":echoerr expr1 ..." Print an error 22346 * Each gets spaces around each argument and a newline at the end for 22347 * echo commands 22348 */ 22349 void 22350 ex_execute(eap) 22351 exarg_T *eap; 22352 { 22353 char_u *arg = eap->arg; 22354 typval_T rettv; 22355 int ret = OK; 22356 char_u *p; 22357 garray_T ga; 22358 int len; 22359 int save_did_emsg; 22360 22361 ga_init2(&ga, 1, 80); 22362 22363 if (eap->skip) 22364 ++emsg_skip; 22365 while (*arg != NUL && *arg != '|' && *arg != '\n') 22366 { 22367 p = arg; 22368 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 22369 { 22370 /* 22371 * Report the invalid expression unless the expression evaluation 22372 * has been cancelled due to an aborting error, an interrupt, or an 22373 * exception. 22374 */ 22375 if (!aborting()) 22376 EMSG2(_(e_invexpr2), p); 22377 ret = FAIL; 22378 break; 22379 } 22380 22381 if (!eap->skip) 22382 { 22383 p = get_tv_string(&rettv); 22384 len = (int)STRLEN(p); 22385 if (ga_grow(&ga, len + 2) == FAIL) 22386 { 22387 clear_tv(&rettv); 22388 ret = FAIL; 22389 break; 22390 } 22391 if (ga.ga_len) 22392 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 22393 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 22394 ga.ga_len += len; 22395 } 22396 22397 clear_tv(&rettv); 22398 arg = skipwhite(arg); 22399 } 22400 22401 if (ret != FAIL && ga.ga_data != NULL) 22402 { 22403 if (eap->cmdidx == CMD_echomsg) 22404 { 22405 MSG_ATTR(ga.ga_data, echo_attr); 22406 out_flush(); 22407 } 22408 else if (eap->cmdidx == CMD_echoerr) 22409 { 22410 /* We don't want to abort following commands, restore did_emsg. */ 22411 save_did_emsg = did_emsg; 22412 EMSG((char_u *)ga.ga_data); 22413 if (!force_abort) 22414 did_emsg = save_did_emsg; 22415 } 22416 else if (eap->cmdidx == CMD_execute) 22417 do_cmdline((char_u *)ga.ga_data, 22418 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 22419 } 22420 22421 ga_clear(&ga); 22422 22423 if (eap->skip) 22424 --emsg_skip; 22425 22426 eap->nextcmd = check_nextcmd(arg); 22427 } 22428 22429 /* 22430 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 22431 * "arg" points to the "&" or '+' when called, to "option" when returning. 22432 * Returns NULL when no option name found. Otherwise pointer to the char 22433 * after the option name. 22434 */ 22435 static char_u * 22436 find_option_end(arg, opt_flags) 22437 char_u **arg; 22438 int *opt_flags; 22439 { 22440 char_u *p = *arg; 22441 22442 ++p; 22443 if (*p == 'g' && p[1] == ':') 22444 { 22445 *opt_flags = OPT_GLOBAL; 22446 p += 2; 22447 } 22448 else if (*p == 'l' && p[1] == ':') 22449 { 22450 *opt_flags = OPT_LOCAL; 22451 p += 2; 22452 } 22453 else 22454 *opt_flags = 0; 22455 22456 if (!ASCII_ISALPHA(*p)) 22457 return NULL; 22458 *arg = p; 22459 22460 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 22461 p += 4; /* termcap option */ 22462 else 22463 while (ASCII_ISALPHA(*p)) 22464 ++p; 22465 return p; 22466 } 22467 22468 /* 22469 * ":function" 22470 */ 22471 void 22472 ex_function(eap) 22473 exarg_T *eap; 22474 { 22475 char_u *theline; 22476 int i; 22477 int j; 22478 int c; 22479 int saved_did_emsg; 22480 int saved_wait_return = need_wait_return; 22481 char_u *name = NULL; 22482 char_u *p; 22483 char_u *arg; 22484 char_u *line_arg = NULL; 22485 garray_T newargs; 22486 garray_T newlines; 22487 int varargs = FALSE; 22488 int mustend = FALSE; 22489 int flags = 0; 22490 ufunc_T *fp; 22491 int indent; 22492 int nesting; 22493 char_u *skip_until = NULL; 22494 dictitem_T *v; 22495 funcdict_T fudi; 22496 static int func_nr = 0; /* number for nameless function */ 22497 int paren; 22498 hashtab_T *ht; 22499 int todo; 22500 hashitem_T *hi; 22501 int sourcing_lnum_off; 22502 22503 /* 22504 * ":function" without argument: list functions. 22505 */ 22506 if (ends_excmd(*eap->arg)) 22507 { 22508 if (!eap->skip) 22509 { 22510 todo = (int)func_hashtab.ht_used; 22511 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 22512 { 22513 if (!HASHITEM_EMPTY(hi)) 22514 { 22515 --todo; 22516 fp = HI2UF(hi); 22517 if (!isdigit(*fp->uf_name)) 22518 list_func_head(fp, FALSE); 22519 } 22520 } 22521 } 22522 eap->nextcmd = check_nextcmd(eap->arg); 22523 return; 22524 } 22525 22526 /* 22527 * ":function /pat": list functions matching pattern. 22528 */ 22529 if (*eap->arg == '/') 22530 { 22531 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 22532 if (!eap->skip) 22533 { 22534 regmatch_T regmatch; 22535 22536 c = *p; 22537 *p = NUL; 22538 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 22539 *p = c; 22540 if (regmatch.regprog != NULL) 22541 { 22542 regmatch.rm_ic = p_ic; 22543 22544 todo = (int)func_hashtab.ht_used; 22545 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 22546 { 22547 if (!HASHITEM_EMPTY(hi)) 22548 { 22549 --todo; 22550 fp = HI2UF(hi); 22551 if (!isdigit(*fp->uf_name) 22552 && vim_regexec(®match, fp->uf_name, 0)) 22553 list_func_head(fp, FALSE); 22554 } 22555 } 22556 vim_regfree(regmatch.regprog); 22557 } 22558 } 22559 if (*p == '/') 22560 ++p; 22561 eap->nextcmd = check_nextcmd(p); 22562 return; 22563 } 22564 22565 /* 22566 * Get the function name. There are these situations: 22567 * func normal function name 22568 * "name" == func, "fudi.fd_dict" == NULL 22569 * dict.func new dictionary entry 22570 * "name" == NULL, "fudi.fd_dict" set, 22571 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 22572 * dict.func existing dict entry with a Funcref 22573 * "name" == func, "fudi.fd_dict" set, 22574 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 22575 * dict.func existing dict entry that's not a Funcref 22576 * "name" == NULL, "fudi.fd_dict" set, 22577 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 22578 * s:func script-local function name 22579 * g:func global function name, same as "func" 22580 */ 22581 p = eap->arg; 22582 name = trans_function_name(&p, eap->skip, 0, &fudi); 22583 paren = (vim_strchr(p, '(') != NULL); 22584 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 22585 { 22586 /* 22587 * Return on an invalid expression in braces, unless the expression 22588 * evaluation has been cancelled due to an aborting error, an 22589 * interrupt, or an exception. 22590 */ 22591 if (!aborting()) 22592 { 22593 if (!eap->skip && fudi.fd_newkey != NULL) 22594 EMSG2(_(e_dictkey), fudi.fd_newkey); 22595 vim_free(fudi.fd_newkey); 22596 return; 22597 } 22598 else 22599 eap->skip = TRUE; 22600 } 22601 22602 /* An error in a function call during evaluation of an expression in magic 22603 * braces should not cause the function not to be defined. */ 22604 saved_did_emsg = did_emsg; 22605 did_emsg = FALSE; 22606 22607 /* 22608 * ":function func" with only function name: list function. 22609 */ 22610 if (!paren) 22611 { 22612 if (!ends_excmd(*skipwhite(p))) 22613 { 22614 EMSG(_(e_trailing)); 22615 goto ret_free; 22616 } 22617 eap->nextcmd = check_nextcmd(p); 22618 if (eap->nextcmd != NULL) 22619 *p = NUL; 22620 if (!eap->skip && !got_int) 22621 { 22622 fp = find_func(name); 22623 if (fp != NULL) 22624 { 22625 list_func_head(fp, TRUE); 22626 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 22627 { 22628 if (FUNCLINE(fp, j) == NULL) 22629 continue; 22630 msg_putchar('\n'); 22631 msg_outnum((long)(j + 1)); 22632 if (j < 9) 22633 msg_putchar(' '); 22634 if (j < 99) 22635 msg_putchar(' '); 22636 msg_prt_line(FUNCLINE(fp, j), FALSE); 22637 out_flush(); /* show a line at a time */ 22638 ui_breakcheck(); 22639 } 22640 if (!got_int) 22641 { 22642 msg_putchar('\n'); 22643 msg_puts((char_u *)" endfunction"); 22644 } 22645 } 22646 else 22647 emsg_funcname(N_("E123: Undefined function: %s"), name); 22648 } 22649 goto ret_free; 22650 } 22651 22652 /* 22653 * ":function name(arg1, arg2)" Define function. 22654 */ 22655 p = skipwhite(p); 22656 if (*p != '(') 22657 { 22658 if (!eap->skip) 22659 { 22660 EMSG2(_("E124: Missing '(': %s"), eap->arg); 22661 goto ret_free; 22662 } 22663 /* attempt to continue by skipping some text */ 22664 if (vim_strchr(p, '(') != NULL) 22665 p = vim_strchr(p, '('); 22666 } 22667 p = skipwhite(p + 1); 22668 22669 ga_init2(&newargs, (int)sizeof(char_u *), 3); 22670 ga_init2(&newlines, (int)sizeof(char_u *), 3); 22671 22672 if (!eap->skip) 22673 { 22674 /* Check the name of the function. Unless it's a dictionary function 22675 * (that we are overwriting). */ 22676 if (name != NULL) 22677 arg = name; 22678 else 22679 arg = fudi.fd_newkey; 22680 if (arg != NULL && (fudi.fd_di == NULL 22681 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 22682 { 22683 if (*arg == K_SPECIAL) 22684 j = 3; 22685 else 22686 j = 0; 22687 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 22688 : eval_isnamec(arg[j]))) 22689 ++j; 22690 if (arg[j] != NUL) 22691 emsg_funcname((char *)e_invarg2, arg); 22692 } 22693 /* Disallow using the g: dict. */ 22694 if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) 22695 EMSG(_("E862: Cannot use g: here")); 22696 } 22697 22698 /* 22699 * Isolate the arguments: "arg1, arg2, ...)" 22700 */ 22701 while (*p != ')') 22702 { 22703 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 22704 { 22705 varargs = TRUE; 22706 p += 3; 22707 mustend = TRUE; 22708 } 22709 else 22710 { 22711 arg = p; 22712 while (ASCII_ISALNUM(*p) || *p == '_') 22713 ++p; 22714 if (arg == p || isdigit(*arg) 22715 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 22716 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 22717 { 22718 if (!eap->skip) 22719 EMSG2(_("E125: Illegal argument: %s"), arg); 22720 break; 22721 } 22722 if (ga_grow(&newargs, 1) == FAIL) 22723 goto erret; 22724 c = *p; 22725 *p = NUL; 22726 arg = vim_strsave(arg); 22727 if (arg == NULL) 22728 goto erret; 22729 22730 /* Check for duplicate argument name. */ 22731 for (i = 0; i < newargs.ga_len; ++i) 22732 if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0) 22733 { 22734 EMSG2(_("E853: Duplicate argument name: %s"), arg); 22735 vim_free(arg); 22736 goto erret; 22737 } 22738 22739 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 22740 *p = c; 22741 newargs.ga_len++; 22742 if (*p == ',') 22743 ++p; 22744 else 22745 mustend = TRUE; 22746 } 22747 p = skipwhite(p); 22748 if (mustend && *p != ')') 22749 { 22750 if (!eap->skip) 22751 EMSG2(_(e_invarg2), eap->arg); 22752 break; 22753 } 22754 } 22755 if (*p != ')') 22756 goto erret; 22757 ++p; /* skip the ')' */ 22758 22759 /* find extra arguments "range", "dict" and "abort" */ 22760 for (;;) 22761 { 22762 p = skipwhite(p); 22763 if (STRNCMP(p, "range", 5) == 0) 22764 { 22765 flags |= FC_RANGE; 22766 p += 5; 22767 } 22768 else if (STRNCMP(p, "dict", 4) == 0) 22769 { 22770 flags |= FC_DICT; 22771 p += 4; 22772 } 22773 else if (STRNCMP(p, "abort", 5) == 0) 22774 { 22775 flags |= FC_ABORT; 22776 p += 5; 22777 } 22778 else 22779 break; 22780 } 22781 22782 /* When there is a line break use what follows for the function body. 22783 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 22784 if (*p == '\n') 22785 line_arg = p + 1; 22786 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 22787 EMSG(_(e_trailing)); 22788 22789 /* 22790 * Read the body of the function, until ":endfunction" is found. 22791 */ 22792 if (KeyTyped) 22793 { 22794 /* Check if the function already exists, don't let the user type the 22795 * whole function before telling him it doesn't work! For a script we 22796 * need to skip the body to be able to find what follows. */ 22797 if (!eap->skip && !eap->forceit) 22798 { 22799 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 22800 EMSG(_(e_funcdict)); 22801 else if (name != NULL && find_func(name) != NULL) 22802 emsg_funcname(e_funcexts, name); 22803 } 22804 22805 if (!eap->skip && did_emsg) 22806 goto erret; 22807 22808 msg_putchar('\n'); /* don't overwrite the function name */ 22809 cmdline_row = msg_row; 22810 } 22811 22812 indent = 2; 22813 nesting = 0; 22814 for (;;) 22815 { 22816 if (KeyTyped) 22817 { 22818 msg_scroll = TRUE; 22819 saved_wait_return = FALSE; 22820 } 22821 need_wait_return = FALSE; 22822 sourcing_lnum_off = sourcing_lnum; 22823 22824 if (line_arg != NULL) 22825 { 22826 /* Use eap->arg, split up in parts by line breaks. */ 22827 theline = line_arg; 22828 p = vim_strchr(theline, '\n'); 22829 if (p == NULL) 22830 line_arg += STRLEN(line_arg); 22831 else 22832 { 22833 *p = NUL; 22834 line_arg = p + 1; 22835 } 22836 } 22837 else if (eap->getline == NULL) 22838 theline = getcmdline(':', 0L, indent); 22839 else 22840 theline = eap->getline(':', eap->cookie, indent); 22841 if (KeyTyped) 22842 lines_left = Rows - 1; 22843 if (theline == NULL) 22844 { 22845 EMSG(_("E126: Missing :endfunction")); 22846 goto erret; 22847 } 22848 22849 /* Detect line continuation: sourcing_lnum increased more than one. */ 22850 if (sourcing_lnum > sourcing_lnum_off + 1) 22851 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 22852 else 22853 sourcing_lnum_off = 0; 22854 22855 if (skip_until != NULL) 22856 { 22857 /* between ":append" and "." and between ":python <<EOF" and "EOF" 22858 * don't check for ":endfunc". */ 22859 if (STRCMP(theline, skip_until) == 0) 22860 { 22861 vim_free(skip_until); 22862 skip_until = NULL; 22863 } 22864 } 22865 else 22866 { 22867 /* skip ':' and blanks*/ 22868 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 22869 ; 22870 22871 /* Check for "endfunction". */ 22872 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 22873 { 22874 if (line_arg == NULL) 22875 vim_free(theline); 22876 break; 22877 } 22878 22879 /* Increase indent inside "if", "while", "for" and "try", decrease 22880 * at "end". */ 22881 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 22882 indent -= 2; 22883 else if (STRNCMP(p, "if", 2) == 0 22884 || STRNCMP(p, "wh", 2) == 0 22885 || STRNCMP(p, "for", 3) == 0 22886 || STRNCMP(p, "try", 3) == 0) 22887 indent += 2; 22888 22889 /* Check for defining a function inside this function. */ 22890 if (checkforcmd(&p, "function", 2)) 22891 { 22892 if (*p == '!') 22893 p = skipwhite(p + 1); 22894 p += eval_fname_script(p); 22895 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 22896 if (*skipwhite(p) == '(') 22897 { 22898 ++nesting; 22899 indent += 2; 22900 } 22901 } 22902 22903 /* Check for ":append" or ":insert". */ 22904 p = skip_range(p, NULL); 22905 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 22906 || (p[0] == 'i' 22907 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 22908 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 22909 skip_until = vim_strsave((char_u *)"."); 22910 22911 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 22912 arg = skipwhite(skiptowhite(p)); 22913 if (arg[0] == '<' && arg[1] =='<' 22914 && ((p[0] == 'p' && p[1] == 'y' 22915 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 22916 || (p[0] == 'p' && p[1] == 'e' 22917 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 22918 || (p[0] == 't' && p[1] == 'c' 22919 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 22920 || (p[0] == 'l' && p[1] == 'u' && p[2] == 'a' 22921 && !ASCII_ISALPHA(p[3])) 22922 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 22923 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 22924 || (p[0] == 'm' && p[1] == 'z' 22925 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 22926 )) 22927 { 22928 /* ":python <<" continues until a dot, like ":append" */ 22929 p = skipwhite(arg + 2); 22930 if (*p == NUL) 22931 skip_until = vim_strsave((char_u *)"."); 22932 else 22933 skip_until = vim_strsave(p); 22934 } 22935 } 22936 22937 /* Add the line to the function. */ 22938 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 22939 { 22940 if (line_arg == NULL) 22941 vim_free(theline); 22942 goto erret; 22943 } 22944 22945 /* Copy the line to newly allocated memory. get_one_sourceline() 22946 * allocates 250 bytes per line, this saves 80% on average. The cost 22947 * is an extra alloc/free. */ 22948 p = vim_strsave(theline); 22949 if (p != NULL) 22950 { 22951 if (line_arg == NULL) 22952 vim_free(theline); 22953 theline = p; 22954 } 22955 22956 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 22957 22958 /* Add NULL lines for continuation lines, so that the line count is 22959 * equal to the index in the growarray. */ 22960 while (sourcing_lnum_off-- > 0) 22961 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 22962 22963 /* Check for end of eap->arg. */ 22964 if (line_arg != NULL && *line_arg == NUL) 22965 line_arg = NULL; 22966 } 22967 22968 /* Don't define the function when skipping commands or when an error was 22969 * detected. */ 22970 if (eap->skip || did_emsg) 22971 goto erret; 22972 22973 /* 22974 * If there are no errors, add the function 22975 */ 22976 if (fudi.fd_dict == NULL) 22977 { 22978 v = find_var(name, &ht, FALSE); 22979 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 22980 { 22981 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 22982 name); 22983 goto erret; 22984 } 22985 22986 fp = find_func(name); 22987 if (fp != NULL) 22988 { 22989 if (!eap->forceit) 22990 { 22991 emsg_funcname(e_funcexts, name); 22992 goto erret; 22993 } 22994 if (fp->uf_calls > 0) 22995 { 22996 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 22997 name); 22998 goto erret; 22999 } 23000 /* redefine existing function */ 23001 ga_clear_strings(&(fp->uf_args)); 23002 ga_clear_strings(&(fp->uf_lines)); 23003 vim_free(name); 23004 name = NULL; 23005 } 23006 } 23007 else 23008 { 23009 char numbuf[20]; 23010 23011 fp = NULL; 23012 if (fudi.fd_newkey == NULL && !eap->forceit) 23013 { 23014 EMSG(_(e_funcdict)); 23015 goto erret; 23016 } 23017 if (fudi.fd_di == NULL) 23018 { 23019 /* Can't add a function to a locked dictionary */ 23020 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, FALSE)) 23021 goto erret; 23022 } 23023 /* Can't change an existing function if it is locked */ 23024 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, FALSE)) 23025 goto erret; 23026 23027 /* Give the function a sequential number. Can only be used with a 23028 * Funcref! */ 23029 vim_free(name); 23030 sprintf(numbuf, "%d", ++func_nr); 23031 name = vim_strsave((char_u *)numbuf); 23032 if (name == NULL) 23033 goto erret; 23034 } 23035 23036 if (fp == NULL) 23037 { 23038 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 23039 { 23040 int slen, plen; 23041 char_u *scriptname; 23042 23043 /* Check that the autoload name matches the script name. */ 23044 j = FAIL; 23045 if (sourcing_name != NULL) 23046 { 23047 scriptname = autoload_name(name); 23048 if (scriptname != NULL) 23049 { 23050 p = vim_strchr(scriptname, '/'); 23051 plen = (int)STRLEN(p); 23052 slen = (int)STRLEN(sourcing_name); 23053 if (slen > plen && fnamecmp(p, 23054 sourcing_name + slen - plen) == 0) 23055 j = OK; 23056 vim_free(scriptname); 23057 } 23058 } 23059 if (j == FAIL) 23060 { 23061 EMSG2(_("E746: Function name does not match script file name: %s"), name); 23062 goto erret; 23063 } 23064 } 23065 23066 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 23067 if (fp == NULL) 23068 goto erret; 23069 23070 if (fudi.fd_dict != NULL) 23071 { 23072 if (fudi.fd_di == NULL) 23073 { 23074 /* add new dict entry */ 23075 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 23076 if (fudi.fd_di == NULL) 23077 { 23078 vim_free(fp); 23079 goto erret; 23080 } 23081 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 23082 { 23083 vim_free(fudi.fd_di); 23084 vim_free(fp); 23085 goto erret; 23086 } 23087 } 23088 else 23089 /* overwrite existing dict entry */ 23090 clear_tv(&fudi.fd_di->di_tv); 23091 fudi.fd_di->di_tv.v_type = VAR_FUNC; 23092 fudi.fd_di->di_tv.v_lock = 0; 23093 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 23094 fp->uf_refcount = 1; 23095 23096 /* behave like "dict" was used */ 23097 flags |= FC_DICT; 23098 } 23099 23100 /* insert the new function in the function list */ 23101 STRCPY(fp->uf_name, name); 23102 if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) 23103 { 23104 vim_free(fp); 23105 goto erret; 23106 } 23107 } 23108 fp->uf_args = newargs; 23109 fp->uf_lines = newlines; 23110 #ifdef FEAT_PROFILE 23111 fp->uf_tml_count = NULL; 23112 fp->uf_tml_total = NULL; 23113 fp->uf_tml_self = NULL; 23114 fp->uf_profiling = FALSE; 23115 if (prof_def_func()) 23116 func_do_profile(fp); 23117 #endif 23118 fp->uf_varargs = varargs; 23119 fp->uf_flags = flags; 23120 fp->uf_calls = 0; 23121 fp->uf_script_ID = current_SID; 23122 goto ret_free; 23123 23124 erret: 23125 ga_clear_strings(&newargs); 23126 ga_clear_strings(&newlines); 23127 ret_free: 23128 vim_free(skip_until); 23129 vim_free(fudi.fd_newkey); 23130 vim_free(name); 23131 did_emsg |= saved_did_emsg; 23132 need_wait_return |= saved_wait_return; 23133 } 23134 23135 /* 23136 * Get a function name, translating "<SID>" and "<SNR>". 23137 * Also handles a Funcref in a List or Dictionary. 23138 * Returns the function name in allocated memory, or NULL for failure. 23139 * flags: 23140 * TFN_INT: internal function name OK 23141 * TFN_QUIET: be quiet 23142 * TFN_NO_AUTOLOAD: do not use script autoloading 23143 * Advances "pp" to just after the function name (if no error). 23144 */ 23145 static char_u * 23146 trans_function_name(pp, skip, flags, fdp) 23147 char_u **pp; 23148 int skip; /* only find the end, don't evaluate */ 23149 int flags; 23150 funcdict_T *fdp; /* return: info about dictionary used */ 23151 { 23152 char_u *name = NULL; 23153 char_u *start; 23154 char_u *end; 23155 int lead; 23156 char_u sid_buf[20]; 23157 int len; 23158 lval_T lv; 23159 23160 if (fdp != NULL) 23161 vim_memset(fdp, 0, sizeof(funcdict_T)); 23162 start = *pp; 23163 23164 /* Check for hard coded <SNR>: already translated function ID (from a user 23165 * command). */ 23166 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 23167 && (*pp)[2] == (int)KE_SNR) 23168 { 23169 *pp += 3; 23170 len = get_id_len(pp) + 3; 23171 return vim_strnsave(start, len); 23172 } 23173 23174 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 23175 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 23176 lead = eval_fname_script(start); 23177 if (lead > 2) 23178 start += lead; 23179 23180 /* Note that TFN_ flags use the same values as GLV_ flags. */ 23181 end = get_lval(start, NULL, &lv, FALSE, skip, flags, 23182 lead > 2 ? 0 : FNE_CHECK_START); 23183 if (end == start) 23184 { 23185 if (!skip) 23186 EMSG(_("E129: Function name required")); 23187 goto theend; 23188 } 23189 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 23190 { 23191 /* 23192 * Report an invalid expression in braces, unless the expression 23193 * evaluation has been cancelled due to an aborting error, an 23194 * interrupt, or an exception. 23195 */ 23196 if (!aborting()) 23197 { 23198 if (end != NULL) 23199 EMSG2(_(e_invarg2), start); 23200 } 23201 else 23202 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 23203 goto theend; 23204 } 23205 23206 if (lv.ll_tv != NULL) 23207 { 23208 if (fdp != NULL) 23209 { 23210 fdp->fd_dict = lv.ll_dict; 23211 fdp->fd_newkey = lv.ll_newkey; 23212 lv.ll_newkey = NULL; 23213 fdp->fd_di = lv.ll_di; 23214 } 23215 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 23216 { 23217 name = vim_strsave(lv.ll_tv->vval.v_string); 23218 *pp = end; 23219 } 23220 else 23221 { 23222 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 23223 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 23224 EMSG(_(e_funcref)); 23225 else 23226 *pp = end; 23227 name = NULL; 23228 } 23229 goto theend; 23230 } 23231 23232 if (lv.ll_name == NULL) 23233 { 23234 /* Error found, but continue after the function name. */ 23235 *pp = end; 23236 goto theend; 23237 } 23238 23239 /* Check if the name is a Funcref. If so, use the value. */ 23240 if (lv.ll_exp_name != NULL) 23241 { 23242 len = (int)STRLEN(lv.ll_exp_name); 23243 name = deref_func_name(lv.ll_exp_name, &len, flags & TFN_NO_AUTOLOAD); 23244 if (name == lv.ll_exp_name) 23245 name = NULL; 23246 } 23247 else 23248 { 23249 len = (int)(end - *pp); 23250 name = deref_func_name(*pp, &len, flags & TFN_NO_AUTOLOAD); 23251 if (name == *pp) 23252 name = NULL; 23253 } 23254 if (name != NULL) 23255 { 23256 name = vim_strsave(name); 23257 *pp = end; 23258 if (STRNCMP(name, "<SNR>", 5) == 0) 23259 { 23260 /* Change "<SNR>" to the byte sequence. */ 23261 name[0] = K_SPECIAL; 23262 name[1] = KS_EXTRA; 23263 name[2] = (int)KE_SNR; 23264 mch_memmove(name + 3, name + 5, STRLEN(name + 5) + 1); 23265 } 23266 goto theend; 23267 } 23268 23269 if (lv.ll_exp_name != NULL) 23270 { 23271 len = (int)STRLEN(lv.ll_exp_name); 23272 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 23273 && STRNCMP(lv.ll_name, "s:", 2) == 0) 23274 { 23275 /* When there was "s:" already or the name expanded to get a 23276 * leading "s:" then remove it. */ 23277 lv.ll_name += 2; 23278 len -= 2; 23279 lead = 2; 23280 } 23281 } 23282 else 23283 { 23284 /* skip over "s:" and "g:" */ 23285 if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':')) 23286 lv.ll_name += 2; 23287 len = (int)(end - lv.ll_name); 23288 } 23289 23290 /* 23291 * Copy the function name to allocated memory. 23292 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 23293 * Accept <SNR>123_name() outside a script. 23294 */ 23295 if (skip) 23296 lead = 0; /* do nothing */ 23297 else if (lead > 0) 23298 { 23299 lead = 3; 23300 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 23301 || eval_fname_sid(*pp)) 23302 { 23303 /* It's "s:" or "<SID>" */ 23304 if (current_SID <= 0) 23305 { 23306 EMSG(_(e_usingsid)); 23307 goto theend; 23308 } 23309 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 23310 lead += (int)STRLEN(sid_buf); 23311 } 23312 } 23313 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) 23314 { 23315 EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"), 23316 start); 23317 goto theend; 23318 } 23319 if (!skip && !(flags & TFN_QUIET)) 23320 { 23321 char_u *cp = vim_strchr(lv.ll_name, ':'); 23322 23323 if (cp != NULL && cp < end) 23324 { 23325 EMSG2(_("E884: Function name cannot contain a colon: %s"), start); 23326 goto theend; 23327 } 23328 } 23329 23330 name = alloc((unsigned)(len + lead + 1)); 23331 if (name != NULL) 23332 { 23333 if (lead > 0) 23334 { 23335 name[0] = K_SPECIAL; 23336 name[1] = KS_EXTRA; 23337 name[2] = (int)KE_SNR; 23338 if (lead > 3) /* If it's "<SID>" */ 23339 STRCPY(name + 3, sid_buf); 23340 } 23341 mch_memmove(name + lead, lv.ll_name, (size_t)len); 23342 name[lead + len] = NUL; 23343 } 23344 *pp = end; 23345 23346 theend: 23347 clear_lval(&lv); 23348 return name; 23349 } 23350 23351 /* 23352 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 23353 * Return 2 if "p" starts with "s:". 23354 * Return 0 otherwise. 23355 */ 23356 static int 23357 eval_fname_script(p) 23358 char_u *p; 23359 { 23360 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 23361 || STRNICMP(p + 1, "SNR>", 4) == 0)) 23362 return 5; 23363 if (p[0] == 's' && p[1] == ':') 23364 return 2; 23365 return 0; 23366 } 23367 23368 /* 23369 * Return TRUE if "p" starts with "<SID>" or "s:". 23370 * Only works if eval_fname_script() returned non-zero for "p"! 23371 */ 23372 static int 23373 eval_fname_sid(p) 23374 char_u *p; 23375 { 23376 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 23377 } 23378 23379 /* 23380 * List the head of the function: "name(arg1, arg2)". 23381 */ 23382 static void 23383 list_func_head(fp, indent) 23384 ufunc_T *fp; 23385 int indent; 23386 { 23387 int j; 23388 23389 msg_start(); 23390 if (indent) 23391 MSG_PUTS(" "); 23392 MSG_PUTS("function "); 23393 if (fp->uf_name[0] == K_SPECIAL) 23394 { 23395 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 23396 msg_puts(fp->uf_name + 3); 23397 } 23398 else 23399 msg_puts(fp->uf_name); 23400 msg_putchar('('); 23401 for (j = 0; j < fp->uf_args.ga_len; ++j) 23402 { 23403 if (j) 23404 MSG_PUTS(", "); 23405 msg_puts(FUNCARG(fp, j)); 23406 } 23407 if (fp->uf_varargs) 23408 { 23409 if (j) 23410 MSG_PUTS(", "); 23411 MSG_PUTS("..."); 23412 } 23413 msg_putchar(')'); 23414 if (fp->uf_flags & FC_ABORT) 23415 MSG_PUTS(" abort"); 23416 if (fp->uf_flags & FC_RANGE) 23417 MSG_PUTS(" range"); 23418 if (fp->uf_flags & FC_DICT) 23419 MSG_PUTS(" dict"); 23420 msg_clr_eos(); 23421 if (p_verbose > 0) 23422 last_set_msg(fp->uf_script_ID); 23423 } 23424 23425 /* 23426 * Find a function by name, return pointer to it in ufuncs. 23427 * Return NULL for unknown function. 23428 */ 23429 static ufunc_T * 23430 find_func(name) 23431 char_u *name; 23432 { 23433 hashitem_T *hi; 23434 23435 hi = hash_find(&func_hashtab, name); 23436 if (!HASHITEM_EMPTY(hi)) 23437 return HI2UF(hi); 23438 return NULL; 23439 } 23440 23441 #if defined(EXITFREE) || defined(PROTO) 23442 void 23443 free_all_functions() 23444 { 23445 hashitem_T *hi; 23446 23447 /* Need to start all over every time, because func_free() may change the 23448 * hash table. */ 23449 while (func_hashtab.ht_used > 0) 23450 for (hi = func_hashtab.ht_array; ; ++hi) 23451 if (!HASHITEM_EMPTY(hi)) 23452 { 23453 func_free(HI2UF(hi)); 23454 break; 23455 } 23456 } 23457 #endif 23458 23459 int 23460 translated_function_exists(name) 23461 char_u *name; 23462 { 23463 if (builtin_function(name, -1)) 23464 return find_internal_func(name) >= 0; 23465 return find_func(name) != NULL; 23466 } 23467 23468 /* 23469 * Return TRUE if a function "name" exists. 23470 */ 23471 static int 23472 function_exists(name) 23473 char_u *name; 23474 { 23475 char_u *nm = name; 23476 char_u *p; 23477 int n = FALSE; 23478 23479 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, 23480 NULL); 23481 nm = skipwhite(nm); 23482 23483 /* Only accept "funcname", "funcname ", "funcname (..." and 23484 * "funcname(...", not "funcname!...". */ 23485 if (p != NULL && (*nm == NUL || *nm == '(')) 23486 n = translated_function_exists(p); 23487 vim_free(p); 23488 return n; 23489 } 23490 23491 char_u * 23492 get_expanded_name(name, check) 23493 char_u *name; 23494 int check; 23495 { 23496 char_u *nm = name; 23497 char_u *p; 23498 23499 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); 23500 23501 if (p != NULL && *nm == NUL) 23502 if (!check || translated_function_exists(p)) 23503 return p; 23504 23505 vim_free(p); 23506 return NULL; 23507 } 23508 23509 /* 23510 * Return TRUE if "name" looks like a builtin function name: starts with a 23511 * lower case letter and doesn't contain AUTOLOAD_CHAR. 23512 * "len" is the length of "name", or -1 for NUL terminated. 23513 */ 23514 static int 23515 builtin_function(name, len) 23516 char_u *name; 23517 int len; 23518 { 23519 char_u *p; 23520 23521 if (!ASCII_ISLOWER(name[0])) 23522 return FALSE; 23523 p = vim_strchr(name, AUTOLOAD_CHAR); 23524 return p == NULL || (len > 0 && p > name + len); 23525 } 23526 23527 #if defined(FEAT_PROFILE) || defined(PROTO) 23528 /* 23529 * Start profiling function "fp". 23530 */ 23531 static void 23532 func_do_profile(fp) 23533 ufunc_T *fp; 23534 { 23535 int len = fp->uf_lines.ga_len; 23536 23537 if (len == 0) 23538 len = 1; /* avoid getting error for allocating zero bytes */ 23539 fp->uf_tm_count = 0; 23540 profile_zero(&fp->uf_tm_self); 23541 profile_zero(&fp->uf_tm_total); 23542 if (fp->uf_tml_count == NULL) 23543 fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len)); 23544 if (fp->uf_tml_total == NULL) 23545 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 23546 (sizeof(proftime_T) * len)); 23547 if (fp->uf_tml_self == NULL) 23548 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 23549 (sizeof(proftime_T) * len)); 23550 fp->uf_tml_idx = -1; 23551 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 23552 || fp->uf_tml_self == NULL) 23553 return; /* out of memory */ 23554 23555 fp->uf_profiling = TRUE; 23556 } 23557 23558 /* 23559 * Dump the profiling results for all functions in file "fd". 23560 */ 23561 void 23562 func_dump_profile(fd) 23563 FILE *fd; 23564 { 23565 hashitem_T *hi; 23566 int todo; 23567 ufunc_T *fp; 23568 int i; 23569 ufunc_T **sorttab; 23570 int st_len = 0; 23571 23572 todo = (int)func_hashtab.ht_used; 23573 if (todo == 0) 23574 return; /* nothing to dump */ 23575 23576 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T *) * todo)); 23577 23578 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 23579 { 23580 if (!HASHITEM_EMPTY(hi)) 23581 { 23582 --todo; 23583 fp = HI2UF(hi); 23584 if (fp->uf_profiling) 23585 { 23586 if (sorttab != NULL) 23587 sorttab[st_len++] = fp; 23588 23589 if (fp->uf_name[0] == K_SPECIAL) 23590 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 23591 else 23592 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 23593 if (fp->uf_tm_count == 1) 23594 fprintf(fd, "Called 1 time\n"); 23595 else 23596 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 23597 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 23598 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 23599 fprintf(fd, "\n"); 23600 fprintf(fd, "count total (s) self (s)\n"); 23601 23602 for (i = 0; i < fp->uf_lines.ga_len; ++i) 23603 { 23604 if (FUNCLINE(fp, i) == NULL) 23605 continue; 23606 prof_func_line(fd, fp->uf_tml_count[i], 23607 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 23608 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 23609 } 23610 fprintf(fd, "\n"); 23611 } 23612 } 23613 } 23614 23615 if (sorttab != NULL && st_len > 0) 23616 { 23617 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 23618 prof_total_cmp); 23619 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 23620 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 23621 prof_self_cmp); 23622 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 23623 } 23624 23625 vim_free(sorttab); 23626 } 23627 23628 static void 23629 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 23630 FILE *fd; 23631 ufunc_T **sorttab; 23632 int st_len; 23633 char *title; 23634 int prefer_self; /* when equal print only self time */ 23635 { 23636 int i; 23637 ufunc_T *fp; 23638 23639 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 23640 fprintf(fd, "count total (s) self (s) function\n"); 23641 for (i = 0; i < 20 && i < st_len; ++i) 23642 { 23643 fp = sorttab[i]; 23644 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 23645 prefer_self); 23646 if (fp->uf_name[0] == K_SPECIAL) 23647 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 23648 else 23649 fprintf(fd, " %s()\n", fp->uf_name); 23650 } 23651 fprintf(fd, "\n"); 23652 } 23653 23654 /* 23655 * Print the count and times for one function or function line. 23656 */ 23657 static void 23658 prof_func_line(fd, count, total, self, prefer_self) 23659 FILE *fd; 23660 int count; 23661 proftime_T *total; 23662 proftime_T *self; 23663 int prefer_self; /* when equal print only self time */ 23664 { 23665 if (count > 0) 23666 { 23667 fprintf(fd, "%5d ", count); 23668 if (prefer_self && profile_equal(total, self)) 23669 fprintf(fd, " "); 23670 else 23671 fprintf(fd, "%s ", profile_msg(total)); 23672 if (!prefer_self && profile_equal(total, self)) 23673 fprintf(fd, " "); 23674 else 23675 fprintf(fd, "%s ", profile_msg(self)); 23676 } 23677 else 23678 fprintf(fd, " "); 23679 } 23680 23681 /* 23682 * Compare function for total time sorting. 23683 */ 23684 static int 23685 #ifdef __BORLANDC__ 23686 _RTLENTRYF 23687 #endif 23688 prof_total_cmp(s1, s2) 23689 const void *s1; 23690 const void *s2; 23691 { 23692 ufunc_T *p1, *p2; 23693 23694 p1 = *(ufunc_T **)s1; 23695 p2 = *(ufunc_T **)s2; 23696 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 23697 } 23698 23699 /* 23700 * Compare function for self time sorting. 23701 */ 23702 static int 23703 #ifdef __BORLANDC__ 23704 _RTLENTRYF 23705 #endif 23706 prof_self_cmp(s1, s2) 23707 const void *s1; 23708 const void *s2; 23709 { 23710 ufunc_T *p1, *p2; 23711 23712 p1 = *(ufunc_T **)s1; 23713 p2 = *(ufunc_T **)s2; 23714 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 23715 } 23716 23717 #endif 23718 23719 /* 23720 * If "name" has a package name try autoloading the script for it. 23721 * Return TRUE if a package was loaded. 23722 */ 23723 static int 23724 script_autoload(name, reload) 23725 char_u *name; 23726 int reload; /* load script again when already loaded */ 23727 { 23728 char_u *p; 23729 char_u *scriptname, *tofree; 23730 int ret = FALSE; 23731 int i; 23732 23733 /* If there is no '#' after name[0] there is no package name. */ 23734 p = vim_strchr(name, AUTOLOAD_CHAR); 23735 if (p == NULL || p == name) 23736 return FALSE; 23737 23738 tofree = scriptname = autoload_name(name); 23739 23740 /* Find the name in the list of previously loaded package names. Skip 23741 * "autoload/", it's always the same. */ 23742 for (i = 0; i < ga_loaded.ga_len; ++i) 23743 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 23744 break; 23745 if (!reload && i < ga_loaded.ga_len) 23746 ret = FALSE; /* was loaded already */ 23747 else 23748 { 23749 /* Remember the name if it wasn't loaded already. */ 23750 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 23751 { 23752 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 23753 tofree = NULL; 23754 } 23755 23756 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 23757 if (source_runtime(scriptname, FALSE) == OK) 23758 ret = TRUE; 23759 } 23760 23761 vim_free(tofree); 23762 return ret; 23763 } 23764 23765 /* 23766 * Return the autoload script name for a function or variable name. 23767 * Returns NULL when out of memory. 23768 */ 23769 static char_u * 23770 autoload_name(name) 23771 char_u *name; 23772 { 23773 char_u *p; 23774 char_u *scriptname; 23775 23776 /* Get the script file name: replace '#' with '/', append ".vim". */ 23777 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 23778 if (scriptname == NULL) 23779 return FALSE; 23780 STRCPY(scriptname, "autoload/"); 23781 STRCAT(scriptname, name); 23782 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 23783 STRCAT(scriptname, ".vim"); 23784 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 23785 *p = '/'; 23786 return scriptname; 23787 } 23788 23789 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 23790 23791 /* 23792 * Function given to ExpandGeneric() to obtain the list of user defined 23793 * function names. 23794 */ 23795 char_u * 23796 get_user_func_name(xp, idx) 23797 expand_T *xp; 23798 int idx; 23799 { 23800 static long_u done; 23801 static hashitem_T *hi; 23802 ufunc_T *fp; 23803 23804 if (idx == 0) 23805 { 23806 done = 0; 23807 hi = func_hashtab.ht_array; 23808 } 23809 if (done < func_hashtab.ht_used) 23810 { 23811 if (done++ > 0) 23812 ++hi; 23813 while (HASHITEM_EMPTY(hi)) 23814 ++hi; 23815 fp = HI2UF(hi); 23816 23817 if (fp->uf_flags & FC_DICT) 23818 return (char_u *)""; /* don't show dict functions */ 23819 23820 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 23821 return fp->uf_name; /* prevents overflow */ 23822 23823 cat_func_name(IObuff, fp); 23824 if (xp->xp_context != EXPAND_USER_FUNC) 23825 { 23826 STRCAT(IObuff, "("); 23827 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 23828 STRCAT(IObuff, ")"); 23829 } 23830 return IObuff; 23831 } 23832 return NULL; 23833 } 23834 23835 #endif /* FEAT_CMDL_COMPL */ 23836 23837 /* 23838 * Copy the function name of "fp" to buffer "buf". 23839 * "buf" must be able to hold the function name plus three bytes. 23840 * Takes care of script-local function names. 23841 */ 23842 static void 23843 cat_func_name(buf, fp) 23844 char_u *buf; 23845 ufunc_T *fp; 23846 { 23847 if (fp->uf_name[0] == K_SPECIAL) 23848 { 23849 STRCPY(buf, "<SNR>"); 23850 STRCAT(buf, fp->uf_name + 3); 23851 } 23852 else 23853 STRCPY(buf, fp->uf_name); 23854 } 23855 23856 /* 23857 * ":delfunction {name}" 23858 */ 23859 void 23860 ex_delfunction(eap) 23861 exarg_T *eap; 23862 { 23863 ufunc_T *fp = NULL; 23864 char_u *p; 23865 char_u *name; 23866 funcdict_T fudi; 23867 23868 p = eap->arg; 23869 name = trans_function_name(&p, eap->skip, 0, &fudi); 23870 vim_free(fudi.fd_newkey); 23871 if (name == NULL) 23872 { 23873 if (fudi.fd_dict != NULL && !eap->skip) 23874 EMSG(_(e_funcref)); 23875 return; 23876 } 23877 if (!ends_excmd(*skipwhite(p))) 23878 { 23879 vim_free(name); 23880 EMSG(_(e_trailing)); 23881 return; 23882 } 23883 eap->nextcmd = check_nextcmd(p); 23884 if (eap->nextcmd != NULL) 23885 *p = NUL; 23886 23887 if (!eap->skip) 23888 fp = find_func(name); 23889 vim_free(name); 23890 23891 if (!eap->skip) 23892 { 23893 if (fp == NULL) 23894 { 23895 EMSG2(_(e_nofunc), eap->arg); 23896 return; 23897 } 23898 if (fp->uf_calls > 0) 23899 { 23900 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 23901 return; 23902 } 23903 23904 if (fudi.fd_dict != NULL) 23905 { 23906 /* Delete the dict item that refers to the function, it will 23907 * invoke func_unref() and possibly delete the function. */ 23908 dictitem_remove(fudi.fd_dict, fudi.fd_di); 23909 } 23910 else 23911 func_free(fp); 23912 } 23913 } 23914 23915 /* 23916 * Free a function and remove it from the list of functions. 23917 */ 23918 static void 23919 func_free(fp) 23920 ufunc_T *fp; 23921 { 23922 hashitem_T *hi; 23923 23924 /* clear this function */ 23925 ga_clear_strings(&(fp->uf_args)); 23926 ga_clear_strings(&(fp->uf_lines)); 23927 #ifdef FEAT_PROFILE 23928 vim_free(fp->uf_tml_count); 23929 vim_free(fp->uf_tml_total); 23930 vim_free(fp->uf_tml_self); 23931 #endif 23932 23933 /* remove the function from the function hashtable */ 23934 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 23935 if (HASHITEM_EMPTY(hi)) 23936 EMSG2(_(e_intern2), "func_free()"); 23937 else 23938 hash_remove(&func_hashtab, hi); 23939 23940 vim_free(fp); 23941 } 23942 23943 /* 23944 * Unreference a Function: decrement the reference count and free it when it 23945 * becomes zero. Only for numbered functions. 23946 */ 23947 void 23948 func_unref(name) 23949 char_u *name; 23950 { 23951 ufunc_T *fp; 23952 23953 if (name != NULL && isdigit(*name)) 23954 { 23955 fp = find_func(name); 23956 if (fp == NULL) 23957 EMSG2(_(e_intern2), "func_unref()"); 23958 else if (--fp->uf_refcount <= 0) 23959 { 23960 /* Only delete it when it's not being used. Otherwise it's done 23961 * when "uf_calls" becomes zero. */ 23962 if (fp->uf_calls == 0) 23963 func_free(fp); 23964 } 23965 } 23966 } 23967 23968 /* 23969 * Count a reference to a Function. 23970 */ 23971 void 23972 func_ref(name) 23973 char_u *name; 23974 { 23975 ufunc_T *fp; 23976 23977 if (name != NULL && isdigit(*name)) 23978 { 23979 fp = find_func(name); 23980 if (fp == NULL) 23981 EMSG2(_(e_intern2), "func_ref()"); 23982 else 23983 ++fp->uf_refcount; 23984 } 23985 } 23986 23987 /* 23988 * Call a user function. 23989 */ 23990 static void 23991 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 23992 ufunc_T *fp; /* pointer to function */ 23993 int argcount; /* nr of args */ 23994 typval_T *argvars; /* arguments */ 23995 typval_T *rettv; /* return value */ 23996 linenr_T firstline; /* first line of range */ 23997 linenr_T lastline; /* last line of range */ 23998 dict_T *selfdict; /* Dictionary for "self" */ 23999 { 24000 char_u *save_sourcing_name; 24001 linenr_T save_sourcing_lnum; 24002 scid_T save_current_SID; 24003 funccall_T *fc; 24004 int save_did_emsg; 24005 static int depth = 0; 24006 dictitem_T *v; 24007 int fixvar_idx = 0; /* index in fixvar[] */ 24008 int i; 24009 int ai; 24010 char_u numbuf[NUMBUFLEN]; 24011 char_u *name; 24012 size_t len; 24013 #ifdef FEAT_PROFILE 24014 proftime_T wait_start; 24015 proftime_T call_start; 24016 #endif 24017 24018 /* If depth of calling is getting too high, don't execute the function */ 24019 if (depth >= p_mfd) 24020 { 24021 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 24022 rettv->v_type = VAR_NUMBER; 24023 rettv->vval.v_number = -1; 24024 return; 24025 } 24026 ++depth; 24027 24028 line_breakcheck(); /* check for CTRL-C hit */ 24029 24030 fc = (funccall_T *)alloc(sizeof(funccall_T)); 24031 fc->caller = current_funccal; 24032 current_funccal = fc; 24033 fc->func = fp; 24034 fc->rettv = rettv; 24035 rettv->vval.v_number = 0; 24036 fc->linenr = 0; 24037 fc->returned = FALSE; 24038 fc->level = ex_nesting_level; 24039 /* Check if this function has a breakpoint. */ 24040 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 24041 fc->dbg_tick = debug_tick; 24042 24043 /* 24044 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 24045 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 24046 * each argument variable and saves a lot of time. 24047 */ 24048 /* 24049 * Init l: variables. 24050 */ 24051 init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE); 24052 if (selfdict != NULL) 24053 { 24054 /* Set l:self to "selfdict". Use "name" to avoid a warning from 24055 * some compiler that checks the destination size. */ 24056 v = &fc->fixvar[fixvar_idx++].var; 24057 name = v->di_key; 24058 STRCPY(name, "self"); 24059 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 24060 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 24061 v->di_tv.v_type = VAR_DICT; 24062 v->di_tv.v_lock = 0; 24063 v->di_tv.vval.v_dict = selfdict; 24064 ++selfdict->dv_refcount; 24065 } 24066 24067 /* 24068 * Init a: variables. 24069 * Set a:0 to "argcount". 24070 * Set a:000 to a list with room for the "..." arguments. 24071 */ 24072 init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE); 24073 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 24074 (varnumber_T)(argcount - fp->uf_args.ga_len)); 24075 /* Use "name" to avoid a warning from some compiler that checks the 24076 * destination size. */ 24077 v = &fc->fixvar[fixvar_idx++].var; 24078 name = v->di_key; 24079 STRCPY(name, "000"); 24080 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24081 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 24082 v->di_tv.v_type = VAR_LIST; 24083 v->di_tv.v_lock = VAR_FIXED; 24084 v->di_tv.vval.v_list = &fc->l_varlist; 24085 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 24086 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 24087 fc->l_varlist.lv_lock = VAR_FIXED; 24088 24089 /* 24090 * Set a:firstline to "firstline" and a:lastline to "lastline". 24091 * Set a:name to named arguments. 24092 * Set a:N to the "..." arguments. 24093 */ 24094 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 24095 (varnumber_T)firstline); 24096 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 24097 (varnumber_T)lastline); 24098 for (i = 0; i < argcount; ++i) 24099 { 24100 ai = i - fp->uf_args.ga_len; 24101 if (ai < 0) 24102 /* named argument a:name */ 24103 name = FUNCARG(fp, i); 24104 else 24105 { 24106 /* "..." argument a:1, a:2, etc. */ 24107 sprintf((char *)numbuf, "%d", ai + 1); 24108 name = numbuf; 24109 } 24110 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 24111 { 24112 v = &fc->fixvar[fixvar_idx++].var; 24113 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24114 } 24115 else 24116 { 24117 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 24118 + STRLEN(name))); 24119 if (v == NULL) 24120 break; 24121 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC; 24122 } 24123 STRCPY(v->di_key, name); 24124 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 24125 24126 /* Note: the values are copied directly to avoid alloc/free. 24127 * "argvars" must have VAR_FIXED for v_lock. */ 24128 v->di_tv = argvars[i]; 24129 v->di_tv.v_lock = VAR_FIXED; 24130 24131 if (ai >= 0 && ai < MAX_FUNC_ARGS) 24132 { 24133 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 24134 fc->l_listitems[ai].li_tv = argvars[i]; 24135 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 24136 } 24137 } 24138 24139 /* Don't redraw while executing the function. */ 24140 ++RedrawingDisabled; 24141 save_sourcing_name = sourcing_name; 24142 save_sourcing_lnum = sourcing_lnum; 24143 sourcing_lnum = 1; 24144 /* need space for function name + ("function " + 3) or "[number]" */ 24145 len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name)) 24146 + STRLEN(fp->uf_name) + 20; 24147 sourcing_name = alloc((unsigned)len); 24148 if (sourcing_name != NULL) 24149 { 24150 if (save_sourcing_name != NULL 24151 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 24152 sprintf((char *)sourcing_name, "%s[%d]..", 24153 save_sourcing_name, (int)save_sourcing_lnum); 24154 else 24155 STRCPY(sourcing_name, "function "); 24156 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 24157 24158 if (p_verbose >= 12) 24159 { 24160 ++no_wait_return; 24161 verbose_enter_scroll(); 24162 24163 smsg((char_u *)_("calling %s"), sourcing_name); 24164 if (p_verbose >= 14) 24165 { 24166 char_u buf[MSG_BUF_LEN]; 24167 char_u numbuf2[NUMBUFLEN]; 24168 char_u *tofree; 24169 char_u *s; 24170 24171 msg_puts((char_u *)"("); 24172 for (i = 0; i < argcount; ++i) 24173 { 24174 if (i > 0) 24175 msg_puts((char_u *)", "); 24176 if (argvars[i].v_type == VAR_NUMBER) 24177 msg_outnum((long)argvars[i].vval.v_number); 24178 else 24179 { 24180 /* Do not want errors such as E724 here. */ 24181 ++emsg_off; 24182 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 24183 --emsg_off; 24184 if (s != NULL) 24185 { 24186 if (vim_strsize(s) > MSG_BUF_CLEN) 24187 { 24188 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); 24189 s = buf; 24190 } 24191 msg_puts(s); 24192 vim_free(tofree); 24193 } 24194 } 24195 } 24196 msg_puts((char_u *)")"); 24197 } 24198 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 24199 24200 verbose_leave_scroll(); 24201 --no_wait_return; 24202 } 24203 } 24204 #ifdef FEAT_PROFILE 24205 if (do_profiling == PROF_YES) 24206 { 24207 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 24208 func_do_profile(fp); 24209 if (fp->uf_profiling 24210 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 24211 { 24212 ++fp->uf_tm_count; 24213 profile_start(&call_start); 24214 profile_zero(&fp->uf_tm_children); 24215 } 24216 script_prof_save(&wait_start); 24217 } 24218 #endif 24219 24220 save_current_SID = current_SID; 24221 current_SID = fp->uf_script_ID; 24222 save_did_emsg = did_emsg; 24223 did_emsg = FALSE; 24224 24225 /* call do_cmdline() to execute the lines */ 24226 do_cmdline(NULL, get_func_line, (void *)fc, 24227 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 24228 24229 --RedrawingDisabled; 24230 24231 /* when the function was aborted because of an error, return -1 */ 24232 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 24233 { 24234 clear_tv(rettv); 24235 rettv->v_type = VAR_NUMBER; 24236 rettv->vval.v_number = -1; 24237 } 24238 24239 #ifdef FEAT_PROFILE 24240 if (do_profiling == PROF_YES && (fp->uf_profiling 24241 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 24242 { 24243 profile_end(&call_start); 24244 profile_sub_wait(&wait_start, &call_start); 24245 profile_add(&fp->uf_tm_total, &call_start); 24246 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 24247 if (fc->caller != NULL && fc->caller->func->uf_profiling) 24248 { 24249 profile_add(&fc->caller->func->uf_tm_children, &call_start); 24250 profile_add(&fc->caller->func->uf_tml_children, &call_start); 24251 } 24252 } 24253 #endif 24254 24255 /* when being verbose, mention the return value */ 24256 if (p_verbose >= 12) 24257 { 24258 ++no_wait_return; 24259 verbose_enter_scroll(); 24260 24261 if (aborting()) 24262 smsg((char_u *)_("%s aborted"), sourcing_name); 24263 else if (fc->rettv->v_type == VAR_NUMBER) 24264 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 24265 (long)fc->rettv->vval.v_number); 24266 else 24267 { 24268 char_u buf[MSG_BUF_LEN]; 24269 char_u numbuf2[NUMBUFLEN]; 24270 char_u *tofree; 24271 char_u *s; 24272 24273 /* The value may be very long. Skip the middle part, so that we 24274 * have some idea how it starts and ends. smsg() would always 24275 * truncate it at the end. Don't want errors such as E724 here. */ 24276 ++emsg_off; 24277 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 24278 --emsg_off; 24279 if (s != NULL) 24280 { 24281 if (vim_strsize(s) > MSG_BUF_CLEN) 24282 { 24283 trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); 24284 s = buf; 24285 } 24286 smsg((char_u *)_("%s returning %s"), sourcing_name, s); 24287 vim_free(tofree); 24288 } 24289 } 24290 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 24291 24292 verbose_leave_scroll(); 24293 --no_wait_return; 24294 } 24295 24296 vim_free(sourcing_name); 24297 sourcing_name = save_sourcing_name; 24298 sourcing_lnum = save_sourcing_lnum; 24299 current_SID = save_current_SID; 24300 #ifdef FEAT_PROFILE 24301 if (do_profiling == PROF_YES) 24302 script_prof_restore(&wait_start); 24303 #endif 24304 24305 if (p_verbose >= 12 && sourcing_name != NULL) 24306 { 24307 ++no_wait_return; 24308 verbose_enter_scroll(); 24309 24310 smsg((char_u *)_("continuing in %s"), sourcing_name); 24311 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 24312 24313 verbose_leave_scroll(); 24314 --no_wait_return; 24315 } 24316 24317 did_emsg |= save_did_emsg; 24318 current_funccal = fc->caller; 24319 --depth; 24320 24321 /* If the a:000 list and the l: and a: dicts are not referenced we can 24322 * free the funccall_T and what's in it. */ 24323 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 24324 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 24325 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 24326 { 24327 free_funccal(fc, FALSE); 24328 } 24329 else 24330 { 24331 hashitem_T *hi; 24332 listitem_T *li; 24333 int todo; 24334 24335 /* "fc" is still in use. This can happen when returning "a:000" or 24336 * assigning "l:" to a global variable. 24337 * Link "fc" in the list for garbage collection later. */ 24338 fc->caller = previous_funccal; 24339 previous_funccal = fc; 24340 24341 /* Make a copy of the a: variables, since we didn't do that above. */ 24342 todo = (int)fc->l_avars.dv_hashtab.ht_used; 24343 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 24344 { 24345 if (!HASHITEM_EMPTY(hi)) 24346 { 24347 --todo; 24348 v = HI2DI(hi); 24349 copy_tv(&v->di_tv, &v->di_tv); 24350 } 24351 } 24352 24353 /* Make a copy of the a:000 items, since we didn't do that above. */ 24354 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 24355 copy_tv(&li->li_tv, &li->li_tv); 24356 } 24357 } 24358 24359 /* 24360 * Return TRUE if items in "fc" do not have "copyID". That means they are not 24361 * referenced from anywhere that is in use. 24362 */ 24363 static int 24364 can_free_funccal(fc, copyID) 24365 funccall_T *fc; 24366 int copyID; 24367 { 24368 return (fc->l_varlist.lv_copyID != copyID 24369 && fc->l_vars.dv_copyID != copyID 24370 && fc->l_avars.dv_copyID != copyID); 24371 } 24372 24373 /* 24374 * Free "fc" and what it contains. 24375 */ 24376 static void 24377 free_funccal(fc, free_val) 24378 funccall_T *fc; 24379 int free_val; /* a: vars were allocated */ 24380 { 24381 listitem_T *li; 24382 24383 /* The a: variables typevals may not have been allocated, only free the 24384 * allocated variables. */ 24385 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 24386 24387 /* free all l: variables */ 24388 vars_clear(&fc->l_vars.dv_hashtab); 24389 24390 /* Free the a:000 variables if they were allocated. */ 24391 if (free_val) 24392 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 24393 clear_tv(&li->li_tv); 24394 24395 vim_free(fc); 24396 } 24397 24398 /* 24399 * Add a number variable "name" to dict "dp" with value "nr". 24400 */ 24401 static void 24402 add_nr_var(dp, v, name, nr) 24403 dict_T *dp; 24404 dictitem_T *v; 24405 char *name; 24406 varnumber_T nr; 24407 { 24408 STRCPY(v->di_key, name); 24409 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 24410 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 24411 v->di_tv.v_type = VAR_NUMBER; 24412 v->di_tv.v_lock = VAR_FIXED; 24413 v->di_tv.vval.v_number = nr; 24414 } 24415 24416 /* 24417 * ":return [expr]" 24418 */ 24419 void 24420 ex_return(eap) 24421 exarg_T *eap; 24422 { 24423 char_u *arg = eap->arg; 24424 typval_T rettv; 24425 int returning = FALSE; 24426 24427 if (current_funccal == NULL) 24428 { 24429 EMSG(_("E133: :return not inside a function")); 24430 return; 24431 } 24432 24433 if (eap->skip) 24434 ++emsg_skip; 24435 24436 eap->nextcmd = NULL; 24437 if ((*arg != NUL && *arg != '|' && *arg != '\n') 24438 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 24439 { 24440 if (!eap->skip) 24441 returning = do_return(eap, FALSE, TRUE, &rettv); 24442 else 24443 clear_tv(&rettv); 24444 } 24445 /* It's safer to return also on error. */ 24446 else if (!eap->skip) 24447 { 24448 /* 24449 * Return unless the expression evaluation has been cancelled due to an 24450 * aborting error, an interrupt, or an exception. 24451 */ 24452 if (!aborting()) 24453 returning = do_return(eap, FALSE, TRUE, NULL); 24454 } 24455 24456 /* When skipping or the return gets pending, advance to the next command 24457 * in this line (!returning). Otherwise, ignore the rest of the line. 24458 * Following lines will be ignored by get_func_line(). */ 24459 if (returning) 24460 eap->nextcmd = NULL; 24461 else if (eap->nextcmd == NULL) /* no argument */ 24462 eap->nextcmd = check_nextcmd(arg); 24463 24464 if (eap->skip) 24465 --emsg_skip; 24466 } 24467 24468 /* 24469 * Return from a function. Possibly makes the return pending. Also called 24470 * for a pending return at the ":endtry" or after returning from an extra 24471 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 24472 * when called due to a ":return" command. "rettv" may point to a typval_T 24473 * with the return rettv. Returns TRUE when the return can be carried out, 24474 * FALSE when the return gets pending. 24475 */ 24476 int 24477 do_return(eap, reanimate, is_cmd, rettv) 24478 exarg_T *eap; 24479 int reanimate; 24480 int is_cmd; 24481 void *rettv; 24482 { 24483 int idx; 24484 struct condstack *cstack = eap->cstack; 24485 24486 if (reanimate) 24487 /* Undo the return. */ 24488 current_funccal->returned = FALSE; 24489 24490 /* 24491 * Cleanup (and inactivate) conditionals, but stop when a try conditional 24492 * not in its finally clause (which then is to be executed next) is found. 24493 * In this case, make the ":return" pending for execution at the ":endtry". 24494 * Otherwise, return normally. 24495 */ 24496 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 24497 if (idx >= 0) 24498 { 24499 cstack->cs_pending[idx] = CSTP_RETURN; 24500 24501 if (!is_cmd && !reanimate) 24502 /* A pending return again gets pending. "rettv" points to an 24503 * allocated variable with the rettv of the original ":return"'s 24504 * argument if present or is NULL else. */ 24505 cstack->cs_rettv[idx] = rettv; 24506 else 24507 { 24508 /* When undoing a return in order to make it pending, get the stored 24509 * return rettv. */ 24510 if (reanimate) 24511 rettv = current_funccal->rettv; 24512 24513 if (rettv != NULL) 24514 { 24515 /* Store the value of the pending return. */ 24516 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 24517 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 24518 else 24519 EMSG(_(e_outofmem)); 24520 } 24521 else 24522 cstack->cs_rettv[idx] = NULL; 24523 24524 if (reanimate) 24525 { 24526 /* The pending return value could be overwritten by a ":return" 24527 * without argument in a finally clause; reset the default 24528 * return value. */ 24529 current_funccal->rettv->v_type = VAR_NUMBER; 24530 current_funccal->rettv->vval.v_number = 0; 24531 } 24532 } 24533 report_make_pending(CSTP_RETURN, rettv); 24534 } 24535 else 24536 { 24537 current_funccal->returned = TRUE; 24538 24539 /* If the return is carried out now, store the return value. For 24540 * a return immediately after reanimation, the value is already 24541 * there. */ 24542 if (!reanimate && rettv != NULL) 24543 { 24544 clear_tv(current_funccal->rettv); 24545 *current_funccal->rettv = *(typval_T *)rettv; 24546 if (!is_cmd) 24547 vim_free(rettv); 24548 } 24549 } 24550 24551 return idx < 0; 24552 } 24553 24554 /* 24555 * Free the variable with a pending return value. 24556 */ 24557 void 24558 discard_pending_return(rettv) 24559 void *rettv; 24560 { 24561 free_tv((typval_T *)rettv); 24562 } 24563 24564 /* 24565 * Generate a return command for producing the value of "rettv". The result 24566 * is an allocated string. Used by report_pending() for verbose messages. 24567 */ 24568 char_u * 24569 get_return_cmd(rettv) 24570 void *rettv; 24571 { 24572 char_u *s = NULL; 24573 char_u *tofree = NULL; 24574 char_u numbuf[NUMBUFLEN]; 24575 24576 if (rettv != NULL) 24577 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 24578 if (s == NULL) 24579 s = (char_u *)""; 24580 24581 STRCPY(IObuff, ":return "); 24582 STRNCPY(IObuff + 8, s, IOSIZE - 8); 24583 if (STRLEN(s) + 8 >= IOSIZE) 24584 STRCPY(IObuff + IOSIZE - 4, "..."); 24585 vim_free(tofree); 24586 return vim_strsave(IObuff); 24587 } 24588 24589 /* 24590 * Get next function line. 24591 * Called by do_cmdline() to get the next line. 24592 * Returns allocated string, or NULL for end of function. 24593 */ 24594 char_u * 24595 get_func_line(c, cookie, indent) 24596 int c UNUSED; 24597 void *cookie; 24598 int indent UNUSED; 24599 { 24600 funccall_T *fcp = (funccall_T *)cookie; 24601 ufunc_T *fp = fcp->func; 24602 char_u *retval; 24603 garray_T *gap; /* growarray with function lines */ 24604 24605 /* If breakpoints have been added/deleted need to check for it. */ 24606 if (fcp->dbg_tick != debug_tick) 24607 { 24608 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 24609 sourcing_lnum); 24610 fcp->dbg_tick = debug_tick; 24611 } 24612 #ifdef FEAT_PROFILE 24613 if (do_profiling == PROF_YES) 24614 func_line_end(cookie); 24615 #endif 24616 24617 gap = &fp->uf_lines; 24618 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 24619 || fcp->returned) 24620 retval = NULL; 24621 else 24622 { 24623 /* Skip NULL lines (continuation lines). */ 24624 while (fcp->linenr < gap->ga_len 24625 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 24626 ++fcp->linenr; 24627 if (fcp->linenr >= gap->ga_len) 24628 retval = NULL; 24629 else 24630 { 24631 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 24632 sourcing_lnum = fcp->linenr; 24633 #ifdef FEAT_PROFILE 24634 if (do_profiling == PROF_YES) 24635 func_line_start(cookie); 24636 #endif 24637 } 24638 } 24639 24640 /* Did we encounter a breakpoint? */ 24641 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 24642 { 24643 dbg_breakpoint(fp->uf_name, sourcing_lnum); 24644 /* Find next breakpoint. */ 24645 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 24646 sourcing_lnum); 24647 fcp->dbg_tick = debug_tick; 24648 } 24649 24650 return retval; 24651 } 24652 24653 #if defined(FEAT_PROFILE) || defined(PROTO) 24654 /* 24655 * Called when starting to read a function line. 24656 * "sourcing_lnum" must be correct! 24657 * When skipping lines it may not actually be executed, but we won't find out 24658 * until later and we need to store the time now. 24659 */ 24660 void 24661 func_line_start(cookie) 24662 void *cookie; 24663 { 24664 funccall_T *fcp = (funccall_T *)cookie; 24665 ufunc_T *fp = fcp->func; 24666 24667 if (fp->uf_profiling && sourcing_lnum >= 1 24668 && sourcing_lnum <= fp->uf_lines.ga_len) 24669 { 24670 fp->uf_tml_idx = sourcing_lnum - 1; 24671 /* Skip continuation lines. */ 24672 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 24673 --fp->uf_tml_idx; 24674 fp->uf_tml_execed = FALSE; 24675 profile_start(&fp->uf_tml_start); 24676 profile_zero(&fp->uf_tml_children); 24677 profile_get_wait(&fp->uf_tml_wait); 24678 } 24679 } 24680 24681 /* 24682 * Called when actually executing a function line. 24683 */ 24684 void 24685 func_line_exec(cookie) 24686 void *cookie; 24687 { 24688 funccall_T *fcp = (funccall_T *)cookie; 24689 ufunc_T *fp = fcp->func; 24690 24691 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 24692 fp->uf_tml_execed = TRUE; 24693 } 24694 24695 /* 24696 * Called when done with a function line. 24697 */ 24698 void 24699 func_line_end(cookie) 24700 void *cookie; 24701 { 24702 funccall_T *fcp = (funccall_T *)cookie; 24703 ufunc_T *fp = fcp->func; 24704 24705 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 24706 { 24707 if (fp->uf_tml_execed) 24708 { 24709 ++fp->uf_tml_count[fp->uf_tml_idx]; 24710 profile_end(&fp->uf_tml_start); 24711 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 24712 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 24713 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 24714 &fp->uf_tml_children); 24715 } 24716 fp->uf_tml_idx = -1; 24717 } 24718 } 24719 #endif 24720 24721 /* 24722 * Return TRUE if the currently active function should be ended, because a 24723 * return was encountered or an error occurred. Used inside a ":while". 24724 */ 24725 int 24726 func_has_ended(cookie) 24727 void *cookie; 24728 { 24729 funccall_T *fcp = (funccall_T *)cookie; 24730 24731 /* Ignore the "abort" flag if the abortion behavior has been changed due to 24732 * an error inside a try conditional. */ 24733 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 24734 || fcp->returned); 24735 } 24736 24737 /* 24738 * return TRUE if cookie indicates a function which "abort"s on errors. 24739 */ 24740 int 24741 func_has_abort(cookie) 24742 void *cookie; 24743 { 24744 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 24745 } 24746 24747 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 24748 typedef enum 24749 { 24750 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 24751 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 24752 VAR_FLAVOUR_VIMINFO /* all uppercase */ 24753 } var_flavour_T; 24754 24755 static var_flavour_T var_flavour __ARGS((char_u *varname)); 24756 24757 static var_flavour_T 24758 var_flavour(varname) 24759 char_u *varname; 24760 { 24761 char_u *p = varname; 24762 24763 if (ASCII_ISUPPER(*p)) 24764 { 24765 while (*(++p)) 24766 if (ASCII_ISLOWER(*p)) 24767 return VAR_FLAVOUR_SESSION; 24768 return VAR_FLAVOUR_VIMINFO; 24769 } 24770 else 24771 return VAR_FLAVOUR_DEFAULT; 24772 } 24773 #endif 24774 24775 #if defined(FEAT_VIMINFO) || defined(PROTO) 24776 /* 24777 * Restore global vars that start with a capital from the viminfo file 24778 */ 24779 int 24780 read_viminfo_varlist(virp, writing) 24781 vir_T *virp; 24782 int writing; 24783 { 24784 char_u *tab; 24785 int type = VAR_NUMBER; 24786 typval_T tv; 24787 24788 if (!writing && (find_viminfo_parameter('!') != NULL)) 24789 { 24790 tab = vim_strchr(virp->vir_line + 1, '\t'); 24791 if (tab != NULL) 24792 { 24793 *tab++ = '\0'; /* isolate the variable name */ 24794 switch (*tab) 24795 { 24796 case 'S': type = VAR_STRING; break; 24797 #ifdef FEAT_FLOAT 24798 case 'F': type = VAR_FLOAT; break; 24799 #endif 24800 case 'D': type = VAR_DICT; break; 24801 case 'L': type = VAR_LIST; break; 24802 } 24803 24804 tab = vim_strchr(tab, '\t'); 24805 if (tab != NULL) 24806 { 24807 tv.v_type = type; 24808 if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST) 24809 tv.vval.v_string = viminfo_readstring(virp, 24810 (int)(tab - virp->vir_line + 1), TRUE); 24811 #ifdef FEAT_FLOAT 24812 else if (type == VAR_FLOAT) 24813 (void)string2float(tab + 1, &tv.vval.v_float); 24814 #endif 24815 else 24816 tv.vval.v_number = atol((char *)tab + 1); 24817 if (type == VAR_DICT || type == VAR_LIST) 24818 { 24819 typval_T *etv = eval_expr(tv.vval.v_string, NULL); 24820 24821 if (etv == NULL) 24822 /* Failed to parse back the dict or list, use it as a 24823 * string. */ 24824 tv.v_type = VAR_STRING; 24825 else 24826 { 24827 vim_free(tv.vval.v_string); 24828 tv = *etv; 24829 vim_free(etv); 24830 } 24831 } 24832 24833 set_var(virp->vir_line + 1, &tv, FALSE); 24834 24835 if (tv.v_type == VAR_STRING) 24836 vim_free(tv.vval.v_string); 24837 else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST) 24838 clear_tv(&tv); 24839 } 24840 } 24841 } 24842 24843 return viminfo_readline(virp); 24844 } 24845 24846 /* 24847 * Write global vars that start with a capital to the viminfo file 24848 */ 24849 void 24850 write_viminfo_varlist(fp) 24851 FILE *fp; 24852 { 24853 hashitem_T *hi; 24854 dictitem_T *this_var; 24855 int todo; 24856 char *s; 24857 char_u *p; 24858 char_u *tofree; 24859 char_u numbuf[NUMBUFLEN]; 24860 24861 if (find_viminfo_parameter('!') == NULL) 24862 return; 24863 24864 fputs(_("\n# global variables:\n"), fp); 24865 24866 todo = (int)globvarht.ht_used; 24867 for (hi = globvarht.ht_array; todo > 0; ++hi) 24868 { 24869 if (!HASHITEM_EMPTY(hi)) 24870 { 24871 --todo; 24872 this_var = HI2DI(hi); 24873 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 24874 { 24875 switch (this_var->di_tv.v_type) 24876 { 24877 case VAR_STRING: s = "STR"; break; 24878 case VAR_NUMBER: s = "NUM"; break; 24879 #ifdef FEAT_FLOAT 24880 case VAR_FLOAT: s = "FLO"; break; 24881 #endif 24882 case VAR_DICT: s = "DIC"; break; 24883 case VAR_LIST: s = "LIS"; break; 24884 default: continue; 24885 } 24886 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 24887 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 24888 if (p != NULL) 24889 viminfo_writestring(fp, p); 24890 vim_free(tofree); 24891 } 24892 } 24893 } 24894 } 24895 #endif 24896 24897 #if defined(FEAT_SESSION) || defined(PROTO) 24898 int 24899 store_session_globals(fd) 24900 FILE *fd; 24901 { 24902 hashitem_T *hi; 24903 dictitem_T *this_var; 24904 int todo; 24905 char_u *p, *t; 24906 24907 todo = (int)globvarht.ht_used; 24908 for (hi = globvarht.ht_array; todo > 0; ++hi) 24909 { 24910 if (!HASHITEM_EMPTY(hi)) 24911 { 24912 --todo; 24913 this_var = HI2DI(hi); 24914 if ((this_var->di_tv.v_type == VAR_NUMBER 24915 || this_var->di_tv.v_type == VAR_STRING) 24916 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 24917 { 24918 /* Escape special characters with a backslash. Turn a LF and 24919 * CR into \n and \r. */ 24920 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 24921 (char_u *)"\\\"\n\r"); 24922 if (p == NULL) /* out of memory */ 24923 break; 24924 for (t = p; *t != NUL; ++t) 24925 if (*t == '\n') 24926 *t = 'n'; 24927 else if (*t == '\r') 24928 *t = 'r'; 24929 if ((fprintf(fd, "let %s = %c%s%c", 24930 this_var->di_key, 24931 (this_var->di_tv.v_type == VAR_STRING) ? '"' 24932 : ' ', 24933 p, 24934 (this_var->di_tv.v_type == VAR_STRING) ? '"' 24935 : ' ') < 0) 24936 || put_eol(fd) == FAIL) 24937 { 24938 vim_free(p); 24939 return FAIL; 24940 } 24941 vim_free(p); 24942 } 24943 #ifdef FEAT_FLOAT 24944 else if (this_var->di_tv.v_type == VAR_FLOAT 24945 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 24946 { 24947 float_T f = this_var->di_tv.vval.v_float; 24948 int sign = ' '; 24949 24950 if (f < 0) 24951 { 24952 f = -f; 24953 sign = '-'; 24954 } 24955 if ((fprintf(fd, "let %s = %c%f", 24956 this_var->di_key, sign, f) < 0) 24957 || put_eol(fd) == FAIL) 24958 return FAIL; 24959 } 24960 #endif 24961 } 24962 } 24963 return OK; 24964 } 24965 #endif 24966 24967 /* 24968 * Display script name where an item was last set. 24969 * Should only be invoked when 'verbose' is non-zero. 24970 */ 24971 void 24972 last_set_msg(scriptID) 24973 scid_T scriptID; 24974 { 24975 char_u *p; 24976 24977 if (scriptID != 0) 24978 { 24979 p = home_replace_save(NULL, get_scriptname(scriptID)); 24980 if (p != NULL) 24981 { 24982 verbose_enter(); 24983 MSG_PUTS(_("\n\tLast set from ")); 24984 MSG_PUTS(p); 24985 vim_free(p); 24986 verbose_leave(); 24987 } 24988 } 24989 } 24990 24991 /* 24992 * List v:oldfiles in a nice way. 24993 */ 24994 void 24995 ex_oldfiles(eap) 24996 exarg_T *eap UNUSED; 24997 { 24998 list_T *l = vimvars[VV_OLDFILES].vv_list; 24999 listitem_T *li; 25000 int nr = 0; 25001 25002 if (l == NULL) 25003 msg((char_u *)_("No old files")); 25004 else 25005 { 25006 msg_start(); 25007 msg_scroll = TRUE; 25008 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 25009 { 25010 msg_outnum((long)++nr); 25011 MSG_PUTS(": "); 25012 msg_outtrans(get_tv_string(&li->li_tv)); 25013 msg_putchar('\n'); 25014 out_flush(); /* output one line at a time */ 25015 ui_breakcheck(); 25016 } 25017 /* Assume "got_int" was set to truncate the listing. */ 25018 got_int = FALSE; 25019 25020 #ifdef FEAT_BROWSE_CMD 25021 if (cmdmod.browse) 25022 { 25023 quit_more = FALSE; 25024 nr = prompt_for_number(FALSE); 25025 msg_starthere(); 25026 if (nr > 0) 25027 { 25028 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 25029 (long)nr); 25030 25031 if (p != NULL) 25032 { 25033 p = expand_env_save(p); 25034 eap->arg = p; 25035 eap->cmdidx = CMD_edit; 25036 cmdmod.browse = FALSE; 25037 do_exedit(eap, NULL); 25038 vim_free(p); 25039 } 25040 } 25041 } 25042 #endif 25043 } 25044 } 25045 25046 /* reset v:option_new, v:option_old and v:option_type */ 25047 void 25048 reset_v_option_vars() 25049 { 25050 set_vim_var_string(VV_OPTION_NEW, NULL, -1); 25051 set_vim_var_string(VV_OPTION_OLD, NULL, -1); 25052 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); 25053 } 25054 25055 25056 #endif /* FEAT_EVAL */ 25057 25058 25059 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 25060 25061 #ifdef WIN3264 25062 /* 25063 * Functions for ":8" filename modifier: get 8.3 version of a filename. 25064 */ 25065 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 25066 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 25067 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 25068 25069 /* 25070 * Get the short path (8.3) for the filename in "fnamep". 25071 * Only works for a valid file name. 25072 * When the path gets longer "fnamep" is changed and the allocated buffer 25073 * is put in "bufp". 25074 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 25075 * Returns OK on success, FAIL on failure. 25076 */ 25077 static int 25078 get_short_pathname(fnamep, bufp, fnamelen) 25079 char_u **fnamep; 25080 char_u **bufp; 25081 int *fnamelen; 25082 { 25083 int l, len; 25084 char_u *newbuf; 25085 25086 len = *fnamelen; 25087 l = GetShortPathName(*fnamep, *fnamep, len); 25088 if (l > len - 1) 25089 { 25090 /* If that doesn't work (not enough space), then save the string 25091 * and try again with a new buffer big enough. */ 25092 newbuf = vim_strnsave(*fnamep, l); 25093 if (newbuf == NULL) 25094 return FAIL; 25095 25096 vim_free(*bufp); 25097 *fnamep = *bufp = newbuf; 25098 25099 /* Really should always succeed, as the buffer is big enough. */ 25100 l = GetShortPathName(*fnamep, *fnamep, l+1); 25101 } 25102 25103 *fnamelen = l; 25104 return OK; 25105 } 25106 25107 /* 25108 * Get the short path (8.3) for the filename in "fname". The converted 25109 * path is returned in "bufp". 25110 * 25111 * Some of the directories specified in "fname" may not exist. This function 25112 * will shorten the existing directories at the beginning of the path and then 25113 * append the remaining non-existing path. 25114 * 25115 * fname - Pointer to the filename to shorten. On return, contains the 25116 * pointer to the shortened pathname 25117 * bufp - Pointer to an allocated buffer for the filename. 25118 * fnamelen - Length of the filename pointed to by fname 25119 * 25120 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 25121 */ 25122 static int 25123 shortpath_for_invalid_fname(fname, bufp, fnamelen) 25124 char_u **fname; 25125 char_u **bufp; 25126 int *fnamelen; 25127 { 25128 char_u *short_fname, *save_fname, *pbuf_unused; 25129 char_u *endp, *save_endp; 25130 char_u ch; 25131 int old_len, len; 25132 int new_len, sfx_len; 25133 int retval = OK; 25134 25135 /* Make a copy */ 25136 old_len = *fnamelen; 25137 save_fname = vim_strnsave(*fname, old_len); 25138 pbuf_unused = NULL; 25139 short_fname = NULL; 25140 25141 endp = save_fname + old_len - 1; /* Find the end of the copy */ 25142 save_endp = endp; 25143 25144 /* 25145 * Try shortening the supplied path till it succeeds by removing one 25146 * directory at a time from the tail of the path. 25147 */ 25148 len = 0; 25149 for (;;) 25150 { 25151 /* go back one path-separator */ 25152 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 25153 --endp; 25154 if (endp <= save_fname) 25155 break; /* processed the complete path */ 25156 25157 /* 25158 * Replace the path separator with a NUL and try to shorten the 25159 * resulting path. 25160 */ 25161 ch = *endp; 25162 *endp = 0; 25163 short_fname = save_fname; 25164 len = (int)STRLEN(short_fname) + 1; 25165 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 25166 { 25167 retval = FAIL; 25168 goto theend; 25169 } 25170 *endp = ch; /* preserve the string */ 25171 25172 if (len > 0) 25173 break; /* successfully shortened the path */ 25174 25175 /* failed to shorten the path. Skip the path separator */ 25176 --endp; 25177 } 25178 25179 if (len > 0) 25180 { 25181 /* 25182 * Succeeded in shortening the path. Now concatenate the shortened 25183 * path with the remaining path at the tail. 25184 */ 25185 25186 /* Compute the length of the new path. */ 25187 sfx_len = (int)(save_endp - endp) + 1; 25188 new_len = len + sfx_len; 25189 25190 *fnamelen = new_len; 25191 vim_free(*bufp); 25192 if (new_len > old_len) 25193 { 25194 /* There is not enough space in the currently allocated string, 25195 * copy it to a buffer big enough. */ 25196 *fname = *bufp = vim_strnsave(short_fname, new_len); 25197 if (*fname == NULL) 25198 { 25199 retval = FAIL; 25200 goto theend; 25201 } 25202 } 25203 else 25204 { 25205 /* Transfer short_fname to the main buffer (it's big enough), 25206 * unless get_short_pathname() did its work in-place. */ 25207 *fname = *bufp = save_fname; 25208 if (short_fname != save_fname) 25209 vim_strncpy(save_fname, short_fname, len); 25210 save_fname = NULL; 25211 } 25212 25213 /* concat the not-shortened part of the path */ 25214 vim_strncpy(*fname + len, endp, sfx_len); 25215 (*fname)[new_len] = NUL; 25216 } 25217 25218 theend: 25219 vim_free(pbuf_unused); 25220 vim_free(save_fname); 25221 25222 return retval; 25223 } 25224 25225 /* 25226 * Get a pathname for a partial path. 25227 * Returns OK for success, FAIL for failure. 25228 */ 25229 static int 25230 shortpath_for_partial(fnamep, bufp, fnamelen) 25231 char_u **fnamep; 25232 char_u **bufp; 25233 int *fnamelen; 25234 { 25235 int sepcount, len, tflen; 25236 char_u *p; 25237 char_u *pbuf, *tfname; 25238 int hasTilde; 25239 25240 /* Count up the path separators from the RHS.. so we know which part 25241 * of the path to return. */ 25242 sepcount = 0; 25243 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 25244 if (vim_ispathsep(*p)) 25245 ++sepcount; 25246 25247 /* Need full path first (use expand_env() to remove a "~/") */ 25248 hasTilde = (**fnamep == '~'); 25249 if (hasTilde) 25250 pbuf = tfname = expand_env_save(*fnamep); 25251 else 25252 pbuf = tfname = FullName_save(*fnamep, FALSE); 25253 25254 len = tflen = (int)STRLEN(tfname); 25255 25256 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 25257 return FAIL; 25258 25259 if (len == 0) 25260 { 25261 /* Don't have a valid filename, so shorten the rest of the 25262 * path if we can. This CAN give us invalid 8.3 filenames, but 25263 * there's not a lot of point in guessing what it might be. 25264 */ 25265 len = tflen; 25266 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 25267 return FAIL; 25268 } 25269 25270 /* Count the paths backward to find the beginning of the desired string. */ 25271 for (p = tfname + len - 1; p >= tfname; --p) 25272 { 25273 #ifdef FEAT_MBYTE 25274 if (has_mbyte) 25275 p -= mb_head_off(tfname, p); 25276 #endif 25277 if (vim_ispathsep(*p)) 25278 { 25279 if (sepcount == 0 || (hasTilde && sepcount == 1)) 25280 break; 25281 else 25282 sepcount --; 25283 } 25284 } 25285 if (hasTilde) 25286 { 25287 --p; 25288 if (p >= tfname) 25289 *p = '~'; 25290 else 25291 return FAIL; 25292 } 25293 else 25294 ++p; 25295 25296 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 25297 vim_free(*bufp); 25298 *fnamelen = (int)STRLEN(p); 25299 *bufp = pbuf; 25300 *fnamep = p; 25301 25302 return OK; 25303 } 25304 #endif /* WIN3264 */ 25305 25306 /* 25307 * Adjust a filename, according to a string of modifiers. 25308 * *fnamep must be NUL terminated when called. When returning, the length is 25309 * determined by *fnamelen. 25310 * Returns VALID_ flags or -1 for failure. 25311 * When there is an error, *fnamep is set to NULL. 25312 */ 25313 int 25314 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 25315 char_u *src; /* string with modifiers */ 25316 int *usedlen; /* characters after src that are used */ 25317 char_u **fnamep; /* file name so far */ 25318 char_u **bufp; /* buffer for allocated file name or NULL */ 25319 int *fnamelen; /* length of fnamep */ 25320 { 25321 int valid = 0; 25322 char_u *tail; 25323 char_u *s, *p, *pbuf; 25324 char_u dirname[MAXPATHL]; 25325 int c; 25326 int has_fullname = 0; 25327 #ifdef WIN3264 25328 char_u *fname_start = *fnamep; 25329 int has_shortname = 0; 25330 #endif 25331 25332 repeat: 25333 /* ":p" - full path/file_name */ 25334 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 25335 { 25336 has_fullname = 1; 25337 25338 valid |= VALID_PATH; 25339 *usedlen += 2; 25340 25341 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 25342 if ((*fnamep)[0] == '~' 25343 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 25344 && ((*fnamep)[1] == '/' 25345 # ifdef BACKSLASH_IN_FILENAME 25346 || (*fnamep)[1] == '\\' 25347 # endif 25348 || (*fnamep)[1] == NUL) 25349 25350 #endif 25351 ) 25352 { 25353 *fnamep = expand_env_save(*fnamep); 25354 vim_free(*bufp); /* free any allocated file name */ 25355 *bufp = *fnamep; 25356 if (*fnamep == NULL) 25357 return -1; 25358 } 25359 25360 /* When "/." or "/.." is used: force expansion to get rid of it. */ 25361 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 25362 { 25363 if (vim_ispathsep(*p) 25364 && p[1] == '.' 25365 && (p[2] == NUL 25366 || vim_ispathsep(p[2]) 25367 || (p[2] == '.' 25368 && (p[3] == NUL || vim_ispathsep(p[3]))))) 25369 break; 25370 } 25371 25372 /* FullName_save() is slow, don't use it when not needed. */ 25373 if (*p != NUL || !vim_isAbsName(*fnamep)) 25374 { 25375 *fnamep = FullName_save(*fnamep, *p != NUL); 25376 vim_free(*bufp); /* free any allocated file name */ 25377 *bufp = *fnamep; 25378 if (*fnamep == NULL) 25379 return -1; 25380 } 25381 25382 #ifdef WIN3264 25383 # if _WIN32_WINNT >= 0x0500 25384 if (vim_strchr(*fnamep, '~') != NULL) 25385 { 25386 /* Expand 8.3 filename to full path. Needed to make sure the same 25387 * file does not have two different names. 25388 * Note: problem does not occur if _WIN32_WINNT < 0x0500. */ 25389 p = alloc(_MAX_PATH + 1); 25390 if (p != NULL) 25391 { 25392 if (GetLongPathName(*fnamep, p, _MAX_PATH)) 25393 { 25394 vim_free(*bufp); 25395 *bufp = *fnamep = p; 25396 } 25397 else 25398 vim_free(p); 25399 } 25400 } 25401 # endif 25402 #endif 25403 /* Append a path separator to a directory. */ 25404 if (mch_isdir(*fnamep)) 25405 { 25406 /* Make room for one or two extra characters. */ 25407 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 25408 vim_free(*bufp); /* free any allocated file name */ 25409 *bufp = *fnamep; 25410 if (*fnamep == NULL) 25411 return -1; 25412 add_pathsep(*fnamep); 25413 } 25414 } 25415 25416 /* ":." - path relative to the current directory */ 25417 /* ":~" - path relative to the home directory */ 25418 /* ":8" - shortname path - postponed till after */ 25419 while (src[*usedlen] == ':' 25420 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 25421 { 25422 *usedlen += 2; 25423 if (c == '8') 25424 { 25425 #ifdef WIN3264 25426 has_shortname = 1; /* Postpone this. */ 25427 #endif 25428 continue; 25429 } 25430 pbuf = NULL; 25431 /* Need full path first (use expand_env() to remove a "~/") */ 25432 if (!has_fullname) 25433 { 25434 if (c == '.' && **fnamep == '~') 25435 p = pbuf = expand_env_save(*fnamep); 25436 else 25437 p = pbuf = FullName_save(*fnamep, FALSE); 25438 } 25439 else 25440 p = *fnamep; 25441 25442 has_fullname = 0; 25443 25444 if (p != NULL) 25445 { 25446 if (c == '.') 25447 { 25448 mch_dirname(dirname, MAXPATHL); 25449 s = shorten_fname(p, dirname); 25450 if (s != NULL) 25451 { 25452 *fnamep = s; 25453 if (pbuf != NULL) 25454 { 25455 vim_free(*bufp); /* free any allocated file name */ 25456 *bufp = pbuf; 25457 pbuf = NULL; 25458 } 25459 } 25460 } 25461 else 25462 { 25463 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 25464 /* Only replace it when it starts with '~' */ 25465 if (*dirname == '~') 25466 { 25467 s = vim_strsave(dirname); 25468 if (s != NULL) 25469 { 25470 *fnamep = s; 25471 vim_free(*bufp); 25472 *bufp = s; 25473 } 25474 } 25475 } 25476 vim_free(pbuf); 25477 } 25478 } 25479 25480 tail = gettail(*fnamep); 25481 *fnamelen = (int)STRLEN(*fnamep); 25482 25483 /* ":h" - head, remove "/file_name", can be repeated */ 25484 /* Don't remove the first "/" or "c:\" */ 25485 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 25486 { 25487 valid |= VALID_HEAD; 25488 *usedlen += 2; 25489 s = get_past_head(*fnamep); 25490 while (tail > s && after_pathsep(s, tail)) 25491 mb_ptr_back(*fnamep, tail); 25492 *fnamelen = (int)(tail - *fnamep); 25493 #ifdef VMS 25494 if (*fnamelen > 0) 25495 *fnamelen += 1; /* the path separator is part of the path */ 25496 #endif 25497 if (*fnamelen == 0) 25498 { 25499 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 25500 p = vim_strsave((char_u *)"."); 25501 if (p == NULL) 25502 return -1; 25503 vim_free(*bufp); 25504 *bufp = *fnamep = tail = p; 25505 *fnamelen = 1; 25506 } 25507 else 25508 { 25509 while (tail > s && !after_pathsep(s, tail)) 25510 mb_ptr_back(*fnamep, tail); 25511 } 25512 } 25513 25514 /* ":8" - shortname */ 25515 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 25516 { 25517 *usedlen += 2; 25518 #ifdef WIN3264 25519 has_shortname = 1; 25520 #endif 25521 } 25522 25523 #ifdef WIN3264 25524 /* 25525 * Handle ":8" after we have done 'heads' and before we do 'tails'. 25526 */ 25527 if (has_shortname) 25528 { 25529 /* Copy the string if it is shortened by :h and when it wasn't copied 25530 * yet, because we are going to change it in place. Avoids changing 25531 * the buffer name for "%:8". */ 25532 if (*fnamelen < (int)STRLEN(*fnamep) || *fnamep == fname_start) 25533 { 25534 p = vim_strnsave(*fnamep, *fnamelen); 25535 if (p == NULL) 25536 return -1; 25537 vim_free(*bufp); 25538 *bufp = *fnamep = p; 25539 } 25540 25541 /* Split into two implementations - makes it easier. First is where 25542 * there isn't a full name already, second is where there is. */ 25543 if (!has_fullname && !vim_isAbsName(*fnamep)) 25544 { 25545 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 25546 return -1; 25547 } 25548 else 25549 { 25550 int l = *fnamelen; 25551 25552 /* Simple case, already have the full-name. 25553 * Nearly always shorter, so try first time. */ 25554 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 25555 return -1; 25556 25557 if (l == 0) 25558 { 25559 /* Couldn't find the filename, search the paths. */ 25560 l = *fnamelen; 25561 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 25562 return -1; 25563 } 25564 *fnamelen = l; 25565 } 25566 } 25567 #endif /* WIN3264 */ 25568 25569 /* ":t" - tail, just the basename */ 25570 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 25571 { 25572 *usedlen += 2; 25573 *fnamelen -= (int)(tail - *fnamep); 25574 *fnamep = tail; 25575 } 25576 25577 /* ":e" - extension, can be repeated */ 25578 /* ":r" - root, without extension, can be repeated */ 25579 while (src[*usedlen] == ':' 25580 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 25581 { 25582 /* find a '.' in the tail: 25583 * - for second :e: before the current fname 25584 * - otherwise: The last '.' 25585 */ 25586 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 25587 s = *fnamep - 2; 25588 else 25589 s = *fnamep + *fnamelen - 1; 25590 for ( ; s > tail; --s) 25591 if (s[0] == '.') 25592 break; 25593 if (src[*usedlen + 1] == 'e') /* :e */ 25594 { 25595 if (s > tail) 25596 { 25597 *fnamelen += (int)(*fnamep - (s + 1)); 25598 *fnamep = s + 1; 25599 #ifdef VMS 25600 /* cut version from the extension */ 25601 s = *fnamep + *fnamelen - 1; 25602 for ( ; s > *fnamep; --s) 25603 if (s[0] == ';') 25604 break; 25605 if (s > *fnamep) 25606 *fnamelen = s - *fnamep; 25607 #endif 25608 } 25609 else if (*fnamep <= tail) 25610 *fnamelen = 0; 25611 } 25612 else /* :r */ 25613 { 25614 if (s > tail) /* remove one extension */ 25615 *fnamelen = (int)(s - *fnamep); 25616 } 25617 *usedlen += 2; 25618 } 25619 25620 /* ":s?pat?foo?" - substitute */ 25621 /* ":gs?pat?foo?" - global substitute */ 25622 if (src[*usedlen] == ':' 25623 && (src[*usedlen + 1] == 's' 25624 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 25625 { 25626 char_u *str; 25627 char_u *pat; 25628 char_u *sub; 25629 int sep; 25630 char_u *flags; 25631 int didit = FALSE; 25632 25633 flags = (char_u *)""; 25634 s = src + *usedlen + 2; 25635 if (src[*usedlen + 1] == 'g') 25636 { 25637 flags = (char_u *)"g"; 25638 ++s; 25639 } 25640 25641 sep = *s++; 25642 if (sep) 25643 { 25644 /* find end of pattern */ 25645 p = vim_strchr(s, sep); 25646 if (p != NULL) 25647 { 25648 pat = vim_strnsave(s, (int)(p - s)); 25649 if (pat != NULL) 25650 { 25651 s = p + 1; 25652 /* find end of substitution */ 25653 p = vim_strchr(s, sep); 25654 if (p != NULL) 25655 { 25656 sub = vim_strnsave(s, (int)(p - s)); 25657 str = vim_strnsave(*fnamep, *fnamelen); 25658 if (sub != NULL && str != NULL) 25659 { 25660 *usedlen = (int)(p + 1 - src); 25661 s = do_string_sub(str, pat, sub, flags); 25662 if (s != NULL) 25663 { 25664 *fnamep = s; 25665 *fnamelen = (int)STRLEN(s); 25666 vim_free(*bufp); 25667 *bufp = s; 25668 didit = TRUE; 25669 } 25670 } 25671 vim_free(sub); 25672 vim_free(str); 25673 } 25674 vim_free(pat); 25675 } 25676 } 25677 /* after using ":s", repeat all the modifiers */ 25678 if (didit) 25679 goto repeat; 25680 } 25681 } 25682 25683 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S') 25684 { 25685 p = vim_strsave_shellescape(*fnamep, FALSE, FALSE); 25686 if (p == NULL) 25687 return -1; 25688 vim_free(*bufp); 25689 *bufp = *fnamep = p; 25690 *fnamelen = (int)STRLEN(p); 25691 *usedlen += 2; 25692 } 25693 25694 return valid; 25695 } 25696 25697 /* 25698 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 25699 * "flags" can be "g" to do a global substitute. 25700 * Returns an allocated string, NULL for error. 25701 */ 25702 char_u * 25703 do_string_sub(str, pat, sub, flags) 25704 char_u *str; 25705 char_u *pat; 25706 char_u *sub; 25707 char_u *flags; 25708 { 25709 int sublen; 25710 regmatch_T regmatch; 25711 int i; 25712 int do_all; 25713 char_u *tail; 25714 char_u *end; 25715 garray_T ga; 25716 char_u *ret; 25717 char_u *save_cpo; 25718 char_u *zero_width = NULL; 25719 25720 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 25721 save_cpo = p_cpo; 25722 p_cpo = empty_option; 25723 25724 ga_init2(&ga, 1, 200); 25725 25726 do_all = (flags[0] == 'g'); 25727 25728 regmatch.rm_ic = p_ic; 25729 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 25730 if (regmatch.regprog != NULL) 25731 { 25732 tail = str; 25733 end = str + STRLEN(str); 25734 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 25735 { 25736 /* Skip empty match except for first match. */ 25737 if (regmatch.startp[0] == regmatch.endp[0]) 25738 { 25739 if (zero_width == regmatch.startp[0]) 25740 { 25741 /* avoid getting stuck on a match with an empty string */ 25742 i = MB_PTR2LEN(tail); 25743 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, 25744 (size_t)i); 25745 ga.ga_len += i; 25746 tail += i; 25747 continue; 25748 } 25749 zero_width = regmatch.startp[0]; 25750 } 25751 25752 /* 25753 * Get some space for a temporary buffer to do the substitution 25754 * into. It will contain: 25755 * - The text up to where the match is. 25756 * - The substituted text. 25757 * - The text after the match. 25758 */ 25759 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 25760 if (ga_grow(&ga, (int)((end - tail) + sublen - 25761 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 25762 { 25763 ga_clear(&ga); 25764 break; 25765 } 25766 25767 /* copy the text up to where the match is */ 25768 i = (int)(regmatch.startp[0] - tail); 25769 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 25770 /* add the substituted text */ 25771 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 25772 + ga.ga_len + i, TRUE, TRUE, FALSE); 25773 ga.ga_len += i + sublen - 1; 25774 tail = regmatch.endp[0]; 25775 if (*tail == NUL) 25776 break; 25777 if (!do_all) 25778 break; 25779 } 25780 25781 if (ga.ga_data != NULL) 25782 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 25783 25784 vim_regfree(regmatch.regprog); 25785 } 25786 25787 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 25788 ga_clear(&ga); 25789 if (p_cpo == empty_option) 25790 p_cpo = save_cpo; 25791 else 25792 /* Darn, evaluating {sub} expression changed the value. */ 25793 free_string_option(save_cpo); 25794 25795 return ret; 25796 } 25797 25798 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 25799